Shop Learn P1 Docs P2 Docs
HID MiniProx RFID card reader help please — Parallax Forums

HID MiniProx RFID card reader help please

bte2bte2 Posts: 152
edited 2011-09-05 01:36 in Propeller 1
Hello all, I have been lurking and reading for awhile, and I am comparatively new to the Propeller. I am stuck on figuring out a suitable course of action regarding reading these 125KHz RFID passcards.

I have a HID brand MiniProx reader that outputs a protocol called Weigand, but there is a daughterboard that converts the Weigand format to a clocked-type of bitstream, and I am having difficulty figuring out how to proceed.

I need to be clear, I have been wrestling with this for quite awhile, and I absolutely am not asking anybody here to write my code for me.

I am a decent at PBasic, PIC Basic PRO, Motorola assembly, BasicX, and a couple others that escape me right now. I need a couple promotions to be considered a novice with Spin, and I am definitely wrestling with Propeller Assembly for now. I have RTFM, and I have purchased a couple Propeller books, one of which is "The Official Guide", so I have no problem doing my homework.

With that out of the way, I am trying to build a standalone controller for these cards that has a power supply, the reader, the daughterboard, and a serial LCD. The reason for the project is because the inkjet ID number wears off of the cards after awhile, and I am looking for a way to extract the ID without scanning the card at the fuel pumps, so that I can engrave them onto the cards.

There are two lines from the daughterboard that I need to decode; a clock, and a data. These two lines idle at +5 volts all day long until a card is scanned. When a card is successfully scanned, the reader beeps and begins pulsing the clock line low for approximately 300 microseconds, with a period of 2 milliseconds per bit. When the clock line pulses low, if the data line is low, that is a 0, and if the data line is high, that is a 1. From my reading, there are 26 bits that arrive from the controller- I can parse the bitstream myself, but I am having trouble setting up the propeller to be waiting for the first bit, and collecting the required number of bits.

After a successful read, the controller will output to the LCD the required information for a few seconds, then clear the screen and start over waiting for another card. I can write to the LCD with no problems, and have created an object with the LCD constants pre-declared.

I have tried "waitpeq", "waitpne", "if" and some other different attempts, but I can't get it to capture a bit, shift it into my variable, and capture the successive bits- it always hangs, and I am not good enough yet to figure out why. I plan on buying Viewport within the next few days but I am waiting on a check that hasn't arrived yet.

So there it is in a (lengthy) nutshell: wait all day for the clock to start pulsing, when it does, count off 26 bits and shift the level of the data line into a variable. It seems easy, and yet I can't figure out how to do it. The low pulses of the clock (and data when it is 0) are kind of quick, but it seems to me that a period of 2 mS is plenty of time to shift the bit in and rearm itself.

Without writing my code (unless you really want to, of course) can somebody maybe offer up some advice on a basic strategy for me? I can't express how much I would appreciate any help.

If I didn't explain it well enough, please let me know.

Thanks big.



  • bte2bte2 Posts: 152
    edited 2011-09-03 19:30
    BTW, I did search the forum and have tried to use a BS2-SX, but I had no luck.
  • Mike GreenMike Green Posts: 23,101
    edited 2011-09-03 20:15
    You could probably use a BS2sx for the signals from the daughterboard. You need to sense the high->low transition of the clock with a "DO UNTIL clockIn = 0 : LOOP", then read in the data bit (myData(i) = dataIn, where myData is a 26 bit array) and wait for the clock to go high again.

    You could also do this with a Propeller. "WAITPEQ(0,|<clockIn,0)" will wait for the I/O pin to go low. You can then read the data bit ("myData |= (ina[dataIn]<<i") and wait for the I/O pin to go high with "WAITPNE(0,|<clockIn,0)". "i" is the bit number starting at 25 and going down to 0.
  • bte2bte2 Posts: 152
    edited 2011-09-03 20:48
    Hi Mike,

    It's neat that you are in Minneapolis, I live in Maple Grove. I appreciate your prompt reply. I have tried some variation of what you suggested, to no avail. I will revisit my prior attempts and compare my code to your suggestion, to see if I got hung up on something that should be obvious (which is likely).

    Logically, I think I have been on the right track, procedurally, though...

    I will post my results after I experiment further.

    Again, thank you.

  • Mike GreenMike Green Posts: 23,101
    edited 2011-09-03 20:51
    It always helps to post your existing code and explain what happens with it when you try it. It also helps to provide schematics or at least links to datasheets for the devices you're having trouble with. Without that, we're guessing about what's wrong. In addition, we end up making general suggestions and suggestions that may or may not apply to what you're doing ... not a good use of time or energy.

  • bte2bte2 Posts: 152
    edited 2011-09-03 21:12
    I don't have any snippets right at the moment (that I wouldn't be embarrassed to post anyway), because the nice, clean, planned for code I had initially was subsequently butchered beyond anything that resembles presentable code. I have to do some tidying up and repairing my commentary before I could post it here, lest you somehow hurt yourself laughing at me (j/k). I am aware of the "code" tags on the forum, though, so I kindly ask for a little time before I do post it.


  • kwinnkwinn Posts: 8,697
    edited 2011-09-03 21:34
    The Weigand interface is pretty simple so it might be easier to interface to that. It consist of 3 wires. One wire is ground, one is the "1" signal, and the third is the "0" signal. Both signal lines are pulled high by a resistor connected to +5V. A 0 is sent by pulling the 0 line low. A 1 is sent by pulling the 1 line low. The two signal lines are not pulled low at the same time.

    If you decide to use the clock and data lines from the daughterboard you might want to download some the I2C objects from the OBEX and take a look at them. The output sounds very much like I2C.

  • bte2bte2 Posts: 152
    edited 2011-09-03 22:48
    kwinn, thanks for taking the time to respond. I initially started out trying to make the Weigand protocol work (without the daughterboard), but what I found is that bit number 1 is a parity bit, that can either be a 0 or a 1. If I wrote the code to watch for a 0 and the first bit was a 1, well, I had an even harder time getting the data from the reader lined up and framed properly. I suspect that this is why they made the daughterboard in the first place, as I have read a few different accounts and recommendations calling for this additional bit of silicon between the reader and the controller. I made a mistake in my first post; the bit time is 40uS, with a bit period of 2 mS.

    I too thought that this was a bastardization of I2C, and I spent a considerable amount of time pursuing that avenue. The problem I ran into there is a) it is quite slow for I2C, and b) the clock comes from the reader and not the propeller.

    I am sure hoping that there is a compelling reason for the manufacturer to make this so difficult, and I am inclined to think it has something to do with security- it is an access controller, after all. It would sure be nice if they would have a jumper to output an asynchronous data word for neophytes like me, or even better, true I2C.

    Thanks for replying, though, I do appreciate you taking the time.

  • stefstef Posts: 173
    edited 2011-09-05 01:36
    Hi Bte2

    I just saw your post. I’m currently doing a lot with the propeller and wiegand. They also helped me to start with it (thanks to other members of this forum). Now it is pretty simple to read wiegand with a propeller. With some resistors and some code you can read any bit stream of wiegand. I’m currently doing a project for 38 bit but I already did some in 80 Bit also.
    This is a snippet of the code to read. (complete code I can not post because it is owned by the end user)

    State := %11<< 16
    Cardnumber[0] := 0
    Cardnumber[1] := 0
    Bits := 0
    Read := ina[D0..D1]
    Cardnumber[0] <<= 1
    Cardnumber[0] |= ((cardbumber[1] & (%1<<31))>>31)
    Cardnumber[1] <<= 1
    If read == %01
    Cardnumber[1] |= %1
    Until Bits == 37

    (I typed this code by head because I do not have the spin file with me now. So don’t kill me for a fault. It gives you a hind for the way to do) I’m travelling now. If I get home I can send you the spin code exactly.

    This is the part that read’s the bitstream into two long variables. I use it also with HID readers. I also have a part of the code that generates wiegand. There are currently 50 readers running on the propeller without any problems.

    Hope this helps a bit in your search

Sign In or Register to comment.