Compare commits

...

17 Commits

Author SHA1 Message Date
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
tugsi 70c8b7bdc0 Delete data directory
Old and not used... Testing from SPIFFS
2025-03-16 19:40:05 +01:00
tugsi c574cc964e Merge branch 'Bambu-Serie-X-MQTT-Fix' of https://github.com/tugsi/Filaman into Bambu-Serie-X-MQTT-Fix 2025-03-16 19:35:08 +01:00
tugsi 9262865b56 - X1C MQTT Fix
- Spoolman Settings Fix
- Spoolman Out Fix
- Spoolman In Fix
2025-03-16 19:30:37 +01:00
Manuel Weiser 3eac0e5ac4 update Discord Link 2025-03-15 16:02:18 +01:00
Manuel Weiser 24d91693d9 update Discord Link 2025-03-15 15:57:46 +01:00
tugsi f7c01eb5f0 Merge remote-tracking branch 'upstream/main' into Bambu-Serie-X-MQTT-Fix 2025-03-14 17:43:52 +01:00
tugsi a41ef9e75a docs: update changelog and header for version v1.4.1
- Die MQTT-Puffergröße auf 16.384 Byte (16 KB) erhöht.
Dies sollte ausreichen, um Ihre 15.403 Byte große JSON-Nutzlast mit etwas mehr Spielraum zu verarbeiten. Diese Änderung ermöglicht es dem MQTT-Client, größere JSON-Nachrichten ohne Kürzung zu empfangen und zu verarbeiten.

Einige wichtige Hinweise zu dieser Änderung:
Die neue Puffergröße von 16 KB verbraucht mehr RAM, der ESP32 sollte jedoch ausreichend Speicher dafür haben.
Die Größe ist auf 16 KB festgelegt, um über die benötigten 15.403 Byte hinaus zusätzlichen Puffer-Overhead bereitzustellen.

Diese Änderung betrifft nur den MQTT-Empfangspuffer
--
- Die Task-Stack-Größe von 8192 auf 16384 Wörter erhöht, um mehr Speicher für die JSON-Verarbeitung bereitzustellen
---
- Erhöhung des Keepalive-Intervalls auf 60 Sekunden
- Verbesserte Fehlerbehandlung und Debugging-Ausgaben
- Detaillierte Statusmeldungen für die MQTT-Verbindung
- Periodische Verbindungsüberprüfung alle 30 Sekunden
- Bessere Handhabung von Verbindungsverlusten
---
- Verwendung einer eindeutigen Client-ID mit Zufallssuffix
- Erhöhung der QoS (Quality of Service) auf 1 für zuverlässigere Übertragung
- Einstellung eines Socket-Timeouts von 60 Sekunden
- Aktivierung von Clean Session und Will Message
- Verbessertes Verbindungs-Logging
2025-03-14 17:42:26 +01:00
ManuelW 659dfb8627 Update README.de.md
Removed OpenSpool
2025-03-12 10:02:30 +01:00
ManuelW b4dd0d357a Update README.md 2025-03-12 10:01:40 +01:00
ManuelW 8e38a68191 Merge pull request #19 from tugsi/patch-1
Update README.de.md
2025-03-12 09:59:54 +01:00
ManuelW c3ec7edf6a Merge pull request #20 from tugsi/patch-2
Update README.md
2025-03-12 09:58:52 +01:00
tugsi e0df5d33f2 Update README.de.md
Einige Kleinigkeiten die mir aufgefallen sind.
- einheitlich Bambu Lab
- generell Namensgebung korrigiert
- die meisten Auflistungen haben ein . am Ende, eigentlich könnte man die weglassen, aber ich habe die, die keine hatten angepasst
- Installation Google Chrome oder Microsoft Edge hinzugefügt
2025-03-11 14:49:28 +01:00
Manuel Weiser 94c26590c8 remove commented-out subscription topic in MQTT setup 2025-03-10 17:41:14 +01:00
10 changed files with 560 additions and 283 deletions
+5
View File
@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
+10
View File
@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}
+9 -10
View File
@@ -1,33 +1,32 @@
# FilaMan - Filament Management System # FilaMan - Filament Management System
FilaMan ist ein Filament-Managementsystem für den 3D-Druck. Es verwendet ESP32-Hardware für Gewichtsmessungen und NFC-Tag-Management. FilaMan ist ein Filament-Managementsystem für den 3D-Druck. Es verwendet ESP32-Hardware für Gewichtsmessungen und NFC-Tag-Management.
Benutzer können Filamentspulen verwalten, den Status des Automatic Material System (AMS) von Bablulab Druckern überwachen und Einstellungen über eine Weboberfläche vornehmen. Benutzer können Filamentspulen verwalten, den Status des Automatic Material System (AMS) von Bambu Lab Druckern überwachen und Einstellungen über eine Weboberfläche vornehmen.
Das System integriert sich nahtlos mit der [Spoolman](https://github.com/Donkie/Spoolman) Filamentverwaltung, zusätzlich mit [Bambulab](https://bambulab.com/en-us) 3D-Druckern und sowie dem [Openspool](https://github.com/spuder/OpenSpool) NFC-TAG Format. Das System integriert sich nahtlos mit der [Spoolman](https://github.com/Donkie/Spoolman) Filamentverwaltung, zusätzlich mit [Bambu Lab](https://bambulab.com/en-us) 3D-Druckern.
![Scale](./img/scale_trans.png) ![Scale](./img/scale_trans.png)
Weitere Bilder finden Sie im [img Ordner](/img/) Weitere Bilder finden Sie im [img Ordner](/img/)
oder auf meiner Website: [FilaMan Website](https://www.filaman.app) oder auf meiner Website: [FilaMan Website](https://www.filaman.app)
Deutsches Erklärvideo: [Youtube](https://youtu.be/uNDe2wh9SS8?si=b-jYx4I1w62zaOHU) Deutsches Erklärvideo: [Youtube](https://youtu.be/uNDe2wh9SS8?si=b-jYx4I1w62zaOHU)
Discord Server: [https://discord.gg/vMAx2gf5](https://discord.gg/vMAx2gf5) Discord Server: [https://discord.gg/my7Gvaxj2v](https://discord.gg/my7Gvaxj2v)
### Es gibt jetzt auch ein Wiki, dort sind nochmal alle Funktionen beschrieben: [Wiki](https://github.com/ManuelW77/Filaman/wiki) ### Es gibt jetzt auch ein Wiki, dort sind nochmal alle Funktionen beschrieben: [Wiki](https://github.com/ManuelW77/Filaman/wiki)
### ESP32 Hardware-Funktionen ### ESP32 Hardware-Funktionen
- **Gewichtsmessung:** Verwendung einer Wägezelle mit HX711-Verstärker für präzise Gewichtsverfolgung. - **Gewichtsmessung:** Verwendung einer Wägezelle mit HX711-Verstärker für präzise Gewichtsverfolgung.
- **NFC-Tag Lesen/Schreiben:** PN532-Modul zum Lesen und Schreiben von Filamentdaten auf NFC-Tags. - **NFC-Tag Lesen/Schreiben:** PN532-Modul zum Lesen und Schreiben von Filamentdaten auf NFC-Tags.
- **OLED-Display:** Zeigt aktuelles Gewicht, Verbindungsstatus (WiFi, Bambu Lab, Spoolman). - **OLED-Display:** Zeigt aktuelles Gewicht, Verbindungsstatus (WiFi, BambuLab, Spoolman).
- **WLAN-Konnektivität:** WiFiManager für einfache Netzwerkkonfiguration. - **WLAN-Konnektivität:** WiFiManager für einfache Netzwerkkonfiguration.
- **MQTT-Integration:** Verbindet sich mit Bambu Lab Drucker für AMS-Steuerung. - **MQTT-Integration:** Verbindet sich mit Bambu Lab Drucker für AMS-Steuerung.
- **NFC-Tag NTAG213 NTAG215:** Verwendung von NTAG213, besser NTAG215 wegen ausreichendem Speicherplatz auf dem Tag - **NFC-Tag NTAG213 NTAG215:** Verwendung von NTAG213 (144 Bytes - Kapazität), besser NTAG215 (540 Bytes - Kapazität) wegen ausreichendem Speicherplatz auf dem Tag
### Weboberflächen-Funktionen ### Weboberflächen-Funktionen
- **Echtzeit-Updates:** WebSocket-Verbindung für Live-Daten-Updates. - **Echtzeit-Updates:** WebSocket-Verbindung für Live-Daten-Updates.
- **NFC-Tag-Verwaltung:** - **NFC-Tag-Verwaltung:**
- Filamentdaten auf NFC-Tags schreiben. - Filamentdaten auf NFC-Tags schreiben.
- Verwendet das NFC-Tag-Format von [Openspool](https://github.com/spuder/OpenSpool) - Ermöglicht automatische Spulenerkennung im AMS.
- Ermöglicht automatische Spulenerkennung im AMS - **Bambu Lab AMS-Integration:**
- **Bambulab AMS-Integration:**
- Anzeige der aktuellen AMS-Fachbelegung. - Anzeige der aktuellen AMS-Fachbelegung.
- Zuordnung von Filamenten zu AMS-Slots. - Zuordnung von Filamenten zu AMS-Slots.
- Unterstützung für externe Spulenhalter. - Unterstützung für externe Spulenhalter.
@@ -36,7 +35,7 @@ Discord Server: [https://discord.gg/vMAx2gf5](https://discord.gg/vMAx2gf5)
- Filtern und Auswählen von Filamenten. - Filtern und Auswählen von Filamenten.
- Automatische Aktualisierung der Spulengewichte. - Automatische Aktualisierung der Spulengewichte.
- Verfolgung von NFC-Tag-Zuweisungen. - Verfolgung von NFC-Tag-Zuweisungen.
- Unterstützt das Spoolman Octoprint Plugin - Unterstützt das Spoolman Octoprint Plugin.
### Wenn Sie meine Arbeit unterstützen möchten, freue ich mich über einen Kaffee ### Wenn Sie meine Arbeit unterstützen möchten, freue ich mich über einen Kaffee
<a href="https://www.buymeacoffee.com/manuelw" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 30px !important;width: 108px !important;" ></a> <a href="https://www.buymeacoffee.com/manuelw" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 30px !important;width: 108px !important;" ></a>
@@ -122,7 +121,7 @@ Du musst Spoolman auf DEBUG Modus setzten, da man bisher in Spoolman keine CORS
``` ```
## Schritt-für-Schritt Installation ## Schritt-für-Schritt Installation
### Einfache Installation ### Einfache Installation (Google Chrome oder Microsoft Edge)
1. **Gehe auf [FilaMan Installer](https://www.filaman.app/installer.html)** 1. **Gehe auf [FilaMan Installer](https://www.filaman.app/installer.html)**
2. **Stecke dein ESP an den Rechner und klicke Connect** 2. **Stecke dein ESP an den Rechner und klicke Connect**
+2 -3
View File
@@ -4,7 +4,7 @@
FilaMan is a filament management system for 3D printing. It uses ESP32 hardware for weight measurement and NFC tag management. FilaMan is a filament management system for 3D printing. It uses ESP32 hardware for weight measurement and NFC tag management.
Users can manage filament spools, monitor the status of the Automatic Material System (AMS) and make settings via a web interface. Users can manage filament spools, monitor the status of the Automatic Material System (AMS) and make settings via a web interface.
The system integrates seamlessly with [Bambu Lab](https://bambulab.com/en-us) 3D printers and [Spoolman](https://github.com/Donkie/Spoolman) filament management as well as the [OpenSpool](https://github.com/spuder/OpenSpool) NFC-TAG format. The system integrates seamlessly with [Bambu Lab](https://bambulab.com/en-us) 3D printers and [Spoolman](https://github.com/Donkie/Spoolman) filament management.
![Scale](./img/scale_trans.png) ![Scale](./img/scale_trans.png)
@@ -13,7 +13,7 @@ The system integrates seamlessly with [Bambu Lab](https://bambulab.com/en-us) 3D
More Images can be found in the [img Folder](/img/) More Images can be found in the [img Folder](/img/)
or my website: [FilaMan Website](https://www.filaman.app) or my website: [FilaMan Website](https://www.filaman.app)
german explanatory video: [Youtube](https://youtu.be/uNDe2wh9SS8?si=b-jYx4I1w62zaOHU) german explanatory video: [Youtube](https://youtu.be/uNDe2wh9SS8?si=b-jYx4I1w62zaOHU)
Discord Server: [https://discord.gg/vMAx2gf5](https://discord.gg/vMAx2gf5) Discord Server: [https://discord.gg/my7Gvaxj2v](https://discord.gg/my7Gvaxj2v)
### Now more detailed informations about the usage: [Wiki](https://github.com/ManuelW77/Filaman/wiki) ### Now more detailed informations about the usage: [Wiki](https://github.com/ManuelW77/Filaman/wiki)
@@ -29,7 +29,6 @@ Discord Server: [https://discord.gg/vMAx2gf5](https://discord.gg/vMAx2gf5)
- **Real-time Updates:** WebSocket connection for live data updates. - **Real-time Updates:** WebSocket connection for live data updates.
- **NFC Tag Management:** - **NFC Tag Management:**
- Write filament data to NFC tags. - Write filament data to NFC tags.
- uses NFC-Tag Format of [OpenSpool](https://github.com/spuder/OpenSpool)
- so you can use it with automatic Spool detection in AMS - so you can use it with automatic Spool detection in AMS
- **Bambulab AMS Integration:** - **Bambulab AMS Integration:**
- Display current AMS tray contents. - Display current AMS tray contents.
+16 -16
View File
@@ -60,13 +60,13 @@ function initWebSocket() {
try { try {
socket = new WebSocket('ws://' + window.location.host + '/ws'); socket = new WebSocket('ws://' + window.location.host + '/ws');
socket.onopen = function() { socket.onopen = function () {
isConnected = true; isConnected = true;
updateConnectionStatus(); updateConnectionStatus();
startHeartbeat(); // Starte Heartbeat nach erfolgreicher Verbindung startHeartbeat(); // Starte Heartbeat nach erfolgreicher Verbindung
}; };
socket.onclose = function() { socket.onclose = function () {
isConnected = false; isConnected = false;
updateConnectionStatus(); updateConnectionStatus();
if (heartbeatTimer) clearInterval(heartbeatTimer); if (heartbeatTimer) clearInterval(heartbeatTimer);
@@ -79,7 +79,7 @@ function initWebSocket() {
} }
}; };
socket.onerror = function(error) { socket.onerror = function (error) {
isConnected = false; isConnected = false;
updateConnectionStatus(); updateConnectionStatus();
if (heartbeatTimer) clearInterval(heartbeatTimer); if (heartbeatTimer) clearInterval(heartbeatTimer);
@@ -91,7 +91,7 @@ function initWebSocket() {
} }
}; };
socket.onmessage = function(event) { socket.onmessage = function (event) {
lastHeartbeatResponse = Date.now(); // Aktualisiere Zeitstempel bei jeder Server-Antwort lastHeartbeatResponse = Date.now(); // Aktualisiere Zeitstempel bei jeder Server-Antwort
const data = JSON.parse(event.data); const data = JSON.parse(event.data);
@@ -115,7 +115,7 @@ function initWebSocket() {
// Add click handler only when offline // Add click handler only when offline
if (!data.bambu_connected) { if (!data.bambu_connected) {
bambuDot.style.cursor = 'pointer'; bambuDot.style.cursor = 'pointer';
bambuDot.onclick = function() { bambuDot.onclick = function () {
if (socket && socket.readyState === WebSocket.OPEN) { if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({ socket.send(JSON.stringify({
type: 'reconnect', type: 'reconnect',
@@ -133,7 +133,7 @@ function initWebSocket() {
// Add click handler only when offline // Add click handler only when offline
if (!data.spoolman_connected) { if (!data.spoolman_connected) {
spoolmanDot.style.cursor = 'pointer'; spoolmanDot.style.cursor = 'pointer';
spoolmanDot.onclick = function() { spoolmanDot.onclick = function () {
if (socket && socket.readyState === WebSocket.OPEN) { if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({ socket.send(JSON.stringify({
type: 'reconnect', type: 'reconnect',
@@ -189,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;
@@ -218,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';
@@ -490,7 +490,7 @@ function handleSpoolIn(amsId, trayId) {
nozzle_temp_max: parseInt(maxTemp), nozzle_temp_max: parseInt(maxTemp),
type: selectedSpool.filament.material, type: selectedSpool.filament.material,
brand: selectedSpool.filament.vendor.name, brand: selectedSpool.filament.vendor.name,
tray_info_idx: selectedSpool.filament.extra.bambu_idx.replace(/['"]+/g, '').trim(), tray_info_idx: selectedSpool.filament.extra.bambu_idx?.replace(/['"]+/g, '').trim() || '',
cali_idx: "-1" // Default-Wert setzen cali_idx: "-1" // Default-Wert setzen
} }
}; };
+153 -43
View File
@@ -18,7 +18,7 @@ PubSubClient client(sslClient);
TaskHandle_t BambuMqttTask; TaskHandle_t BambuMqttTask;
String report_topic = ""; String report_topic = "";
//String request_topic = ""; String request_topic = "";
const char* bambu_username = "bblp"; const char* bambu_username = "bblp";
const char* bambu_ip = nullptr; const char* bambu_ip = nullptr;
const char* bambu_accesscode = nullptr; const char* bambu_accesscode = nullptr;
@@ -92,7 +92,7 @@ bool loadBambuCredentials() {
bambu_serialnr = g_bambu_serialnr.c_str(); bambu_serialnr = g_bambu_serialnr.c_str();
report_topic = "device/" + String(bambu_serialnr) + "/report"; report_topic = "device/" + String(bambu_serialnr) + "/report";
//request_topic = "device/" + String(bambu_serialnr) + "/request"; request_topic = "device/" + String(bambu_serialnr) + "/request";
return true; return true;
} }
Serial.println("Keine gültigen Bambu-Credentials gefunden."); Serial.println("Keine gültigen Bambu-Credentials gefunden.");
@@ -197,18 +197,69 @@ FilamentResult findFilamentIdx(String brand, String type) {
} }
bool sendMqttMessage(const String& payload) { bool sendMqttMessage(const String& payload) {
Serial.println("Sending MQTT message"); // Check MQTT client state first
Serial.println(payload); if (!client.connected()) {
if (client.publish(report_topic.c_str(), payload.c_str())) Serial.println("Error: MQTT client not connected when trying to send message");
{ Serial.print("MQTT client state: ");
return true; Serial.println(client.state());
return false;
} }
// Check if request_topic is empty
if (request_topic.isEmpty()) {
Serial.println("Error: request_topic is empty!");
return false; return false;
}
// Check payload
if (payload.isEmpty()) {
Serial.println("Error: Empty payload!");
return false;
}
Serial.println("Attempting to send MQTT message:");
Serial.println("Topic: " + request_topic);
Serial.println("Payload: " + payload);
Serial.println("Payload length: " + String(payload.length()));
// Try to publish with QoS 1 and retain flag false
bool published = client.publish(request_topic.c_str(), payload.c_str(), false);
if (published) {
Serial.println("MQTT message published successfully");
return true;
} else {
Serial.println("Failed to publish MQTT message");
Serial.print("MQTT client state after publish attempt: ");
Serial.println(client.state());
// Additional error information
switch(client.state()) {
case -4:
Serial.println("Reason: Connection timeout");
break;
case -3:
Serial.println("Reason: Connection lost");
break;
case -2:
Serial.println("Reason: Connect failed");
break;
case -1:
Serial.println("Reason: Disconnected");
break;
case 0:
Serial.println("Reason: Connected but publish failed");
break;
default:
Serial.println("Reason: Unknown error");
break;
}
return false;
}
} }
bool setBambuSpool(String payload) { bool setBambuSpool(String payload) {
Serial.println("Spool settings in"); Serial.println("Spool settings received from WebSocket");
Serial.println(payload); Serial.println(payload);
// Parse the JSON // Parse the JSON
@@ -220,21 +271,28 @@ bool setBambuSpool(String payload) {
return false; return false;
} }
int amsId = doc["amsId"]; // Check if we have all required fields
int trayId = doc["trayId"]; if (!doc["amsId"].is<int>() || !doc["trayId"].is<int>()) {
Serial.println("Error: Missing or invalid required fields in payload");
return false;
}
int amsId = doc["amsId"].as<int>();
int trayId = doc["trayId"].as<int>();
String color = doc["color"].as<String>(); String color = doc["color"].as<String>();
color.toUpperCase(); color.toUpperCase();
int minTemp = doc["nozzle_temp_min"]; int minTemp = doc["nozzle_temp_min"] | 0; // Default to 0 if not present
int maxTemp = doc["nozzle_temp_max"]; int maxTemp = doc["nozzle_temp_max"] | 0; // Default to 0 if not present
String type = doc["type"].as<String>(); String type = doc["type"] | ""; // Default to empty string if not present
(type == "PLA+") ? type = "PLA" : type; (type == "PLA+") ? type = "PLA" : type;
String brand = doc["brand"].as<String>(); String brand = doc["brand"] | ""; // Default to empty string if not present
String tray_info_idx = (doc["tray_info_idx"].as<String>() != "-1") ? doc["tray_info_idx"].as<String>() : ""; String tray_info_idx = (doc["tray_info_idx"].as<String>() != "-1") ? doc["tray_info_idx"].as<String>() : "";
if (tray_info_idx == "") { if (tray_info_idx == "") {
if (brand != "" && type != "") { if (brand != "" && type != "") {
FilamentResult result = findFilamentIdx(brand, type); FilamentResult result = findFilamentIdx(brand, type);
tray_info_idx = result.key; tray_info_idx = result.key;
type = result.type; // Aktualisiere den type mit dem gefundenen Basistyp type = result.type; // Aktualisiere den type mit dem gefundenen Basistyp
Serial.println("Found filament idx: " + tray_info_idx + " for type: " + type);
} }
} }
String setting_id = doc["bambu_setting_id"].as<String>(); String setting_id = doc["bambu_setting_id"].as<String>();
@@ -242,6 +300,7 @@ bool setBambuSpool(String payload) {
doc.clear(); doc.clear();
// Create MQTT message
doc["print"]["sequence_id"] = "0"; doc["print"]["sequence_id"] = "0";
doc["print"]["command"] = "ams_filament_setting"; doc["print"]["command"] = "ams_filament_setting";
doc["print"]["ams_id"] = amsId < 200 ? amsId : 255; doc["print"]["ams_id"] = amsId < 200 ? amsId : 255;
@@ -250,26 +309,25 @@ bool setBambuSpool(String payload) {
doc["print"]["nozzle_temp_min"] = minTemp; doc["print"]["nozzle_temp_min"] = minTemp;
doc["print"]["nozzle_temp_max"] = maxTemp; doc["print"]["nozzle_temp_max"] = maxTemp;
doc["print"]["tray_type"] = type; doc["print"]["tray_type"] = type;
//doc["print"]["cali_idx"] = (cali_idx != "") ? cali_idx : "";
doc["print"]["tray_info_idx"] = tray_info_idx; doc["print"]["tray_info_idx"] = tray_info_idx;
doc["print"]["setting_id"] = setting_id; doc["print"]["setting_id"] = setting_id;
// Serialize the JSON // Serialize and send MQTT message
String output; String output;
serializeJson(doc, output); serializeJson(doc, output);
Serial.println("Sending to Bambu printer:");
Serial.println(output);
if (sendMqttMessage(output)) { if (!sendMqttMessage(output)) {
Serial.println("Spool successfully set"); Serial.println("Failed to send filament settings to printer");
}
else
{
Serial.println("Failed to set spool");
return false; return false;
} }
Serial.println("Filament settings sent successfully");
doc.clear(); doc.clear();
yield(); yield();
// Send calibration if available
if (cali_idx != "") { if (cali_idx != "") {
yield(); yield();
doc["print"]["sequence_id"] = "0"; doc["print"]["sequence_id"] = "0";
@@ -278,21 +336,18 @@ bool setBambuSpool(String payload) {
doc["print"]["nozzle_diameter"] = "0.4"; doc["print"]["nozzle_diameter"] = "0.4";
doc["print"]["cali_idx"] = cali_idx.toInt(); doc["print"]["cali_idx"] = cali_idx.toInt();
doc["print"]["tray_id"] = trayId < 200 ? trayId : 254; doc["print"]["tray_id"] = trayId < 200 ? trayId : 254;
//doc["print"]["ams_id"] = amsId < 200 ? amsId : 255;
// Serialize the JSON
String output; String output;
serializeJson(doc, output); serializeJson(doc, output);
Serial.println("Sending calibration to printer:");
Serial.println(output);
if (sendMqttMessage(output)) { if (!sendMqttMessage(output)) {
Serial.println("Extrusion calibration successfully set"); Serial.println("Failed to send calibration settings to printer");
}
else
{
Serial.println("Failed to set extrusion calibration");
return false; return false;
} }
Serial.println("Calibration settings sent successfully");
doc.clear(); doc.clear();
yield(); yield();
} }
@@ -549,20 +604,47 @@ void reconnect() {
uint8_t retries = 0; uint8_t retries = 0;
while (!client.connected()) { while (!client.connected()) {
Serial.println("Attempting MQTT re/connection..."); Serial.println("Attempting MQTT re/connection...");
Serial.print("State before connect: ");
Serial.println(client.state());
bambu_connected = false; bambu_connected = false;
oledShowTopRow(); oledShowTopRow();
// Attempt to connect // Generate a random client ID suffix
if (client.connect(bambu_serialnr, bambu_username, bambu_accesscode)) { String clientId = String(bambu_serialnr) + "_" + String(random(0xffff), HEX);
Serial.print("Reconnecting with client ID: ");
Serial.println(clientId);
// Attempt to connect with clean session and will message
if (client.connect(clientId.c_str(), bambu_username, bambu_accesscode, nullptr, 0, true, nullptr)) {
Serial.println("MQTT re/connected"); Serial.println("MQTT re/connected");
client.subscribe(report_topic.c_str()); // Subscribe with QoS 1
if (client.subscribe(report_topic.c_str(), 1)) {
Serial.println("Successfully subscribed to topic with QoS 1: " + report_topic);
} else {
Serial.println("Failed to subscribe to topic: " + report_topic);
}
bambu_connected = true; bambu_connected = true;
oledShowTopRow(); oledShowTopRow();
} else { } else {
int state = client.state();
Serial.print("failed, rc="); Serial.print("failed, rc=");
Serial.print(client.state()); Serial.print(state);
Serial.println(" try again in 5 seconds"); Serial.print(" (");
// Print detailed error message
switch(state) {
case -4: Serial.print("MQTT_CONNECTION_TIMEOUT"); break;
case -3: Serial.print("MQTT_CONNECTION_LOST"); break;
case -2: Serial.print("MQTT_CONNECT_FAILED"); break;
case -1: Serial.print("MQTT_DISCONNECTED"); break;
case 1: Serial.print("MQTT_CONNECT_BAD_PROTOCOL"); break;
case 2: Serial.print("MQTT_CONNECT_BAD_CLIENT_ID"); break;
case 3: Serial.print("MQTT_CONNECT_UNAVAILABLE"); break;
case 4: Serial.print("MQTT_CONNECT_BAD_CREDENTIALS"); break;
case 5: Serial.print("MQTT_CONNECT_UNAUTHORIZED"); break;
default: Serial.print("UNKNOWN"); break;
}
Serial.println(") try again in 5 seconds");
bambu_connected = false; bambu_connected = false;
oledShowTopRow(); oledShowTopRow();
@@ -570,11 +652,9 @@ void reconnect() {
vTaskDelay(5000 / portTICK_PERIOD_MS); vTaskDelay(5000 / portTICK_PERIOD_MS);
if (retries > 5) { if (retries > 5) {
Serial.println("Disable Bambu MQTT Task after 5 retries"); Serial.println("Disable Bambu MQTT Task after 5 retries");
//vTaskSuspend(BambuMqttTask);
vTaskDelete(BambuMqttTask); vTaskDelete(BambuMqttTask);
break; break;
} }
retries++; retries++;
} }
} }
@@ -582,17 +662,32 @@ void reconnect() {
void mqtt_loop(void * parameter) { void mqtt_loop(void * parameter) {
Serial.println("Bambu MQTT Task gestartet"); Serial.println("Bambu MQTT Task gestartet");
unsigned long lastCheck = 0;
for(;;) { for(;;) {
if (pauseBambuMqttTask) { if (pauseBambuMqttTask) {
vTaskDelay(10000); vTaskDelay(10000);
continue;
} }
unsigned long now = millis();
if (!client.connected()) { if (!client.connected()) {
Serial.println("Connection lost, attempting reconnect...");
reconnect(); reconnect();
yield(); yield();
esp_task_wdt_reset(); esp_task_wdt_reset();
vTaskDelay(100); vTaskDelay(100);
continue;
} }
// Periodically check connection status
if (now - lastCheck > 30000) { // Check every 30 seconds
Serial.print("MQTT Status Check - Connected: ");
Serial.println(client.connected() ? "Yes" : "No");
lastCheck = now;
}
client.loop(); client.loop();
yield(); yield();
esp_task_wdt_reset(); esp_task_wdt_reset();
@@ -617,15 +712,30 @@ bool setupMqtt() {
sslClient.setInsecure(); sslClient.setInsecure();
client.setServer(bambu_ip, 8883); client.setServer(bambu_ip, 8883);
// Generate a random client ID suffix
String clientId = String(bambu_serialnr) + "_" + String(random(0xffff), HEX);
// MQTT Connection Options
client.setKeepAlive(60);
client.setSocketTimeout(60); // Increase socket timeout
Serial.print("Connecting with client ID: ");
Serial.println(clientId);
// Verbinden mit dem MQTT-Server // Verbinden mit dem MQTT-Server
bool connected = true; bool connected = true;
if (client.connect(bambu_serialnr, bambu_username, bambu_accesscode)) if (client.connect(clientId.c_str(), bambu_username, bambu_accesscode, nullptr, 0, true, nullptr))
{ {
client.setCallback(mqtt_callback); client.setCallback(mqtt_callback);
client.setBufferSize(5120); client.setBufferSize(16384); // Increased to 16KB to handle larger JSON
// Optional: Topic abonnieren
client.subscribe(report_topic.c_str()); // Subscribe with QoS 1
//client.subscribe(request_topic.c_str()); if (client.subscribe(report_topic.c_str(), 1)) {
Serial.println("Successfully subscribed to topic with QoS 1: " + report_topic);
} else {
Serial.println("Failed to subscribe to topic: " + report_topic);
}
Serial.println("MQTT-Client initialisiert"); Serial.println("MQTT-Client initialisiert");
oledShowMessage("Bambu Connected"); oledShowMessage("Bambu Connected");
@@ -635,7 +745,7 @@ bool setupMqtt() {
xTaskCreatePinnedToCore( xTaskCreatePinnedToCore(
mqtt_loop, /* Function to implement the task */ mqtt_loop, /* Function to implement the task */
"BambuMqtt", /* Name of the task */ "BambuMqtt", /* Name of the task */
8192, /* Stack size in words */ 16384, /* Stack size in words */
NULL, /* Task input parameter */ NULL, /* Task input parameter */
mqttTaskPrio, /* Priority of the task */ mqttTaskPrio, /* Priority of the task */
&BambuMqttTask, /* Task handle. */ &BambuMqttTask, /* Task handle. */
-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);