PDA

View Full Version : Serial interface with RFID reader



brid0030
- 16th January 2007, 01:34
Dear Helpful People:

I am trying to interface a PIC16F874A with an ID2 RFID reader (Mannings RFID; http://www.rfidshop.com), and am having no luck. The RD2 outputs a "start of text" code ($02) followed by 10 ASCII characters (an identification code) then a carriage return and a line feed. As a first step in a more in depth project, I want to read in those ten ascii characters and send them to a PC via another rs232 line. I have gotten all the components to work, but the whole thing won't come together.

I can send and recieve data from the PIC to a PC, and when I hook the ID2 up directly to the computer, I can read in the 10 character codes no problem at 9600 baud. So why can't the PIC read the codes in as well??

Here is some code I would like to use:

Include "modedefs.bas" ' Include serial modes
DEFINE OSC 20

SO VAR portb.0 ' Define serial out pin
SI VAR portb.1 ' Define serial in pin
RI VAR portb.3 ' serial in from reader
RR VAR portb.2 ' reader reset
B0 VAR byte 'byte variable
tag VAR BYTE[10] ' Creates a byte array of 10 bytes

HIGH RR 'reset Reader

loop: Serin SI,N9600,B0 ' B0 = input character
PAUSE 1500 'wait a sec
Serout SO,N9600,["ready", $0A, $0D] 'Send ready
SERIN2 RI, N9600,[WAIT($02),STR tag\10] 'get tag code
SEROUT SO,N9600,["got the code", $0A, $0D] 'acknowledge reciept
print: Serout SO,N9600,[tag,$0A, $0D] 'send code
Serout SO,N9600,[" done", $0A, $0D] 'send done
Goto loop 'do it again

I just can't get past the serin from the reader. I have tried T9600, and I've tried adding a pullup resistor to the line between the ID2 output and PIN B3. Also, I know that the reader is working because it has an LED indicator.

brid0030
- 17th January 2007, 17:41
OK. I have sort of solved my own problem. The following code works:

Include "modedefs.bas" ' Include serial modes
DEFINE OSC 20

SO var portb.0 ' Define serial out pin
SI var portb.1 ' Define serial in pin
RI VAR portb.3 ' serial in from reader
RR VAR portb.2 ' reader reset
B0 var byte 'byte variable
B1 var byte 'byte variable
B2 var byte 'byte variable
B3 var byte 'byte variable
B4 var byte 'byte variable
B5 var byte 'byte variable
B6 var byte 'byte variable
B7 var byte 'byte variable
B8 var byte 'byte variable
B9 var byte 'byte variable
B10 var byte 'byte variable

HIGH RR 'reset Reader

loop: Serin SI,N9600,B0 ' B0 = input character
PAUSE 1500 'wait a sec
Serout SO,N9600,["ready "] 'Send ready
SERIn RI, N9600,B0 'useless input
SERIn RI, N9600,B0 'useless input
SERIn RI, N9600,B1 '1st real data
SERIn RI, N9600,B2 '2nd character
SERIn RI, N9600,B3
SERIn RI, N9600,B4
SERIn RI, N9600,B5
SERIn RI, N9600,B6
SERIn RI, N9600,B7
SERIn RI, N9600,B8
SERIn RI, N9600,B9
SERIn RI, N9600,B10 'last character
SEROUT SO,N9600,["got the code: "]
print: Serout SO,N9600,[B1] 'output 1st character
Serout SO,N9600,[B2] 'output 2nd character
Serout SO,N9600,[B3]
Serout SO,N9600,[B4]
Serout SO,N9600,[B5]
Serout SO,N9600,[B6]
Serout SO,N9600,[B7]
Serout SO,N9600,[B8]
Serout SO,N9600,[B9]
Serout SO,N9600,[B10] 'output last character
Serout SO,N9600,[" done"]
Goto loop

The first two characters from the RFID reader are junk, so they are read in and then disregarded. the following 10 characters are the ones I want. As you more experienced PICers will note, the code above is not a very elegant program. Surely there is a way to do this without 11 byte variables. Here's a program that uses arrays that does not work:

' SERIN & SEROUT Commands
'
' Upper case serial filter.

Include "modedefs.bas" ' Include serial modes
DEFINE OSC 20
Define HSER_

SO var portb.0 ' Define serial out pin
SI var portb.1 ' Define serial in pin
RI VAR portb.3 ' serial in from reader
RR VAR portb.2 ' reader reset
B0 var byte 'byte variable
tag var BYTE[10] ' Creates a byte array of 10 bytes

HIGH RR 'reset Reader

loop: Serin SI,N9600,B0 ' B0 = input character
PAUSE 1500 'wait a sec
Serout SO,N9600,["ready "] 'Send ready
SERIN2 RI, N9600,[skip 2, STR tag\10]
SEROUT SO,N9600,["got the code: "]
print: Serout2 SO,N9600,[STR tag]
Serout SO,N9600,[" done"]
Goto loop

This program just seems to skip the SERIN2 line altogether and just outputs "ready got the code: done" all at once. Anybody have any ideas about what I am doing wrong?.

skimask
- 17th January 2007, 17:50
loop: Serin SI,N9600,B0 ' B0 = input character
PAUSE 1500 'wait a sec
Serout SO,N9600,["ready "] 'Send ready
SERIN2 RI, N9600,[skip 2, STR tag\10]
SEROUT SO,N9600,["got the code: "]
print: Serout2 SO,N9600,[STR tag]
Serout SO,N9600,[" done"]
Goto loop

This program just seems to skip the SERIN2 line altogether and just outputs "ready got the code: done" all at once. Anybody have any ideas about what I am doing wrong?.

Re-read page 132-136 of the PBP manual on the proper use of the SERIN2 statement, then you'll be good to go...

brid0030
- 17th January 2007, 19:47
I've been pouring over those pages trying to figure out what is wrong. Do you see my mistake, skimask?

skimask
- 17th January 2007, 20:19
I've been pouring over those pages trying to figure out what is wrong. Do you see my mistake, skimask?

Yes, place your SERIN2 statement over the one's in the book on pg's 132-136 and tell me what's wrong? Plain as day...piece of cake...

brid0030
- 17th January 2007, 23:57
My serin2 statement differs from the examples in the book in many ways. And I don't know which differences are important. I've tried lots of variations, and the error is not "plain as day" to me. Can I just get an answer? I promise I have not come the forum as a first resort.

skimask
- 18th January 2007, 00:42
My serin2 statement differs from the examples in the book in many ways. And I don't know which differences are important. I've tried lots of variations, and the error is not "plain as day" to me. Can I just get an answer? I promise I have not come the forum as a first resort.

My point exactly: You're serin2 statement differs from the examples in the book in many ways.

Does that tell you anything? Such as that if it differs, it probably won't work right.

Try to make your serin2 statement look like something in the book. Compare the SERIN with the SERIN2 statement. What's different about the two? Specifically, the 3rd paragraph of Page 132 and the 2nd paragraph of Page 130.
It's just that easy! Really it is.

You could 'just get an answer', but you're not going to learn anything about learning anything.

brid0030
- 23rd January 2007, 00:34
The following code works. Serin2 modes differ from serin modes, and I think the variables for serin and serout ports have to have numbers.

DEFINE OSC 20

S0 var portb.0 ' Define serial out pin
S1 var portb.1 ' Define serial in pin
RDR1 VAR portb.3 ' serial in from reader
RST1 VAR portb.2 ' reader reset
B0 var byte 'byte variable
tag var BYTE[10] ' Creates a byte array of 10 bytes

HIGH RST1 'reset Reader

loop: Serin S1,6,B0 ' B0 = input character
PAUSE 1500 'wait a sec
Serout S0,6,["ready "] 'Send ready
SERIn2 RDR1, 16468,[skip 2, STR tag\10] 'read in tag ID
SEROUT S0,6,["got the code: "] 'acknowledge
print: Serout2 S0,16468,[STR tag] 'send out tag ID
Serout S0,6,[" done"] 'print done
Goto loop 'do it again

skimask
- 23rd January 2007, 07:23
The following code works. Serin2 modes differ from serin modes, and I think the variables for serin and serout ports have to have numbers.

Good game....That's what I was getting at the whole time.

SERIN/SEROUT; use modes (t2400, n9600, etc)

SERIN2/SEROUT2; you have to figure out the 'mode number' depending on what you want to do according to the manual (or towards the back somewhere there's a table with a lot of values already in it). But one of the advantages of the SERIN2/SEROUT2 over regular SERIN/SEROUT is that you can set it up to run at 4,578 baud if you want (I don't know if that works out in the math, but I think you get my point), that and the big one is the much better string/variable handling options.