Refactor, add initial PN532 support
This commit is contained in:
parent
42245e5f6c
commit
8dab83dad6
|
@ -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;
|
|
||||||
};
|
|
|
@ -4,8 +4,20 @@
|
||||||
#include "logos.h"
|
#include "logos.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
void drawLogo(U8G2 u8g2, e_logo logo);
|
class OLED {
|
||||||
void drawStatusText(U8G2 u8g2, const String& status, const String& statusRightAligned = "");
|
private:
|
||||||
|
U8G2 u8g2;
|
||||||
void updateOLED(U8G2 u8g2, e_state state, const String& statusText, const String& statusTextRightAligned = "");
|
String revision;
|
||||||
void updateOLED(const U8G2& u8g2, e_state state);
|
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);
|
||||||
|
};
|
||||||
|
|
58
AfRApay.MateCard/include/readers.h
Normal file
58
AfRApay.MateCard/include/readers.h
Normal 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;
|
||||||
|
};
|
|
@ -22,3 +22,8 @@ enum e_state {
|
||||||
STATE_RESULT_FAILURE,
|
STATE_RESULT_FAILURE,
|
||||||
STATE_RESULT_DISPLAY,
|
STATE_RESULT_DISPLAY,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum e_scanstate {
|
||||||
|
SCANSTATE_IDLE,
|
||||||
|
SCANSTATE_ACTIVE,
|
||||||
|
};
|
||||||
|
|
|
@ -10,13 +10,21 @@
|
||||||
#ifndef AFRAPAY_GIT_COMMIT
|
#ifndef AFRAPAY_GIT_COMMIT
|
||||||
#define AFRAPAY_GIT_COMMIT "unknown"
|
#define AFRAPAY_GIT_COMMIT "unknown"
|
||||||
#endif
|
#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 (front) 3V3 RST GND IRQ MISO MOSI SCK SDA
|
||||||
//MFRC522 pinout (rear) SDA SCK MOSI MISO IRQ GND RST 3V3
|
//MFRC522 pinout (rear) SDA SCK MOSI MISO IRQ GND RST 3V3
|
||||||
#define PIN_HSPI_RST 4
|
#define PIN_HSPI_RST 4
|
||||||
#define PIN_HSPI_MISO 12
|
#define PIN_HSPI_MISO 12
|
||||||
#define PIN_HSPI_MOSI 13
|
#define PIN_HSPI_MOSI 13
|
||||||
#define PIN_HSPI_SCLK 14
|
#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_RX 16
|
||||||
#define PIN_HWSERIAL_TX 17
|
#define PIN_HWSERIAL_TX 17
|
||||||
#define PIN_BUZZER 19
|
#define PIN_BUZZER 19
|
||||||
|
@ -26,3 +34,4 @@
|
||||||
#define PIN_INTERRUPT_BALANCE 25
|
#define PIN_INTERRUPT_BALANCE 25
|
||||||
#define PIN_INTERRUPT_LINK 33
|
#define PIN_INTERRUPT_LINK 33
|
||||||
#define PIN_INTERRUPT_CANCEL 32
|
#define PIN_INTERRUPT_CANCEL 32
|
||||||
|
#define PIN_INTERRUPT_IRQ_PN532 27
|
||||||
|
|
|
@ -23,6 +23,7 @@ lib_deps =
|
||||||
mcxiaoke/ESPDateTime@^1.0.4
|
mcxiaoke/ESPDateTime@^1.0.4
|
||||||
arduino12/rdm6300@^2.0.0
|
arduino12/rdm6300@^2.0.0
|
||||||
bblanchon/ArduinoJson@^6.20.0
|
bblanchon/ArduinoJson@^6.20.0
|
||||||
|
adafruit/Adafruit PN532@^1.3.0
|
||||||
check_tool = clangtidy
|
check_tool = clangtidy
|
||||||
check_flags =
|
check_flags =
|
||||||
clangtidy: --config-file=.clang-tidy
|
clangtidy: --config-file=.clang-tidy
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -6,40 +6,44 @@
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <HTTPClient.h>
|
#include <HTTPClient.h>
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include <MFRC522.h>
|
|
||||||
#include <ESPDateTime.h>
|
#include <ESPDateTime.h>
|
||||||
#include <DateTimeTZ.h>
|
#include <DateTimeTZ.h>
|
||||||
#include <rdm6300.h>
|
|
||||||
|
|
||||||
#include "wifiFix.h"
|
#include "wifiFix.h"
|
||||||
#include "pitches.h"
|
#include "pitches.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "oled.h"
|
#include "oled.h"
|
||||||
#include "cardReader.h"
|
#include "readers.h"
|
||||||
#include "vars.h"
|
#include "vars.h"
|
||||||
|
|
||||||
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
|
OLED oled(U8G2_SH1106_128X64_NONAME_F_HW_I2C(U8G2_R0, U8X8_PIN_NONE));
|
||||||
MFRC522 mfrc522(PIN_HSPI_SS, PIN_HSPI_RST);
|
|
||||||
WiFiClient* wifi = new WiFiClientFixed();
|
WiFiClient* wifi = new WiFiClientFixed();
|
||||||
HTTPClient* http = new HTTPClient();
|
HTTPClient* http = new HTTPClient();
|
||||||
Rdm6300 rdm6300;
|
|
||||||
|
|
||||||
auto mfrc522reader = MFRC522CardReader(&mfrc522);
|
Reader* readers[] = {
|
||||||
auto rdm6300reader = RDM6300CardReader(&rdm6300);
|
//new MFRC522CardReader(PIN_HSPI_SS, PIN_HSPI_RST),
|
||||||
CardReader* readers[2] = {&mfrc522reader, &rdm6300reader};
|
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_state state = STATE_IDLE;
|
||||||
|
e_scanstate scanstate = SCANSTATE_IDLE;
|
||||||
String apiUrl = "";
|
String apiUrl = "";
|
||||||
const int gTimeout = 5000;
|
const int gTimeout = 5000;
|
||||||
const int scanTimeout = 15000;
|
const int scanTimeout = 15000;
|
||||||
|
|
||||||
CardReader* scannedCardReader;
|
Reader* scannedCardReader;
|
||||||
String scannedCardId = "";
|
String scannedCardId = "";
|
||||||
String lastStatusText = "";
|
String lastStatusText = "";
|
||||||
|
|
||||||
|
|
||||||
volatile bool interruptFired = false;
|
volatile bool interruptFired = false;
|
||||||
unsigned long timer = 0;
|
unsigned long timer = 0;
|
||||||
|
|
||||||
|
void IRAM_ATTR PN532_IRQ() {
|
||||||
|
PN532Reader::irq++;
|
||||||
|
}
|
||||||
|
|
||||||
void IRAM_ATTR TransactInterruptHandler() {
|
void IRAM_ATTR TransactInterruptHandler() {
|
||||||
if (interruptFired || state != STATE_IDLE || digitalRead(PIN_INTERRUPT_TRANSACT)) {
|
if (interruptFired || state != STATE_IDLE || digitalRead(PIN_INTERRUPT_TRANSACT)) {
|
||||||
return;
|
return;
|
||||||
|
@ -73,28 +77,58 @@ void IRAM_ATTR CancelInterruptHandler() {
|
||||||
bool cooldownCheck(long timeout) {
|
bool cooldownCheck(long timeout) {
|
||||||
if (millis() - timer > timeout) {
|
if (millis() - timer > timeout) {
|
||||||
state = STATE_IDLE;
|
state = STATE_IDLE;
|
||||||
updateOLED(u8g2, state);
|
oled.updateOLED(state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
oled.begin();
|
||||||
Serial2.begin(115200, SERIAL_8N1, PIN_HWSERIAL_RX, PIN_HWSERIAL_TX);
|
Serial2.begin(115200, SERIAL_8N1, PIN_HWSERIAL_RX, PIN_HWSERIAL_TX);
|
||||||
SPI.begin(PIN_HSPI_SCLK, PIN_HSPI_MISO, PIN_HSPI_MOSI);
|
SPI.begin(PIN_HSPI_SCLK, PIN_HSPI_MISO, PIN_HSPI_MOSI);
|
||||||
|
|
||||||
ledcSetup(0, 5000, 12);
|
ledcSetup(0, 5000, 12);
|
||||||
|
pinMode(PIN_INTERRUPT_IRQ_PN532, INPUT_PULLUP);
|
||||||
pinMode(PIN_INTERRUPT_TRANSACT, INPUT_PULLUP);
|
pinMode(PIN_INTERRUPT_TRANSACT, INPUT_PULLUP);
|
||||||
pinMode(PIN_INTERRUPT_BALANCE, INPUT_PULLUP);
|
pinMode(PIN_INTERRUPT_BALANCE, INPUT_PULLUP);
|
||||||
pinMode(PIN_INTERRUPT_CANCEL, INPUT_PULLUP);
|
pinMode(PIN_INTERRUPT_CANCEL, INPUT_PULLUP);
|
||||||
pinMode(PIN_INTERRUPT_LINK, INPUT_PULLUP);
|
pinMode(PIN_INTERRUPT_LINK, INPUT_PULLUP);
|
||||||
|
|
||||||
u8g2.begin();
|
|
||||||
drawLogo(u8g2, LOGO_MATECARD);
|
|
||||||
u8g2.sendBuffer();
|
|
||||||
|
|
||||||
SPIFFS.begin(true);
|
SPIFFS.begin(true);
|
||||||
WiFiSettings.hostname = "afrapay-";
|
WiFiSettings.hostname = "afrapay-";
|
||||||
apiUrl = WiFiSettings.string("AfRApay.Web API", "http://192.168.50.170:5296");
|
apiUrl = WiFiSettings.string("AfRApay.Web API", "http://192.168.50.170:5296");
|
||||||
|
@ -103,14 +137,15 @@ void setup() {
|
||||||
else
|
else
|
||||||
WiFiSettings.connect();
|
WiFiSettings.connect();
|
||||||
|
|
||||||
rdm6300.begin(PIN_HWSERIAL_RX);
|
for (Reader* reader : readers) {
|
||||||
rdm6300.set_tag_timeout(65);
|
reader->init();
|
||||||
mfrc522.PCD_Init();
|
}
|
||||||
mfrc522.PCD_DumpVersionToSerial();
|
|
||||||
DateTime.setTimeZone(TZ_Europe_Berlin);
|
DateTime.setTimeZone(TZ_Europe_Berlin);
|
||||||
DateTime.begin();
|
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_TRANSACT, TransactInterruptHandler, FALLING);
|
||||||
attachInterrupt(PIN_INTERRUPT_BALANCE, BalanceInterruptHandler, FALLING);
|
attachInterrupt(PIN_INTERRUPT_BALANCE, BalanceInterruptHandler, FALLING);
|
||||||
attachInterrupt(PIN_INTERRUPT_CANCEL, CancelInterruptHandler, FALLING);
|
attachInterrupt(PIN_INTERRUPT_CANCEL, CancelInterruptHandler, FALLING);
|
||||||
|
@ -119,13 +154,15 @@ void setup() {
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
if (WiFiClass::status() != WL_CONNECTED) {
|
if (WiFiClass::status() != WL_CONNECTED) {
|
||||||
updateOLED(u8g2, state, "WiFi disconnected :(");
|
oled.updateOLED(state, "WiFi disconnected :(");
|
||||||
state = STATE_IDLE;
|
state = STATE_IDLE;
|
||||||
WiFi.reconnect();
|
WiFi.reconnect();
|
||||||
delay(50);
|
delay(50);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateCardscan();
|
||||||
|
|
||||||
if (interruptFired) {
|
if (interruptFired) {
|
||||||
timer = millis();
|
timer = millis();
|
||||||
interruptFired = false;
|
interruptFired = false;
|
||||||
|
@ -133,10 +170,10 @@ void loop() {
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE_IDLE:
|
case STATE_IDLE:
|
||||||
updateOLED(u8g2, state);
|
oled.updateOLED(state);
|
||||||
break;
|
break;
|
||||||
case STATE_TRANSACT_CARDSCAN:
|
case STATE_TRANSACT_CARDSCAN:
|
||||||
for (CardReader* reader : readers) {
|
for (Reader* reader : readers) {
|
||||||
if (reader->isNewCardPresent()) {
|
if (reader->isNewCardPresent()) {
|
||||||
scannedCardId = reader->getCardUid();
|
scannedCardId = reader->getCardUid();
|
||||||
lastStatusText = "Card #" + scannedCardId;
|
lastStatusText = "Card #" + scannedCardId;
|
||||||
|
@ -146,11 +183,11 @@ void loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!cooldownCheck(scanTimeout)) {
|
if (!cooldownCheck(scanTimeout)) {
|
||||||
updateOLED(u8g2, state, String("1.50€"), String(cooldownSecondsRemaining(scanTimeout, timer)));
|
oled.updateOLED(state, String("1.50€"), String(cooldownSecondsRemaining(scanTimeout, timer)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_TRANSACT_VERIFY:
|
case STATE_TRANSACT_VERIFY:
|
||||||
updateOLED(u8g2, state, lastStatusText);
|
oled.updateOLED(state, lastStatusText);
|
||||||
tone(PIN_BUZZER, NOTE_A5, 25);
|
tone(PIN_BUZZER, NOTE_A5, 25);
|
||||||
tone(PIN_BUZZER, NOTE_NONE, 150);
|
tone(PIN_BUZZER, NOTE_NONE, 150);
|
||||||
lastStatusText = cardTransaction(wifi, http, apiUrl, scannedCardId, "-150");
|
lastStatusText = cardTransaction(wifi, http, apiUrl, scannedCardId, "-150");
|
||||||
|
@ -167,7 +204,7 @@ void loop() {
|
||||||
timer = millis();
|
timer = millis();
|
||||||
return;
|
return;
|
||||||
case STATE_LINK_CARD_SCAN:
|
case STATE_LINK_CARD_SCAN:
|
||||||
for (CardReader* reader : readers) {
|
for (Reader* reader : readers) {
|
||||||
if (reader->isNewCardPresent()) {
|
if (reader->isNewCardPresent()) {
|
||||||
scannedCardReader = reader;
|
scannedCardReader = reader;
|
||||||
scannedCardId = reader->getCardUid();
|
scannedCardId = reader->getCardUid();
|
||||||
|
@ -185,7 +222,7 @@ void loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!cooldownCheck(scanTimeout)) {
|
if (!cooldownCheck(scanTimeout)) {
|
||||||
updateOLED(u8g2, state, "Link", String(cooldownSecondsRemaining(scanTimeout, timer)));
|
oled.updateOLED(state, "Link", String(cooldownSecondsRemaining(scanTimeout, timer)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_LINK_CARD_RESCAN:
|
case STATE_LINK_CARD_RESCAN:
|
||||||
|
@ -202,11 +239,11 @@ void loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!cooldownCheck(scanTimeout)) {
|
if (!cooldownCheck(scanTimeout)) {
|
||||||
updateOLED(u8g2, state, "Link - rescan", String(cooldownSecondsRemaining(scanTimeout, timer)));
|
oled.updateOLED(state, "Link - rescan ", String(cooldownSecondsRemaining(scanTimeout, timer)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_LINK_VERIFY:
|
case STATE_LINK_VERIFY:
|
||||||
updateOLED(u8g2, state, lastStatusText);
|
oled.updateOLED(state, lastStatusText);
|
||||||
tone(PIN_BUZZER, NOTE_A5, 25);
|
tone(PIN_BUZZER, NOTE_A5, 25);
|
||||||
tone(PIN_BUZZER, NOTE_NONE, 150);
|
tone(PIN_BUZZER, NOTE_NONE, 150);
|
||||||
lastStatusText = cardLink(wifi, http, apiUrl, scannedCardId);
|
lastStatusText = cardLink(wifi, http, apiUrl, scannedCardId);
|
||||||
|
@ -225,7 +262,7 @@ void loop() {
|
||||||
timer = millis();
|
timer = millis();
|
||||||
return;
|
return;
|
||||||
case STATE_BALANCE_CARDSCAN:
|
case STATE_BALANCE_CARDSCAN:
|
||||||
for (CardReader* reader : readers) {
|
for (Reader* reader : readers) {
|
||||||
if (reader->isNewCardPresent()) {
|
if (reader->isNewCardPresent()) {
|
||||||
scannedCardId = reader->getCardUid();
|
scannedCardId = reader->getCardUid();
|
||||||
lastStatusText = "Card #" + scannedCardId;
|
lastStatusText = "Card #" + scannedCardId;
|
||||||
|
@ -234,11 +271,11 @@ void loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!cooldownCheck(scanTimeout)) {
|
if (!cooldownCheck(scanTimeout)) {
|
||||||
updateOLED(u8g2, state, "Balance", String(cooldownSecondsRemaining(scanTimeout, timer)));
|
oled.updateOLED(state, "Balance", String(cooldownSecondsRemaining(scanTimeout, timer)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_BALANCE_VERIFY:
|
case STATE_BALANCE_VERIFY:
|
||||||
updateOLED(u8g2, state, lastStatusText);
|
oled.updateOLED(state, lastStatusText);
|
||||||
tone(PIN_BUZZER, NOTE_A5, 25);
|
tone(PIN_BUZZER, NOTE_A5, 25);
|
||||||
tone(PIN_BUZZER, NOTE_NONE, 150);
|
tone(PIN_BUZZER, NOTE_NONE, 150);
|
||||||
lastStatusText = cardBalance(wifi, http, apiUrl, scannedCardId);
|
lastStatusText = cardBalance(wifi, http, apiUrl, scannedCardId);
|
||||||
|
@ -261,7 +298,7 @@ void loop() {
|
||||||
case STATE_RESULT_FAILURE:
|
case STATE_RESULT_FAILURE:
|
||||||
case STATE_RESULT_DISPLAY:
|
case STATE_RESULT_DISPLAY:
|
||||||
if (!cooldownCheck(gTimeout)) {
|
if (!cooldownCheck(gTimeout)) {
|
||||||
updateOLED(u8g2, state, lastStatusText, String(cooldownSecondsRemaining(gTimeout, timer)));
|
oled.updateOLED(state, lastStatusText, String(cooldownSecondsRemaining(gTimeout, timer)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,38 @@
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <ESPDateTime.h>
|
#include <ESPDateTime.h>
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "U8g2lib.h"
|
#include "U8g2lib.h"
|
||||||
#include "logos.h"
|
#include "logos.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "vars.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, yStart + 1, vert);
|
||||||
u8g2.drawVLine(xStart + 1, yStart, 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);
|
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, horiz);
|
||||||
u8g2.drawHLine(xStart, yStart + 1, 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);
|
u8g2.drawVLine(xStart + horiz + 1, yStart + 1, vert);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawLogoAfraPay(U8G2 u8g2) {
|
void OLED::drawLogoAfraPay() {
|
||||||
u8g2.setFontMode(1);
|
u8g2.setFontMode(1);
|
||||||
u8g2.setFontDirection(0);
|
u8g2.setFontDirection(0);
|
||||||
|
|
||||||
|
@ -39,42 +65,42 @@ void drawLogoAfraPay(U8G2 u8g2) {
|
||||||
//u8g2.drawHLine(0, yOffset-12, xOffset);
|
//u8g2.drawHLine(0, yOffset-12, xOffset);
|
||||||
//u8g2.drawHLine(127-xOffset-1, yOffset, xOffset);
|
//u8g2.drawHLine(127-xOffset-1, yOffset, xOffset);
|
||||||
|
|
||||||
drawCurvedLineV(u8g2, xOffset + 69, yOffset, 7, 32);
|
drawCurvedLineV(xOffset + 69, yOffset, 7, 32);
|
||||||
drawCurvedLine(u8g2, xOffset + 73, yOffset - 8, 28, 15);
|
drawCurvedLine(xOffset + 73, yOffset - 8, 28, 15);
|
||||||
u8g2.drawPixel(xOffset + 101, yOffset + 7);
|
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;
|
int offset = (128 - width) / 2;
|
||||||
u8g2.drawXBM(offset, yOffset, width, height, bits);
|
u8g2.drawXBM(offset, yOffset, width, height, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawLogo(U8G2 u8g2, e_logo logo) {
|
void OLED::drawLogo(e_logo logo) {
|
||||||
switch (logo) {
|
switch (logo) {
|
||||||
case LOGO_AFRAPAY:
|
case LOGO_AFRAPAY:
|
||||||
drawLogoAfraPay(u8g2);
|
drawLogoAfraPay();
|
||||||
break;
|
break;
|
||||||
case LOGO_CONTACTLESS:
|
case LOGO_CONTACTLESS:
|
||||||
drawLogoBitmap(u8g2, contactless_width, contactless_height, contactless_bits);
|
drawLogoBitmap( contactless_width, contactless_height, contactless_bits);
|
||||||
break;
|
break;
|
||||||
case LOGO_MATECARD:
|
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.setFont(u8g2_font_bpixeldouble_tr);
|
||||||
u8g2.drawStr((126 - u8g2.getStrWidth("matecard")) / 2, 57, "matecard");
|
u8g2.drawStr((126 - u8g2.getStrWidth("matecard")) / 2, 57, "matecard");
|
||||||
break;
|
break;
|
||||||
case LOGO_PENDING:
|
case LOGO_PENDING:
|
||||||
drawLogoBitmap(u8g2, pending_width, pending_height, pending_bits, 5);
|
drawLogoBitmap(pending_width, pending_height, pending_bits, 5);
|
||||||
break;
|
break;
|
||||||
case LOGO_SUCCESS:
|
case LOGO_SUCCESS:
|
||||||
drawLogoBitmap(u8g2, success_width, success_height, success_bits, 5);
|
drawLogoBitmap(success_width, success_height, success_bits, 5);
|
||||||
break;
|
break;
|
||||||
case LOGO_FAILURE:
|
case LOGO_FAILURE:
|
||||||
drawLogoBitmap(u8g2, failure_width, failure_height, failure_bits, 5);
|
drawLogoBitmap(failure_width, failure_height, failure_bits, 5);
|
||||||
break;
|
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.setFont(u8g2_font_bpixel_te);
|
||||||
u8g2.drawUTF8(0, 61, status.c_str());
|
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.setFont(u8g2_font_chargen_92_tr);
|
||||||
u8g2.drawUTF8((127-u8g2.getUTF8Width(textTop.c_str()))/2, 13, textTop.c_str());
|
u8g2.drawUTF8((127-u8g2.getUTF8Width(textTop.c_str()))/2, 13, textTop.c_str());
|
||||||
u8g2.setFont(u8g2_font_maniac_te);
|
u8g2.setFont(u8g2_font_maniac_te);
|
||||||
u8g2.drawUTF8((127-u8g2.getUTF8Width(textBottom.c_str()))/2, 45, textBottom.c_str());
|
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();
|
u8g2.clearBuffer();
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE_IDLE:
|
case STATE_IDLE:
|
||||||
drawLogo(u8g2, LOGO_AFRAPAY);
|
drawLogo(LOGO_AFRAPAY);
|
||||||
break;
|
break;
|
||||||
case STATE_TRANSACT_CARDSCAN:
|
case STATE_TRANSACT_CARDSCAN:
|
||||||
case STATE_BALANCE_CARDSCAN:
|
case STATE_BALANCE_CARDSCAN:
|
||||||
case STATE_LINK_CARD_SCAN:
|
case STATE_LINK_CARD_SCAN:
|
||||||
case STATE_LINK_CARD_RESCAN:
|
case STATE_LINK_CARD_RESCAN:
|
||||||
drawLogo(u8g2, LOGO_CONTACTLESS);
|
drawLogo(LOGO_CONTACTLESS);
|
||||||
break;
|
break;
|
||||||
case STATE_RESULT_SUCCESS:
|
case STATE_RESULT_SUCCESS:
|
||||||
drawLogo(u8g2, LOGO_SUCCESS);
|
drawLogo(LOGO_SUCCESS);
|
||||||
break;
|
break;
|
||||||
case STATE_RESULT_FAILURE:
|
case STATE_RESULT_FAILURE:
|
||||||
drawLogo(u8g2, LOGO_FAILURE);
|
drawLogo(LOGO_FAILURE);
|
||||||
break;
|
break;
|
||||||
case STATE_RESULT_DISPLAY:
|
case STATE_RESULT_DISPLAY:
|
||||||
drawFullScreenText(u8g2, splitString(statusText, ':', 0), splitString(statusText, ':', 1) + "€");
|
drawFullScreenText(splitString(statusText, ':', 0), splitString(statusText, ':', 1) + "€");
|
||||||
drawStatusText(u8g2, splitString(statusText, ':', 2), statusTextRightAligned);
|
drawStatusText(splitString(statusText, ':', 2), statusTextRightAligned);
|
||||||
u8g2.sendBuffer();
|
u8g2.sendBuffer();
|
||||||
return;
|
return;
|
||||||
case STATE_TRANSACT_VERIFY:
|
case STATE_TRANSACT_VERIFY:
|
||||||
case STATE_BALANCE_VERIFY:
|
case STATE_BALANCE_VERIFY:
|
||||||
case STATE_LINK_VERIFY:
|
case STATE_LINK_VERIFY:
|
||||||
drawLogo(u8g2, LOGO_PENDING);
|
drawLogo(LOGO_PENDING);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawStatusText(u8g2, statusText, statusTextRightAligned);
|
drawStatusText(statusText, statusTextRightAligned);
|
||||||
u8g2.sendBuffer();
|
u8g2.sendBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateOLED(const U8G2& u8g2, e_state state) {
|
void OLED::updateOLED(e_state state) {
|
||||||
String time = DateTime.format(DateFormatter::TIME_ONLY);
|
String time = DateTime.format(DateFormatter::TIME_ONLY);
|
||||||
if (!digitalRead(PIN_INTERRUPT_CANCEL) || millis()%20000 < 10000)
|
if (!digitalRead(PIN_INTERRUPT_CANCEL) || millis()%20000 < 10000) {
|
||||||
updateOLED(u8g2, state, time, AFRAPAY_GIT_COMMIT);
|
updateOLED(state, time, revision);
|
||||||
else
|
}
|
||||||
updateOLED(u8g2, state, time, WiFi.localIP().toString());
|
else {
|
||||||
|
updateOLED(state, time, WiFi.localIP().toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
31
AfRApay.MateCard/src/readers/mfrc522.cpp
Normal file
31
AfRApay.MateCard/src/readers/mfrc522.cpp
Normal 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();
|
||||||
|
}
|
53
AfRApay.MateCard/src/readers/pn532.cpp
Normal file
53
AfRApay.MateCard/src/readers/pn532.cpp
Normal 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);
|
||||||
|
}
|
37
AfRApay.MateCard/src/readers/rdm6300.cpp
Normal file
37
AfRApay.MateCard/src/readers/rdm6300.cpp
Normal 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);
|
||||||
|
}
|
Loading…
Reference in a new issue