PDA

View Full Version : Reading in Biphase - I thought this would be easy



brid0030
- 27th September 2010, 19:51
Long ago I made a simple PIC based RFID reader that used an atmel u2270b front end for the RFID communication. This device works quite well for EM4001 RFID tags which produce a manchester output stream (code posted long ago). I am now trying to adapt it to work with a different type of RFID tag (ISO 11784/5). I started by making the necessary hardware adjustments and then visualizing the input from the tag using the logic analyzer on my PICKIT2. I got nice clean biphase input, which is just what I hoped for. Looks like this:http://www.animalmigration.org/RFID/TAG.jpg

Now all I had to do was read in this code in a manner similar to that of the previous tags. There are two important differences between the old working code and the new situation: 1) the data rate is now twice as fast; each bit transmission last about 240uS. The published data rate is 4106 bits/s. 2) the output is biphase, wherein each bit begins and ends with a transition, and 1s and 0s are determined by whether there is a transition in the middle of the bit (a transition = 0 and no transition = 1). Like this:

__---__---____------__---____--__------__---
0 0 1 1 0 1 0 1 0

First I tried reading in some pulse widths using PULSIN, and I got reasonable results. And that's when things stopped working.

To actually read in the biphase code, first I tried some code based on an example in this forum:


' Hardware definitions
LineIn var portB.0 'or whatever moves you


' Software definitions
A var byte
B var byte
C var byte
Msg var byte[8] ' up to 64 bits of timecode data
Valu var bit ' data bit from the biPhase data stream
Width var byte ' the number of 20 uSec chunks in the bit period
' 2400 bps is approx 416 uSecs per bit
' a ZERO should return a count of approx 20
' a ONE should yield a count of approx 10
Pattern var word ' this must match the SYNC pattern to start

'************************* Initialise block *************************
FlashLEDs: ' show em we are alive, etc
PickNose: ' etc
ScratchBum: ' etc

goto start 'jump subroutines at startup

'************************* Subroutines ****************************
FindBit:
' This extracts the 0 or 1 data bits from the incoming data stream
width = 0
FindEdge:
a = linein
pauseus 20
width = width + 1
if width > 14 then foundzero ' can't be a ONE - must be a ZERO.
' important that we exit early so we have approx 100 uSecs for
' other tasks before the next data transition. Allow for jitter
' and don't make the width comparison too tight
if linein = a then findedge
' sample a second time - repeat if no change
FoundOne:
'at this point we have a transition under 15 counts so must be a ONE.
valu = 1
goto findbitdone
FoundZero:
valu = 0
FindBitDone:
return


This code times periods between transitions and uses an IF/THEN to determine if a 1 or a 0 was transmitted. My result was a repeatable but incorrect stream of code.

I have since tried many other approaches including removing the IF/THEN and using BIT1 /^ BIT2 (opposing of Exclusive OR) to generate 1s and 0s from the first and second halves of a bit transfer.

After some tinkering I tried this:


B3 = 0
FOR B1 = 0 to 34
searchloop:
X1 = RFIDIN
B3 = B3 + 1
IF RFIDIN = X1 THEN searchloop
ID[B1] = B3
B3 = 0
NEXT B1

...This stores the lengths of the pulse periods. The result looks like this:

31 10 9 22 21 66 17 4 21 21 6 4 5 10 22 14 22 21 6 4 9 6 4 5 22 15 9 22 28 4 9 11 21 11 9

I expected to see basically two appoximate values over and over (~10 and ~20) with some error around them. Instead there are lots of unexpected low and high values.

Then I tried this:


ID.0(0) = RFIDIN
ID.0(0) = RFIDIN
ID.0(1) = RFIDIN
ID.0(2) = RFIDIN
ID.0(3) = RFIDIN
ID.0(4) = RFIDIN
........
ID.0(279) = RFIDIN


...to very quickly get 1s and 0s roughly equivalent to the logic analyzer. I got this:

11111111 11111111 00000000 00000000 00000000 11110000 11111111 11111111 11111111 00001111 00000000 00000000 00000000 11111100 11111111 11111111 11111111 00000001 00000000 00000000 00000000 11111111 11111111 11111111 00111111 00000000 00000000 00000000 11100000 11111111 11111111 11111111 00001111 00000000 00000000

This is mostly what I expected, but there are a few unexpected 1s and 0s (bold print above) that I suspect are throwing things off.

I'm working with a PIC 16F688 with the OSCCON maxed out at to 8MHz (I also tried 4MHz). I know that 240us is not a lot of time to get something done, but it seems like it ought to be enough. The RFID IC works via a Schmid trigger and connects to the PIC with a 10Kohm pullup resistor (I tried 4.7K as well). I do not ever see any bounce using the logic analyzer, so I suspect there is something I'm not getting about how the PIC is reading the input pin. I welcome any questions or insights.

mackrackit
- 28th September 2010, 07:13
Can you try an external OSC? Maybe the internal is not stable enough?

brid0030
- 29th September 2010, 03:58
So I just discovered that I was displaying data incorrectly. I should have been using REV 8 to flip each byte around so the entire bit sequence would be ordered correct. I did this and found that most of my "failed" strategies to read in biphase actually work fine. I'm still not sure about the bounce apparent above, but it is not actually that big a problem. I'll post some working code so that this thread is not a complete waste of cyberspace. Sorry to all who read and were confused.