RFID (wiegand 26) wrong reading

Hello everyone,

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.

Does anyone have any ideas?
Thank you in advance!

This is the "Programming" section of the forum.

Yes, I know, but It`s possible to become this error from programming...

I don't see any programming.

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;
  }
}
1 Like

This is my project where I use three such readers and the pin change interrupt.
http://www.thebox.myzen.co.uk/Hardware/Crazy_People.html

Look out for the link to download the code.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.