RFID Code help

cbounds

New Member
I have built a project with a sparkfun ID-12 RFID reader and a vibration motor. I was able to get the RFID reader to read RFID cards properly with the following code:

'This program Reads RFID cards and displays the 10 digit HEX number in the terminal
Pause 2000
SetFreq M8
SerTxd( "Starting", CR, LF )
Do
Serin 2, N9600_8, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9
SerTxd( "Tag = ",#b0, " ", b1, " ", b2, " ", b3, " ", b4, " " )
SerTxd( b5, " ", b6, " ", b7, " ", b8, " ", b9, CR, LF )
Loop

The card are read properly in the terminal as:
Starting
Tag = 2 5 0 0 0 8 F F 1 A


I have 5 RFID cards. What I would like to happen is have the vibration motor buzz one time for RFID card tag #1, 2 buzzez for RFID card tag #2... etc.

I know how to make the buzzer go high and low. That is not the issue. I just do not know how to code my "if then statement" to take the output of the rfid reader and get the result I want. I have only been working with picaxe a month or so and probably know this is basic but I just need some guidance if anyone could help.

Thank You
 

KeithRB

Senior Member
If they only vary in the last 4 bytes, then you could do something like this:
wx = b9+16*b8+256*b7+512 *b6

select w1
case 0xFF1A
gosub buzz1

case 0xFF1B
gosub buzz2

...

Else
gosub Whoops
Endselect
 

SAborn

Senior Member
Can you read each card and give us the tag numbers, as this will make it easy to help code the function, it will also help to assemble a simpler example using If/then that you might understand.
 

cbounds

New Member
tag 1 : Tag = 2 2 5 0 0 5 E B E 0
tag 2 : Tag = 2 2 5 0 0 5 F 1 3 C
tag 3 : Tag = 2 2 5 0 0 5 E A 6 8
tag 4 : Tag = 2 2 5 0 0 5 E A 0 D
tag 5 : Tag = 2 5 0 0 0 8 F A C 7

Thanks for any help!
 

KeithRB

Senior Member
Is my post visible?
Since the are all different in the last 4 nibbles, you can create a 32 bit word with them and then use select/case. That way it will be easy to add new tags.
(I think shift would be better than the multiply I used in my other post - it would be much quicker, assuming that the PicAxe is not smart enough to change multiply-by-powers-of-2 into shifts.)
 

cbounds

New Member
Thanks KeithRB... I was just putting the tags on the post because SAborn was going to show how to use IF/Then statements. Your method will work Im sure and Im going to test tonight. Much appreciated!
 

hippy

Technical Support
Staff member
Since the are all different in the last 4 nibbles, you can create a 32 bit word with them and then use select/case.
Presumably you meant 16-bit, so easy to handle as you suggest in word variables. And not too hard to match with two byte pairs from EEPROM or TABLE.
 

KeithRB

Senior Member
Thanks for the correction, yes, 16 bit. But I think the TABLE is overkill, since you can just hard code it in the select.
One other point: I believe that your hex data is ascii, not, well, hex, so you would need to convert the numbers to hex in order to use the 16bit trick.
 

cbounds

New Member
Something like this?

main:
Pause 2000
SetFreq M8
SerTxd( "Starting", CR, LF )
Serin 2, N9600_8, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9
SerTxd( "Tag = ",#b0, " ", b1, " ", b2, " ", b3, " ", b4, " " )
SerTxd( b5, " ", b6, " ", b7, " ", b8, " ", b9, CR, LF )
w1 = b9+16*b8+256*b7+512 *b6

select w1
case 0xEBE0
gosub buzz1
goto main

case 0xF13C
gosub buzz2
goto main

Else
gosub Whoops
goto main
Endselect

buzz1:
high 0
pause 50
low 0
pause 50
return

buzz2:
high 0
pause 50
low 0
pause 50
high 0
pause 50
low 0
pause 50
return

whoops:
high 0
pause 50
low 0
pause 50
high 0
pause 50
low 0
pause 50
return
 

KeithRB

Senior Member
Yes, but I would move the "goto main" out of the select/case loop - it is not needed, the control will jump past endselect as soon as you handle a case - and you need to convert the Ascii Hex digits to binary.
 

AllyCat

Senior Member
w1 = b9+16*b8+256*b7+512 *b6
Hi,

I don't think that takes into account the (lack of) operator precedence in PICaxe basic. I believe it should be:

w1 = b6 * 16 + b7 * 16 + b8 * 16 + b9

IMHO it's simpler just to use a basic IF construct (which the PE will convert Select .. Case to anyway):

Code:
main:
    IF w1 = $EBE0 then buzz1
    IF w1 = $F13C then buzz2
    ..
whoops:
    ...
    GOTO main
buzz1:
    ...
    GOTO main
etc..
Personally, I use something like b9 = b9 / "A" * 249 + b9 - "0" to convert from ASCII Hex to binary, but there may be more elegant methods (Note: 249 represents -7, the gap between 9 and A).

Cheers, Alan.
 

cbounds

New Member
Ca you give me an example of how to construct the code after:
main:
Pause 2000
SetFreq M8
SerTxd( "Starting", CR, LF )
Serin 2, N9600_8, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9
SerTxd( "Tag = ",#b0, " ", b1, " ", b2, " ", b3, " ", b4, " " )
SerTxd( b5, " ", b6, " ", b7, " ", b8, " ", b9, CR, LF )

I got a little confused with the
w1 = b6 * 16 + b7 * 16 + b8 * 16 + b9 and then the hex conversion....
 

AllyCat

Senior Member
Hi,

Yes, there are several quite difficult concepts for a beginner, all mixed up together. Firstly, the RFID device is not sending "numbers" but "ASCII characters". So perhaps start with a form which is (hopefully) more understandable (note that the quotation marks " are important):

IF b6 = "E" AND b7 = "B" AND b8 = "E" AND b9 = "0" THEN GOTO buzz1

See if you can write some code using that format. The IF structure just replaces each CASE element. Some programmers may frown on all the GOTOs, but it's probably easiest to understand and is quite close to how the microcontroler actually works.

However, you may appreciate that the above would become rather inefficient with lots of keycodes, hence the suggestion of working with numbers rather than character codes. See if you can understand what the following code is doing (particularly the #), probably by using the simulator:

Code:
for b1 = 48 to 70
sertxd(#b1," ",b1,cr,lf)
next
As far as the PICaxe mathematical precedence is concerned, see the User Manual and try short formulae in the simulator, for example modify the above code as follows, and then try adding more elements onto the equation for b2.

Code:
for b1 = 48 to 70
b2 = b1 / "A"
sertxd(#b1," ",b1," ",#b2,cr,lf)
next
Cheers, Alan.
 

tony_g

Senior Member
Code:
#picaxe 08m2

eeprom  0,("225005EBE0")    'tag 1
eeprom 10,("225005F13C")    'tag 2
eeprom 20,("225005EA68")    'tag 3
eeprom 30,("225005EA0D")    'tag 4
eeprom 40,("250008FAC7")    'tag 5

SYMBOL tagNum = B14  ' from EEPROM table
SYMBOL pntr = B15    ' pointer to char in table
SYMBOL char = B16    ' character from table

setfreq m8

main:
if pinc.3 = 1 then incoming
goto main

incoming:
serin c.4,N9600_8,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9
goto verify

verify:
FOR tagnum = 0 TO 4                      ' scan through known tags saved in EEPROM
pntr = tagNum * 14 + 0 : READ pntr, char ' Read char from EEPROM
IF char <> b0 THEN Bad_Char              ' Compare tag data with char from EEPROM one at a time
pntr = tagNum * 10 + 1 : READ pntr, char
IF char <> b1 THEN Bad_Char
pntr = tagNum * 10 + 2 : READ pntr, char
IF char <> b2 THEn Bad_Char
pntr = tagNum * 10 + 3 : READ pntr, char
IF char <> b3 THEn Bad_Char
pntr = tagNum * 10 + 4 : READ pntr, char
IF char <> b4 THEN Bad_Char
pntr = tagNum * 10 + 5 : READ pntr, char
IF char <> b5 THEN Bad_Char
pntr = tagNum * 10 + 6 : READ pntr, char
IF char <> b6 THEN Bad_Char
pntr = tagNum * 10 + 7 : READ pntr, char
IF char <> b7 THEN Bad_Char
pntr = tagNum * 10 + 8 : READ pntr, char
IF char <> b8 THEN Bad_Char
pntr = tagNum * 10 + 9 : READ pntr, char
IF char <> b9 THEN Bad_Char

GOTO Tag_Found                            ' all characters matched EEPROM Data, valid tag found

Bad_Char: 
NEXT

Bad_Tag:
for b17 =1 to 2
high c.0
pause 2000
low c.0
pause 2000
next b17
goto main

Tag_Found:
for b18 =1 to 2
high c.1
pause 1000
low c.1
pause 1000
next b18
goto tagid

tagid:
pause 1000

if tagNum=0 then 
high c.1
pause 1000
low c.1
end if

if tagNum=1 then 
high c.1
pause 1000
low c.1
pause 500
high c.1
pause 1000
low c.1
end if

if tagNum=2 then 
high c.1
pause 1000
low c.1
pause 500
high c.1
pause 1000
low c.1
end if

if tagNum=3 then 
high c.1
pause 1000
low c.1
pause 500
high c.1
pause 1000
low c.1
pause 500
high c.1
pause 1000
low c.1
end if

if tagNum=4 then 
high c.1
pause 1000
low c.1
pause 500
high c.1
pause 1000
low c.1
pause 500
high c.1
pause 1000
low c.1
pause 500
high c.1
pause 1000
low c.1
end if

goto main
altered version of what i used for my cheap ebay rfid reader, you may have to tweek setfreq if at first it reads gobbledegook but it works for me, i had 3 cards and used a red and green led on a couple of outputs to signal a good or bad card and a relay switched for varying periods with each of the cards.
 
Top