Refactor, add initial PN532 support

This commit is contained in:
Laura Hausmann 2023-04-20 15:18:00 +02:00
parent 42245e5f6c
commit 8dab83dad6
Signed by: zotan
GPG key ID: D044E84C5BE01605
12 changed files with 339 additions and 156 deletions

View file

@ -1,34 +0,0 @@
#pragma once
#include <Arduino.h>
#include <MFRC522.h>
#include <rdm6300.h>
class CardReader {
public:
virtual bool canHaveUnstableIdentifier() = 0;
virtual bool isNewCardPresent() = 0;
virtual String getCardUid() = 0;
virtual void reset() = 0;
};
class MFRC522CardReader : public CardReader {
private:
MFRC522* iReader;
public:
explicit MFRC522CardReader(MFRC522* reader);
bool canHaveUnstableIdentifier() override;
bool isNewCardPresent() override;
String getCardUid() override;
void reset() override;
};
class RDM6300CardReader : public CardReader {
private:
Rdm6300* iReader;
public:
explicit RDM6300CardReader(Rdm6300* reader);
bool canHaveUnstableIdentifier() override;
bool isNewCardPresent() override;
String getCardUid() override;
void reset() override;
};

View file

@ -4,8 +4,20 @@
#include "logos.h"
#include "utils.h"
void drawLogo(U8G2 u8g2, e_logo logo);
void drawStatusText(U8G2 u8g2, const String& status, const String& statusRightAligned = "");
void updateOLED(U8G2 u8g2, e_state state, const String& statusText, const String& statusTextRightAligned = "");
void updateOLED(const U8G2& u8g2, e_state state);
class OLED {
private:
U8G2 u8g2;
String revision;
void drawCurvedLineV(int xStart, int yStart, int vert, int horiz);
void drawCurvedLine(int xStart, int yStart, int horiz, int vert);
void drawLogoAfraPay();
void drawLogoBitmap(int width, int height, unsigned char bits[], int yOffset = 0);
void drawFullScreenText(const String& textTop, const String& textBottom);
public:
explicit OLED(U8G2 u8g2);
void begin();
void drawLogo(e_logo logo);
void drawStatusText(const String& status, const String& statusRightAligned = "");
void updateOLED(e_state state, const String& statusText, const String& statusTextRightAligned = "");
void updateOLED(e_state state);
};

View file

@ -0,0 +1,58 @@
#pragma once
#include <Arduino.h>
#include <MFRC522.h>
#include <rdm6300.h>
#include <Adafruit_PN532.h>
class Reader {
public:
virtual bool canHaveUnstableIdentifier() = 0;
virtual bool isNewCardPresent() = 0;
virtual String getCardUid() = 0;
virtual void begin() = 0;
virtual void reset() = 0;
virtual void init() = 0;
virtual void end() = 0;
};
class MFRC522Reader : public Reader {
private:
MFRC522* mfrc522;
public:
explicit MFRC522Reader(byte chipSelectPin, byte resetPowerDownPin);
bool canHaveUnstableIdentifier() override;
bool isNewCardPresent() override;
String getCardUid() override;
void reset() override;
void init() override;
};
class RDM6300Reader : public Reader {
private:
Rdm6300* rdm6300;
int pin;
public:
explicit RDM6300Reader(int pin);
bool canHaveUnstableIdentifier() override;
bool isNewCardPresent() override;
String getCardUid() override;
void reset() override;
void init() override;
};
class PN532Reader : public Reader {
private:
Adafruit_PN532* pn532;
uint8_t uid[7];
uint8_t uidLength;
public:
static volatile int irq;
explicit PN532Reader(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t ss);
bool canHaveUnstableIdentifier() override;
bool isNewCardPresent() override;
String getCardUid() override;
void begin() override;
void reset() override;
void init() override;
void end() override;
};

View file

@ -22,3 +22,8 @@ enum e_state {
STATE_RESULT_FAILURE,
STATE_RESULT_DISPLAY,
};
enum e_scanstate {
SCANSTATE_IDLE,
SCANSTATE_ACTIVE,
};

View file

@ -10,13 +10,21 @@
#ifndef AFRAPAY_GIT_COMMIT
#define AFRAPAY_GIT_COMMIT "unknown"
#endif
/*
* We're using an Az-Delivery ESP-32 Kit:
* Product: https://web.archive.org/web/20230420182915/https://www.azdelivery.de/en/products/esp32-developmentboard
* Pinout: https://web.archive.org/web/20210901112537/https://cdn.shopify.com/s/files/1/1509/1638/files/ESP-32_NodeMCU_Developmentboard_Pinout.pdf
* Datasheet: https://web.archive.org/web/20221209154701/https://cdn.shopify.com/s/files/1/1509/1638/files/ESP-32_NodeMCU_Developmentboard_Schematic_korr.pdf?v=1666000508
*/
//MFRC522 pinout (front) 3V3 RST GND IRQ MISO MOSI SCK SDA
//MFRC522 pinout (rear) SDA SCK MOSI MISO IRQ GND RST 3V3
#define PIN_HSPI_RST 4
#define PIN_HSPI_MISO 12
#define PIN_HSPI_MOSI 13
#define PIN_HSPI_SCLK 14
#define PIN_HSPI_SS 15
#define PIN_HSPI_CS0 15 //CS0 (Chip Select 0) = SS channel 0
#define PIN_HWSERIAL_RX 16
#define PIN_HWSERIAL_TX 17
#define PIN_BUZZER 19
@ -26,3 +34,4 @@
#define PIN_INTERRUPT_BALANCE 25
#define PIN_INTERRUPT_LINK 33
#define PIN_INTERRUPT_CANCEL 32
#define PIN_INTERRUPT_IRQ_PN532 27

View file

@ -23,6 +23,7 @@ lib_deps =
mcxiaoke/ESPDateTime@^1.0.4
arduino12/rdm6300@^2.0.0
bblanchon/ArduinoJson@^6.20.0
adafruit/Adafruit PN532@^1.3.0
check_tool = clangtidy
check_flags =
clangtidy: --config-file=.clang-tidy

View file

@ -1,54 +0,0 @@
#include <Arduino.h>
#include <MFRC522.h>
#include <rdm6300.h>
#include "utils.h"
#include "cardReader.h"
MFRC522CardReader::MFRC522CardReader(MFRC522* reader) {
iReader = reader;
}
bool MFRC522CardReader::isNewCardPresent() {
return iReader->PICC_IsNewCardPresent() && iReader->PICC_ReadCardSerial();
}
String MFRC522CardReader::getCardUid() {
return byteArrayAsHexString(iReader->uid.uidByte, iReader->uid.size);
}
void MFRC522CardReader::reset() {
iReader->PCD_AntennaOff();
iReader->PCD_Init();
iReader->PCD_AntennaOn();
}
inline bool MFRC522CardReader::canHaveUnstableIdentifier() {
return true;
}
RDM6300CardReader::RDM6300CardReader(Rdm6300* reader) {
iReader = reader;
}
bool RDM6300CardReader::isNewCardPresent() {
return iReader->get_new_tag_id();
}
String RDM6300CardReader::getCardUid() {
auto uid = iReader->get_tag_id();
char buf[16];
sprintf(buf, "%010u", uid);
return {buf};
}
void RDM6300CardReader::reset() {
/*
* We don't need to do anything here
* RDM6300 readers don't report a new card as present til the old card is removed and re-presented
*/
}
inline bool RDM6300CardReader::canHaveUnstableIdentifier() {
// As far as I am aware, there are no 125khz tags with unstable identifiers
return false;
}

View file

@ -6,40 +6,44 @@
#include <WiFi.h>
#include <HTTPClient.h>
#include <SPI.h>
#include <MFRC522.h>
#include <ESPDateTime.h>
#include <DateTimeTZ.h>
#include <rdm6300.h>
#include "wifiFix.h"
#include "pitches.h"
#include "utils.h"
#include "oled.h"
#include "cardReader.h"
#include "readers.h"
#include "vars.h"
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
MFRC522 mfrc522(PIN_HSPI_SS, PIN_HSPI_RST);
OLED oled(U8G2_SH1106_128X64_NONAME_F_HW_I2C(U8G2_R0, U8X8_PIN_NONE));
WiFiClient* wifi = new WiFiClientFixed();
HTTPClient* http = new HTTPClient();
Rdm6300 rdm6300;
auto mfrc522reader = MFRC522CardReader(&mfrc522);
auto rdm6300reader = RDM6300CardReader(&rdm6300);
CardReader* readers[2] = {&mfrc522reader, &rdm6300reader};
Reader* readers[] = {
//new MFRC522CardReader(PIN_HSPI_SS, PIN_HSPI_RST),
new PN532Reader(PIN_HSPI_SCLK, PIN_HSPI_MISO, PIN_HSPI_MOSI, PIN_HSPI_CS0),
//new RDM6300Reader(PIN_HWSERIAL_RX)
};
e_state state = STATE_IDLE;
e_scanstate scanstate = SCANSTATE_IDLE;
String apiUrl = "";
const int gTimeout = 5000;
const int scanTimeout = 15000;
CardReader* scannedCardReader;
Reader* scannedCardReader;
String scannedCardId = "";
String lastStatusText = "";
volatile bool interruptFired = false;
unsigned long timer = 0;
void IRAM_ATTR PN532_IRQ() {
PN532Reader::irq++;
}
void IRAM_ATTR TransactInterruptHandler() {
if (interruptFired || state != STATE_IDLE || digitalRead(PIN_INTERRUPT_TRANSACT)) {
return;
@ -73,28 +77,58 @@ void IRAM_ATTR CancelInterruptHandler() {
bool cooldownCheck(long timeout) {
if (millis() - timer > timeout) {
state = STATE_IDLE;
updateOLED(u8g2, state);
oled.updateOLED(state);
return true;
}
return false;
}
void updateCardscan() {
switch (state) {
case STATE_TRANSACT_CARDSCAN:
case STATE_LINK_CARD_SCAN:
case STATE_LINK_CARD_RESCAN:
case STATE_BALANCE_CARDSCAN:
if (scanstate == SCANSTATE_ACTIVE)
return;
for (Reader* reader : readers) {
reader->begin();
}
scanstate = SCANSTATE_ACTIVE;
break;
case STATE_IDLE:
case STATE_TRANSACT_VERIFY:
case STATE_LINK_VERIFY:
case STATE_BALANCE_VERIFY:
case STATE_RESULT_SUCCESS:
case STATE_RESULT_FAILURE:
case STATE_RESULT_DISPLAY:
if (scanstate == SCANSTATE_IDLE)
return;
for (Reader* reader : readers) {
reader->end();
}
scanstate = SCANSTATE_IDLE;
break;
}
}
void setup() {
Serial.begin(115200);
oled.begin();
Serial2.begin(115200, SERIAL_8N1, PIN_HWSERIAL_RX, PIN_HWSERIAL_TX);
SPI.begin(PIN_HSPI_SCLK, PIN_HSPI_MISO, PIN_HSPI_MOSI);
ledcSetup(0, 5000, 12);
pinMode(PIN_INTERRUPT_IRQ_PN532, INPUT_PULLUP);
pinMode(PIN_INTERRUPT_TRANSACT, INPUT_PULLUP);
pinMode(PIN_INTERRUPT_BALANCE, INPUT_PULLUP);
pinMode(PIN_INTERRUPT_CANCEL, INPUT_PULLUP);
pinMode(PIN_INTERRUPT_LINK, INPUT_PULLUP);
u8g2.begin();
drawLogo(u8g2, LOGO_MATECARD);
u8g2.sendBuffer();
SPIFFS.begin(true);
WiFiSettings.hostname = "afrapay-";
apiUrl = WiFiSettings.string("AfRApay.Web API", "http://192.168.50.170:5296");
@ -103,14 +137,15 @@ void setup() {
else
WiFiSettings.connect();
rdm6300.begin(PIN_HWSERIAL_RX);
rdm6300.set_tag_timeout(65);
mfrc522.PCD_Init();
mfrc522.PCD_DumpVersionToSerial();
for (Reader* reader : readers) {
reader->init();
}
DateTime.setTimeZone(TZ_Europe_Berlin);
DateTime.begin();
updateOLED(u8g2, state);
oled.updateOLED(state);
attachInterrupt(PIN_INTERRUPT_IRQ_PN532, PN532_IRQ, FALLING);
attachInterrupt(PIN_INTERRUPT_TRANSACT, TransactInterruptHandler, FALLING);
attachInterrupt(PIN_INTERRUPT_BALANCE, BalanceInterruptHandler, FALLING);
attachInterrupt(PIN_INTERRUPT_CANCEL, CancelInterruptHandler, FALLING);
@ -119,13 +154,15 @@ void setup() {
void loop() {
if (WiFiClass::status() != WL_CONNECTED) {
updateOLED(u8g2, state, "WiFi disconnected :(");
oled.updateOLED(state, "WiFi disconnected :(");
state = STATE_IDLE;
WiFi.reconnect();
delay(50);
return;
}
updateCardscan();
if (interruptFired) {
timer = millis();
interruptFired = false;
@ -133,10 +170,10 @@ void loop() {
switch (state) {
case STATE_IDLE:
updateOLED(u8g2, state);
oled.updateOLED(state);
break;
case STATE_TRANSACT_CARDSCAN:
for (CardReader* reader : readers) {
for (Reader* reader : readers) {
if (reader->isNewCardPresent()) {
scannedCardId = reader->getCardUid();
lastStatusText = "Card #" + scannedCardId;
@ -146,11 +183,11 @@ void loop() {
}
}
if (!cooldownCheck(scanTimeout)) {
updateOLED(u8g2, state, String("1.50€"), String(cooldownSecondsRemaining(scanTimeout, timer)));
oled.updateOLED(state, String("1.50€"), String(cooldownSecondsRemaining(scanTimeout, timer)));
}
break;
case STATE_TRANSACT_VERIFY:
updateOLED(u8g2, state, lastStatusText);
oled.updateOLED(state, lastStatusText);
tone(PIN_BUZZER, NOTE_A5, 25);
tone(PIN_BUZZER, NOTE_NONE, 150);
lastStatusText = cardTransaction(wifi, http, apiUrl, scannedCardId, "-150");
@ -167,7 +204,7 @@ void loop() {
timer = millis();
return;
case STATE_LINK_CARD_SCAN:
for (CardReader* reader : readers) {
for (Reader* reader : readers) {
if (reader->isNewCardPresent()) {
scannedCardReader = reader;
scannedCardId = reader->getCardUid();
@ -185,7 +222,7 @@ void loop() {
}
}
if (!cooldownCheck(scanTimeout)) {
updateOLED(u8g2, state, "Link", String(cooldownSecondsRemaining(scanTimeout, timer)));
oled.updateOLED(state, "Link", String(cooldownSecondsRemaining(scanTimeout, timer)));
}
break;
case STATE_LINK_CARD_RESCAN:
@ -202,11 +239,11 @@ void loop() {
}
}
if (!cooldownCheck(scanTimeout)) {
updateOLED(u8g2, state, "Link - rescan", String(cooldownSecondsRemaining(scanTimeout, timer)));
oled.updateOLED(state, "Link - rescan ", String(cooldownSecondsRemaining(scanTimeout, timer)));
}
break;
case STATE_LINK_VERIFY:
updateOLED(u8g2, state, lastStatusText);
oled.updateOLED(state, lastStatusText);
tone(PIN_BUZZER, NOTE_A5, 25);
tone(PIN_BUZZER, NOTE_NONE, 150);
lastStatusText = cardLink(wifi, http, apiUrl, scannedCardId);
@ -225,7 +262,7 @@ void loop() {
timer = millis();
return;
case STATE_BALANCE_CARDSCAN:
for (CardReader* reader : readers) {
for (Reader* reader : readers) {
if (reader->isNewCardPresent()) {
scannedCardId = reader->getCardUid();
lastStatusText = "Card #" + scannedCardId;
@ -234,11 +271,11 @@ void loop() {
}
}
if (!cooldownCheck(scanTimeout)) {
updateOLED(u8g2, state, "Balance", String(cooldownSecondsRemaining(scanTimeout, timer)));
oled.updateOLED(state, "Balance", String(cooldownSecondsRemaining(scanTimeout, timer)));
}
break;
case STATE_BALANCE_VERIFY:
updateOLED(u8g2, state, lastStatusText);
oled.updateOLED(state, lastStatusText);
tone(PIN_BUZZER, NOTE_A5, 25);
tone(PIN_BUZZER, NOTE_NONE, 150);
lastStatusText = cardBalance(wifi, http, apiUrl, scannedCardId);
@ -261,7 +298,7 @@ void loop() {
case STATE_RESULT_FAILURE:
case STATE_RESULT_DISPLAY:
if (!cooldownCheck(gTimeout)) {
updateOLED(u8g2, state, lastStatusText, String(cooldownSecondsRemaining(gTimeout, timer)));
oled.updateOLED(state, lastStatusText, String(cooldownSecondsRemaining(gTimeout, timer)));
}
break;
}

View file

@ -1,12 +1,38 @@
#include <WiFi.h>
#include <ESPDateTime.h>
#include <utility>
#include "Arduino.h"
#include "U8g2lib.h"
#include "logos.h"
#include "utils.h"
#include "vars.h"
#include "oled.h"
void drawCurvedLineV(U8G2 u8g2, int xStart, int yStart, int vert, int horiz) {
OLED::OLED(U8G2 u8g2) {
this->u8g2 = std::move(u8g2);
}
void OLED::begin() {
u8g2.begin();
u8g2.setFont(u8g2_font_bpixel_te);
u8g2_uint_t maxLength = 127 - u8g2.getUTF8Width("00:00:00 ");
if (u8g2.getUTF8Width(AFRAPAY_GIT_BRANCH "-" AFRAPAY_GIT_COMMIT) < maxLength) {
revision = AFRAPAY_GIT_BRANCH "-" AFRAPAY_GIT_COMMIT;
}
else if (u8g2.getUTF8Width(AFRAPAY_GIT_BRANCH) < maxLength) {
revision = AFRAPAY_GIT_BRANCH;
}
else if (u8g2.getUTF8Width(AFRAPAY_GIT_COMMIT) < maxLength) {
revision = AFRAPAY_GIT_COMMIT;
}
drawLogo(LOGO_MATECARD);
u8g2.sendBuffer();
}
void OLED::drawCurvedLineV(int xStart, int yStart, int vert, int horiz) {
u8g2.drawVLine(xStart, yStart + 1, vert);
u8g2.drawVLine(xStart + 1, yStart, vert);
@ -14,7 +40,7 @@ void drawCurvedLineV(U8G2 u8g2, int xStart, int yStart, int vert, int horiz) {
u8g2.drawHLine(xStart + 1, yStart + vert + 1, horiz);
}
void drawCurvedLine(U8G2 u8g2, int xStart, int yStart, int horiz, int vert) {
void OLED::drawCurvedLine(int xStart, int yStart, int horiz, int vert) {
u8g2.drawHLine(xStart, yStart, horiz);
u8g2.drawHLine(xStart, yStart + 1, horiz);
@ -22,7 +48,7 @@ void drawCurvedLine(U8G2 u8g2, int xStart, int yStart, int horiz, int vert) {
u8g2.drawVLine(xStart + horiz + 1, yStart + 1, vert);
}
void drawLogoAfraPay(U8G2 u8g2) {
void OLED::drawLogoAfraPay() {
u8g2.setFontMode(1);
u8g2.setFontDirection(0);
@ -39,42 +65,42 @@ void drawLogoAfraPay(U8G2 u8g2) {
//u8g2.drawHLine(0, yOffset-12, xOffset);
//u8g2.drawHLine(127-xOffset-1, yOffset, xOffset);
drawCurvedLineV(u8g2, xOffset + 69, yOffset, 7, 32);
drawCurvedLine(u8g2, xOffset + 73, yOffset - 8, 28, 15);
drawCurvedLineV(xOffset + 69, yOffset, 7, 32);
drawCurvedLine(xOffset + 73, yOffset - 8, 28, 15);
u8g2.drawPixel(xOffset + 101, yOffset + 7);
}
void drawLogoBitmap(U8G2 u8g2, int width, int height, unsigned char bits[], int yOffset = 0) {
void OLED::drawLogoBitmap(int width, int height, unsigned char bits[], int yOffset) {
int offset = (128 - width) / 2;
u8g2.drawXBM(offset, yOffset, width, height, bits);
}
void drawLogo(U8G2 u8g2, e_logo logo) {
void OLED::drawLogo(e_logo logo) {
switch (logo) {
case LOGO_AFRAPAY:
drawLogoAfraPay(u8g2);
drawLogoAfraPay();
break;
case LOGO_CONTACTLESS:
drawLogoBitmap(u8g2, contactless_width, contactless_height, contactless_bits);
drawLogoBitmap( contactless_width, contactless_height, contactless_bits);
break;
case LOGO_MATECARD:
drawLogoBitmap(u8g2, matecard_width, matecard_height, matecard_bits, 5);
drawLogoBitmap(matecard_width, matecard_height, matecard_bits, 5);
u8g2.setFont(u8g2_font_bpixeldouble_tr);
u8g2.drawStr((126 - u8g2.getStrWidth("matecard")) / 2, 57, "matecard");
break;
case LOGO_PENDING:
drawLogoBitmap(u8g2, pending_width, pending_height, pending_bits, 5);
drawLogoBitmap(pending_width, pending_height, pending_bits, 5);
break;
case LOGO_SUCCESS:
drawLogoBitmap(u8g2, success_width, success_height, success_bits, 5);
drawLogoBitmap(success_width, success_height, success_bits, 5);
break;
case LOGO_FAILURE:
drawLogoBitmap(u8g2, failure_width, failure_height, failure_bits, 5);
drawLogoBitmap(failure_width, failure_height, failure_bits, 5);
break;
}
}
void drawStatusText(U8G2 u8g2, const String& status, const String& statusRightAligned = "") {
void OLED::drawStatusText(const String& status, const String& statusRightAligned) {
u8g2.setFont(u8g2_font_bpixel_te);
u8g2.drawUTF8(0, 61, status.c_str());
@ -84,52 +110,54 @@ void drawStatusText(U8G2 u8g2, const String& status, const String& statusRightAl
}
}
void drawFullScreenText(U8G2 u8g2, const String& textTop, const String& textBottom) {
void OLED::drawFullScreenText(const String& textTop, const String& textBottom) {
u8g2.setFont(u8g2_font_chargen_92_tr);
u8g2.drawUTF8((127-u8g2.getUTF8Width(textTop.c_str()))/2, 13, textTop.c_str());
u8g2.setFont(u8g2_font_maniac_te);
u8g2.drawUTF8((127-u8g2.getUTF8Width(textBottom.c_str()))/2, 45, textBottom.c_str());
}
void updateOLED(U8G2 u8g2, e_state state, const String& statusText, const String& statusTextRightAligned = "") {
void OLED::updateOLED(e_state state, const String& statusText, const String& statusTextRightAligned) {
u8g2.clearBuffer();
switch (state) {
case STATE_IDLE:
drawLogo(u8g2, LOGO_AFRAPAY);
drawLogo(LOGO_AFRAPAY);
break;
case STATE_TRANSACT_CARDSCAN:
case STATE_BALANCE_CARDSCAN:
case STATE_LINK_CARD_SCAN:
case STATE_LINK_CARD_RESCAN:
drawLogo(u8g2, LOGO_CONTACTLESS);
drawLogo(LOGO_CONTACTLESS);
break;
case STATE_RESULT_SUCCESS:
drawLogo(u8g2, LOGO_SUCCESS);
drawLogo(LOGO_SUCCESS);
break;
case STATE_RESULT_FAILURE:
drawLogo(u8g2, LOGO_FAILURE);
drawLogo(LOGO_FAILURE);
break;
case STATE_RESULT_DISPLAY:
drawFullScreenText(u8g2, splitString(statusText, ':', 0), splitString(statusText, ':', 1) + "");
drawStatusText(u8g2, splitString(statusText, ':', 2), statusTextRightAligned);
drawFullScreenText(splitString(statusText, ':', 0), splitString(statusText, ':', 1) + "");
drawStatusText(splitString(statusText, ':', 2), statusTextRightAligned);
u8g2.sendBuffer();
return;
case STATE_TRANSACT_VERIFY:
case STATE_BALANCE_VERIFY:
case STATE_LINK_VERIFY:
drawLogo(u8g2, LOGO_PENDING);
drawLogo(LOGO_PENDING);
break;
}
drawStatusText(u8g2, statusText, statusTextRightAligned);
drawStatusText(statusText, statusTextRightAligned);
u8g2.sendBuffer();
}
void updateOLED(const U8G2& u8g2, e_state state) {
void OLED::updateOLED(e_state state) {
String time = DateTime.format(DateFormatter::TIME_ONLY);
if (!digitalRead(PIN_INTERRUPT_CANCEL) || millis()%20000 < 10000)
updateOLED(u8g2, state, time, AFRAPAY_GIT_COMMIT);
else
updateOLED(u8g2, state, time, WiFi.localIP().toString());
if (!digitalRead(PIN_INTERRUPT_CANCEL) || millis()%20000 < 10000) {
updateOLED(state, time, revision);
}
else {
updateOLED(state, time, WiFi.localIP().toString());
}
}

View file

@ -0,0 +1,31 @@
#include <Arduino.h>
#include "MFRC522.h"
#include "utils.h"
#include "readers.h"
MFRC522Reader::MFRC522Reader(byte chipSelectPin, byte resetPowerDownPin) {
mfrc522 = new MFRC522(chipSelectPin, resetPowerDownPin);
}
bool MFRC522Reader::isNewCardPresent() {
return mfrc522->PICC_IsNewCardPresent() && mfrc522->PICC_ReadCardSerial();
}
String MFRC522Reader::getCardUid() {
return byteArrayAsHexString(mfrc522->uid.uidByte, mfrc522->uid.size);
}
void MFRC522Reader::reset() {
mfrc522->PCD_AntennaOff();
mfrc522->PCD_Init();
mfrc522->PCD_AntennaOn();
}
inline bool MFRC522Reader::canHaveUnstableIdentifier() {
return true;
}
void MFRC522Reader::init() {
mfrc522->PCD_Init();
mfrc522->PCD_DumpVersionToSerial();
}

View file

@ -0,0 +1,53 @@
#include <Arduino.h>
#include "utils.h"
#include "readers.h"
#include "vars.h"
volatile int PN532Reader::irq = 0;
PN532Reader::PN532Reader(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t ss) {
pn532 = new Adafruit_PN532(clk, miso, mosi, ss);
}
void PN532Reader::begin() {
pn532->begin();
irq = 0;
pn532->startPassiveTargetIDDetection(PN532_MIFARE_ISO14443A);
}
void PN532Reader::end() {
pn532->sendCommandCheckAck(new byte[1]{PN532_COMMAND_POWERDOWN}, 1, 1);
}
bool PN532Reader::isNewCardPresent() {
return irq > 1;
}
String PN532Reader::getCardUid() {
pn532->readDetectedPassiveTargetID(uid, &uidLength);
Serial.println(byteArrayAsHexString(uid, uidLength));
return byteArrayAsHexString(uid, uidLength);
}
void PN532Reader::reset() {
this->end();
this->begin();
}
inline bool PN532Reader::canHaveUnstableIdentifier() {
return true;
}
void PN532Reader::init() {
pn532->begin();
uint32_t version = pn532->getFirmwareVersion();
if (!version) {
Serial.print("Couldn't find PN53x board");
return;
//esp_restart();
}
Serial.print("Found chip PN5"); Serial.println((version>>24) & 0xFF, HEX);
Serial.print("Firmware ver. "); Serial.print((version>>16) & 0xFF, DEC);
Serial.print('.'); Serial.println((version>>8) & 0xFF, DEC);
}

View file

@ -0,0 +1,37 @@
#include <Arduino.h>
#include "rdm6300.h"
#include "utils.h"
#include "readers.h"
RDM6300Reader::RDM6300Reader(int pin) {
this->pin = pin;
rdm6300 = new Rdm6300;
}
bool RDM6300Reader::isNewCardPresent() {
return rdm6300->get_new_tag_id();
}
String RDM6300Reader::getCardUid() {
auto uid = rdm6300->get_tag_id();
char buf[16];
sprintf(buf, "%010u", uid);
return {buf};
}
void RDM6300Reader::reset() {
/*
* We don't need to do anything here
* RDM6300 readers don't report a new card as present til the old card is removed and re-presented
*/
}
inline bool RDM6300Reader::canHaveUnstableIdentifier() {
// As far as I am aware, there are no 125khz tags with unstable identifiers
return false;
}
void RDM6300Reader::init() {
rdm6300->begin(pin);
rdm6300->set_tag_timeout(65);
}