I have setup a wiegand card reader and I am getting nothing but inconsistant results. I have tried different power supplies, different code, different arduino boards, and it usually never gives the same output unless it has been powered off for a while. Then if I do get consistant output, if I power the card reader off and on, then I get different results again.
Here is the most recent code I have been using, because it is simple:
// * Interrupt service routine gathers Wiegand pulses (zero or one) until 26 have been recieved
// * Then a sting is sent to processing
// */
int i;
String reader1[30];
volatile int reader1Count = 0;
void reader1One(void) {
reader1[reader1Count] = "1";
reader1Count++;
}
void reader1Zero(void) {
reader1[reader1Count] = "0";
reader1Count++;
}
void setup()
{
Serial.begin(57600);
// Attach pin change interrupt service routines from the Wiegand RFID readers
attachInterrupt(0, reader1Zero, FALLING);//DATA0 to pin 2
attachInterrupt(1, reader1One, FALLING); //DATA1 to pin 3
delay(10);
// the interrupt in the Atmel processor mises out the first negitave pulse as the inputs are already high,
// so this gives a pulse to each reader input line to get the interrupts working properly.
// Then clear out the reader variables.
// The readers are open collector sitting normally at a one so this is OK
for(int i = 2; i<4; i++){
pinMode(i, OUTPUT);
digitalWrite(i, HIGH); // enable internal pull up causing a one
digitalWrite(i, LOW); // disable internal pull up causing zero and thus an interrupt
pinMode(i, INPUT);
digitalWrite(i, HIGH); // enable internal pull up
}
delay(10);
// put the reader input variables to zero
for (i = 0; i < 30; i = i + 1) {
reader1[i] = 0;
}
reader1Count = 0;
//digitalWrite(13, HIGH); // show Arduino has finished initilisation
}
void loop() {
if(reader1Count >= 26){
// Serial.print(" Reader 1 ");Serial.println(reader1,HEX);
Serial.println("A");
for (i = 0; i < 26; i = i + 1) {
Serial.print(reader1[i]);
reader1[i] = 0;
}
Serial.println("");
reader1Count = 0;
}
}
Any ideas on what the problem is? Could it simply be a bad card reader?
That code gathers data from a 26 bit wiegand reader. It sounds like your reader is generating more than 26 bits. Not all wiegand output is 26 bits.
Try extending that code to just count how many bits you get per card.
The device has "26" checked of on the sticker located in the back, so I assumed it was 26 bits.
The thing that I find odd is the results are only inconsistent when its powered off and on again. That doesn't seem like a code problem or a bit length problem to me.
And inconsistent as in, it will give me the same result over and over until its powered off and back on.
That code is very poor. Once it gets out of sync there is nothing to pull it into sync again. Write it so that there is a time out if nothing has been recieved for a second. That is it will break out of the loop and start counting again.
Ok, just to be clear the original code I was using is the one from "Crazy People", and I get the exact same inconsistent results with it. The first bit of code I posted was the code I was using after many hours of troubleshooting.
The code from Crazy People has the internal pull up resistor enabled as specified in the code. Yet still inconsistent results....
Just to be sure, this is the exact reader I have, as far as I can tell it will output 26 bits.
//WG26 Card Reader
//12v Power to red
//Ground to Black
//Green to pin 2
//Yellow to pin 3
//Reads cards and does a serial print
//*Need to add verification to allow only certain cards
/* Crazy People
* By Mike Cook April 2009
* Three RFID readers outputing 26 bit Wiegand code to pins:-
* Reader A (Head) Pins 2 & 3
* Interrupt service routine gathers Wiegand pulses (zero or one) until 26 have been recieved
* Then a sting is sent to processing
*/
int validSiteCodes[] = {144, 360, 147, 318, 316};
int validSerialNumbers[] = {11779, 14740, 2985, 5605, 3411};// see if site code and serial number are in the lists...
volatile long reader1 = 0;
volatile int reader1Count = 0;
void reader1One(void) {
reader1Count++;
reader1 = reader1 << 1;
reader1 |= 1;
}
void reader1Zero(void) {
reader1Count++;
reader1 = reader1 << 1;
}
void setup()
{
Serial.begin(9600);
// Attach pin change interrupt service routines from the Wiegand RFID readers
attachInterrupt(0, reader1Zero, RISING);//DATA0 to pin 2
attachInterrupt(1, reader1One, RISING); //DATA1 to pin 3
delay(10);
// the interrupt in the Atmel processor mises out the first negitave pulse as the inputs are already high,
// so this gives a pulse to each reader input line to get the interrupts working properly.
// Then clear out the reader variables.
// The readers are open collector sitting normally at a one so this is OK
for(int i = 2; i<4; i++){
pinMode(i, OUTPUT);
digitalWrite(i, HIGH); // enable internal pull up causing a one
digitalWrite(i, LOW); // disable internal pull up causing zero and thus an interrupt
pinMode(i, INPUT);
digitalWrite(i, HIGH); // enable internal pull up
}
delay(10);
// put the reader input variables to zero
reader1 = 0;
reader1Count = 0;
//digitalWrite(8, HIGH); // show Arduino has finished initilisation
pinMode(12, OUTPUT);
}
void loop()
{
if(reader1Count >=26){
//Serial.print(" Reader 1 ");
//Serial.println(reader1,HEX);
// Serial.println("A");
//Serial.println(reader1& 0xfffffff);
int serialNumber=(reader1 >> 1) & 0x3fff;
int siteCode= (reader1 >> 17) & 0x3ff;
Serial.print(siteCode);
Serial.print(" ");
Serial.println(serialNumber);
reader1 = 0;
reader1Count = 0;
if(IsTagValid(siteCode, serialNumber)
){
digitalWrite(12,HIGH);
}
else
digitalWrite(12,LOW);
delay(200);
digitalWrite(12,LOW); // Open the door. It's cold out here!
}
}
boolean IsTagValid(int siteCode, int serialNumber)
{
boolean valid = false;
// Determine how many valid tags there are
int validTagCount = sizeof(validSiteCodes)/sizeof(int);
// Loop through the arrays to see if siteCode
// and serialNumber are present
for(int t=0; t<validTagCount; t++)
{
if(validSiteCodes[t] == siteCode &&
validSerialNumbers[t] == serialNumber)
{
valid = true;
break;
}
}
return valid;
}
just to be clear the original code I was using is the one from "Crazy People",
I wrote that.
I still think it might be going out of sync.
Get the consistant but inconsistent results and write down the code you get in binary. Then power cycle again and write down what you get again in binary. Compaire the two. Can you make them match by sliding the bit patterns to left or right? That would indicate going out of sync.
just to be clear the original code I was using is the one from "Crazy People",
I wrote that.
I still think it might be going out of sync.
Get the consistant but inconsistent results and write down the code you get in binary. Then power cycle again and write down what you get again in binary. Compaire the two. Can you make them match by sliding the bit patterns to left or right? That would indicate going out of sync.
Hey Mike,
I think you guys are right, it must be going out of sync from what I see here:
This is two cards read, 4 time each. Scenario is explained before each of the 8 card reads:
Power on, all systems connected, Initial read:
Card1:
Binary Code:
11001111000110000000000111
Hex Code: 678C00F
SiteCode & Serial Number: 241 31
Binary Code:
11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 633 31
Binary Code:
11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 633 31
Binary Code:
11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 633 31
Card2:
Binary Code:
110000110000000000111100
Hex Code: C3003C
SiteCode & Serial Number: 97 30
Binary Code:
110000110000000000111100
Hex Code: C3003C
SiteCode & Serial Number: 97 30
Binary Code:
110000110000000000111100
Hex Code: C3003C
SiteCode & Serial Number: 97 30
Binary Code:
1100001100000000000111100
Hex Code: 30C0078
SiteCode & Serial Number: 536 241
****************************************************************
Re-upload code, no restart of card reader (causes a reset on the arduino)
Card1:
Binary Code:
11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 633 31
Binary Code:
11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 633 31
Binary Code:
11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 633 31
Binary Code:
11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 633 31
Card2:
Binary Code:
110000110000000000111100
Hex Code: C3003C
SiteCode & Serial Number: 97 30
Binary Code:
110000110000000000111100
Hex Code: C3003C
SiteCode & Serial Number: 97 30
Binary Code:
111000011000000000011110
Hex Code: 1C3003C
SiteCode & Serial Number: 225 30
Binary Code:
110000110000000000111100
Hex Code: C3003C
SiteCode & Serial Number: 97 30
*******************************************************************
No code re-upload, power off and on reader and restart serial monitor
Card1:
Binary Code:
11001111001100000000000111
Hex Code: 679800F
SiteCode & Serial Number: 243 31
Binary Code:
11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 633 31
Binary Code:
11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 633 31
Binary Code:
11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 633 31
Card2:
Binary Code:
110000111000000000011110
Hex Code: 187003C
SiteCode & Serial Number: 195 30
Binary Code:
11000011000000000011110
Hex Code: C3003C
SiteCode & Serial Number: 97 30
Binary Code:
110000110000000000111100
Hex Code: C3003C
SiteCode & Serial Number: 97 30
Binary Code:
110000110000000000011110
Hex Code: 186003C
SiteCode & Serial Number: 195 30
**************************************************************
Only power off reader and power back on:
Card1:
Binary Code:
100100100111001111100110
Hex Code: 124E7CC
SiteCode & Serial Number: 146 13286
Binary Code:
11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 633 31
Binary Code:
11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 633 31
Binary Code:
11100111100110000000000111
Hex Code: 73CC00F
SiteCode & Serial Number: 633 31
Card2:
Binary Code:
110000110000000000111100
Hex Code: C3003C
SiteCode & Serial Number: 97 30
Binary Code:
110000011000000000011110
Hex Code: 183003C
SiteCode & Serial Number: 193 30
Binary Code:
110000011000000000011110
Hex Code: 183003C
SiteCode & Serial Number: 193 30
Binary Code:
11000011000000000011110
Hex Code: C3003C
SiteCode & Serial Number: 97 30
It looks like there is some consistencies between the cards, as card 1 should probably output "633 31" and card2 should output "97 30"
Now a little while later, using the same two fobs, I get a different site and serial number result for card1, but the binary and hex code is exactly the same as before......hmmmm
This to me seems like there is nothing wrong with the card reader, but perhaps the code that calculates the site and serial numbers?
It sort of works now, it still seems as if I am not getting the correct response from the boolean. I added three fobs to the allowed site code and serial numbers list.
97 30
97 2040
828 15
Output in the serial monitor shows that one of the cards works (97 30), as it says opening door, but it goes on to say invalid fob right underneath it. Yet it still turns over the relay, so it is working. But the other two fobs are not working at all even though they are in the site and serial numbers list.
I have included the most recent code with my modifications.
Binary Code: 11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 828 15
Invalid FOB
Binary Code: 110000110000000000111100
Hex Code: C3003C
SiteCode & Serial Number: 97 30
Opening Door
Door Open
Invalid FOB
Binary Code: 11001111001100000000001111
Hex Code: 33CC00F
SiteCode & Serial Number: 828 15
Invalid FOB
Binary Code: 110000110000111111110000
Hex Code: C30FF0
SiteCode & Serial Number: 97 2040
Invalid FOB
Binary Code: 11000011111111000011000000
Hex Code: 30FF0C0
SiteCode & Serial Number: 783 12480
Invalid FOB
Binary Code: 11000011000000000011110
Hex Code: C3003C
SiteCode & Serial Number: 97 30
Opening Door
Door Open
Invalid FOB
//WG26 Card Reader
//12v Power to red
//Ground to Black
//Green to pin 2
//Yellow to pin 3
//Reads cards and does a serial print
//*Need to add verification to allow only certain cards
/* Crazy People
* By Mike Cook April 2009
* Three RFID readers outputing 26 bit Wiegand code to pins:-
* Reader A (Head) Pins 2 & 3
* Interrupt service routine gathers Wiegand pulses (zero or one) until 26 have been recieved
* Then a sting is sent to processing
*/
int validSiteCodes[] = {97, 828};
int validSerialNumbers[] = {30, 2040, 15};// see if site code and serial number are in the lists...
volatile long reader1 = 0;
volatile int reader1Count = 0;
void reader1One(void) {
reader1Count++;
reader1 = reader1 << 1;
reader1 |= 1;
}
void reader1Zero(void) {
reader1Count++;
reader1 = reader1 << 1;
}
void setup()
{
Serial.begin(9600);
// Attach pin change interrupt service routines from the Wiegand RFID readers
attachInterrupt(0, reader1Zero, RISING);//DATA0 to pin 2
attachInterrupt(1, reader1One, RISING); //DATA1 to pin 3
delay(10);
// the interrupt in the Atmel processor mises out the first negitave pulse as the inputs are already high,
// so this gives a pulse to each reader input line to get the interrupts working properly.
// Then clear out the reader variables.
// The readers are open collector sitting normally at a one so this is OK
for(int i = 2; i<4; i++){
pinMode(i, OUTPUT);
digitalWrite(i, HIGH); // enable internal pull up causing a one
digitalWrite(i, LOW); // disable internal pull up causing zero and thus an interrupt
pinMode(i, INPUT);
digitalWrite(i, HIGH); // enable internal pull up
}
delay(10);
// put the reader input variables to zero
reader1 = 0;
reader1Count = 0;
//digitalWrite(8, HIGH); // show Arduino has finished initilisation
pinMode(12, OUTPUT);
}
void loop()
{
if(reader1Count >=26){
//Serial.print(" Reader 1 ");
Serial.print("Binary Code: ");
Serial.print(reader1,BIN);
Serial.println(" ");
Serial.print("Hex Code: ");
Serial.println(reader1,HEX);
// Serial.print("SiteCode & Serial Number: ");
// Serial.println(reader1& 0xfffffff);
long serialNumber=(reader1 >> 1) & 0x3fff;
int siteCode= (reader1 >> 17) & 0x3ff;
Serial.print("SiteCode & Serial Number: ");
Serial.print(siteCode);
Serial.print(" ");
Serial.println(serialNumber);
Serial.println(" ");
reader1 = 0;
reader1Count = 0;
if(IsTagValid(siteCode, serialNumber)
){
digitalWrite(12,HIGH); // Open the door. It's cold out here!
Serial.println(" ");
Serial.print("Opening Door");
Serial.println(" ");
delay(200);
Serial.println(" ");
Serial.print("Door Open");
Serial.println(" ");
digitalWrite(12,LOW);
}
else
digitalWrite(12,LOW);
Serial.println(" ");
Serial.print("Invalid FOB");
Serial.println(" ");
}
}
boolean IsTagValid(int siteCode, int serialNumber)
{
boolean valid = false;
// Determine how many valid tags there are
int validTagCount = sizeof(validSiteCodes)/sizeof(int);
// Loop through the arrays to see if siteCode
// and serialNumber are present
for(int t=0; t<validTagCount; t++)
{
if(validSiteCodes[t] == siteCode &&
validSerialNumbers[t] == serialNumber)
{
valid = true;
break;
}
}
return valid;
}
Yes, it was a grounding problem. I had to ground the power supply from the rfid reader to the arduino. Not sure this is the best idea, but it solved the problem.