-
Notifications
You must be signed in to change notification settings - Fork 31
Description
I've been trying to make ESP32 read Wiegand Cards using a Bosch ARD-AYK12 Wiegand 26bit Proximity Reader.
I have built upon the interrupts example https://github.com/paulo-raca/YetAnotherArduinoWiegandLibrary/blob/master/examples/interrupts/interrupts.ino because the polling one doesn't work at all.
The project also has a web interface served using https://github.com/me-no-dev/ESPAsyncWebServer.
Taking into account that the receiveData() callback needs to be very fast #22 I thought of writing it like this:
void receivedData(uint8_t *data, uint8_t bits, const char *message)
{
uint8_t bytes = (bits + 7) / 8;
// Wiegand 26, first and last bits are for control, remaining 24 bits
if (bits == 24)
{
wiegandFacilityCode = String(data[0] >> 4, 16) + String(data[0] & 0xF, 16);
wiegandCardNumber = "";
for (int i = 1; i < bytes; i++)
{
wiegandCardNumber += String(data[i] >> 4, 16);
wiegandCardNumber += String(data[i] & 0xF, 16);
}
didReadWiegandCard = true;
}
}I create two strings outside receiveData() and I use them to store the card data.
I then set a flag to true so that I can use that data elsewhere.
This is the part of the project that handles reading Wiegand cards, the rest of it has been commented out so it doesn't interfere:
// readWiegand.h
#include <state.h>
#include <Wiegand.h>
#define PIN_D0 14
#define PIN_D1 13
void pinStateChanged();
void stateChanged(bool, const char *);
void IRAM_ATTR receivedData(uint8_t *, uint8_t, const char *);
void receivedDataError(Wiegand::DataError, uint8_t *, uint8_t, const char *);
void setupReadingWiegand();
void readWiegandRoutine();// readWiegand.cpp
#include <readWiegand.h>
// The object that handles the wiegand protocol
Wiegand wiegand;
// When any of the pins have changed, update the state of the wiegand library
void pinStateChanged()
{
wiegand.setPin0State(digitalRead(PIN_D0));
wiegand.setPin1State(digitalRead(PIN_D1));
}
// Notifies when a reader has been connected or disconnected.
// Instead of a message, the seconds parameter can be anything you want -- Whatever you specify on `wiegand.onStateChange()`
void stateChanged(bool plugged, const char *message)
{
Serial.print(message);
Serial.println(plugged ? "CONNECTED" : "DISCONNECTED");
}
// Notifies when a card was read.
// Instead of a message, the seconds parameter can be anything you want -- Whatever you specify on `wiegand.onReceive()`
void IRAM_ATTR receivedData(uint8_t *data, uint8_t bits, const char *message)
{
uint8_t bytes = (bits + 7) / 8;
// Wiegand 26, first and last bits are for control, remaining 24 bits
if (bits == 24)
{
wiegandFacilityCode = String(data[0] >> 4, 16) + String(data[0] & 0xF, 16);
wiegandCardNumber = "";
for (int i = 1; i < bytes; i++)
{
wiegandCardNumber += String(data[i] >> 4, 16);
wiegandCardNumber += String(data[i] & 0xF, 16);
}
didReadWiegandCard = true;
}
}
// Notifies when an invalid transmission is detected
void receivedDataError(Wiegand::DataError error, uint8_t *rawData, uint8_t rawBits, const char *message)
{
Serial.print(message);
Serial.print(Wiegand::DataErrorStr(error));
Serial.print(" - Raw data: ");
Serial.print(rawBits);
Serial.print("bits / ");
// Print value in HEX
uint8_t bytes = (rawBits + 7) / 8;
for (int i = 0; i < bytes; i++)
{
Serial.print(rawData[i] >> 4, 16);
Serial.print(rawData[i] & 0xF, 16);
}
Serial.println();
}
void setupReadingWiegand()
{
// Install listeners and initialize Wiegand reader
wiegand.onReceive(receivedData, "Card read: ");
wiegand.onReceiveError(receivedDataError, "Card read error: ");
// wiegand.onStateChange(stateChanged, "State changed: ");
wiegand.begin(26, true); // CHANGE THIS
// initialize pins as INPUT and attaches interruptions
pinMode(PIN_D0, INPUT);
pinMode(PIN_D1, INPUT);
attachInterrupt(digitalPinToInterrupt(PIN_D0), pinStateChanged, CHANGE);
attachInterrupt(digitalPinToInterrupt(PIN_D1), pinStateChanged, CHANGE);
// Sends the initial pin state to the Wiegand library
pinStateChanged();
}
void readWiegandRoutine()
{
noInterrupts();
wiegand.flush();
interrupts();
}//main.cpp
#include <Arduino.h>
#include <readWiegand.h>
void setup()
{
enableCore1WDT();
delay(100);
Serial.begin(115200);
// Connect to a network
startConnection();
// Start back-end server
startEspServer();
setupReadingWiegand();
}
void loop()
{
delay(1);
readWiegandRoutine();
}Unfortunately, as I mentioned above, the reading is not consistent:
Card read error: Message size unexpected - Raw data: 25bits / 008AB2B6
Card read error: Communication Error - Raw data: 24bits / 8AB2B6
Card read: 24bits / HEX: 45595B / DEC: 4544859 / Facility Code: 69 / Card Number: 22875After more testing I found out that whenever I comment the Server Routine, so basically running the project without an HTTP server, the Wiegand cards are read perfectly.
I investigated and found that after refreshing the web interface or navigating to another page, the first card reading is also an error.
So I came to the conclusion that after each Server "initialization " the first reading is always an error.
What could the connection be ?