Compare commits

..

1 Commits

Author SHA1 Message Date
tugsi e5e3dcba8c gitignore 2025-03-23 17:51:09 +01:00
6 changed files with 369 additions and 467 deletions
+147 -91
View File
@@ -53,7 +53,13 @@ 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;
} }
@@ -61,110 +67,80 @@ function initWebSocket() {
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 () { socket.onclose = function(event) {
console.log('WebSocket connection closed:', event.code, event.reason);
isConnected = false; isConnected = false;
updateConnectionStatus(); updateConnectionStatus();
if (heartbeatTimer) clearInterval(heartbeatTimer); if (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) clearInterval(heartbeatTimer); if (heartbeatTimer) {
clearInterval(heartbeatTimer);
// Bei Fehler Verbindung schließen und neu aufbauen heartbeatTimer = null;
if (socket) {
socket.close();
socket = null;
} }
}; };
socket.onmessage = function(event) { socket.onmessage = function(event) {
lastHeartbeatResponse = Date.now(); // Aktualisiere Zeitstempel bei jeder Server-Antwort try {
lastHeartbeatResponse = Date.now();
const data = JSON.parse(event.data); const data = JSON.parse(event.data);
if (data.type === 'amsData') {
displayAmsData(data.payload);
} else if (data.type === 'nfcTag') {
updateNfcStatusIndicator(data.payload);
} else if (data.type === 'nfcData') {
updateNfcData(data.payload);
} else if (data.type === 'writeNfcTag') {
handleWriteNfcTagResponse(data.success);
} else if (data.type === 'heartbeat') {
// Optional: Spezifische Behandlung von Heartbeat-Antworten
// Update status dots
const bambuDot = document.getElementById('bambuDot');
const spoolmanDot = document.getElementById('spoolmanDot');
const ramStatus = document.getElementById('ramStatus');
if (bambuDot) { // Handle different message types
bambuDot.className = 'status-dot ' + (data.bambu_connected ? 'online' : 'offline'); switch(data.type) {
// Add click handler only when offline case 'amsData':
if (!data.bambu_connected) { displayAmsData(data.payload);
bambuDot.style.cursor = 'pointer'; break;
bambuDot.onclick = function () { case 'nfcTag':
if (socket && socket.readyState === WebSocket.OPEN) { updateNfcStatusIndicator(data.payload);
socket.send(JSON.stringify({ break;
type: 'reconnect', case 'nfcData':
payload: 'bambu' updateNfcData(data.payload);
})); break;
} case 'writeNfcTag':
}; handleWriteNfcTagResponse(data.success);
} else { break;
bambuDot.style.cursor = 'default'; case 'heartbeat':
bambuDot.onclick = null; handleHeartbeatResponse(data);
} break;
} case 'setSpoolmanSettings':
if (spoolmanDot) { handleSpoolmanSettingsResponse(data);
spoolmanDot.className = 'status-dot ' + (data.spoolman_connected ? 'online' : 'offline'); break;
// Add click handler only when offline default:
if (!data.spoolman_connected) { console.warn('Unknown message type:', data.type);
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);
} }
@@ -389,6 +365,7 @@ 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;
@@ -419,6 +396,7 @@ 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 = {
@@ -443,17 +421,21 @@ function handleSpoolOut() {
} }
} }
// Neue Funktion zum Behandeln des Spool-In-Klicks // Verbesserte 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"); console.error("WebSocket not connected, state:", socket ? socket.readyState : "no socket");
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;
@@ -466,53 +448,55 @@ 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 (Array.isArray(selectedSpool.filament.nozzle_temperature) && if (selectedSpool.filament &&
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.color_hex || "FFFFFF", color: selectedSpool.filament && selectedSpool.filament.color_hex ? 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.material, type: selectedSpool.filament && selectedSpool.filament.material ? selectedSpool.filament.material : "PLA",
brand: selectedSpool.filament.vendor.name, brand: selectedSpool.filament && selectedSpool.filament.vendor ? selectedSpool.filament.vendor.name : "",
tray_info_idx: selectedSpool.filament.extra.bambu_idx?.replace(/['"]+/g, '').trim() || '', tray_info_idx: bambuIdx,
cali_idx: "-1" // Default-Wert setzen cali_idx: "-1" // Default-Wert setzen
} }
}; };
// Prüfe, ob der Key cali_idx vorhanden ist und setze ihn console.log("Sending payload:", payload);
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 set in AMS ${amsId} Tray ${trayId}. Pls wait`, true); showNotification(`Spool settings sent to printer. Please wait...`, true);
} catch (error) { } catch (error) {
console.error("Fehler beim Senden der WebSocket Nachricht:", error); console.error("Error sending WebSocket message:", error);
showNotification("Error while sending", false); showNotification("Error sending spool settings!", false);
} }
} }
@@ -687,3 +671,75 @@ 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,6 +6,8 @@
//#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)
+5 -13
View File
@@ -1,13 +1,10 @@
#pragma once #ifndef CONFIG_H
#define CONFIG_H
#include <Arduino.h> #include <Arduino.h>
// ***** PN532 (RFID) extern const uint8_t PN532_IRQ;
//#define PN532_SCK 18 extern const uint8_t PN532_RESET;
//#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;
@@ -50,9 +47,4 @@ 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)
+101 -243
View File
@@ -7,23 +7,9 @@
#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>
// Pin definitions for both PN532 chips //Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
#define PN532_SCK (18) // SPI SCK Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
#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;
@@ -42,165 +28,6 @@ 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) {
@@ -253,7 +80,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 (!nfc1.ntag2xx_WritePage(pageOffset + (i / 4), &ndefInit[i])) { if (!nfc.ntag2xx_WritePage(pageOffset + (i / 4), &ndefInit[i])) {
success = false; success = false;
break; break;
} }
@@ -262,15 +89,16 @@ bool formatNdefTag() {
return success; return success;
} }
uint16_t readTagSize(Adafruit_PN532 &pn532) { uint16_t readTagSize()
{
uint8_t buffer[4]; uint8_t buffer[4];
memset(buffer, 0, 4); memset(buffer, 0, 4);
pn532.ntag2xx_ReadPage(3, buffer); nfc.ntag2xx_ReadPage(3, buffer);
return buffer[2]*8; return buffer[2]*8;
} }
uint8_t ntag2xx_WriteNDEF(const char *payload, Adafruit_PN532 &pn532) { uint8_t ntag2xx_WriteNDEF(const char *payload) {
uint16_t tagSize = readTagSize(pn532); uint16_t tagSize = readTagSize();
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};
@@ -329,7 +157,11 @@ uint8_t ntag2xx_WriteNDEF(const char *payload, Adafruit_PN532 &pn532) {
int bytesToWrite = (totalSize < 4) ? totalSize : 4; int bytesToWrite = (totalSize < 4) ? totalSize : 4;
memcpy(pageBuffer, combinedData + a, bytesToWrite); memcpy(pageBuffer, combinedData + a, bytesToWrite);
if (!(pn532.ntag2xx_WritePage(4+i, pageBuffer))) //uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
//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);
@@ -337,6 +169,8 @@ uint8_t ntag2xx_WriteNDEF(const char *payload, Adafruit_PN532 &pn532) {
} }
yield(); yield();
//esp_task_wdt_reset();
i++; i++;
a += 4; a += 4;
totalSize -= bytesToWrite; totalSize -= bytesToWrite;
@@ -345,7 +179,7 @@ uint8_t ntag2xx_WriteNDEF(const char *payload, Adafruit_PN532 &pn532) {
// 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 (!(pn532.ntag2xx_WritePage(4+i, pageBuffer))) if (!(nfc.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);
@@ -404,6 +238,7 @@ 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);
@@ -411,36 +246,24 @@ 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");
// Try both readers // Wait 10sec for tag
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++) {
// Try first reader 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;
success = nfc1.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 250); success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 500);
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 += ":"; uidString += ":"; // Optional: Trennzeichen hinzufügen
} }
} }
foundNfcTag(nullptr, success); foundNfcTag(nullptr, success);
@@ -454,36 +277,44 @@ void writeJsonToTag(void *parameter) {
vTaskDelay(pdMS_TO_TICKS(1)); vTaskDelay(pdMS_TO_TICKS(1));
} }
if (success && activeReader != nullptr) { if (success)
{
oledShowIcon("transfer"); oledShowIcon("transfer");
// Schreibe die NDEF-Message auf den Tag // Schreibe die NDEF-Message auf den Tag
success = ntag2xx_WriteNDEF(payload, *activeReader); success = ntag2xx_WriteNDEF(payload);
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 }; uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
uint8_t uidLength; uint8_t uidLength;
oledShowIcon("success"); oledShowIcon("success");
while (activeReader->readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 500)) { while (nfc.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);
@@ -519,92 +350,122 @@ 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(;;) {
if (hasReadRfidTag != 3) { // Wenn geschrieben wird Schleife aussetzen
if (hasReadRfidTag != 3)
{
yield(); yield();
uint8_t success = 0; uint8_t success;
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
uint8_t uidLength; uint8_t uidLength;
Adafruit_PN532* activeReader = nullptr;
// Try first reader with increased timeout success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 1000);
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 && activeReader != nullptr) { if (success && hasReadRfidTag != 1)
{
// 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); {
if(tagSize > 0) { uint16_t tagSize = readTagSize();
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(*activeReader)/4; uint8_t numPages = readTagSize()/4;
for (uint8_t i = 4; i < 4+numPages; i++) { for (uint8_t i = 4; i < 4+numPages; i++) {
if (!activeReader->ntag2xx_ReadPage(i, data+(i-4) * 4)) { if (!nfc.ntag2xx_ReadPage(i, data+(i-4) * 4))
break; {
break; // Stop if reading fails
} }
if (data[(i - 4) * 4] == 0xFE) { // Check for NDEF message end
break; if (data[(i - 4) * 4] == 0xFE)
{
break; // End of NDEF message
} }
yield(); yield();
esp_task_wdt_reset(); esp_task_wdt_reset();
vTaskDelay(pdMS_TO_TICKS(5)); // Increased delay between page reads vTaskDelay(pdMS_TO_TICKS(1));
} }
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() {
initNfc(); nfc.begin(); // Beginne Kommunikation mit RFID Leser
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 */
@@ -620,7 +481,4 @@ void startNfc() {
Serial.println("RFID Task erfolgreich erstellt"); Serial.println("RFID Task erfolgreich erstellt");
} }
} }
String createTagId(uint8_t *uid, uint8_t uidLength) {
// Implementierung der Funktion
} }
+4 -10
View File
@@ -1,15 +1,11 @@
#pragma once #ifndef NFC_H
#define NFC_H
#include <Arduino.h> #include <Arduino.h>
#include <Adafruit_PN532.h>
void startNfc(); void startNfc();
void startWriteJsonToTag(const char* payload);
void writeJsonToTag(void *parameter);
void scanRfidTask(void * parameter); void scanRfidTask(void * parameter);
void processTag(uint8_t *uid, uint8_t uidLength, uint8_t readerNumber); void startWriteJsonToTag(const char* payload);
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;
@@ -17,6 +13,4 @@ extern String spoolId;
extern volatile uint8_t hasReadRfidTag; extern volatile uint8_t hasReadRfidTag;
extern volatile bool pauseBambuMqttTask; extern volatile bool pauseBambuMqttTask;
// Function declarations #endif
uint16_t readTagSize(Adafruit_PN532 &pn532);
String createTagId(uint8_t *uid, uint8_t uidLength);