RFID reader troubles
First, I apologize for not being able to get the below code to format correctly on the forum.
I've spent the morning trying to get the 28440 RFID reader working in Spin attached to a WX board. The code below will occasionally return the same distinct codes for 3 different rfid tags. Occasionally it will return 7255255255255 not sure what the significance of that number is.
Once it has returned one value, the rfid reader will not exit the idle state (led stays green) even though I believe the code should loop and send a new read command.
I haven't coded in Spin in a long time. I'm sure I could be making fundamental logic mistakes,1. but I can't figure out what.
Joel
CON
_clkmode = xtal1
_xinfreq = 5_000_000
RFID_Read = $01 ' Read data from specified address, valid locations 1 to 33 (5)
RFID_Write = $02 ' Write data to specified address, valid locations 3 to 31 (1)
RFID_Login = $03 ' Login to tag with password (1)
RFID_SetPass = $04 ' Change tag's password from old to new (1)
RFID_Protect = $05 ' Enable/disable password protection (1)
RFID_Reset = $06 ' Reset tag (1)
RFID_ReadLegacy = $0F ' Read unique ID from EM4102 read-only tag (for backwards compatibility with Parallax RFID Card Reader, #28140 and #28340) (12)
' Memory map/address locations for EM4x50 tag
' Each address holds/returns a 32-bit (4 byte) value
ADDR_Password = 0 ' Password (not readable)
ADDR_Protect = 1 ' Protection Word
ADDR_Control = 2 ' Control Word
' ADDR 3-31 are User EEPROM area
ADDR_Serial = 32 ' Device Serial Number
ADDR_DeviceID = 33 ' Device Identification
' Status/error return codes
ERR_OK = $01 ' No errors
ERR_LIW = $02 ' Did not find a listen window
ERR_NAK = $03 ' Received a NAK, could be invalid command
ERR_NAK_OLDPW = $04 ' Received a NAK sending old password (RFID_SetPass), could be incorrect password
ERR_NAK_NEWPW = $05 ' Received a NAK sending new password (RFID_SetPass)
ERR_LIW_NEWPW = $06 ' Did not find a listen window after setting new password (RFID_SetPass)
ERR_PARITY = $07 ' Parity error when reading data
obj
IO : "FullDuplexSerial"
Term : "Parallax Serial Terminal"
Var
byte ErrorCode
byte SerialNumber[4]
long mainindex
long index1
long index2
long index3
long running
long ValidCard
Pub Main
IO.start( 1, 0, 0, 9600 )
waitcnt(10_000_000 + cnt) 'Pause so I can enable Serial Terminal
StartTerminal
ValidCard:=0
repeat mainindex from 0 to 2000 'Main loop to scan for RFID cards
ReadCard
if ValidCard == 1 'If a valid card is read print to terminal
PrintSerialNumber
waitcnt(1000)
Pub StartTerminal
Term.start (9600)
Term.Str(string("Waiting for Card Serial Number"))
Pub ReadCard
IO.str( string( "!RW", RFID_Read, ADDR_Serial ) )
waitcnt(100)
ErrorCode := IO.rxCheck
if ErrorCode:= ERR_OK
repeat index2 from 0 to 3
SerialNumber[index2] := IO.rxCheck
ValidCard := 1
else
ValidCard := 0
Pub PrintSerialNumber
term.clear
repeat index3 from 0 to 3
term.hex(SerialNumber[index3],2)
term.newline
ModEdit: code formatting
Comments
I do see one mistake. In Pub ReadCard I believe "if ErrorCode := ERR_OK" should have the == operator not the := assignment operator.
Also in that same pub ReadCard , make sure the indentation is correct for the ValidCard := 1 line.
I think I've narrowed my trouble down to serial comm errors. I ran the simple program below.
On several runs, it returns 255 and then the error code and 4 byte tag serial number. I'm assuming the 255 is full duplex serial returning a2s compliment -1 saying the buffer is empty. On most runs though, the serial communication seems to be corrupted. I had two 2K resistors between the reader and the propeller pins since the reader is 5V. I ordered some level translator BOBs to see if that doesn't solve the problem.
VonSzarvas, thanks for the feedback, I will go back and check my indention as well.
CON _clkmode = xtal1 _xinfreq = 5_000_000 RFID_Read = $01 ' Read data from specified address, valid locations 1 to 33 (5) RFID_Write = $02 ' Write data to specified address, valid locations 3 to 31 (1) RFID_Login = $03 ' Login to tag with password (1) RFID_SetPass = $04 ' Change tag's password from old to new (1) RFID_Protect = $05 ' Enable/disable password protection (1) RFID_Reset = $06 ' Reset tag (1) RFID_ReadLegacy = $0F ' Read unique ID from EM4102 read-only tag (for backwards compatibility with Parallax RFID Card Reader, #28140 and #28340) (12) ' Memory map/address locations for EM4x50 tag ' Each address holds/returns a 32-bit (4 byte) value ADDR_Password = 0 ' Password (not readable) ADDR_Protect = 1 ' Protection Word ADDR_Control = 2 ' Control Word ' ADDR 3-31 are User EEPROM area ADDR_Serial = 32 ' Device Serial Number ADDR_DeviceID = 33 ' Device Identification ' Status/error return codes ERR_OK = $01 ' No errors ERR_LIW = $02 ' Did not find a listen window ERR_NAK = $03 ' Received a NAK, could be invalid command ERR_NAK_OLDPW = $04 ' Received a NAK sending old password (RFID_SetPass), could be incorrect password ERR_NAK_NEWPW = $05 ' Received a NAK sending new password (RFID_SetPass) ERR_LIW_NEWPW = $06 ' Did not find a listen window after setting new password (RFID_SetPass) ERR_PARITY = $07 ' Parity error when reading data obj IO : "FullDuplexSerial" Term : "Parallax Serial Terminal" var long index long running byte serialreceived Pub Main Term.start (9600) Term.clear Term.Str(string("Sending Read Command")) Term.newline IO.start( 1, 0, 0, 9600 ) repeat index from 0 to 3 waitcnt(10_000 + cnt) IO.str( string( "!RW", RFID_Read, ADDR_Serial ) ) repeat index from 0 to 200 waitcnt(100_000 +cnt) serialreceived := io.rxCheck term.dec(serialreceived) term.newline Term.Str(string("new loop"))
Do I need to use cognew when I start the fullduplexserial? Playing around with the code it almost seems like the PST and the fullduplexserial are interferring with each other?
I think I solved the problem. I had a WiFi module in the socket on the WX board. There was no wire to SEL. When I removed the WiFi module the code and PST began working as expected.
The below spin code will now very reliably read tags for 20 seconds. I guess this was a lesson to not leave a device with inputs floating in a system. It was really hard for me to find.
CON _clkmode = xtal1 _xinfreq = 5_000_000 RFID_Read = $01 ' Read data from specified address, valid locations 1 to 33 (5) RFID_Write = $02 ' Write data to specified address, valid locations 3 to 31 (1) RFID_Login = $03 ' Login to tag with password (1) RFID_SetPass = $04 ' Change tag's password from old to new (1) RFID_Protect = $05 ' Enable/disable password protection (1) RFID_Reset = $06 ' Reset tag (1) RFID_ReadLegacy = $0F ' Read unique ID from EM4102 read-only tag (for backwards compatibility with Parallax RFID Card Reader, #28140 and #28340) (12) ' Memory map/address locations for EM4x50 tag ' Each address holds/returns a 32-bit (4 byte) value ADDR_Password = 0 ' Password (not readable) ADDR_Protect = 1 ' Protection Word ADDR_Control = 2 ' Control Word ' ADDR 3-31 are User EEPROM area ADDR_Serial = 32 ' Device Serial Number ADDR_DeviceID = 33 ' Device Identification ' Status/error return codes ERR_OK = $01 ' No errors ERR_LIW = $02 ' Did not find a listen window ERR_NAK = $03 ' Received a NAK, could be invalid command ERR_NAK_OLDPW = $04 ' Received a NAK sending old password (RFID_SetPass), could be incorrect password ERR_NAK_NEWPW = $05 ' Received a NAK sending new password (RFID_SetPass) ERR_LIW_NEWPW = $06 ' Did not find a listen window after setting new password (RFID_SetPass) ERR_PARITY = $07 ' Parity error when reading data obj IO : "FullDuplexSerial" Term : "Parallax Serial Terminal" var long mainindex long index1 long index2 long index3 long running byte serialreceived[200] Pub Main Term.start (9600) IO.start( 3, 2, 0, 9600 ) waitcnt(100_000 + cnt) repeat mainindex from 0 to 10 Term.clear Term.Str(string("Sending Read Command")) Term.newline IO.str( string( "!RW", RFID_Read, ADDR_Serial ) ) waitcnt(1000_000 + cnt) repeat index1 from 0 to 199 serialreceived[0] := io.rxCheck if serialreceived[0] <> %11111111 quit waitcnt(100_000 + cnt) repeat index2 from 1 to 4 serialreceived[index2] := io.rxCheck if serialreceived[0] == 1 term.STR(string("Tag serial number: ")) repeat index3 from 1 to 4 term.dec(serialreceived[index3]) else term.STR(string("No Tag Found")) waitcnt(10_000_000 + cnt) term.newline term.STR(string("done"))