Compare commits
15 Commits
v1.5.12-be
...
recyclingf
Author | SHA1 | Date | |
---|---|---|---|
213b9c099c | |||
687e57b77a | |||
aea11e0c06 | |||
bd8f4606c6 | |||
ac91e71c14 | |||
0d3503f4f1 | |||
1460c6e5f9 | |||
fef7e5aa4b | |||
bda8c3dd98 | |||
8702469020 | |||
2a0f999f3b | |||
c89adb6256 | |||
1f21954703 | |||
3e59ce1366 | |||
1f880fc8f1 |
31
CHANGELOG.md
31
CHANGELOG.md
@@ -1,5 +1,36 @@
|
||||
# Changelog
|
||||
|
||||
## [1.5.12-beta17] - 2025-08-29
|
||||
### Added
|
||||
- add progress bar updates for vendor and filament creation processes
|
||||
|
||||
### Changed
|
||||
- update platformio.ini for beta version v1.5.12-beta17
|
||||
- optimize page limit detection and remove redundant verification code
|
||||
|
||||
### Fixed
|
||||
- update vendor check to use shorthand key in payload
|
||||
|
||||
|
||||
## [1.5.12-beta16] - 2025-08-29
|
||||
### Changed
|
||||
- update platformio.ini for beta version v1.5.12-beta16
|
||||
- Refactor NFC interface handling and improve error diagnostics
|
||||
|
||||
|
||||
## [1.5.12-beta15] - 2025-08-29
|
||||
### Changed
|
||||
- update platformio.ini for beta version v1.5.12-beta15
|
||||
- enhance NFC write operation diagnostics and improve error handling
|
||||
- enhance NFC write operation handling and prevent tag operations during write
|
||||
|
||||
|
||||
## [1.5.12-beta14] - 2025-08-29
|
||||
### Changed
|
||||
- update platformio.ini for beta version v1.5.12-beta14
|
||||
- optimize JSON payload structure and enhance NFC tag validation process
|
||||
|
||||
|
||||
## [1.5.12-beta13] - 2025-08-29
|
||||
### Changed
|
||||
- update platformio.ini for beta version v1.5.12-beta13
|
||||
|
@@ -9,7 +9,7 @@
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[common]
|
||||
version = "1.5.12-beta13"
|
||||
version = "1.5.12-beta17"
|
||||
to_old_version = "1.5.0"
|
||||
|
||||
##
|
||||
|
84
src/api.cpp
84
src/api.cpp
@@ -9,18 +9,6 @@
|
||||
#include <time.h>
|
||||
volatile spoolmanApiStateType spoolmanApiState = API_IDLE;
|
||||
|
||||
// Returns current date and time in ISO8601 format
|
||||
String getCurrentDateISO8601() {
|
||||
struct tm timeinfo;
|
||||
if(!getLocalTime(&timeinfo)) {
|
||||
Serial.println("Failed to obtain time");
|
||||
return "1970-01-01T00:00:00Z";
|
||||
}
|
||||
char timeStringBuff[25];
|
||||
strftime(timeStringBuff, sizeof(timeStringBuff), "%Y-%m-%dT%H:%M:%SZ", &timeinfo);
|
||||
return String(timeStringBuff);
|
||||
}
|
||||
|
||||
//bool spoolman_connected = false;
|
||||
String spoolmanUrl = "";
|
||||
bool octoEnabled = false;
|
||||
@@ -614,6 +602,8 @@ bool updateSpoolBambuData(String payload) {
|
||||
|
||||
// #### Brand Filament
|
||||
uint16_t createVendor(String vendor) {
|
||||
oledShowProgressBar(2, 5, "New Brand", "Create new Vendor");
|
||||
|
||||
// Create new vendor in Spoolman database using task system
|
||||
// Note: Due to async nature, the ID will be stored in createdVendorId global variable
|
||||
// Note: This function assumes that the caller has already ensured API is IDLE
|
||||
@@ -627,7 +617,6 @@ uint16_t createVendor(String vendor) {
|
||||
JsonDocument vendorDoc;
|
||||
vendorDoc["name"] = vendor;
|
||||
vendorDoc["comment"] = "automatically generated";
|
||||
vendorDoc["empty_spool_weight"] = 180;
|
||||
vendorDoc["external_id"] = vendor;
|
||||
|
||||
String vendorPayload;
|
||||
@@ -675,6 +664,8 @@ uint16_t createVendor(String vendor) {
|
||||
}
|
||||
|
||||
uint16_t checkVendor(String vendor) {
|
||||
oledShowProgressBar(1, 5, "New Brand", "Check Vendor");
|
||||
|
||||
// Check if vendor exists using task system
|
||||
foundVendorId = 65535; // Reset to invalid value to detect when API response is received
|
||||
|
||||
@@ -737,6 +728,8 @@ uint16_t checkVendor(String vendor) {
|
||||
}
|
||||
|
||||
uint16_t createFilament(uint16_t vendorId, const JsonDocument& payload) {
|
||||
oledShowProgressBar(4, 5, "New Brand", "Create Filament");
|
||||
|
||||
// Create new filament in Spoolman database using task system
|
||||
// Note: Due to async nature, the ID will be stored in createdFilamentId global variable
|
||||
// Note: This function assumes that the caller has already ensured API is IDLE
|
||||
@@ -748,34 +741,34 @@ uint16_t createFilament(uint16_t vendorId, const JsonDocument& payload) {
|
||||
|
||||
// Create JSON payload for filament creation
|
||||
JsonDocument filamentDoc;
|
||||
filamentDoc["name"] = payload["color_name"].as<String>();
|
||||
filamentDoc["name"] = payload["cn"].as<String>();
|
||||
filamentDoc["vendor_id"] = String(vendorId);
|
||||
filamentDoc["material"] = payload["type"].as<String>();
|
||||
filamentDoc["density"] = (payload["density"].is<String>() && payload["density"].as<String>().length() > 0) ? payload["density"].as<String>() : "1.24";
|
||||
filamentDoc["diameter"] = (payload["diameter"].is<String>() && payload["diameter"].as<String>().length() > 0) ? payload["diameter"].as<String>() : "1.75";
|
||||
filamentDoc["material"] = payload["t"].as<String>();
|
||||
filamentDoc["density"] = (payload["de"].is<String>() && payload["de"].as<String>().length() > 0) ? payload["de"].as<String>() : "1.24";
|
||||
filamentDoc["diameter"] = (payload["di"].is<String>() && payload["di"].as<String>().length() > 0) ? payload["di"].as<String>() : "1.75";
|
||||
filamentDoc["weight"] = String(weight);
|
||||
filamentDoc["spool_weight"] = payload["spool_weight"].as<String>();
|
||||
filamentDoc["article_number"] = payload["artnr"].as<String>();
|
||||
filamentDoc["settings_extruder_temp"] = payload["extruder_temp"].is<String>() ? payload["extruder_temp"].as<String>() : "";
|
||||
filamentDoc["settings_bed_temp"] = payload["bed_temp"].is<String>() ? payload["bed_temp"].as<String>() : "";
|
||||
|
||||
if (payload["artnr"].is<String>())
|
||||
filamentDoc["spool_weight"] = payload["sw"].as<String>();
|
||||
filamentDoc["article_number"] = payload["an"].as<String>();
|
||||
filamentDoc["settings_extruder_temp"] = payload["et"].is<String>() ? payload["et"].as<String>() : "";
|
||||
filamentDoc["settings_bed_temp"] = payload["bt"].is<String>() ? payload["bt"].as<String>() : "";
|
||||
|
||||
if (payload["an"].is<String>())
|
||||
{
|
||||
filamentDoc["external_id"] = payload["artnr"].as<String>();
|
||||
filamentDoc["comment"] = payload["url"].is<String>() ? payload["url"].as<String>() + payload["artnr"].as<String>() : "automatically generated";
|
||||
filamentDoc["external_id"] = payload["an"].as<String>();
|
||||
filamentDoc["comment"] = payload["u"].is<String>() ? payload["u"].as<String>() + payload["an"].as<String>() : "automatically generated";
|
||||
}
|
||||
else
|
||||
{
|
||||
filamentDoc["comment"] = payload["url"].is<String>() ? payload["url"].as<String>() : "automatically generated";
|
||||
filamentDoc["comment"] = payload["u"].is<String>() ? payload["u"].as<String>() : "automatically generated";
|
||||
}
|
||||
|
||||
if (payload["multi_color_hexes"].is<String>()) {
|
||||
filamentDoc["multi_color_hexes"] = payload["multi_color_hexes"].as<String>();
|
||||
filamentDoc["multi_color_direction"] = payload["multi_color_direction"].is<String>() ? payload["multi_color_direction"].as<String>() : "";
|
||||
if (payload["mc"].is<String>()) {
|
||||
filamentDoc["multi_color_hexes"] = payload["mc"].as<String>();
|
||||
filamentDoc["multi_color_direction"] = payload["mcd"].is<String>() ? payload["mcd"].as<String>() : "";
|
||||
}
|
||||
else
|
||||
{
|
||||
filamentDoc["color_hex"] = (payload["color_hex"].is<String>() && payload["color_hex"].as<String>().length() >= 6) ? payload["color_hex"].as<String>() : "FFFFFF";
|
||||
filamentDoc["color_hex"] = (payload["c"].is<String>() && payload["c"].as<String>().length() >= 6) ? payload["c"].as<String>() : "FFFFFF";
|
||||
}
|
||||
|
||||
String filamentPayload;
|
||||
@@ -823,6 +816,8 @@ uint16_t createFilament(uint16_t vendorId, const JsonDocument& payload) {
|
||||
}
|
||||
|
||||
uint16_t checkFilament(uint16_t vendorId, const JsonDocument& payload) {
|
||||
oledShowProgressBar(3, 5, "New Brand", "Check Filament");
|
||||
|
||||
// Check if filament exists using task system
|
||||
foundFilamentId = 65535; // Reset to invalid value to detect when API response is received
|
||||
|
||||
@@ -875,6 +870,8 @@ uint16_t checkFilament(uint16_t vendorId, const JsonDocument& payload) {
|
||||
}
|
||||
|
||||
uint16_t createSpool(uint16_t vendorId, uint16_t filamentId, JsonDocument& payload, String uidString) {
|
||||
oledShowProgressBar(5, 5, "New Brand", "Create new Spool");
|
||||
|
||||
// Create new spool in Spoolman database using task system
|
||||
// Note: Due to async nature, the ID will be stored in createdSpoolId global variable
|
||||
// Note: This function assumes that the caller has already ensured API is IDLE
|
||||
@@ -883,17 +880,14 @@ uint16_t createSpool(uint16_t vendorId, uint16_t filamentId, JsonDocument& paylo
|
||||
String spoolsUrl = spoolmanUrl + apiUrl + "/spool";
|
||||
Serial.print("Create spool with URL: ");
|
||||
Serial.println(spoolsUrl);
|
||||
//String currentDate = getCurrentDateISO8601();
|
||||
|
||||
// Create JSON payload for spool creation
|
||||
JsonDocument spoolDoc;
|
||||
//spoolDoc["first_used"] = String(currentDate);
|
||||
//spoolDoc["last_used"] = String(currentDate);
|
||||
spoolDoc["filament_id"] = String(filamentId);
|
||||
spoolDoc["initial_weight"] = weight > 10 ? String(weight-payload["spool_weight"].as<int>()) : "1000";
|
||||
spoolDoc["spool_weight"] = (payload["spool_weight"].is<String>() && payload["spool_weight"].as<String>().length() > 0) ? payload["spool_weight"].as<String>() : "180";
|
||||
spoolDoc["remaining_weight"] = (payload["weight"].is<String>() && payload["weight"].as<String>().length() > 0) ? payload["weight"].as<String>() : "1000";
|
||||
spoolDoc["lot_nr"] = (payload["lotnr"].is<String>() && payload["lotnr"].as<String>().length() > 0) ? payload["lotnr"].as<String>() : "";
|
||||
spoolDoc["initial_weight"] = weight > 10 ? String(weight - payload["sw"].as<int>()) : "1000";
|
||||
spoolDoc["spool_weight"] = (payload["sw"].is<String>() && payload["sw"].as<String>().length() > 0) ? payload["sw"].as<String>() : "180";
|
||||
spoolDoc["remaining_weight"] = spoolDoc["initial_weight"];
|
||||
spoolDoc["lot_nr"] = (payload["an"].is<String>() && payload["an"].as<String>().length() > 0) ? payload["an"].as<String>() : "";
|
||||
spoolDoc["comment"] = "automatically generated";
|
||||
spoolDoc["extra"]["nfc_id"] = "\"" + uidString + "\"";
|
||||
|
||||
@@ -938,10 +932,20 @@ uint16_t createSpool(uint16_t vendorId, uint16_t filamentId, JsonDocument& paylo
|
||||
|
||||
// Write data to tag with startWriteJsonToTag
|
||||
// void startWriteJsonToTag(const bool isSpoolTag, const char* payload);
|
||||
payload["sm_id"].set(String(createdSpoolId));
|
||||
|
||||
// Create optimized JSON structure with sm_id at the beginning for fast-path detection
|
||||
JsonDocument optimizedPayload;
|
||||
optimizedPayload["sm_id"] = String(createdSpoolId); // Place sm_id first for fast scanning
|
||||
optimizedPayload["b"] = payload["b"].as<String>();
|
||||
optimizedPayload["cn"] = payload["an"].as<String>();
|
||||
|
||||
String payloadString;
|
||||
serializeJson(payload, payloadString);
|
||||
serializeJson(optimizedPayload, payloadString);
|
||||
|
||||
Serial.println("Optimized JSON with sm_id first:");
|
||||
Serial.println(payloadString);
|
||||
|
||||
optimizedPayload.clear();
|
||||
|
||||
nfcReaderState = NFC_IDLE;
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
@@ -951,7 +955,7 @@ uint16_t createSpool(uint16_t vendorId, uint16_t filamentId, JsonDocument& paylo
|
||||
}
|
||||
|
||||
bool createBrandFilament(JsonDocument& payload, String uidString) {
|
||||
uint16_t vendorId = checkVendor(payload["brand"].as<String>());
|
||||
uint16_t vendorId = checkVendor(payload["b"].as<String>());
|
||||
if (vendorId == 0) {
|
||||
Serial.println("ERROR: Failed to create/find vendor");
|
||||
return false;
|
||||
|
@@ -235,7 +235,7 @@ void oledShowIcon(const char* icon) {
|
||||
display.display();
|
||||
}
|
||||
|
||||
void oledShowProgressBar(const uint8_t step, const uint8_t numSteps, const char* largeText, const char* statusMessage){
|
||||
void oledShowProgressBar(const uint8_t step, const uint8_t numSteps, const char* largeText, const char* statusMessage) {
|
||||
assert(step <= numSteps);
|
||||
|
||||
// clear data and bar area
|
||||
|
853
src/nfc.cpp
853
src/nfc.cpp
@@ -23,6 +23,7 @@ bool tagProcessed = false;
|
||||
volatile bool pauseBambuMqttTask = false;
|
||||
volatile bool nfcReadingTaskSuspendRequest = false;
|
||||
volatile bool nfcReadingTaskSuspendState = false;
|
||||
volatile bool nfcWriteInProgress = false; // Prevent any tag operations during write
|
||||
|
||||
struct NfcWriteParameterType {
|
||||
bool tagType;
|
||||
@@ -314,6 +315,71 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
|
||||
Serial.print("Max Writable Page: ");Serial.println(maxWritablePage);
|
||||
Serial.println("========================");
|
||||
|
||||
// Perform additional tag validation by testing write boundaries
|
||||
Serial.println("=== TAG VALIDATION ===");
|
||||
uint8_t testBuffer[4] = {0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
// Test if we can actually read the max page
|
||||
if (!nfc.ntag2xx_ReadPage(maxWritablePage, testBuffer)) {
|
||||
Serial.print("WARNING: Cannot read declared max page ");
|
||||
Serial.println(maxWritablePage);
|
||||
|
||||
// Find actual maximum writable page by testing backwards with optimized approach
|
||||
uint16_t actualMaxPage = maxWritablePage;
|
||||
Serial.println("Searching for actual maximum writable page...");
|
||||
|
||||
// Use binary search approach for faster page limit detection
|
||||
uint16_t lowPage = 4;
|
||||
uint16_t highPage = maxWritablePage;
|
||||
uint16_t testAttempts = 0;
|
||||
const uint16_t maxTestAttempts = 15; // Limit search attempts
|
||||
|
||||
while (lowPage <= highPage && testAttempts < maxTestAttempts) {
|
||||
uint16_t midPage = (lowPage + highPage) / 2;
|
||||
testAttempts++;
|
||||
|
||||
Serial.print("Testing page ");
|
||||
Serial.print(midPage);
|
||||
Serial.print(" (attempt ");
|
||||
Serial.print(testAttempts);
|
||||
Serial.print("/");
|
||||
Serial.print(maxTestAttempts);
|
||||
Serial.print(")... ");
|
||||
|
||||
if (nfc.ntag2xx_ReadPage(midPage, testBuffer)) {
|
||||
Serial.println("✓");
|
||||
actualMaxPage = midPage;
|
||||
lowPage = midPage + 1; // Search higher
|
||||
} else {
|
||||
Serial.println("❌");
|
||||
highPage = midPage - 1; // Search lower
|
||||
}
|
||||
|
||||
// Small delay to prevent interface overload
|
||||
vTaskDelay(5 / portTICK_PERIOD_MS);
|
||||
yield();
|
||||
}
|
||||
|
||||
Serial.print("Found actual max readable page: ");
|
||||
Serial.println(actualMaxPage);
|
||||
Serial.print("Search completed in ");
|
||||
Serial.print(testAttempts);
|
||||
Serial.println(" attempts");
|
||||
|
||||
maxWritablePage = actualMaxPage;
|
||||
} else {
|
||||
Serial.print("✓ Max page ");Serial.print(maxWritablePage);Serial.println(" is readable");
|
||||
}
|
||||
|
||||
// Calculate maximum available user data based on actual writable pages
|
||||
uint16_t actualUserDataSize = (maxWritablePage - 3) * 4; // -3 because pages 0-3 are header
|
||||
availableUserData = actualUserDataSize;
|
||||
|
||||
Serial.print("Actual available user data: ");
|
||||
Serial.print(actualUserDataSize);
|
||||
Serial.println(" bytes");
|
||||
Serial.println("========================");
|
||||
|
||||
uint8_t pageBuffer[4] = {0, 0, 0, 0};
|
||||
Serial.println("Beginne mit dem Schreiben der NDEF-Nachricht...");
|
||||
|
||||
@@ -375,15 +441,317 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
|
||||
|
||||
Serial.println("✓ Payload passt in den Tag - Schreibvorgang wird fortgesetzt");
|
||||
|
||||
// IMPORTANT: Use safe NDEF initialization instead of aggressive clearing
|
||||
Serial.println("Schritt 1: Sichere NDEF-Initialisierung...");
|
||||
// STEP 1: NFC Interface Reset and Reinitialization
|
||||
Serial.println();
|
||||
Serial.println("=== SCHRITT 1: NFC-INTERFACE RESET UND NEUINITIALISIERUNG ===");
|
||||
|
||||
// First, check if the NFC interface is working at all
|
||||
Serial.println("Teste aktuellen NFC-Interface-Zustand...");
|
||||
|
||||
// Try to read capability container (which worked during detection)
|
||||
uint8_t ccTest[4];
|
||||
bool ccReadable = nfc.ntag2xx_ReadPage(3, ccTest);
|
||||
Serial.print("Capability Container (Seite 3) lesbar: ");
|
||||
Serial.println(ccReadable ? "✓" : "❌");
|
||||
|
||||
if (!ccReadable) {
|
||||
Serial.println("❌ NFC-Interface ist nicht funktionsfähig - führe Reset durch");
|
||||
|
||||
// Perform NFC interface reset and reinitialization
|
||||
Serial.println("Führe NFC-Interface Reset durch...");
|
||||
|
||||
// Step 1: Try to reinitialize the NFC interface completely
|
||||
Serial.println("1. Neuinitialisierung des PN532...");
|
||||
|
||||
// Reinitialize the PN532
|
||||
nfc.begin();
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS); // Give it time to initialize
|
||||
|
||||
// Check firmware version to ensure communication is working
|
||||
uint32_t versiondata = nfc.getFirmwareVersion();
|
||||
if (versiondata) {
|
||||
Serial.print("PN532 Firmware Version: 0x");
|
||||
Serial.println(versiondata, HEX);
|
||||
Serial.println("✓ PN532 Kommunikation wiederhergestellt");
|
||||
} else {
|
||||
Serial.println("❌ PN532 Kommunikation fehlgeschlagen");
|
||||
oledShowMessage("NFC Reset failed");
|
||||
vTaskDelay(3000 / portTICK_PERIOD_MS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Step 2: Reconfigure SAM
|
||||
Serial.println("2. SAM-Konfiguration...");
|
||||
nfc.SAMConfig();
|
||||
vTaskDelay(200 / portTICK_PERIOD_MS);
|
||||
|
||||
// Step 3: Re-detect the tag
|
||||
Serial.println("3. Tag-Wiedererkennung...");
|
||||
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
|
||||
uint8_t uidLength;
|
||||
bool tagRedetected = false;
|
||||
|
||||
for (int attempts = 0; attempts < 5; attempts++) {
|
||||
Serial.print("Tag-Erkennungsversuch ");
|
||||
Serial.print(attempts + 1);
|
||||
Serial.print("/5... ");
|
||||
|
||||
if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 1000)) {
|
||||
Serial.println("✓");
|
||||
tagRedetected = true;
|
||||
break;
|
||||
} else {
|
||||
Serial.println("❌");
|
||||
vTaskDelay(300 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
if (!tagRedetected) {
|
||||
Serial.println("❌ Tag konnte nach Reset nicht wiedererkannt werden");
|
||||
oledShowMessage("Tag lost after reset");
|
||||
vTaskDelay(3000 / portTICK_PERIOD_MS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Serial.println("✓ Tag erfolgreich wiedererkannt");
|
||||
|
||||
// Step 4: Test basic page reading
|
||||
Serial.println("4. Test der Grundfunktionalität...");
|
||||
vTaskDelay(200 / portTICK_PERIOD_MS); // Give interface time to stabilize
|
||||
|
||||
ccReadable = nfc.ntag2xx_ReadPage(3, ccTest);
|
||||
Serial.print("Capability Container nach Reset lesbar: ");
|
||||
Serial.println(ccReadable ? "✓" : "❌");
|
||||
|
||||
if (!ccReadable) {
|
||||
Serial.println("❌ NFC-Interface funktioniert nach Reset immer noch nicht");
|
||||
oledShowMessage("NFC still broken");
|
||||
vTaskDelay(3000 / portTICK_PERIOD_MS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Serial.println("✓ NFC-Interface erfolgreich wiederhergestellt");
|
||||
} else {
|
||||
Serial.println("✓ NFC-Interface ist funktionsfähig");
|
||||
}
|
||||
|
||||
// Display CC content for debugging
|
||||
if (ccReadable) {
|
||||
Serial.print("CC Inhalt: ");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (ccTest[i] < 0x10) Serial.print("0");
|
||||
Serial.print(ccTest[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
Serial.println("=== SCHRITT 2: INTERFACE-FUNKTIONSTEST ===");
|
||||
|
||||
// Test a few critical pages to ensure stable operation
|
||||
uint8_t testData[4];
|
||||
bool basicPagesReadable = true;
|
||||
|
||||
for (uint8_t testPage = 0; testPage <= 6; testPage++) {
|
||||
bool readable = nfc.ntag2xx_ReadPage(testPage, testData);
|
||||
Serial.print("Seite ");
|
||||
Serial.print(testPage);
|
||||
Serial.print(": ");
|
||||
if (readable) {
|
||||
Serial.print("✓ - ");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (testData[i] < 0x10) Serial.print("0");
|
||||
Serial.print(testData[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
} else {
|
||||
Serial.println("❌ - Nicht lesbar");
|
||||
if (testPage >= 3 && testPage <= 6) { // Critical pages for NDEF
|
||||
basicPagesReadable = false;
|
||||
}
|
||||
}
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS); // Small delay between reads
|
||||
}
|
||||
|
||||
if (!basicPagesReadable) {
|
||||
Serial.println("❌ KRITISCHER FEHLER: Grundlegende NDEF-Seiten nicht lesbar!");
|
||||
Serial.println("Tag oder Interface ist defekt");
|
||||
oledShowMessage("Tag/Interface defect");
|
||||
vTaskDelay(3000 / portTICK_PERIOD_MS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Serial.println("✓ Alle kritischen Seiten sind lesbar");
|
||||
Serial.println("===================================================");
|
||||
|
||||
Serial.println();
|
||||
Serial.println("=== SCHRITT 3: SCHREIBBEREITSCHAFTSTEST ===");
|
||||
|
||||
// Test write capabilities before attempting the full write
|
||||
Serial.println("Teste Schreibfähigkeiten des Tags...");
|
||||
|
||||
uint8_t testPage[4] = {0xAA, 0xBB, 0xCC, 0xDD}; // Test pattern
|
||||
uint8_t originalPage[4]; // Store original content
|
||||
|
||||
// First, read original content of test page
|
||||
if (!nfc.ntag2xx_ReadPage(10, originalPage)) {
|
||||
Serial.println("FEHLER: Kann Testseite nicht lesen für Backup");
|
||||
oledShowMessage("Test page read error");
|
||||
vTaskDelay(3000 / portTICK_PERIOD_MS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Serial.print("Original Inhalt Seite 10: ");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (originalPage[i] < 0x10) Serial.print("0");
|
||||
Serial.print(originalPage[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// Perform write test
|
||||
if (!nfc.ntag2xx_WritePage(10, testPage)) {
|
||||
Serial.println("FEHLER: Schreibtest fehlgeschlagen!");
|
||||
Serial.println("Tag ist möglicherweise schreibgeschützt oder defekt");
|
||||
|
||||
// Additional diagnostics
|
||||
Serial.println("=== ERWEITERTE SCHREIBTEST-DIAGNOSE ===");
|
||||
|
||||
// Check if tag is still present
|
||||
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
|
||||
uint8_t uidLength;
|
||||
bool tagStillPresent = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 1000);
|
||||
Serial.print("Tag noch erkannt: ");
|
||||
Serial.println(tagStillPresent ? "✓" : "❌");
|
||||
|
||||
if (!tagStillPresent) {
|
||||
Serial.println("URSACHE: Tag wurde während Schreibtest entfernt!");
|
||||
oledShowMessage("Tag removed");
|
||||
} else {
|
||||
Serial.println("URSACHE: Tag ist vorhanden aber nicht beschreibbar");
|
||||
Serial.println("Möglicherweise: Schreibschutz, Defekt, oder Interface-Problem");
|
||||
oledShowMessage("Tag write protected?");
|
||||
}
|
||||
Serial.println("==========================================");
|
||||
|
||||
vTaskDelay(3000 / portTICK_PERIOD_MS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Verify test write
|
||||
uint8_t readBack[4];
|
||||
vTaskDelay(20 / portTICK_PERIOD_MS); // Wait for write to complete
|
||||
|
||||
if (!nfc.ntag2xx_ReadPage(10, readBack)) {
|
||||
Serial.println("FEHLER: Kann Testdaten nicht zurücklesen!");
|
||||
oledShowMessage("Test verify failed");
|
||||
vTaskDelay(3000 / portTICK_PERIOD_MS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool testSuccess = true;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (readBack[i] != testPage[i]) {
|
||||
testSuccess = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!testSuccess) {
|
||||
Serial.println("FEHLER: Schreibtest fehlgeschlagen - Daten stimmen nicht überein!");
|
||||
Serial.print("Geschrieben: ");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Serial.print(testPage[i], HEX); Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
Serial.print("Gelesen: ");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Serial.print(readBack[i], HEX); Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Restore original content
|
||||
Serial.println("Stelle ursprünglichen Inhalt wieder her...");
|
||||
if (!nfc.ntag2xx_WritePage(10, originalPage)) {
|
||||
Serial.println("WARNUNG: Konnte ursprünglichen Inhalt nicht wiederherstellen!");
|
||||
} else {
|
||||
Serial.println("✓ Ursprünglicher Inhalt wiederhergestellt");
|
||||
}
|
||||
|
||||
Serial.println("✓ Schreibtest erfolgreich - Tag ist voll funktionsfähig");
|
||||
Serial.println("======================================================");
|
||||
|
||||
// STEP 4: NDEF initialization with verification
|
||||
Serial.println();
|
||||
Serial.println("=== SCHRITT 4: NDEF-INITIALISIERUNG ===");
|
||||
if (!initializeNdefStructure()) {
|
||||
Serial.println("FEHLER: Konnte NDEF-Struktur nicht initialisieren!");
|
||||
oledShowMessage("NDEF init failed");
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
return 0;
|
||||
}
|
||||
Serial.println("✓ NDEF-Struktur sicher initialisiert");
|
||||
|
||||
// Verify NDEF initialization
|
||||
uint8_t ndefCheck[8];
|
||||
bool ndefVerified = true;
|
||||
for (uint8_t page = 4; page < 6; page++) {
|
||||
if (!nfc.ntag2xx_ReadPage(page, &ndefCheck[(page-4)*4])) {
|
||||
ndefVerified = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ndefVerified) {
|
||||
Serial.print("NDEF-Header nach Initialisierung: ");
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (ndefCheck[i] < 0x10) Serial.print("0");
|
||||
Serial.print(ndefCheck[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
Serial.println("✓ NDEF-Struktur initialisiert und verifiziert");
|
||||
Serial.println("==========================================");
|
||||
|
||||
// STEP 5: Allow interface to stabilize before major write operation
|
||||
Serial.println();
|
||||
Serial.println("=== SCHRITT 5: NFC-INTERFACE STABILISIERUNG ===");
|
||||
Serial.println("Stabilisiere NFC-Interface vor Hauptschreibvorgang...");
|
||||
|
||||
// Give the interface time to fully settle after NDEF initialization
|
||||
vTaskDelay(200 / portTICK_PERIOD_MS);
|
||||
|
||||
// Test interface stability with a simple read
|
||||
uint8_t stabilityTest[4];
|
||||
bool interfaceStable = false;
|
||||
for (int attempts = 0; attempts < 3; attempts++) {
|
||||
if (nfc.ntag2xx_ReadPage(4, stabilityTest)) {
|
||||
Serial.print("Interface stability test ");
|
||||
Serial.print(attempts + 1);
|
||||
Serial.println("/3: ✓");
|
||||
interfaceStable = true;
|
||||
break;
|
||||
} else {
|
||||
Serial.print("Interface stability test ");
|
||||
Serial.print(attempts + 1);
|
||||
Serial.println("/3: ❌");
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
if (!interfaceStable) {
|
||||
Serial.println("FEHLER: NFC-Interface ist nicht stabil genug für Schreibvorgang");
|
||||
oledShowMessage("NFC Interface unstable");
|
||||
vTaskDelay(3000 / portTICK_PERIOD_MS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Serial.println("✓ NFC-Interface ist stabil - Schreibvorgang kann beginnen");
|
||||
Serial.println("=========================================================");
|
||||
|
||||
// Allocate memory for the complete TLV structure
|
||||
uint8_t* tlvData = (uint8_t*) malloc(totalTlvSize);
|
||||
@@ -444,7 +812,8 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
|
||||
uint8_t pageNumber = 4;
|
||||
uint16_t totalBytes = offset + 1;
|
||||
|
||||
Serial.println("Schritt 2: Schreibe neue NDEF-Daten...");
|
||||
Serial.println();
|
||||
Serial.println("=== SCHRITT 6: SCHREIBE NEUE NDEF-DATEN ===");
|
||||
Serial.print("Schreibe ");
|
||||
Serial.print(totalBytes);
|
||||
Serial.print(" Bytes in ");
|
||||
@@ -452,6 +821,13 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
|
||||
Serial.println(" Seiten...");
|
||||
|
||||
while (bytesWritten < totalBytes && pageNumber <= maxWritablePage) {
|
||||
// Additional safety check before writing each page
|
||||
if (pageNumber > maxWritablePage) {
|
||||
Serial.print("STOP: Reached maximum writable page ");
|
||||
Serial.println(maxWritablePage);
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear page buffer
|
||||
memset(pageBuffer, 0, 4);
|
||||
|
||||
@@ -461,16 +837,98 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
|
||||
// Copy data to page buffer
|
||||
memcpy(pageBuffer, &tlvData[bytesWritten], bytesToWrite);
|
||||
|
||||
// Write page to tag
|
||||
if (!nfc.ntag2xx_WritePage(pageNumber, pageBuffer)) {
|
||||
// Write page to tag with retry mechanism
|
||||
bool writeSuccess = false;
|
||||
for (int writeAttempt = 0; writeAttempt < 3; writeAttempt++) {
|
||||
if (nfc.ntag2xx_WritePage(pageNumber, pageBuffer)) {
|
||||
writeSuccess = true;
|
||||
break;
|
||||
} else {
|
||||
Serial.print("Schreibversuch ");
|
||||
Serial.print(writeAttempt + 1);
|
||||
Serial.print("/3 für Seite ");
|
||||
Serial.print(pageNumber);
|
||||
Serial.println(" fehlgeschlagen");
|
||||
|
||||
if (writeAttempt < 2) {
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS); // Wait before retry
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!writeSuccess) {
|
||||
Serial.print("FEHLER beim Schreiben der Seite ");
|
||||
Serial.println(pageNumber);
|
||||
Serial.print("Möglicherweise Page-Limit erreicht für ");
|
||||
Serial.println(tagType);
|
||||
Serial.print("Erwartetes Maximum: ");
|
||||
Serial.println(maxWritablePage);
|
||||
Serial.print("Tatsächliches Maximum scheint niedriger zu sein!");
|
||||
|
||||
// Update max page for future operations
|
||||
if (pageNumber > 4) {
|
||||
Serial.print("Setze neues Maximum auf Seite ");
|
||||
Serial.println(pageNumber - 1);
|
||||
}
|
||||
|
||||
free(tlvData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IMMEDIATE verification after each write - this is critical!
|
||||
Serial.print("Verifiziere Seite ");
|
||||
Serial.print(pageNumber);
|
||||
Serial.print("... ");
|
||||
|
||||
uint8_t verifyBuffer[4];
|
||||
vTaskDelay(20 / portTICK_PERIOD_MS); // Increased delay before verification
|
||||
|
||||
// Verification with retry mechanism
|
||||
bool verifySuccess = false;
|
||||
for (int verifyAttempt = 0; verifyAttempt < 3; verifyAttempt++) {
|
||||
if (nfc.ntag2xx_ReadPage(pageNumber, verifyBuffer)) {
|
||||
bool writeMatches = true;
|
||||
for (int i = 0; i < bytesToWrite; i++) {
|
||||
if (verifyBuffer[i] != pageBuffer[i]) {
|
||||
writeMatches = false;
|
||||
Serial.println();
|
||||
Serial.print("VERIFIKATIONSFEHLER bei Byte ");
|
||||
Serial.print(i);
|
||||
Serial.print(" - Erwartet: 0x");
|
||||
Serial.print(pageBuffer[i], HEX);
|
||||
Serial.print(", Gelesen: 0x");
|
||||
Serial.println(verifyBuffer[i], HEX);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (writeMatches) {
|
||||
verifySuccess = true;
|
||||
break;
|
||||
} else if (verifyAttempt < 2) {
|
||||
Serial.print("Verifikationsversuch ");
|
||||
Serial.print(verifyAttempt + 1);
|
||||
Serial.println("/3 fehlgeschlagen, wiederhole...");
|
||||
vTaskDelay(30 / portTICK_PERIOD_MS);
|
||||
}
|
||||
} else {
|
||||
Serial.print("Verifikations-Read-Versuch ");
|
||||
Serial.print(verifyAttempt + 1);
|
||||
Serial.println("/3 fehlgeschlagen");
|
||||
if (verifyAttempt < 2) {
|
||||
vTaskDelay(30 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!verifySuccess) {
|
||||
Serial.println("❌ SCHREIBVORGANG/VERIFIKATION FEHLGESCHLAGEN!");
|
||||
free(tlvData);
|
||||
return 0;
|
||||
} else {
|
||||
Serial.println("✓");
|
||||
}
|
||||
|
||||
Serial.print("Seite ");
|
||||
Serial.print(pageNumber);
|
||||
Serial.print(" ✓: ");
|
||||
@@ -485,7 +943,7 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
|
||||
pageNumber++;
|
||||
|
||||
yield();
|
||||
vTaskDelay(5 / portTICK_PERIOD_MS); // Small delay between page writes
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS); // Slightly increased delay between page writes
|
||||
}
|
||||
|
||||
free(tlvData);
|
||||
@@ -511,7 +969,58 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
|
||||
Serial.print((bytesWritten * 100) / availableUserData);
|
||||
Serial.println("%");
|
||||
Serial.println("✓ Bestehende Daten wurden überschrieben");
|
||||
|
||||
// CRITICAL: Allow NFC interface to stabilize after write operation
|
||||
Serial.println();
|
||||
Serial.println("=== SCHRITT 7: NFC-INTERFACE STABILISIERUNG NACH SCHREIBVORGANG ===");
|
||||
Serial.println("Stabilisiere NFC-Interface nach Schreibvorgang...");
|
||||
|
||||
// Give the tag and interface time to settle after write operation
|
||||
vTaskDelay(300 / portTICK_PERIOD_MS); // Increased stabilization time
|
||||
|
||||
// Test if the interface is still responsive
|
||||
uint8_t postWriteTest[4];
|
||||
bool interfaceResponsive = false;
|
||||
|
||||
for (int stabilityAttempt = 0; stabilityAttempt < 5; stabilityAttempt++) {
|
||||
Serial.print("Post-write interface test ");
|
||||
Serial.print(stabilityAttempt + 1);
|
||||
Serial.print("/5... ");
|
||||
|
||||
if (nfc.ntag2xx_ReadPage(3, postWriteTest)) { // Read capability container
|
||||
Serial.println("✓");
|
||||
interfaceResponsive = true;
|
||||
break;
|
||||
} else {
|
||||
Serial.println("❌");
|
||||
|
||||
if (stabilityAttempt < 4) {
|
||||
Serial.println("Warte und versuche Interface zu stabilisieren...");
|
||||
vTaskDelay(200 / portTICK_PERIOD_MS);
|
||||
|
||||
// Try to re-establish communication with a simple tag presence check
|
||||
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
|
||||
uint8_t uidLength;
|
||||
bool tagStillPresent = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 1000);
|
||||
Serial.print("Tag presence check: ");
|
||||
Serial.println(tagStillPresent ? "✓" : "❌");
|
||||
|
||||
if (!tagStillPresent) {
|
||||
Serial.println("Tag wurde während/nach Schreibvorgang entfernt!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!interfaceResponsive) {
|
||||
Serial.println("WARNUNG: NFC-Interface reagiert nach Schreibvorgang nicht mehr stabil");
|
||||
Serial.println("Schreibvorgang war erfolgreich, aber Interface benötigt möglicherweise Reset");
|
||||
} else {
|
||||
Serial.println("✓ NFC-Interface ist nach Schreibvorgang stabil");
|
||||
}
|
||||
|
||||
Serial.println("==================================================================");
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -735,7 +1244,7 @@ bool decodeNdefAndReturnJson(const byte* encodedMessage, String uidString) {
|
||||
}
|
||||
// Brand Filament not registered to Spoolman
|
||||
else if ((!doc["sm_id"].is<String>() || (doc["sm_id"].is<String>() && (doc["sm_id"] == "0" || doc["sm_id"] == "")))
|
||||
&& doc["brand"].is<String>() && doc["artnr"].is<String>())
|
||||
&& doc["b"].is<String>() && doc["an"].is<String>())
|
||||
{
|
||||
doc["sm_id"] = "0"; // Ensure sm_id is set to 0
|
||||
// If no sm_id is present but the brand is Brand Filament then
|
||||
@@ -759,6 +1268,216 @@ bool decodeNdefAndReturnJson(const byte* encodedMessage, String uidString) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool quickSpoolIdCheck(String uidString) {
|
||||
// Fast-path: Read NDEF structure to quickly locate and check JSON payload
|
||||
// This dramatically speeds up known spool recognition
|
||||
|
||||
// CRITICAL: Do not execute during write operations!
|
||||
if (nfcWriteInProgress) {
|
||||
Serial.println("FAST-PATH: Skipped during write operation");
|
||||
return false;
|
||||
}
|
||||
|
||||
Serial.println("=== FAST-PATH: Quick sm_id Check ===");
|
||||
|
||||
// Read enough pages to cover NDEF header + beginning of payload (pages 4-8 = 20 bytes)
|
||||
uint8_t ndefData[20];
|
||||
memset(ndefData, 0, 20);
|
||||
|
||||
for (uint8_t page = 4; page < 9; page++) {
|
||||
if (!nfc.ntag2xx_ReadPage(page, ndefData + (page - 4) * 4)) {
|
||||
Serial.print("Failed to read page ");
|
||||
Serial.println(page);
|
||||
return false; // Fall back to full read
|
||||
}
|
||||
}
|
||||
|
||||
// Parse NDEF structure to find JSON payload start
|
||||
Serial.print("Raw NDEF data (first 20 bytes): ");
|
||||
for (int i = 0; i < 20; i++) {
|
||||
if (ndefData[i] < 0x10) Serial.print("0");
|
||||
Serial.print(ndefData[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// Look for NDEF TLV (0x03) at the beginning
|
||||
int tlvOffset = -1;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (ndefData[i] == 0x03) {
|
||||
tlvOffset = i;
|
||||
Serial.print("Found NDEF TLV at offset: ");
|
||||
Serial.println(tlvOffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tlvOffset == -1) {
|
||||
Serial.println("✗ FAST-PATH: No NDEF TLV found");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse NDEF record to find JSON payload
|
||||
int ndefRecordStart;
|
||||
if (ndefData[tlvOffset + 1] == 0xFF) {
|
||||
// Extended length format
|
||||
ndefRecordStart = tlvOffset + 4;
|
||||
} else {
|
||||
// Standard length format
|
||||
ndefRecordStart = tlvOffset + 2;
|
||||
}
|
||||
|
||||
if (ndefRecordStart >= 20) {
|
||||
Serial.println("✗ FAST-PATH: NDEF record starts beyond read data");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse NDEF record header
|
||||
uint8_t recordHeader = ndefData[ndefRecordStart];
|
||||
uint8_t typeLength = ndefData[ndefRecordStart + 1];
|
||||
|
||||
// Calculate payload offset
|
||||
uint8_t payloadLengthBytes = (recordHeader & 0x10) ? 1 : 4; // SR flag check
|
||||
uint8_t idLength = (recordHeader & 0x08) ? ndefData[ndefRecordStart + 2 + payloadLengthBytes + typeLength] : 0; // IL flag check
|
||||
|
||||
int payloadOffset = ndefRecordStart + 1 + 1 + payloadLengthBytes + typeLength + idLength;
|
||||
|
||||
Serial.print("NDEF Record Header: 0x");
|
||||
Serial.print(recordHeader, HEX);
|
||||
Serial.print(", Type Length: ");
|
||||
Serial.print(typeLength);
|
||||
Serial.print(", Payload offset: ");
|
||||
Serial.println(payloadOffset);
|
||||
|
||||
// Check if payload starts within our read data
|
||||
if (payloadOffset >= 20) {
|
||||
Serial.println("✗ FAST-PATH: JSON payload starts beyond quick read data - need more pages");
|
||||
|
||||
// Read additional pages to get to JSON payload
|
||||
uint8_t extraData[16]; // Read 4 more pages
|
||||
memset(extraData, 0, 16);
|
||||
|
||||
for (uint8_t page = 9; page < 13; page++) {
|
||||
if (!nfc.ntag2xx_ReadPage(page, extraData + (page - 9) * 4)) {
|
||||
Serial.print("Failed to read additional page ");
|
||||
Serial.println(page);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Combine data
|
||||
uint8_t combinedData[36];
|
||||
memcpy(combinedData, ndefData, 20);
|
||||
memcpy(combinedData + 20, extraData, 16);
|
||||
|
||||
// Extract JSON from combined data
|
||||
String jsonStart = "";
|
||||
int jsonStartPos = payloadOffset;
|
||||
for (int i = 0; i < 36 - payloadOffset && i < 30; i++) {
|
||||
uint8_t currentByte = combinedData[payloadOffset + i];
|
||||
if (currentByte >= 32 && currentByte <= 126) {
|
||||
jsonStart += (char)currentByte;
|
||||
}
|
||||
// Stop at first brace to get just the beginning
|
||||
if (currentByte == '{' && i > 0) break;
|
||||
}
|
||||
|
||||
Serial.print("JSON start from extended read: ");
|
||||
Serial.println(jsonStart);
|
||||
|
||||
// Check for sm_id pattern - look for non-zero sm_id values
|
||||
if (jsonStart.indexOf("\"sm_id\":\"") >= 0) {
|
||||
int smIdStart = jsonStart.indexOf("\"sm_id\":\"") + 9;
|
||||
int smIdEnd = jsonStart.indexOf("\"", smIdStart);
|
||||
|
||||
if (smIdEnd > smIdStart && smIdEnd < jsonStart.length()) {
|
||||
String quickSpoolId = jsonStart.substring(smIdStart, smIdEnd);
|
||||
Serial.print("Found sm_id in extended read: ");
|
||||
Serial.println(quickSpoolId);
|
||||
|
||||
// Only process if sm_id is not "0" (known spool)
|
||||
if (quickSpoolId != "0" && quickSpoolId.length() > 0) {
|
||||
Serial.println("✓ FAST-PATH: Known spool detected!");
|
||||
|
||||
// Set as active spool immediately
|
||||
activeSpoolId = quickSpoolId;
|
||||
lastSpoolId = activeSpoolId;
|
||||
|
||||
oledShowProgressBar(2, octoEnabled?5:4, "Known Spool", "Quick mode");
|
||||
Serial.println("✓ FAST-PATH SUCCESS: Known spool processed quickly");
|
||||
return true;
|
||||
} else {
|
||||
Serial.println("✗ FAST-PATH: sm_id is 0 - new brand filament, need full read");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("✗ FAST-PATH: No sm_id pattern in extended read");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract JSON payload from the available data
|
||||
String quickJson = "";
|
||||
for (int i = payloadOffset; i < 20 && i < payloadOffset + 15; i++) {
|
||||
uint8_t currentByte = ndefData[i];
|
||||
if (currentByte >= 32 && currentByte <= 126) {
|
||||
quickJson += (char)currentByte;
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("Quick JSON data: ");
|
||||
Serial.println(quickJson);
|
||||
|
||||
// Look for sm_id pattern in the beginning of JSON - check for known vs new spools
|
||||
if (quickJson.indexOf("\"sm_id\":\"") >= 0) {
|
||||
Serial.println("✓ FAST-PATH: sm_id field found");
|
||||
|
||||
// Extract sm_id from quick data
|
||||
int smIdStart = quickJson.indexOf("\"sm_id\":\"") + 9;
|
||||
int smIdEnd = quickJson.indexOf("\"", smIdStart);
|
||||
|
||||
if (smIdEnd > smIdStart && smIdEnd < quickJson.length()) {
|
||||
String quickSpoolId = quickJson.substring(smIdStart, smIdEnd);
|
||||
Serial.print("✓ Quick extracted sm_id: ");
|
||||
Serial.println(quickSpoolId);
|
||||
|
||||
// Only process known spools (sm_id != "0") via fast path
|
||||
if (quickSpoolId != "0" && quickSpoolId.length() > 0) {
|
||||
Serial.println("✓ FAST-PATH: Known spool detected!");
|
||||
|
||||
// Set as active spool immediately
|
||||
activeSpoolId = quickSpoolId;
|
||||
lastSpoolId = activeSpoolId;
|
||||
|
||||
oledShowProgressBar(2, octoEnabled?5:4, "Known Spool", "Quick mode");
|
||||
Serial.println("✓ FAST-PATH SUCCESS: Known spool processed quickly");
|
||||
return true;
|
||||
} else {
|
||||
Serial.println("✗ FAST-PATH: sm_id is 0 - new brand filament, need full read");
|
||||
return false; // sm_id="0" means new brand filament, needs full processing
|
||||
}
|
||||
} else {
|
||||
Serial.println("✗ FAST-PATH: Could not extract complete sm_id value");
|
||||
return false; // Need full read to get complete sm_id
|
||||
}
|
||||
}
|
||||
|
||||
// Check for other patterns that require full read
|
||||
if (quickJson.indexOf("\"location\":\"") >= 0) {
|
||||
Serial.println("✓ FAST-PATH: Location tag detected");
|
||||
return false; // Need full read for location processing
|
||||
}
|
||||
|
||||
if (quickJson.indexOf("\"brand\":\"") >= 0) {
|
||||
Serial.println("✓ FAST-PATH: Brand filament detected - may need full processing");
|
||||
return false; // Need full read for brand filament creation
|
||||
}
|
||||
|
||||
Serial.println("✗ FAST-PATH: No recognizable pattern - falling back to full read");
|
||||
return false; // Fall back to full tag reading
|
||||
}
|
||||
|
||||
void writeJsonToTag(void *parameter) {
|
||||
NfcWriteParameterType* params = (NfcWriteParameterType*)parameter;
|
||||
|
||||
@@ -767,12 +1486,11 @@ void writeJsonToTag(void *parameter) {
|
||||
Serial.println(params->payload);
|
||||
|
||||
nfcReaderState = NFC_WRITING;
|
||||
nfcWriteInProgress = true; // Block high-level tag operations during write
|
||||
|
||||
// First request the reading task to be suspended and than wait until it responds
|
||||
nfcReadingTaskSuspendRequest = true;
|
||||
while(nfcReadingTaskSuspendState == false){
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
}
|
||||
// Do NOT suspend the reading task - we need NFC interface for verification
|
||||
// Just use nfcWriteInProgress to prevent scanning and fast-path operations
|
||||
Serial.println("NFC Write Task starting - High-level operations blocked, low-level NFC available");
|
||||
|
||||
//pauseBambuMqttTask = true;
|
||||
// aktualisieren der Website wenn sich der Status ändert
|
||||
@@ -831,13 +1549,80 @@ void writeJsonToTag(void *parameter) {
|
||||
}else{
|
||||
oledShowProgressBar(1, 1, "Write Tag", "Done!");
|
||||
}
|
||||
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
|
||||
|
||||
// CRITICAL: Properly stabilize NFC interface after write operation
|
||||
Serial.println();
|
||||
Serial.println("=== POST-WRITE NFC STABILIZATION ===");
|
||||
|
||||
// Wait for tag operations to complete
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
|
||||
// Test tag presence and remove detection
|
||||
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
|
||||
uint8_t uidLength;
|
||||
yield();
|
||||
esp_task_wdt_reset();
|
||||
while (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 400)) {
|
||||
int tagRemovalChecks = 0;
|
||||
|
||||
Serial.println("Warte bis Tag entfernt wird...");
|
||||
|
||||
// Monitor tag presence
|
||||
while (tagRemovalChecks < 10) {
|
||||
yield();
|
||||
}
|
||||
esp_task_wdt_reset();
|
||||
|
||||
bool tagPresent = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 500);
|
||||
|
||||
if (!tagPresent) {
|
||||
Serial.println("✓ Tag wurde entfernt - NFC bereit für nächsten Scan");
|
||||
break;
|
||||
}
|
||||
|
||||
tagRemovalChecks++;
|
||||
Serial.print("Tag noch vorhanden (");
|
||||
Serial.print(tagRemovalChecks);
|
||||
Serial.println("/10)");
|
||||
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
if (tagRemovalChecks >= 10) {
|
||||
Serial.println("WARNUNG: Tag wurde nicht entfernt - fahre trotzdem fort");
|
||||
}
|
||||
|
||||
// Additional interface stabilization before resuming normal operations
|
||||
Serial.println("Stabilisiere NFC-Interface für normale Operationen...");
|
||||
vTaskDelay(200 / portTICK_PERIOD_MS);
|
||||
|
||||
// Test if interface is ready for normal scanning
|
||||
uint8_t interfaceTestBuffer[4];
|
||||
bool interfaceReady = false;
|
||||
|
||||
for (int testAttempt = 0; testAttempt < 3; testAttempt++) {
|
||||
// Try a simple interface operation (without requiring tag presence)
|
||||
Serial.print("Interface readiness test ");
|
||||
Serial.print(testAttempt + 1);
|
||||
Serial.print("/3... ");
|
||||
|
||||
// Use a safe read operation that doesn't depend on tag presence
|
||||
// This tests if the PN532 chip itself is responsive
|
||||
uint32_t versiondata = nfc.getFirmwareVersion();
|
||||
if (versiondata != 0) {
|
||||
Serial.println("✓");
|
||||
interfaceReady = true;
|
||||
break;
|
||||
} else {
|
||||
Serial.println("❌");
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
if (!interfaceReady) {
|
||||
Serial.println("WARNUNG: NFC-Interface reagiert nicht - könnte normale Scans beeinträchtigen");
|
||||
} else {
|
||||
Serial.println("✓ NFC-Interface ist bereit für normale Scans");
|
||||
}
|
||||
|
||||
Serial.println("=========================================");
|
||||
|
||||
vTaskResume(RfidReaderTask);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
}
|
||||
@@ -860,7 +1645,8 @@ void writeJsonToTag(void *parameter) {
|
||||
sendWriteResult(nullptr, success);
|
||||
sendNfcData();
|
||||
|
||||
nfcReadingTaskSuspendRequest = false;
|
||||
// Only reset the write protection flag - reading task was never suspended
|
||||
nfcWriteInProgress = false; // Re-enable high-level tag operations
|
||||
pauseBambuMqttTask = false;
|
||||
|
||||
free(params->payload);
|
||||
@@ -895,8 +1681,8 @@ void startWriteJsonToTag(const bool isSpoolTag, const char* payload) {
|
||||
void scanRfidTask(void * parameter) {
|
||||
Serial.println("RFID Task gestartet");
|
||||
for(;;) {
|
||||
// Wenn geschrieben wird Schleife aussetzen
|
||||
if (nfcReaderState != NFC_WRITING && !nfcReadingTaskSuspendRequest && !booting)
|
||||
// Skip scanning during write operations, but keep NFC interface active
|
||||
if (nfcReaderState != NFC_WRITING && !nfcWriteInProgress && !nfcReadingTaskSuspendRequest && !booting)
|
||||
{
|
||||
nfcReadingTaskSuspendState = false;
|
||||
yield();
|
||||
@@ -938,6 +1724,18 @@ void scanRfidTask(void * parameter) {
|
||||
|
||||
if (uidLength == 7)
|
||||
{
|
||||
// Try fast-path detection first for known spools
|
||||
if (quickSpoolIdCheck(uidString)) {
|
||||
Serial.println("✓ FAST-PATH: Tag processed quickly, skipping full read");
|
||||
pauseBambuMqttTask = false;
|
||||
// Set reader back to idle for next scan
|
||||
nfcReaderState = NFC_READ_SUCCESS;
|
||||
delay(500); // Small delay before next scan
|
||||
continue; // Skip full tag reading and continue scan loop
|
||||
}
|
||||
|
||||
Serial.println("Continuing with full tag read after fast-path check");
|
||||
|
||||
uint16_t tagSize = readTagSize();
|
||||
if(tagSize > 0)
|
||||
{
|
||||
@@ -1029,8 +1827,17 @@ void scanRfidTask(void * parameter) {
|
||||
else
|
||||
{
|
||||
nfcReadingTaskSuspendState = true;
|
||||
Serial.println("NFC Reading disabled");
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
|
||||
// Different behavior for write protection vs. full suspension
|
||||
if (nfcWriteInProgress) {
|
||||
// During write: Just pause scanning, don't disable NFC interface
|
||||
// Serial.println("NFC Scanning paused during write operation");
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS); // Shorter delay during write
|
||||
} else {
|
||||
// Full suspension requested
|
||||
Serial.println("NFC Reading disabled");
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@ typedef enum{
|
||||
void startNfc();
|
||||
void scanRfidTask(void * parameter);
|
||||
void startWriteJsonToTag(const bool isSpoolTag, const char* payload);
|
||||
bool quickSpoolIdCheck(String uidString);
|
||||
|
||||
extern TaskHandle_t RfidReaderTask;
|
||||
extern String nfcJsonData;
|
||||
@@ -23,6 +24,7 @@ extern String activeSpoolId;
|
||||
extern String lastSpoolId;
|
||||
extern volatile nfcReaderStateType nfcReaderState;
|
||||
extern volatile bool pauseBambuMqttTask;
|
||||
extern volatile bool nfcWriteInProgress;
|
||||
extern bool tagProcessed;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user