Take the 2-minute tour ×
Raspberry Pi Stack Exchange is a question and answer site for users and developers of hardware and software for Raspberry Pi. It's 100% free, no registration required.

I'm totally stumped trying to figure out how to read input to the SDA/SCL GPIO pins on the Pi.

Context: I have a Wiegand 26 RFID reader that I would like to read data from. The idea is that I get the bits from the reader, parse/interpret them as Wiegand, and from there I can do a number of things. For now, I'm only concerned with troubleshooting this part, even though my setup is part of a larger system.

References: I have been using the Pi Doorman website as a guide, and I am using his C program that consumes the WiringPi library. I followed the instructions to install the WiringPi library and I compile wiegand.c with the switches, as shown on the website.

There are two parts I know I need to debug, the circuit and the code.

The Circuit: The circuit is shown in the image/attachment below. I have a Revision 1 Pi, which I verified by writing a small program to call the method that returns the revision from including wiringpi.h. I got some help from some of the electronics folks, as this is not my wheelhouse. As you can see, the Pi Cobbler is used, and we connect the ground from the 12V power supply to the reader to one of the Pi ground pins. 5V comes out of the reader on D0 (green) and D1 (white), which we step down to 3.3V, before attaching to SDA and SCL, respectively. This is also how it is described in the comment in wiegand.c.

the circuit

The comment also notes the voltage is held high on both data lines, so I tested with a multimeter and saw that close to 3.3V was going into the Pi Cobbler pins for each line. Also, we hooked up the lines to an oscilloscope, and when I swipe the RFID card, as described, the voltage drops to 0V briefly. That gives us confidence is the circuit is accurate, but feel free to review the image and let me know if you have any pointers, especially if you've gotten this successfully working.

The Code: The wiegand.c program, seems to be written well. It's basically two threads that hold on the waitForInterrupt on each data line, indefinitely, until bits are read. A counter is triggered, which more or less tries to collect all the bits possible from a pulse.

I compiled the code per Pi Doorman instructions, and ran it. It prompts me to use standard site code, I say Y and then hit enter. When I swipe the RFID card, nothing appears.

There are some things I did to debug the code, mostly print statements. I didn't get very far, except to confirm the code should work the way it's written. Like I said above, I downloaded the source for the WiringPi library and inspected the methods to see what was happening behind the scenes, and verified I had a Revision 1 Pi with a small program to rule that out. Also, in the /sys/class/gpio/ folder on the Pi, there is gpio0 and gpio1 symlinks defined, so I think I have strong evidence I have a Revision 1 board.

I took a closer look at the wiringPiSetupSys function that is one of the first things called by wiegand.c. There's a loop in here:

for (pin = 0 ; pin < 64 ; ++pin)
{
    sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
    sysFds [pin] = open (fName, O_RDWR) ;
}

So, there's something that happens here. When I go back to wiegand.c and add some code to each thread, to print out the return value of the waitForInterrupt function, it's -2. waitForInterrupt basically pulls the value out from the file descriptor array, so the -2 is ultimately the return value from the open() call here in the setup function.

I don't know what that means, but it's probably a safe guess the open() call for read/write failed, just because it's C convention to return negative values for things like that. So if I can't open the pin for read/write, I can't read data.

I should also note: the compilation and running of wiegand.c was done under the root user, so I don't think this is a permissions issue. Additionally, I'm running wheezy debian on this Pi, in case that matters.

So, a couple of questions: - Where do I go from here, in terms of tracking down what the error means, or modifying the code to narrow this down further? - Has anyone successfully used the Raspi and this software to read data in this manner, from an RFID reader like this or something similar?

I hope I haven't left anything out, but let me know if I need to provide some additional info.

share|improve this question
    
Does the reader make a beep when it reads a card ok? Or is that upto us to make happen? I have same reader I'm trying to connect to a piface board but it does nothing... –  user13102 Feb 25 at 23:32
    
did you get this working properly? would you be able to clarify the hand drawing? are both resistor values 100ohm? where do the d0 and d1 pins connect into this circuit? :) –  Richard Apr 21 at 12:38

2 Answers 2

First and foremost:

If I were in your shoes, I would stay away from Wiegand in general!!!

Why:

  1. Wiegand is a swipecard protocol developed in the 1980s. It does not use any form of clock signal or speed indication, the data timing is done based on the last bit that was transferred + the Wiegand delay time. This is a disadvantage but does not make it impossible to use. Besides that there are plenty different implementation and alterations on the protocol itself, this is not done because it is such a good protocol.
  2. Wiegand 26, transfers a 24 bit code + 2 parity bits, even the most cheap RFID implementation (125Khz EM4102 RFID chips) use 40 bit code in every RFID card. Your reader emulates Wiegand because 'real' readers for that stuff do not exist anymore. Meaning that it will send the FIRST 24 bits of the RFID card and will drop the remaining 26 bits. This will result in duplicate cards, because the bigger part of the data is not even transferred! This issue even even more important when you use EPC (96 bit or more), then only a fraction of the total data is transferred.
  3. Most (I guess even all!) of the modern RFID reader have Wiegand as option to be compatible with very old installations, chances are your reader will also support serial output, please do yourself a favor and use whatever else is available except Wiegand.

About the Hardware:

The only thing you can do is methodically, and very precise, check every part of your hardware first. The fact that a line gets momentarily pulled to 0V does not mean that the communication is actually working.

On a scope you should see a 'pulse train' when checking the communication wires. When no data is being sent both DATA0 and DATA1 are pulled up to the 'high' voltage level. When a 0 is sent the DATA0 wire is pulled to a low voltage while the DATA1 wire stays at a high voltage. When a 1 is sent the DATA1 wire is pulled to a low voltage while DATA0 stays at a high voltage. You should see this on a scope, on 5v before the level converters and at 3.3v after.

You should trace/monitor this signal all the way to the GPIO connected ON the RPI board, if that is constant you can say that the hardware is working stable. Be also sure you're using the correct pins and the signal looks still acceptable when it enter the RPi. Breadboard, because of the way they are built, do have some effects that are unwanted (mainly capacities), but for the average speed of Wiegand this should not influence too much I guess, but check it anyway.

After that you can start to look at the software. Those errors (-2) you talk about are an indication that something is not happy, you'll need to check those before you continue. I am sure Google or a man page can provide the answer to that. Further, when data comes in those interrupt handlers should fire (I guess around 26 times per 'swipe'), if that does not happen, data is still not coming in. But checking the code, it looks that it should be able to work, so I guess for the moment, the hardware is still not in optimal shape.

You can also see if those interrupt handlers trigger by just manually connecting and de-connecting the 3.3v to the input that you are using, if you add some printf() to the interrupt handler, something should be printed at least one time when you disconnect the 3.3v from that pin (edge and falling are used by gpio, I assume that means trigger on falling edge).

And to answer your last question, Yes, I had no problem using RFID readers on the RPi, but I avoided Wiegand from the beginning!

Hope this helps...

share|improve this answer
    
Thanks for the tips! It ended up being the hardware (weak signal) as you can see from the answer below. So, if I get a better reader, I could read all 40 bits in a similar software program? It's good to know for a future upgrade. –  emptyset Jan 29 '13 at 2:44
    
Chances are your current reader already can send you the real data (all 40 bits), because of the reasons I pointed out in point 2 and 3 under 'Why'. –  ikku Jan 29 '13 at 9:38
up vote 0 down vote accepted

So, I got some help from a fellow Freeside member on wiring the RFID reader to the Pi's GPIO. I don't completely understand the circuit, but the gist is that there wasn't enough signal reaching the Pi's GPIO with the circuit the way I had it wired. Instead, we came up with this (see below).

the circuit diagram

the implemented circuit

Then, when running the wiegand.c program again, this time we got a good signal and the program was able to decode the bit array correctly, and generate the RFID token ID!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.