I need help from the community to solve a small problem with reading a label, using the Wiegand-26 reader. I made an stand-alone access control panel, using a solar panel (50W), a 12V 7Ah battery, 12V 1A electromagnetic lock and an Arduino UNO as controller. The device reads perfectly on the first 20 attempts, after which the code read on Wiegand-26 changes, or rather, is no longer the true code of the label. Once it starts reading the tags incorrectly, I reset the RFID reader, after which it will read the tags correctly again for a while. Using the oscilloscope, nothing out of the ordinary can be seen on the power supply of the RFID reader. On the power supply wires of the electromagnetic lock I made a filter with ultra fast diodes, on the idea not to induce parasitic current from the lock. Nothing has changed like that either.
Here is a sketch for reading Wiegand data. It will tell you if it is the sender or receiver that is mesing up.
/**********
This sketch displays the raw bits received from a Weigand device along with bit count and parity
Connect the D0 line to Pin 2 and the D1 line to Pin 3 on an Arduino UNO.
Connect the signal ground to GND on the Arduino
Note: If the bit count is not consistent you probably have a bad connection.
This is especially true if you are only receiving 0 bits or 1 bits.
************/
// Connect D0 to Pin 2 and D1 to Pin 3
const byte PinD0 = 2;
const byte PinD1 = 3;
volatile unsigned BitCount = 0;
volatile byte Bits[100];
volatile unsigned long LastBitTime;
volatile boolean Parity = 0;
void setup()
{
Serial.begin(9600);
while (!Serial); // Wait for Leonardo/Micro USB to connect
pinMode(PinD0, INPUT); // Set D0 pin as input
pinMode(PinD1, INPUT); // Set D1 pin as input
// The two data lines idle HIGH
if (digitalRead(PinD0) == LOW)
{
Serial.println(F("WARNING: D0 line (on Pin 2) is not in a HIGH state. Wiring error?"));
}
if (digitalRead(PinD1) == LOW)
{
Serial.println(F("WARNING: D1 line (on Pin 3) is not in a HIGH state. Wiring error?"));
}
attachInterrupt(digitalPinToInterrupt(PinD0), ReadD0, FALLING); // Hardware interrupt - high to low edge
attachInterrupt(digitalPinToInterrupt(PinD1), ReadD1, FALLING); // Hardware interrupt - high to low edge
}
void loop()
{
byte localBits[100];
// Grab volatile variables with interupts disabled
noInterrupts();
unsigned long interval = millis() - LastBitTime;
unsigned count = BitCount;
boolean parity = Parity;
interrupts();
// Process data when we have new bits, but not for a while.
if (count != 0 && interval > 100)
{
// Grab a local copy of the bit pattern
noInterrupts();
for (unsigned i = 0; i < count; i++)
{
localBits[i] = Bits[i];
}
// Reset for next message
BitCount = 0;
Parity = 0;
interrupts();
// Display the received bits in binary, along with bit count and parity
Serial.print(count);
Serial.print(" bits: ");
for (unsigned i = 0; i < count; i++)
{
Serial.print(localBits[i]);
}
Serial.println(parity ? " parity=1 (Odd)" : " parity=0 (Even)");
}
}
void ReadD0()
{
if (BitCount < 100)
{
LastBitTime = millis();
Bits[BitCount++] = 0;
}
}
void ReadD1()
{
if (BitCount < 100)
{
LastBitTime = millis();
Bits[BitCount++] = 1;
Parity = !Parity;
}
}