Add 125khz rfid support
This commit is contained in:
parent
94ca5da794
commit
da50b2ab99
28
AfRApay.MateCard/include/cardReader.h
Normal file
28
AfRApay.MateCard/include/cardReader.h
Normal 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;
|
||||
};
|
|
@ -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
|
||||
};
|
|
@ -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);
|
|
@ -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
|
|
@ -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
|
||||
};
|
|
@ -1,9 +1,6 @@
|
|||
#ifndef AFRAPAY_WIFIFIX_H
|
||||
#define AFRAPAY_WIFIFIX_H
|
||||
#pragma once
|
||||
|
||||
class WiFiClientFixed : public WiFiClient {
|
||||
public:
|
||||
void flush() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
};
|
|
@ -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
|
||||
|
|
25
AfRApay.MateCard/src/cardReader.cpp
Normal file
25
AfRApay.MateCard/src/cardReader.cpp
Normal 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());
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue