RFID Master Working, Read the RFID and enter it into the database

This commit is contained in:
Carsten Graf
2025-06-08 14:44:41 +02:00
parent c35e857904
commit f2fe9ac13c
5 changed files with 308 additions and 124 deletions

View File

@@ -88,7 +88,7 @@
try {
// API Aufruf zum Erstellen des Benutzers
const response = await fetch(`/api/users`, {
const response = await fetch(`/api/users/insert`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -110,9 +110,6 @@
// Formular zurücksetzen
clearForm();
// Daten neu laden
await loadUserData();
// UID Feld fokussieren für nächsten Eintrag
setTimeout(() => {
document.getElementById('uid').focus();
@@ -223,7 +220,7 @@
try {
// API Aufruf zum RFID Reader
const response = await fetch(`/api/rfid/read`, {
method: 'POST',
method: 'GET',
headers: {
'Content-Type': 'application/json',
}
@@ -233,7 +230,7 @@
if (result.success && result.uid) {
// UID in das Eingabefeld setzen
uidInput.value = result.uid.toUpperCase();
uidInput.value = result.uid.match(/.{1,2}/g).join(':').toUpperCase();
uidInput.focus();
// Visuelles Feedback

View File

@@ -14,7 +14,6 @@ default_envs = esp32dev
[env]
platform = https://github.com/platformio/platform-espressif32.git
framework = arduino
lib_deps = esp32async/ESPAsyncWebServer@^3.7.7
lib_compat_mode = strict
[env:wemos_d1_mini32]

View File

@@ -81,6 +81,43 @@ UserData checkUser(const String& uid) {
return userData;
}
//Function to enter user data into the database
bool enterUserData(const String& uid, const String& firstname, const String& lastname, int alter) {
if (!backendOnline()) {
Serial.println("No internet connection, cannot enter user data.");
return false;
}
HTTPClient http;
http.begin(String(BACKEND_SERVER) + "/api/users/insert");
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", String("Bearer ") + BACKEND_TOKEN);
// Create JSON payload
StaticJsonDocument<256> requestDoc;
requestDoc["uid"] = uid;
requestDoc["vorname"] = firstname;
requestDoc["nachname"] = lastname;
requestDoc["alter"] = alter;
String requestBody;
serializeJson(requestDoc, requestBody);
int httpCode = http.POST(requestBody);
if (httpCode == HTTP_CODE_CREATED) {
Serial.println("User data entered successfully.");
http.end();
return true;
} else {
Serial.printf("Failed to enter user data, HTTP code: %d\n", httpCode);
http.end();
return false;
}
}
// Keep this for backward compatibility
bool userExists(const String& uid) {
return checkUser(uid).exists;

View File

@@ -19,7 +19,7 @@
#include <webserverrouter.h>
#include <communication.h>
#include <databasebackend.h>
#include <rfid.h>
const char* firmwareversion = "1.0.0"; // Version der Firmware
@@ -249,7 +249,8 @@ void setup() {
setupTimeAPI(server);
setupLicenceAPI(server);
setupDebugAPI(server);
setupBackendRoutes(server);// Speichere WLAN-Einstellungen, falls noch nicht vorhanden
setupBackendRoutes(server);
setupRFIDRoute(server);
// Gespeicherte Daten laden
@@ -264,6 +265,7 @@ void setup() {
setupWebSocket();
setupLED();
setupMqttServer(); // MQTT Server initialisieren
setupRFID();
}
@@ -272,4 +274,5 @@ void loop() {
checkAutoReset();
loopMqttServer(); // MQTT Server in der Loop aufrufen
loopWebSocket();
loopRFID(); // RFID Loop aufrufen
}

View File

@@ -1,141 +1,289 @@
#pragma once
#include <Arduino.h>
#include <WebServer.h>
#include <ArduinoJson.h>
#include <SPI.h>
#include <MFRC522.h>
// RFID Konfiguration
#define SS_PIN 21
#define RST_PIN 22
MFRC522 mfrc522(SS_PIN, RST_PIN);
#define RST_PIN 21 // Configurable, see typical pin layout above
#define SS_PIN 5 // Configurable, see typical pin layout above
// Webserver auf Port 80
WebServer server(80);
// Struktur für Benutzerdaten
struct User {
String uid;
String vorname;
String nachname;
int alter;
unsigned long timestamp;
};
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
std::map<String, unsigned long> blockedUIDs; // Map to store blocked UIDs and their timestamps
const unsigned long BLOCK_DURATION = 10 * 1000; // 10 Seconds in milliseconds
// Neue Variablen für API-basiertes Lesen
bool rfidReadRequested = false;
String lastReadUID = "";
bool rfidReadSuccess = false;
unsigned long rfidReadStartTime = 0;
const unsigned long RFID_READ_TIMEOUT = 10000; // 10 Sekunden Timeout für API Requests
void setupRFID() {
// SPI und RFID initialisieren
SPI.begin();
mfrc522.PCD_Init();
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
delay(4); // Optional delay. Some boards need more time after init to be ready
mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details
}
void setupRoutes() {
// CORS Header für alle Anfragen
server.onNotFound([]() {
if (server.method() == HTTP_OPTIONS) {
server.sendHeader("Access-Control-Allow-Origin", "*");
server.sendHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
server.sendHeader("Access-Control-Allow-Headers", "Content-Type");
server.send(200);
} else {
server.send(404, "text/plain", "Not Found");
}
});
// API: RFID UID lesen
server.on("/api/rfid/read", HTTP_POST, []() {
server.sendHeader("Access-Control-Allow-Origin", "*");
server.sendHeader("Content-Type", "application/json");
String uid = readRFIDCard();
DynamicJsonDocument doc(200);
if (uid != "") {
doc["success"] = true;
doc["uid"] = uid;
Serial.println("UID gelesen: " + uid);
} else {
doc["success"] = false;
doc["error"] = "Keine RFID Karte gefunden";
}
String response;
serializeJson(doc, response);
server.send(200, "application/json", response);
});
// API: Neuen Benutzer erstellen
server.on("/api/users", HTTP_POST, []() {
server.sendHeader("Access-Control-Allow-Origin", "*");
server.sendHeader("Content-Type", "application/json");
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, server.arg("plain"));
if (error) {
DynamicJsonDocument errorDoc(200);
errorDoc["success"] = false;
errorDoc["error"] = "Ungültige JSON Daten";
String response;
serializeJson(errorDoc, response);
server.send(400, "application/json", response);
return;
}
// Daten aus JSON extrahieren
String uid = doc["uid"].as<String>();
String vorname = doc["vorname"].as<String>();
String nachname = doc["nachname"].as<String>();
int alter = doc["alter"].as<int>();
// Prüfen ob UID bereits existiert
// Benutzer hinzufügen
// Erfolgreiche Antwort
DynamicJsonDocument successDoc(200);
successDoc["success"] = true;
successDoc["message"] = "Benutzer erfolgreich gespeichert";
String response;
serializeJson(successDoc, response);
server.send(201, "application/json", response);
Serial.println("Neuer Benutzer: " + vorname + " " + nachname + " (UID: " + uid + ")");
});
}
// RFID Karte lesen
String readRFIDCard() {
// Prüfen ob neue Karte vorhanden
void handleAutomaticRFID() {
if (!mfrc522.PICC_IsNewCardPresent()) {
return "";
return;
}
// Select one of the cards
if (!mfrc522.PICC_ReadCardSerial()) {
return;
}
// Read the UID
String uid = "";
for (byte i = 0; i < mfrc522.uid.size; i++) {
if (i > 0)
uid += ":";
if (mfrc522.uid.uidByte[i] < 0x10)
uid += "0";
uid += String(mfrc522.uid.uidByte[i], HEX);
}
// Check if the UID is blocked
unsigned long currentTime = millis();
if (blockedUIDs.find(uid) != blockedUIDs.end()) {
if (currentTime - blockedUIDs[uid] < BLOCK_DURATION) {
Serial.print(F("UID blocked for 10 seconds. Remaining time: "));
Serial.print((BLOCK_DURATION - (currentTime - blockedUIDs[uid])) / 1000);
Serial.println(F(" seconds."));
Serial.println(uid);
return;
} else {
// Remove the UID from the blocked list if the block duration has passed
blockedUIDs.erase(uid);
}
}
// Process the UID
Serial.print(F("UID: "));
Serial.println(uid);
// Block the UID for 10 seconds
blockedUIDs[uid] = currentTime;
//show the remaining time for the block
Serial.print(F("UID blocked for 10 seconds. Remaining time: "));
Serial.print((BLOCK_DURATION - (currentTime - blockedUIDs[uid])) / 1000);
Serial.println(F(" seconds."));
// Halt the card
mfrc522.PICC_HaltA();
}
// Neue Funktion für API-basiertes RFID Lesen
void handleAPIRFIDRead() {
unsigned long currentTime = millis();
// Timeout prüfen
if (currentTime - rfidReadStartTime > RFID_READ_TIMEOUT) {
Serial.println("RFID API Timeout - keine Karte erkannt");
rfidReadRequested = false;
rfidReadSuccess = false;
lastReadUID = "";
return;
}
// Prüfen ob neue Karte vorhanden ist
if (!mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Karte auswählen
if (!mfrc522.PICC_ReadCardSerial()) {
return "";
return;
}
// UID zusammensetzen
// UID für API lesen (ohne Doppelpunkt-Trenner, Großbuchstaben)
String uid = "";
for (byte i = 0; i < mfrc522.uid.size; i++) {
if (i > 0) uid += ":";
if (mfrc522.uid.uidByte[i] < 0x10) uid += "0";
if (mfrc522.uid.uidByte[i] < 0x10) {
uid += "0"; // Leading Zero für einstellige Hex-Werte
}
uid += String(mfrc522.uid.uidByte[i], HEX);
}
// UID in Großbuchstaben konvertieren
uid.toUpperCase();
// Karte deaktivieren
mfrc522.PICC_HaltA();
Serial.println("RFID API UID gelesen: " + uid);
return uid;
// Ergebnis speichern
lastReadUID = uid;
rfidReadSuccess = true;
rfidReadRequested = false;
// Karte "halt" setzen
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
}
// API Funktion: RFID Lesevorgang starten
void startRFIDRead() {
Serial.println("RFID API Lesevorgang gestartet...");
rfidReadRequested = true;
rfidReadSuccess = false;
lastReadUID = "";
rfidReadStartTime = millis();
}
// API Funktion: Prüfen ob Lesevorgang abgeschlossen
bool isRFIDReadComplete() {
return !rfidReadRequested;
}
// API Funktion: Ergebnis des Lesevorgangs abrufen
String getRFIDReadResult(bool& success) {
success = rfidReadSuccess;
return lastReadUID;
}
void setupRFIDRoute(AsyncWebServer& server) {
server.on("/api/rfid/read", HTTP_GET, [](AsyncWebServerRequest *request) {
Serial.println("api/rfid/read");
// Start RFID-Lesevorgang
startRFIDRead();
unsigned long startTime = millis();
// Warten, bis eine UID gelesen wird oder Timeout eintritt
while (!isRFIDReadComplete()) {
if (millis() - startTime > RFID_READ_TIMEOUT) {
break;
}
delay(10); // Kurze Pause, um die CPU nicht zu blockieren
}
DynamicJsonDocument response(200);
if (rfidReadSuccess && lastReadUID.length() > 0) {
response["success"] = true;
response["uid"] = lastReadUID;
response["message"] = "UID erfolgreich gelesen";
} else {
response["success"] = false;
response["error"] = "Keine RFID Karte erkannt oder Timeout";
response["uid"] = "";
}
String jsonString;
serializeJson(response, jsonString);
request->send(200, "application/json", jsonString);
});
server.on("/api/users/insert", HTTP_POST, [](AsyncWebServerRequest *request) {}, NULL, [](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) {
Serial.println("/api/users/insert");
// Parse the incoming JSON payload
DynamicJsonDocument doc(512);
DeserializationError error = deserializeJson(doc, data, len);
DynamicJsonDocument response(200);
if (error) {
Serial.println("Fehler beim Parsen der JSON-Daten");
response["success"] = false;
response["error"] = "Ungültige JSON-Daten";
} else {
// Extract user data from the JSON payload
String uid = doc["uid"] | "";
String vorname = doc["vorname"] | "";
String nachname = doc["nachname"] | "";
int alter = doc["alter"] | 0;
// Validate the data
if (uid.isEmpty() || vorname.isEmpty() || nachname.isEmpty() || alter <= 0) {
Serial.println("Ungültige Eingabedaten");
response["success"] = false;
response["error"] = "Ungültige Eingabedaten";
} else {
// Process the data using the enterUserData function
Serial.println("Benutzerdaten empfangen:");
Serial.println("UID: " + uid);
Serial.println("Vorname: " + vorname);
Serial.println("Nachname: " + nachname);
Serial.println("Alter: " + String(alter));
bool dbSuccess = enterUserData(uid, vorname, nachname, alter);
if (dbSuccess) {
response["success"] = true;
response["message"] = "Benutzer erfolgreich gespeichert";
} else {
response["success"] = false;
response["error"] = "Fehler beim Speichern in der Datenbank";
}
}
}
// Send the response back to the client
String jsonString;
serializeJson(response, jsonString);
request->send(200, "application/json", jsonString);
});
}
// API Funktion: RFID Reader Status prüfen
bool checkRFIDReaderStatus() {
byte version = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
// Bekannte MFRC522 Versionen: 0x91, 0x92
if (version == 0x91 || version == 0x92) {
Serial.println("RFID Reader OK (Version: 0x" + String(version, HEX) + ")");
return true;
} else {
Serial.println("RFID Reader Fehler (Version: 0x" + String(version, HEX) + ")");
return false;
}
}
// Hilfsfunktion: Blockierte UIDs aufräumen
void cleanupBlockedUIDs() {
unsigned long currentTime = millis();
// Iterator für sicheres Löschen während der Iteration
for (auto it = blockedUIDs.begin(); it != blockedUIDs.end();) {
if (currentTime - it->second >= BLOCK_DURATION) {
it = blockedUIDs.erase(it);
} else {
++it;
}
}
}
void loopRFID(){
// Originale Funktionalität für automatisches Lesen
if (!rfidReadRequested) {
handleAutomaticRFID();
}
// API-basiertes Lesen verarbeiten
if (rfidReadRequested) {
handleAPIRFIDRead();
}
}