import machine import pn532_i2c import digitalio import time import network, ujson, socket, utime last_uid = None PORT = 80 HOST="" PATH="" def connect_wifi(): SSID=""; PASS="" # connect Wi-Fi sta = network.WLAN(network.STA_IF) sta.active(True) sta.connect(SSID, PASS) while not sta.isconnected(): print("Connecting to Wi-Fi...") utime.sleep(1) def setup_pn532(): global last_uid i2c = machine.I2C(0,scl=machine.Pin(7), sda=machine.Pin(6)) devices = i2c.scan() if len(devices) == 0: print("No i2c device !") else: print('i2c devices found:', len(devices)) for device in devices: print("Decimal address: ", device, " | Hex address: ", hex(device)) pn532 = pn532_i2c.PN532_I2C(i2c, debug=False) ic, ver, rev, support = pn532.get_firmware_version() print("Found PN532 with firmware version: {0}.{1}".format(ver, rev)) pn532.SAM_configuration() # Loop and look for RFID tags every second. while True: time.sleep(1) uid = pn532.read_passive_target() print("Read UID:", uid) if uid == None: last_uid = None # reset last_uid continue if uid == last_uid: continue last_uid = uid # Can read the actual value here. data = read_data(pn532) encoded_string = retrieve_ndef_string(data) send_http_request(encoded_string) print("Sent HTTP request for album:", encoded_string) def read_data(pn532): # This will read whatever it can from the tag, starting at page 4 start_page = 4 data = bytearray() uid = pn532.ntag2xx_read_block(0) count = 0 while True: page_data = pn532.ntag2xx_read_block(start_page + count) # print(page_data) if not page_data or page_data == bytearray(b'\x00\x00\x00\x00'): print("Failed to read page", start_page + count) break data.extend(page_data) count += 1 return data def retrieve_ndef_string(arrays): user_data = arrays # DEBUG print_hex_blocks([user_data]) # Read tlv blocks offset = 0 tlvs = [] tlv_start = user_data[offset] # print(tlv_start) while offset < len(user_data)-1: if tlv_start in [0x01, 0x03]: # lock tlv, ndef tlv tlv_len = user_data[offset+1] tlvs.append(user_data[offset:offset+tlv_len+2]) # 2: type and len offset += tlv_len + 2 for i, tlv in enumerate(tlvs): # print("Handling TLV", i) if not tlv[0] == 0x03: # not NDEF print(f"{i}: Not an ndef message.") continue ndef = tlv[2:] # Assuming the short record bit is set and the type name format is 001 # If the SR bit is set, the payload length is expressed in one byte. metadata = ndef[0] record_type_len = ndef[1] payload_len = ndef[2] record_type = ndef[3] # assuming it's "T", or 0x54, for text type if not record_type == 0x54: print("Not a text type record.") continue language_code_len = ndef[4] # assuming it's 2, because 'en' (english) if not language_code_len == 0x02: print("Record language has unexpected length.") continue language = ndef[5:7] if not language.decode("utf-8") == 'en': print("Record is not in English.", str(language)) continue # Assume utf-8 byte-encoding and convert bytearray to string. text = ndef[7:].decode("utf-8") return text def print_hex_blocks(data): for i, block in enumerate(data): hex_str = ' '.join(['{:02X}'.format(byte) for byte in block]) print(f"{i:2}: {hex_str}") def send_http_request(album): # prepare request data = ujson.dumps({"album": album}) req = ( f"POST {PATH} HTTP/1.1\r\n" f"Host: {HOST}\r\n" "Content-Type: application/json\r\n" f"Content-Length: {len(data)}\r\n" "Connection: close\r\n\r\n" f"{data}" ) # send addr = socket.getaddrinfo(HOST, PORT)[0][-1] s = socket.socket() s.connect(addr) s.send(req.encode()) # read and print response resp = s.recv(1024) print(resp.decode()) s.close() connect_wifi() setup_pn532()