Add 125khz rfid support

This commit is contained in:
Laura Hausmann 2023-02-08 02:25:12 +01:00
parent 94ca5da794
commit da50b2ab99
Signed by: zotan
GPG key ID: D044E84C5BE01605
11 changed files with 122 additions and 68 deletions

View file

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

View file

@ -1,5 +1,4 @@
#ifndef AFRAPAY_LOGOS_H
#define AFRAPAY_LOGOS_H
#pragma once
enum e_logo {
LOGO_AFRAPAY, LOGO_CONTACTLESS, LOGO_MATECARD, LOGO_PENDING, LOGO_SUCCESS, LOGO_FAILURE
@ -150,6 +149,4 @@ static unsigned char matecard_bits[] = {
0x00, 0xAA, 0xFE, 0x6F, 0x94, 0x82, 0x10, 0x00, 0x00, 0x00, 0xF8, 0xAB,
0x1A, 0x80, 0x28, 0x4A, 0x00, 0x00, 0x00, 0x40, 0xFF, 0x0B, 0x20, 0xA2,
0x00, 0x00, 0x00, 0x00, 0x80, 0xAA, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
};
#endif
};

View file

@ -1,15 +1,11 @@
#pragma once
#include "Arduino.h"
#include <U8g2lib.h>
#include "logos.h"
#include "utils.h"
#ifndef AFRAPAY_OLED_H
#define AFRAPAY_OLED_H
void drawLogo(U8G2 u8g2, e_logo logo);
void drawStatusText(U8G2 u8g2, String status, String statusRightAligned = "");
void updateOLED(U8G2 u8g2, e_state state, String statusText, String statusTextRightAligned = "");
void updateOLED(U8G2 u8g2, e_state state);
#endif
void updateOLED(U8G2 u8g2, e_state state);

View file

@ -1,5 +1,4 @@
#ifndef AFRAPAY_PITCHES_H
#define AFRAPAY_PITCHES_H
#pragma once
#define NOTE_NONE 0
#define NOTE_B0 31
@ -90,6 +89,4 @@
#define NOTE_C8 4186
#define NOTE_CS8 4435
#define NOTE_D8 4699
#define NOTE_DS8 4978
#endif
#define NOTE_DS8 4978

View file

@ -1,10 +1,10 @@
#pragma once
#include <Arduino.h>
#include <HTTPClient.h>
#ifndef AFRAPAY_UTILS_H
#define AFRAPAY_UTILS_H
unsigned long cooldownSecondsRemaining(unsigned long timeout, unsigned long timer);
String byteArrayAsHexString(byte *buffer, byte bufferSize);
String uint32AsHexString(uint32_t input);
String cardLink(WiFiClient* wifi, HTTPClient* http, String apiUrl, String cardId);
String cardBalance(WiFiClient* wifi, HTTPClient* http, String apiUrl, String cardId);
String cardTransaction(WiFiClient* wifi, HTTPClient* http, String apiUrl, String cardId, String amount);
@ -21,6 +21,4 @@ enum e_state {
STATE_RESULT_SUCCESS,
STATE_RESULT_FAILURE,
STATE_RESULT_DISPLAY,
};
#endif
};

View file

@ -1,9 +1,6 @@
#ifndef AFRAPAY_WIFIFIX_H
#define AFRAPAY_WIFIFIX_H
#pragma once
class WiFiClientFixed : public WiFiClient {
public:
void flush() override;
};
#endif
};

View file

@ -20,3 +20,4 @@ lib_deps =
miguelbalboa/MFRC522@^1.4.10
arduino-libraries/NTPClient@^3.2.1
mcxiaoke/ESPDateTime@^1.0.4
arduino12/rdm6300@^2.0.0

View file

@ -0,0 +1,25 @@
#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);
}
RDM6300CardReader::RDM6300CardReader(Rdm6300 *reader) { iReader = reader; }
bool RDM6300CardReader::isNewCardPresent() {
return iReader->get_new_tag_id();
}
String RDM6300CardReader::getCardUid() {
return uint32AsHexString(iReader->get_tag_id());
}

View file

@ -9,22 +9,27 @@
#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"
#pragma clang diagnostic push
#pragma ide diagnostic ignored "OCUnusedMacroInspection"
//MFRC522 pinout (front) 3V3 RST GND IRQ MISO MOSI SCK SDA
//MFRC522 pinout (rear) SDA SCK MOSI MISO IRQ GND RST 3V3
#define PIN_HWSERIAL_RX 16
#define PIN_HWSERIAL_TX 17
#define HSPI_MISO 12
#define HSPI_MOSI 13
#define HSPI_SCLK 14
#define HSPI_SS 15
#define HSPI_RST 16
#define HSPI_RST 4
#define PIN_BUZZER 19
//#define PIN_OLED_SDA 21
@ -38,6 +43,11 @@ U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
MFRC522 mfrc522(HSPI_SS, HSPI_RST);
WiFiClient *wifi = new WiFiClientFixed();
HTTPClient *http = new HTTPClient();
Rdm6300 rdm6300;
auto mfrc522reader = MFRC522CardReader(&mfrc522);
auto rdm6300reader = RDM6300CardReader(&rdm6300);
CardReader* readers[2] = {&mfrc522reader, &rdm6300reader};
e_state state = STATE_IDLE;
String apiUrl = "";
@ -47,32 +57,30 @@ const int scanTimeout = 15000;
String scannedCardId = "";
String lastStatusText = "";
bool interruptFired = false;
unsigned long timer = 0;
void IRAM_ATTR TransactInterruptHandler() {
Serial.println("transact interrupt hit");
if (state != STATE_IDLE) {
if (interruptFired || state != STATE_IDLE) {
return;
}
timer = millis();
interruptFired = true;
state = STATE_TRANSACT_CARDSCAN;
}
void IRAM_ATTR LinkInterruptHandler() {
Serial.println("link interrupt hit");
if (state != STATE_IDLE) {
if (interruptFired || state != STATE_IDLE) {
return;
}
timer = millis();
interruptFired = true;
state = STATE_LINK_CARDSCAN;
}
void IRAM_ATTR BalanceInterruptHandler() {
Serial.println("balance interrupt hit");
if (state != STATE_IDLE) {
if (interruptFired || state != STATE_IDLE) {
return;
}
timer = millis();
interruptFired = true;
state = STATE_BALANCE_CARDSCAN;
}
@ -88,6 +96,7 @@ bool cooldownCheck(long timeout) {
void setup() {
Serial.begin(115200);
Serial2.begin(115200, SERIAL_8N1, PIN_HWSERIAL_RX, PIN_HWSERIAL_TX);
u8g2.begin();
drawLogo(u8g2, LOGO_MATECARD);
u8g2.sendBuffer();
@ -96,6 +105,7 @@ void setup() {
WiFiSettings.hostname = "afrapay-";
apiUrl = WiFiSettings.string("AfRApay.Web API", "http://192.168.50.170:5296");
WiFiSettings.connect();
rdm6300.begin(PIN_HWSERIAL_RX);
mfrc522.PCD_Init();
mfrc522.PCD_DumpVersionToSerial();
DateTime.setTimeZone(TZ_Europe_Berlin);
@ -121,22 +131,27 @@ void loop() {
return;
}
if (interruptFired) {
timer = millis();
interruptFired = false;
}
switch (state) {
case STATE_IDLE:
updateOLED(u8g2, state);
break;
case STATE_TRANSACT_CARDSCAN:
if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
scannedCardId = byteArrayAsHexString(mfrc522.uid.uidByte, mfrc522.uid.size);
mfrc522.PICC_HaltA();
lastStatusText = "Card #" + scannedCardId;
state = STATE_TRANSACT_VERIFY;
return;
} else {
if (!cooldownCheck(scanTimeout)) {
updateOLED(u8g2, state, String("1.50€"), String(cooldownSecondsRemaining(scanTimeout, timer)));
for (CardReader *reader : readers) {
if (reader->isNewCardPresent()){
scannedCardId = reader->getCardUid();
lastStatusText = "Card #" + scannedCardId;
state = STATE_TRANSACT_VERIFY;
return;
}
}
if (!cooldownCheck(scanTimeout)) {
updateOLED(u8g2, state, String("1.50€"), String(cooldownSecondsRemaining(scanTimeout, timer)));
}
break;
case STATE_TRANSACT_VERIFY:
updateOLED(u8g2, state, lastStatusText);
@ -157,17 +172,17 @@ void loop() {
timer = millis();
return;
case STATE_LINK_CARDSCAN:
if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
scannedCardId = byteArrayAsHexString(mfrc522.uid.uidByte, mfrc522.uid.size);
mfrc522.PICC_HaltA();
lastStatusText = "Card #" + scannedCardId;
state = STATE_LINK_VERIFY;
return;
} else {
if (!cooldownCheck(scanTimeout)) {
updateOLED(u8g2, state, "Link", String(cooldownSecondsRemaining(scanTimeout, timer)));
for (CardReader *reader : readers) {
if (reader->isNewCardPresent()){
scannedCardId = reader->getCardUid();
lastStatusText = "Card #" + scannedCardId;
state = STATE_LINK_VERIFY;
return;
}
}
if (!cooldownCheck(scanTimeout)) {
updateOLED(u8g2, state, "Link", String(cooldownSecondsRemaining(scanTimeout, timer)));
}
break;
case STATE_LINK_VERIFY:
updateOLED(u8g2, state, lastStatusText);
@ -189,17 +204,17 @@ void loop() {
timer = millis();
return;
case STATE_BALANCE_CARDSCAN:
if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
scannedCardId = byteArrayAsHexString(mfrc522.uid.uidByte, mfrc522.uid.size);
mfrc522.PICC_HaltA();
lastStatusText = "Card #" + scannedCardId;
state = STATE_BALANCE_VERIFY;
return;
} else {
if (!cooldownCheck(scanTimeout)) {
updateOLED(u8g2, state, "Balance", String(cooldownSecondsRemaining(scanTimeout, timer)));
for (CardReader *reader : readers) {
if (reader->isNewCardPresent()){
scannedCardId = reader->getCardUid();
lastStatusText = "Card #" + scannedCardId;
state = STATE_BALANCE_VERIFY;
return;
}
}
if (!cooldownCheck(scanTimeout)) {
updateOLED(u8g2, state, "Balance", String(cooldownSecondsRemaining(scanTimeout, timer)));
}
break;
case STATE_BALANCE_VERIFY:
updateOLED(u8g2, state, lastStatusText);

View file

@ -11,6 +11,10 @@ String byteArrayAsHexString(byte *buffer, byte bufferSize) {
return s;
}
String uint32AsHexString(uint32_t input) {
return byteArrayAsHexString(reinterpret_cast<byte *>(&input), sizeof input);
}
unsigned long cooldownSecondsRemaining(unsigned long timeout, unsigned long timer) {
return (timeout - (millis() - timer)) / 1000 + 1;
}

View file

@ -1,13 +1,9 @@
#include <WiFi.h>
#include <lwip/sockets.h>
#include "wifiFix.h"
#define WIFI_CLIENT_FLUSH_BUFFER_SIZE (1024)
class WiFiClientFixed : public WiFiClient {
public:
void flush() override;
};
void WiFiClientFixed::flush() {
int res;
size_t a = available(), toRead = 0;