Skip to content

Card read error when using me-no-dev/ESPAsyncWebServer #32

@ghost

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: 22875

After 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 ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions