Compare commits

...

5 Commits

Author SHA1 Message Date
tugsi 2068810386 git 2025-03-23 18:31:25 +01:00
tugsi f2bf5e96f0 - RFID-Reader-Task optimized 2025-03-18 11:54:56 +01:00
tugsi 9a7ba2845d -RFID SPI Pins angepasst
- NFC-Tag verbessert
2025-03-18 11:36:10 +01:00
tugsi f1a9c3c5d4 -Abfrage Error gefixt, wenn leer dann kein Error mehr 2025-03-17 11:19:28 +01:00
tugsi ccca159a10 rfid.js wieder auf Originalstand gebracht 2025-03-17 09:31:26 +01:00
6 changed files with 466 additions and 366 deletions
+2
View File
@@ -1,5 +1,7 @@
.pio .pio
.vscode
.vscode/.browse.c_cpp.db* .vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json .vscode/c_cpp_properties.json
.vscode/launch.json .vscode/launch.json
.vscode/ipch .vscode/ipch
data
+100 -156
View File
@@ -53,94 +53,118 @@ function initWebSocket() {
// Wenn eine existierende Verbindung besteht, diese erst schließen // Wenn eine existierende Verbindung besteht, diese erst schließen
if (socket) { if (socket) {
try {
socket.onclose = null; // Remove onclose handler before closing
socket.onerror = null; // Remove error handler
socket.close(); socket.close();
} catch (e) {
console.error('Error closing existing socket:', e);
}
socket = null; socket = null;
} }
try { try {
socket = new WebSocket('ws://' + window.location.host + '/ws'); socket = new WebSocket('ws://' + window.location.host + '/ws');
socket.onopen = function() { socket.onopen = function () {
console.log('WebSocket connection established');
isConnected = true; isConnected = true;
updateConnectionStatus(); updateConnectionStatus();
startHeartbeat(); // Starte Heartbeat nach erfolgreicher Verbindung startHeartbeat(); // Starte Heartbeat nach erfolgreicher Verbindung
}; };
socket.onclose = function(event) { socket.onclose = function () {
console.log('WebSocket connection closed:', event.code, event.reason);
isConnected = false; isConnected = false;
updateConnectionStatus(); updateConnectionStatus();
if (heartbeatTimer) { if (heartbeatTimer) clearInterval(heartbeatTimer);
clearInterval(heartbeatTimer);
heartbeatTimer = null;
}
// Nur neue Verbindung versuchen, wenn kein Timer läuft // Nur neue Verbindung versuchen, wenn kein Timer läuft
if (!reconnectTimer) { if (!reconnectTimer) {
reconnectTimer = setTimeout(() => { reconnectTimer = setTimeout(() => {
console.log('Attempting to reconnect...');
initWebSocket(); initWebSocket();
}, RECONNECT_INTERVAL); }, RECONNECT_INTERVAL);
} }
}; };
socket.onerror = function(error) { socket.onerror = function (error) {
console.error('WebSocket error occurred:', error);
isConnected = false; isConnected = false;
updateConnectionStatus(); updateConnectionStatus();
if (heartbeatTimer) { if (heartbeatTimer) clearInterval(heartbeatTimer);
clearInterval(heartbeatTimer);
heartbeatTimer = null; // Bei Fehler Verbindung schließen und neu aufbauen
if (socket) {
socket.close();
socket = null;
} }
}; };
socket.onmessage = function(event) { socket.onmessage = function (event) {
try { lastHeartbeatResponse = Date.now(); // Aktualisiere Zeitstempel bei jeder Server-Antwort
lastHeartbeatResponse = Date.now();
const data = JSON.parse(event.data); const data = JSON.parse(event.data);
if (data.type === 'amsData') {
// Handle different message types
switch(data.type) {
case 'amsData':
displayAmsData(data.payload); displayAmsData(data.payload);
break; } else if (data.type === 'nfcTag') {
case 'nfcTag':
updateNfcStatusIndicator(data.payload); updateNfcStatusIndicator(data.payload);
break; } else if (data.type === 'nfcData') {
case 'nfcData':
updateNfcData(data.payload); updateNfcData(data.payload);
break; } else if (data.type === 'writeNfcTag') {
case 'writeNfcTag':
handleWriteNfcTagResponse(data.success); handleWriteNfcTagResponse(data.success);
break; } else if (data.type === 'heartbeat') {
case 'heartbeat': // Optional: Spezifische Behandlung von Heartbeat-Antworten
handleHeartbeatResponse(data); // Update status dots
break; const bambuDot = document.getElementById('bambuDot');
case 'setSpoolmanSettings': const spoolmanDot = document.getElementById('spoolmanDot');
handleSpoolmanSettingsResponse(data); const ramStatus = document.getElementById('ramStatus');
break;
default: if (bambuDot) {
console.warn('Unknown message type:', data.type); bambuDot.className = 'status-dot ' + (data.bambu_connected ? 'online' : 'offline');
// Add click handler only when offline
if (!data.bambu_connected) {
bambuDot.style.cursor = 'pointer';
bambuDot.onclick = function () {
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({
type: 'reconnect',
payload: 'bambu'
}));
}
};
} else {
bambuDot.style.cursor = 'default';
bambuDot.onclick = null;
}
}
if (spoolmanDot) {
spoolmanDot.className = 'status-dot ' + (data.spoolman_connected ? 'online' : 'offline');
// Add click handler only when offline
if (!data.spoolman_connected) {
spoolmanDot.style.cursor = 'pointer';
spoolmanDot.onclick = function () {
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({
type: 'reconnect',
payload: 'spoolman'
}));
}
};
} else {
spoolmanDot.style.cursor = 'default';
spoolmanDot.onclick = null;
}
}
if (ramStatus) {
ramStatus.textContent = `${data.freeHeap}k`;
}
}
else if (data.type === 'setSpoolmanSettings') {
if (data.payload == 'success') {
showNotification(`Spoolman Settings set successfully`, true);
} else {
showNotification(`Error setting Spoolman Settings`, false);
} }
} catch (error) {
console.error('Error processing WebSocket message:', error);
} }
}; };
} catch (error) { } catch (error) {
console.error('Error initializing WebSocket:', error);
isConnected = false; isConnected = false;
updateConnectionStatus(); updateConnectionStatus();
// Nur neue Verbindung versuchen, wenn kein Timer läuft
if (!reconnectTimer) { if (!reconnectTimer) {
reconnectTimer = setTimeout(() => { reconnectTimer = setTimeout(() => {
console.log('Attempting to reconnect after error...');
initWebSocket(); initWebSocket();
}, RECONNECT_INTERVAL); }, RECONNECT_INTERVAL);
} }
@@ -165,26 +189,26 @@ function updateConnectionStatus() {
} }
// Event Listeners // Event Listeners
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function () {
initWebSocket(); initWebSocket();
// Event Listener für Checkbox // Event Listener für Checkbox
document.getElementById("onlyWithoutSmId").addEventListener("change", function() { document.getElementById("onlyWithoutSmId").addEventListener("change", function () {
const spoolsData = window.getSpoolData(); const spoolsData = window.getSpoolData();
window.populateVendorDropdown(spoolsData); window.populateVendorDropdown(spoolsData);
}); });
}); });
// Event Listener für Spoolman Events // Event Listener für Spoolman Events
document.addEventListener('spoolDataLoaded', function(event) { document.addEventListener('spoolDataLoaded', function (event) {
window.populateVendorDropdown(event.detail); window.populateVendorDropdown(event.detail);
}); });
document.addEventListener('spoolmanError', function(event) { document.addEventListener('spoolmanError', function (event) {
showNotification(`Spoolman Error: ${event.detail.message}`, false); showNotification(`Spoolman Error: ${event.detail.message}`, false);
}); });
document.addEventListener('filamentSelected', function(event) { document.addEventListener('filamentSelected', function (event) {
updateNfcInfo(); updateNfcInfo();
// Zeige Spool-Buttons wenn ein Filament ausgewählt wurde // Zeige Spool-Buttons wenn ein Filament ausgewählt wurde
const selectedText = document.getElementById("selected-filament").textContent; const selectedText = document.getElementById("selected-filament").textContent;
@@ -194,12 +218,12 @@ document.addEventListener('filamentSelected', function(event) {
// Hilfsfunktion für kontrastreiche Textfarbe // Hilfsfunktion für kontrastreiche Textfarbe
function getContrastColor(hexcolor) { function getContrastColor(hexcolor) {
// Konvertiere Hex zu RGB // Konvertiere Hex zu RGB
const r = parseInt(hexcolor.substr(0,2),16); const r = parseInt(hexcolor.substr(0, 2), 16);
const g = parseInt(hexcolor.substr(2,2),16); const g = parseInt(hexcolor.substr(2, 2), 16);
const b = parseInt(hexcolor.substr(4,2),16); const b = parseInt(hexcolor.substr(4, 2), 16);
// Berechne Helligkeit (YIQ Formel) // Berechne Helligkeit (YIQ Formel)
const yiq = ((r*299)+(g*587)+(b*114))/1000; const yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
// Return schwarz oder weiß basierend auf Helligkeit // Return schwarz oder weiß basierend auf Helligkeit
return (yiq >= 128) ? '#000000' : '#FFFFFF'; return (yiq >= 128) ? '#000000' : '#FFFFFF';
@@ -365,7 +389,6 @@ function updateSpoolButtons(show) {
}); });
} }
// Verbesserte Funktion zum Behandeln von Spoolman Settings
function handleSpoolmanSettings(tray_info_idx, setting_id, cali_idx, nozzle_temp_min, nozzle_temp_max) { function handleSpoolmanSettings(tray_info_idx, setting_id, cali_idx, nozzle_temp_min, nozzle_temp_max) {
// Hole das ausgewählte Filament // Hole das ausgewählte Filament
const selectedText = document.getElementById("selected-filament").textContent; const selectedText = document.getElementById("selected-filament").textContent;
@@ -396,7 +419,6 @@ function handleSpoolmanSettings(tray_info_idx, setting_id, cali_idx, nozzle_temp
} }
} }
// Verbesserte Funktion zum Behandeln von Spool Out
function handleSpoolOut() { function handleSpoolOut() {
// Erstelle Payload // Erstelle Payload
const payload = { const payload = {
@@ -421,21 +443,17 @@ function handleSpoolOut() {
} }
} }
// Verbesserte Funktion zum Behandeln des Spool-In-Klicks // Neue Funktion zum Behandeln des Spool-In-Klicks
function handleSpoolIn(amsId, trayId) { function handleSpoolIn(amsId, trayId) {
console.log("handleSpoolIn called with amsId:", amsId, "trayId:", trayId);
// Prüfe WebSocket Verbindung zuerst // Prüfe WebSocket Verbindung zuerst
if (!socket || socket.readyState !== WebSocket.OPEN) { if (!socket || socket.readyState !== WebSocket.OPEN) {
showNotification("No active WebSocket connection!", false); showNotification("No active WebSocket connection!", false);
console.error("WebSocket not connected, state:", socket ? socket.readyState : "no socket"); console.error("WebSocket not connected");
return; return;
} }
// Hole das ausgewählte Filament // Hole das ausgewählte Filament
const selectedText = document.getElementById("selected-filament").textContent; const selectedText = document.getElementById("selected-filament").textContent;
console.log("Selected filament:", selectedText);
if (selectedText === "Please choose...") { if (selectedText === "Please choose...") {
showNotification("Choose Filament first", false); showNotification("Choose Filament first", false);
return; return;
@@ -448,55 +466,53 @@ function handleSpoolIn(amsId, trayId) {
if (!selectedSpool) { if (!selectedSpool) {
showNotification("Selected Spool not found", false); showNotification("Selected Spool not found", false);
console.error("Selected spool not found in spoolsData");
return; return;
} }
console.log("Found spool data:", selectedSpool);
// Temperaturwerte extrahieren // Temperaturwerte extrahieren
let minTemp = "175"; let minTemp = "175";
let maxTemp = "275"; let maxTemp = "275";
if (selectedSpool.filament && if (Array.isArray(selectedSpool.filament.nozzle_temperature) &&
Array.isArray(selectedSpool.filament.nozzle_temperature) &&
selectedSpool.filament.nozzle_temperature.length >= 2) { selectedSpool.filament.nozzle_temperature.length >= 2) {
minTemp = selectedSpool.filament.nozzle_temperature[0]; minTemp = selectedSpool.filament.nozzle_temperature[0];
maxTemp = selectedSpool.filament.nozzle_temperature[1]; maxTemp = selectedSpool.filament.nozzle_temperature[1];
} }
// Extrahiere bambu_idx
let bambuIdx = "GFL99"; // Default zu Generic PLA
if (selectedSpool.filament?.extra?.bambu_idx) {
bambuIdx = selectedSpool.filament.extra.bambu_idx.replace(/['"]/g, '');
} else if (selectedSpool.extra?.bambu_idx) {
bambuIdx = selectedSpool.extra.bambu_idx.replace(/['"]/g, '');
}
// Erstelle Payload // Erstelle Payload
const payload = { const payload = {
type: 'setBambuSpool', type: 'setBambuSpool',
payload: { payload: {
amsId: amsId, amsId: amsId,
trayId: trayId, trayId: trayId,
color: selectedSpool.filament && selectedSpool.filament.color_hex ? selectedSpool.filament.color_hex : "FFFFFF", color: selectedSpool.filament.color_hex || "FFFFFF",
nozzle_temp_min: parseInt(minTemp), nozzle_temp_min: parseInt(minTemp),
nozzle_temp_max: parseInt(maxTemp), nozzle_temp_max: parseInt(maxTemp),
type: selectedSpool.filament && selectedSpool.filament.material ? selectedSpool.filament.material : "PLA", type: selectedSpool.filament.material,
brand: selectedSpool.filament && selectedSpool.filament.vendor ? selectedSpool.filament.vendor.name : "", brand: selectedSpool.filament.vendor.name,
tray_info_idx: bambuIdx, tray_info_idx: selectedSpool.filament.extra.bambu_idx?.replace(/['"]+/g, '').trim() || '',
cali_idx: "-1" // Default-Wert setzen cali_idx: "-1" // Default-Wert setzen
} }
}; };
console.log("Sending payload:", payload); // Prüfe, ob der Key cali_idx vorhanden ist und setze ihn
if (selectedSpool.filament.extra.bambu_cali_id) {
payload.payload.cali_idx = selectedSpool.filament.extra.bambu_cali_id.replace(/['"]+/g, '').trim();
}
// Prüfe, ob der Key bambu_setting_id vorhanden ist
if (selectedSpool.filament.extra.bambu_setting_id) {
payload.payload.bambu_setting_id = selectedSpool.filament.extra.bambu_setting_id.replace(/['"]+/g, '').trim();
}
console.log("Spool-In Payload:", payload);
try { try {
socket.send(JSON.stringify(payload)); socket.send(JSON.stringify(payload));
showNotification(`Spool settings sent to printer. Please wait...`, true); showNotification(`Spool set in AMS ${amsId} Tray ${trayId}. Pls wait`, true);
} catch (error) { } catch (error) {
console.error("Error sending WebSocket message:", error); console.error("Fehler beim Senden der WebSocket Nachricht:", error);
showNotification("Error sending spool settings!", false); showNotification("Error while sending", false);
} }
} }
@@ -671,75 +687,3 @@ function showNotification(message, isSuccess) {
}, 300); }, 300);
}, 3000); }, 3000);
} }
// Neue Handler-Funktionen für bessere Modularität
function handleHeartbeatResponse(data) {
const bambuDot = document.getElementById('bambuDot');
const spoolmanDot = document.getElementById('spoolmanDot');
const ramStatus = document.getElementById('ramStatus');
if (bambuDot) {
bambuDot.className = 'status-dot ' + (data.bambu_connected ? 'online' : 'offline');
if (!data.bambu_connected) {
bambuDot.style.cursor = 'pointer';
bambuDot.onclick = function() {
sendReconnectRequest('bambu');
};
} else {
bambuDot.style.cursor = 'default';
bambuDot.onclick = null;
}
}
if (spoolmanDot) {
spoolmanDot.className = 'status-dot ' + (data.spoolman_connected ? 'online' : 'offline');
if (!data.spoolman_connected) {
spoolmanDot.style.cursor = 'pointer';
spoolmanDot.onclick = function() {
sendReconnectRequest('spoolman');
};
} else {
spoolmanDot.style.cursor = 'default';
spoolmanDot.onclick = null;
}
}
if (ramStatus) {
ramStatus.textContent = `${data.freeHeap}k`;
}
}
function handleSpoolmanSettingsResponse(data) {
if (data.payload === 'success') {
showNotification(`Spoolman Settings set successfully`, true);
} else {
showNotification(`Error setting Spoolman Settings`, false);
}
}
function sendReconnectRequest(target) {
if (socket?.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({
type: 'reconnect',
payload: target
}));
}
}
// Verbesserte Funktion zum Senden von WebSocket-Nachrichten
function sendWebSocketMessage(message) {
if (!socket || socket.readyState !== WebSocket.OPEN) {
console.error('WebSocket is not connected');
showNotification("Connection error - please try again", false);
return;
}
try {
const jsonString = JSON.stringify(message);
console.log('Sending WebSocket message:', jsonString);
socket.send(jsonString);
} catch (error) {
console.error('Error sending WebSocket message:', error);
showNotification("Error sending message", false);
}
}
-2
View File
@@ -6,8 +6,6 @@
//#define PN532_MOSI 23 //#define PN532_MOSI 23
//#define PN532_SS 5 //#define PN532_SS 5
//#define PN532_MISO 19 //#define PN532_MISO 19
const uint8_t PN532_IRQ = 32;
const uint8_t PN532_RESET = 33;
// ***** PN532 // ***** PN532
// ***** HX711 (Waage) // ***** HX711 (Waage)
+13 -5
View File
@@ -1,10 +1,13 @@
#ifndef CONFIG_H #pragma once
#define CONFIG_H
#include <Arduino.h> #include <Arduino.h>
extern const uint8_t PN532_IRQ; // ***** PN532 (RFID)
extern const uint8_t PN532_RESET; //#define PN532_SCK 18
//#define PN532_MOSI 23
//#define PN532_SS 5
//#define PN532_MISO 19
// ***** PN532
extern const uint8_t LOADCELL_DOUT_PIN; extern const uint8_t LOADCELL_DOUT_PIN;
extern const uint8_t LOADCELL_SCK_PIN; extern const uint8_t LOADCELL_SCK_PIN;
@@ -47,4 +50,9 @@ extern uint8_t scaleTaskCore;
extern uint8_t scaleTaskPrio; extern uint8_t scaleTaskPrio;
extern uint16_t defaultScaleCalibrationValue; extern uint16_t defaultScaleCalibrationValue;
#endif
#define PN532_SCK (18)
#define PN532_MISO (19)
#define PN532_MOSI (23)
#define PN532_CS1 (5)
#define PN532_CS2 (4)
+245 -103
View File
@@ -7,9 +7,23 @@
#include "api.h" #include "api.h"
#include "esp_task_wdt.h" #include "esp_task_wdt.h"
#include "scale.h" #include "scale.h"
#include <SPI.h>
//Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS); // Pin definitions for both PN532 chips
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET); #define PN532_SCK (18) // SPI SCK
#define PN532_MISO (19) // SPI MISO
#define PN532_MOSI (23) // SPI MOSI
// CS pins for each PN532
#define PN532_CS1 (5) // CS for first PN532
#define PN532_CS2 (4) // CS for second PN532
// Mifare authentication key
uint8_t keyA[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
// Create two PN532 instances
Adafruit_PN532 nfc1(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_CS1);
Adafruit_PN532 nfc2(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_CS2);
TaskHandle_t RfidReaderTask; TaskHandle_t RfidReaderTask;
@@ -28,6 +42,165 @@ volatile uint8_t hasReadRfidTag = 0;
// 6 = reading // 6 = reading
// ***** PN532 // ***** PN532
// Buffer for reading data
uint8_t data[32];
// Function to initialize a specific PN532
bool initPN532(Adafruit_PN532 &pn532) {
pn532.begin();
uint32_t versiondata = pn532.getFirmwareVersion();
if (!versiondata) {
Serial.println("Didn't find PN532 board");
return false;
}
// Got valid data, print it out!
Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX);
Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC);
Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);
// Configure board to read RFID tags
pn532.SAMConfig();
Serial.println("Waiting for an ISO14443A Card ...");
return true;
}
void initNfc() {
// Configure CS pins as outputs
pinMode(PN532_CS1, OUTPUT);
pinMode(PN532_CS2, OUTPUT);
digitalWrite(PN532_CS1, HIGH); // Deselect both chips initially
digitalWrite(PN532_CS2, HIGH);
// Initialize SPI
SPI.begin(PN532_SCK, PN532_MISO, PN532_MOSI);
SPI.setFrequency(1000000); // 1MHz SPI clock
// Initialize both PN532 chips
if (!initPN532(nfc1)) {
Serial.println("Failed to initialize PN532 #1");
return;
}
if (!initPN532(nfc2)) {
Serial.println("Failed to initialize PN532 #2");
return;
}
Serial.println("Both PN532 chips initialized successfully");
}
// Function to read a specific PN532
bool readPN532(Adafruit_PN532 &pn532, uint8_t *uid, uint8_t *uidLength) {
uint8_t success;
success = pn532.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, uidLength);
return success;
}
// Function to write to a specific PN532
bool writePN532(Adafruit_PN532 &pn532, uint8_t *uid, uint8_t uidLength, uint8_t *data, uint8_t dataLen) {
if (!pn532.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 1, keyA)) {
Serial.println("Failed to authenticate block");
return false;
}
if (!pn532.mifareclassic_WriteDataBlock(4, data)) {
Serial.println("Failed to write block");
return false;
}
return true;
}
void loopNfc() {
uint8_t uid1[] = {0, 0, 0, 0, 0, 0, 0};
uint8_t uid2[] = {0, 0, 0, 0, 0, 0, 0};
uint8_t uidLength1 = 0;
uint8_t uidLength2 = 0;
// Try to read from both PN532 chips
bool success1 = readPN532(nfc1, uid1, &uidLength1);
bool success2 = readPN532(nfc2, uid2, &uidLength2);
if (success1 || success2) {
// Process the first tag if found
if (success1) {
processTag(uid1, uidLength1, 1);
}
// Process the second tag if found
if (success2) {
processTag(uid2, uidLength2, 2);
}
}
}
void processTag(uint8_t *uid, uint8_t uidLength, uint8_t readerNumber) {
Adafruit_PN532 &pn532 = (readerNumber == 1) ? nfc1 : nfc2;
Serial.print("Reader "); Serial.print(readerNumber); Serial.println(" found tag:");
Serial.print("UID Length: "); Serial.println(uidLength);
Serial.print("UID Value: ");
for (uint8_t i = 0; i < uidLength; i++) {
Serial.print(" 0x"); Serial.print(uid[i], HEX);
}
Serial.println("");
if (uidLength == 7) {
uint16_t tagSize = readTagSize(pn532);
if(tagSize > 0) {
Serial.print("Tag size: "); Serial.println(tagSize);
uint8_t* data = (uint8_t*)malloc(tagSize);
memset(data, 0, tagSize);
// Mehrere Leseversuche
bool readSuccess = false;
for(int attempt = 0; attempt < 3 && !readSuccess; attempt++) {
readSuccess = true;
uint8_t numPages = tagSize / 4;
for (uint8_t i = 4; i < 4 + numPages; i++) {
if (!pn532.ntag2xx_ReadPage(i, data + (i - 4) * 4)) {
Serial.print("Failed to read page "); Serial.println(i);
readSuccess = false;
break;
}
delay(5); // Kleine Pause zwischen den Seiten
}
if (!readSuccess) {
delay(50); // Pause vor erneutem Versuch
}
}
if (readSuccess) {
Serial.println("Successfully read tag data.");
processNfcData(data, createTagId(uid, uidLength));
} else {
Serial.println("Failed to read tag data after 3 attempts");
oledShowMessage("Read Error");
}
free(data);
}
}
}
void processNfcData(uint8_t *data, String tagId) {
// Process the data and send it via WebSocket
if (decodeNdefAndReturnJson(data)) {
hasReadRfidTag = 1;
sendNfcData(nullptr);
} else {
hasReadRfidTag = 2;
oledShowMessage("NFC-Tag unknown");
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
// Function to write to a specific tag
bool writeNfcTag(uint8_t *uid, uint8_t uidLength, uint8_t *data, uint8_t dataLen, uint8_t readerNumber) {
// Select the appropriate PN532 based on reader number
Adafruit_PN532 &pn532 = (readerNumber == 1) ? nfc1 : nfc2;
return writePN532(pn532, uid, uidLength, data, dataLen);
}
// ##### Funktionen für RFID ##### // ##### Funktionen für RFID #####
void payloadToJson(uint8_t *data) { void payloadToJson(uint8_t *data) {
@@ -80,7 +253,7 @@ bool formatNdefTag() {
// Schreibe die Initialisierungsnachricht auf die ersten Seiten // Schreibe die Initialisierungsnachricht auf die ersten Seiten
for (int i = 0; i < sizeof(ndefInit); i += 4) { for (int i = 0; i < sizeof(ndefInit); i += 4) {
if (!nfc.ntag2xx_WritePage(pageOffset + (i / 4), &ndefInit[i])) { if (!nfc1.ntag2xx_WritePage(pageOffset + (i / 4), &ndefInit[i])) {
success = false; success = false;
break; break;
} }
@@ -89,16 +262,15 @@ bool formatNdefTag() {
return success; return success;
} }
uint16_t readTagSize() uint16_t readTagSize(Adafruit_PN532 &pn532) {
{
uint8_t buffer[4]; uint8_t buffer[4];
memset(buffer, 0, 4); memset(buffer, 0, 4);
nfc.ntag2xx_ReadPage(3, buffer); pn532.ntag2xx_ReadPage(3, buffer);
return buffer[2]*8; return buffer[2] * 8;
} }
uint8_t ntag2xx_WriteNDEF(const char *payload) { uint8_t ntag2xx_WriteNDEF(const char *payload, Adafruit_PN532 &pn532) {
uint16_t tagSize = readTagSize(); uint16_t tagSize = readTagSize(pn532);
Serial.print("Tag Size: ");Serial.println(tagSize); Serial.print("Tag Size: ");Serial.println(tagSize);
uint8_t pageBuffer[4] = {0, 0, 0, 0}; uint8_t pageBuffer[4] = {0, 0, 0, 0};
@@ -157,11 +329,7 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
int bytesToWrite = (totalSize < 4) ? totalSize : 4; int bytesToWrite = (totalSize < 4) ? totalSize : 4;
memcpy(pageBuffer, combinedData + a, bytesToWrite); memcpy(pageBuffer, combinedData + a, bytesToWrite);
//uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID if (!(pn532.ntag2xx_WritePage(4+i, pageBuffer)))
//uint8_t uidLength;
//nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 100);
if (!(nfc.ntag2xx_WritePage(4+i, pageBuffer)))
{ {
Serial.println("Fehler beim Schreiben der Seite."); Serial.println("Fehler beim Schreiben der Seite.");
free(combinedData); free(combinedData);
@@ -169,8 +337,6 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
} }
yield(); yield();
//esp_task_wdt_reset();
i++; i++;
a += 4; a += 4;
totalSize -= bytesToWrite; totalSize -= bytesToWrite;
@@ -179,7 +345,7 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
// Ensure the NDEF message is properly terminated // Ensure the NDEF message is properly terminated
memset(pageBuffer, 0, 4); memset(pageBuffer, 0, 4);
pageBuffer[0] = 0xFE; // NDEF record footer pageBuffer[0] = 0xFE; // NDEF record footer
if (!(nfc.ntag2xx_WritePage(4+i, pageBuffer))) if (!(pn532.ntag2xx_WritePage(4+i, pageBuffer)))
{ {
Serial.println("Fehler beim Schreiben des End-Bits."); Serial.println("Fehler beim Schreiben des End-Bits.");
free(combinedData); free(combinedData);
@@ -238,7 +404,6 @@ bool decodeNdefAndReturnJson(const byte* encodedMessage) {
void writeJsonToTag(void *parameter) { void writeJsonToTag(void *parameter) {
const char* payload = (const char*)parameter; const char* payload = (const char*)parameter;
// Gib die erstellte NDEF-Message aus
Serial.println("Erstelle NDEF-Message..."); Serial.println("Erstelle NDEF-Message...");
Serial.println(payload); Serial.println(payload);
@@ -246,24 +411,36 @@ void writeJsonToTag(void *parameter) {
vTaskSuspend(RfidReaderTask); vTaskSuspend(RfidReaderTask);
vTaskDelay(50 / portTICK_PERIOD_MS); vTaskDelay(50 / portTICK_PERIOD_MS);
//pauseBambuMqttTask = true;
// aktualisieren der Website wenn sich der Status ändert
sendNfcData(nullptr); sendNfcData(nullptr);
vTaskDelay(100 / portTICK_PERIOD_MS); vTaskDelay(100 / portTICK_PERIOD_MS);
oledShowMessage("Waiting for NFC-Tag"); oledShowMessage("Waiting for NFC-Tag");
// Wait 10sec for tag // Try both readers
uint8_t success = 0; uint8_t success = 0;
String uidString = ""; String uidString = "";
Adafruit_PN532* activeReader = nullptr;
for (uint16_t i = 0; i < 20; i++) { for (uint16_t i = 0; i < 20; i++) {
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID // Try first reader
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
uint8_t uidLength; uint8_t uidLength;
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 500); success = nfc1.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 250);
if (!success) {
// Try second reader
success = nfc2.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 250);
if (success) {
activeReader = &nfc2;
}
} else {
activeReader = &nfc1;
}
if (success) { if (success) {
for (uint8_t i = 0; i < uidLength; i++) { for (uint8_t i = 0; i < uidLength; i++) {
uidString += String(uid[i], HEX); uidString += String(uid[i], HEX);
if (i < uidLength - 1) { if (i < uidLength - 1) {
uidString += ":"; // Optional: Trennzeichen hinzufügen uidString += ":";
} }
} }
foundNfcTag(nullptr, success); foundNfcTag(nullptr, success);
@@ -277,44 +454,36 @@ void writeJsonToTag(void *parameter) {
vTaskDelay(pdMS_TO_TICKS(1)); vTaskDelay(pdMS_TO_TICKS(1));
} }
if (success) if (success && activeReader != nullptr) {
{
oledShowIcon("transfer"); oledShowIcon("transfer");
// Schreibe die NDEF-Message auf den Tag // Schreibe die NDEF-Message auf den Tag
success = ntag2xx_WriteNDEF(payload); success = ntag2xx_WriteNDEF(payload, *activeReader);
if (success) if (success) {
{
Serial.println("NDEF-Message erfolgreich auf den Tag geschrieben"); Serial.println("NDEF-Message erfolgreich auf den Tag geschrieben");
//oledShowMessage("NFC-Tag written");
oledShowIcon("success"); oledShowIcon("success");
vTaskDelay(1000 / portTICK_PERIOD_MS); vTaskDelay(1000 / portTICK_PERIOD_MS);
hasReadRfidTag = 5; hasReadRfidTag = 5;
// aktualisieren der Website wenn sich der Status ändert
sendNfcData(nullptr); sendNfcData(nullptr);
pauseBambuMqttTask = false; pauseBambuMqttTask = false;
if (updateSpoolTagId(uidString, payload)) { if (updateSpoolTagId(uidString, payload)) {
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
uint8_t uidLength; uint8_t uidLength;
oledShowIcon("success"); oledShowIcon("success");
while (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 500)) { while (activeReader->readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 500)) {
yield(); yield();
} }
} }
vTaskResume(RfidReaderTask); vTaskResume(RfidReaderTask);
vTaskDelay(500 / portTICK_PERIOD_MS); vTaskDelay(500 / portTICK_PERIOD_MS);
} } else {
else
{
Serial.println("Fehler beim Schreiben der NDEF-Message auf den Tag"); Serial.println("Fehler beim Schreiben der NDEF-Message auf den Tag");
oledShowIcon("failed"); oledShowIcon("failed");
vTaskDelay(2000 / portTICK_PERIOD_MS); vTaskDelay(2000 / portTICK_PERIOD_MS);
hasReadRfidTag = 4; hasReadRfidTag = 4;
} }
} } else {
else
{
Serial.println("Fehler: Kein Tag zu schreiben gefunden."); Serial.println("Fehler: Kein Tag zu schreiben gefunden.");
oledShowMessage("No NFC-Tag found"); oledShowMessage("No NFC-Tag found");
vTaskDelay(2000 / portTICK_PERIOD_MS); vTaskDelay(2000 / portTICK_PERIOD_MS);
@@ -350,122 +519,92 @@ void startWriteJsonToTag(const char* payload) {
void scanRfidTask(void * parameter) { void scanRfidTask(void * parameter) {
Serial.println("RFID Task gestartet"); Serial.println("RFID Task gestartet");
for(;;) { for(;;) {
// Wenn geschrieben wird Schleife aussetzen if (hasReadRfidTag != 3) {
if (hasReadRfidTag != 3)
{
yield(); yield();
uint8_t success; uint8_t success = 0;
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
uint8_t uidLength; uint8_t uidLength;
Adafruit_PN532* activeReader = nullptr;
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 1000); // Try first reader with increased timeout
success = nfc1.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 150);
if (success) {
activeReader = &nfc1;
} else {
delay(50); // Small delay between readers
// Try second reader with increased timeout
success = nfc2.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 150);
if (success) {
activeReader = &nfc2;
}
}
foundNfcTag(nullptr, success); foundNfcTag(nullptr, success);
if (success && hasReadRfidTag != 1) if (success && hasReadRfidTag != 1 && activeReader != nullptr) {
{
// Display some basic information about the card
Serial.println("Found an ISO14443A card"); Serial.println("Found an ISO14443A card");
hasReadRfidTag = 6; hasReadRfidTag = 6;
oledShowIcon("transfer"); oledShowIcon("transfer");
vTaskDelay(500 / portTICK_PERIOD_MS); vTaskDelay(500 / portTICK_PERIOD_MS);
if (uidLength == 7) if (uidLength == 7) {
{ uint16_t tagSize = readTagSize(*activeReader);
uint16_t tagSize = readTagSize(); if(tagSize > 0) {
if(tagSize > 0)
{
// Create a buffer depending on the size of the tag
uint8_t* data = (uint8_t*)malloc(tagSize); uint8_t* data = (uint8_t*)malloc(tagSize);
memset(data, 0, tagSize); memset(data, 0, tagSize);
// We probably have an NTAG2xx card (though it could be Ultralight as well)
Serial.println("Seems to be an NTAG2xx tag (7 byte UID)"); Serial.println("Seems to be an NTAG2xx tag (7 byte UID)");
uint8_t numPages = readTagSize()/4; uint8_t numPages = readTagSize(*activeReader)/4;
for (uint8_t i = 4; i < 4+numPages; i++) { for (uint8_t i = 4; i < 4+numPages; i++) {
if (!nfc.ntag2xx_ReadPage(i, data+(i-4) * 4)) if (!activeReader->ntag2xx_ReadPage(i, data+(i-4) * 4)) {
{ break;
break; // Stop if reading fails
} }
// Check for NDEF message end if (data[(i - 4) * 4] == 0xFE) {
if (data[(i - 4) * 4] == 0xFE) break;
{
break; // End of NDEF message
} }
yield(); yield();
esp_task_wdt_reset(); esp_task_wdt_reset();
vTaskDelay(pdMS_TO_TICKS(1)); vTaskDelay(pdMS_TO_TICKS(5)); // Increased delay between page reads
} }
if (!decodeNdefAndReturnJson(data)) if (!decodeNdefAndReturnJson(data)) {
{
oledShowMessage("NFC-Tag unknown"); oledShowMessage("NFC-Tag unknown");
vTaskDelay(2000 / portTICK_PERIOD_MS); vTaskDelay(2000 / portTICK_PERIOD_MS);
hasReadRfidTag = 2; hasReadRfidTag = 2;
} } else {
else
{
hasReadRfidTag = 1; hasReadRfidTag = 1;
} }
free(data); free(data);
} } else {
else
{
oledShowMessage("NFC-Tag read error"); oledShowMessage("NFC-Tag read error");
hasReadRfidTag = 2; hasReadRfidTag = 2;
} }
} } else {
else
{
Serial.println("This doesn't seem to be an NTAG2xx tag (UUID length != 7 bytes)!"); Serial.println("This doesn't seem to be an NTAG2xx tag (UUID length != 7 bytes)!");
} }
} }
if (!success && hasReadRfidTag > 0) if (!success && hasReadRfidTag > 0) {
{
hasReadRfidTag = 0; hasReadRfidTag = 0;
//uidString = "";
nfcJsonData = ""; nfcJsonData = "";
Serial.println("Tag entfernt"); Serial.println("Tag entfernt");
if (!autoSendToBambu) oledShowWeight(weight); if (!autoSendToBambu) oledShowWeight(weight);
} }
// aktualisieren der Website wenn sich der Status ändert
sendNfcData(nullptr); sendNfcData(nullptr);
delay(100); // Add small delay at end of loop
} }
yield(); yield();
} }
} }
void startNfc() { void startNfc() {
nfc.begin(); // Beginne Kommunikation mit RFID Leser initNfc();
delay(1000);
unsigned long versiondata = nfc.getFirmwareVersion(); // Lese Versionsnummer der Firmware aus
if (! versiondata) { // Wenn keine Antwort kommt
Serial.println("Kann kein RFID Board finden !"); // Sende Text "Kann kein..." an seriellen Monitor
//delay(5000);
//ESP.restart();
oledShowMessage("No RFID Board found");
delay(2000);
}
else {
Serial.print("Chip PN5 gefunden"); Serial.println((versiondata >> 24) & 0xFF, HEX); // Sende Text und Versionsinfos an seriellen
Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC); // Monitor, wenn Antwort vom Board kommt
Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC); //
nfc.SAMConfig();
// Set the max number of retry attempts to read from a card
// This prevents us from waiting forever for a card, which is
// the default behaviour of the PN532.
//nfc.setPassiveActivationRetries(0x7F);
//nfc.setPassiveActivationRetries(0xFF);
BaseType_t result = xTaskCreatePinnedToCore( BaseType_t result = xTaskCreatePinnedToCore(
scanRfidTask, /* Function to implement the task */ scanRfidTask, /* Function to implement the task */
"RfidReader", /* Name of the task */ "RfidReader", /* Name of the task */
@@ -480,5 +619,8 @@ void startNfc() {
} else { } else {
Serial.println("RFID Task erfolgreich erstellt"); Serial.println("RFID Task erfolgreich erstellt");
} }
} }
String createTagId(uint8_t *uid, uint8_t uidLength) {
// Implementierung der Funktion
} }
+10 -4
View File
@@ -1,11 +1,15 @@
#ifndef NFC_H #pragma once
#define NFC_H
#include <Arduino.h> #include <Arduino.h>
#include <Adafruit_PN532.h>
void startNfc(); void startNfc();
void scanRfidTask(void * parameter);
void startWriteJsonToTag(const char* payload); void startWriteJsonToTag(const char* payload);
void writeJsonToTag(void *parameter);
void scanRfidTask(void * parameter);
void processTag(uint8_t *uid, uint8_t uidLength, uint8_t readerNumber);
void processNfcData(uint8_t *data, String tagId);
bool decodeNdefAndReturnJson(const byte* encodedMessage);
extern TaskHandle_t RfidReaderTask; extern TaskHandle_t RfidReaderTask;
extern String nfcJsonData; extern String nfcJsonData;
@@ -13,4 +17,6 @@ extern String spoolId;
extern volatile uint8_t hasReadRfidTag; extern volatile uint8_t hasReadRfidTag;
extern volatile bool pauseBambuMqttTask; extern volatile bool pauseBambuMqttTask;
#endif // Function declarations
uint16_t readTagSize(Adafruit_PN532 &pn532);
String createTagId(uint8_t *uid, uint8_t uidLength);