Compare commits
	
		
			7 Commits
		
	
	
		
			v1.5.12-be
			...
			v1.5.12-be
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0d3503f4f1 | |||
| 1460c6e5f9 | |||
| fef7e5aa4b | |||
| bda8c3dd98 | |||
| 8702469020 | |||
| 2a0f999f3b | |||
| c89adb6256 | 
							
								
								
									
										13
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -1,5 +1,18 @@
 | 
				
			|||||||
# Changelog
 | 
					# Changelog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [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
 | 
					## [1.5.12-beta14] - 2025-08-29
 | 
				
			||||||
### Changed
 | 
					### Changed
 | 
				
			||||||
- update platformio.ini for beta version v1.5.12-beta14
 | 
					- update platformio.ini for beta version v1.5.12-beta14
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@
 | 
				
			|||||||
; https://docs.platformio.org/page/projectconf.html
 | 
					; https://docs.platformio.org/page/projectconf.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[common]
 | 
					[common]
 | 
				
			||||||
version = "1.5.12-beta14"
 | 
					version = "1.5.12-beta16"
 | 
				
			||||||
to_old_version = "1.5.0"
 | 
					to_old_version = "1.5.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##
 | 
					##
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										68
									
								
								src/api.cpp
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								src/api.cpp
									
									
									
									
									
								
							@@ -9,18 +9,6 @@
 | 
				
			|||||||
#include <time.h>
 | 
					#include <time.h>
 | 
				
			||||||
volatile spoolmanApiStateType spoolmanApiState = API_IDLE;
 | 
					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;
 | 
					//bool spoolman_connected = false;
 | 
				
			||||||
String spoolmanUrl = "";
 | 
					String spoolmanUrl = "";
 | 
				
			||||||
bool octoEnabled = false;
 | 
					bool octoEnabled = false;
 | 
				
			||||||
@@ -627,7 +615,6 @@ uint16_t createVendor(String vendor) {
 | 
				
			|||||||
    JsonDocument vendorDoc;
 | 
					    JsonDocument vendorDoc;
 | 
				
			||||||
    vendorDoc["name"] = vendor;
 | 
					    vendorDoc["name"] = vendor;
 | 
				
			||||||
    vendorDoc["comment"] = "automatically generated";
 | 
					    vendorDoc["comment"] = "automatically generated";
 | 
				
			||||||
    vendorDoc["empty_spool_weight"] = 180;
 | 
					 | 
				
			||||||
    vendorDoc["external_id"] = vendor;
 | 
					    vendorDoc["external_id"] = vendor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    String vendorPayload;
 | 
					    String vendorPayload;
 | 
				
			||||||
@@ -748,34 +735,34 @@ uint16_t createFilament(uint16_t vendorId, const JsonDocument& payload) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Create JSON payload for filament creation
 | 
					    // Create JSON payload for filament creation
 | 
				
			||||||
    JsonDocument filamentDoc;
 | 
					    JsonDocument filamentDoc;
 | 
				
			||||||
    filamentDoc["name"] = payload["color_name"].as<String>();
 | 
					    filamentDoc["name"] = payload["cn"].as<String>();
 | 
				
			||||||
    filamentDoc["vendor_id"] = String(vendorId);
 | 
					    filamentDoc["vendor_id"] = String(vendorId);
 | 
				
			||||||
    filamentDoc["material"] = payload["type"].as<String>();
 | 
					    filamentDoc["material"] = payload["t"].as<String>();
 | 
				
			||||||
    filamentDoc["density"] = (payload["density"].is<String>() && payload["density"].as<String>().length() > 0) ? payload["density"].as<String>() : "1.24";
 | 
					    filamentDoc["density"] = (payload["de"].is<String>() && payload["de"].as<String>().length() > 0) ? payload["de"].as<String>() : "1.24";
 | 
				
			||||||
    filamentDoc["diameter"] = (payload["diameter"].is<String>() && payload["diameter"].as<String>().length() > 0) ? payload["diameter"].as<String>() : "1.75";
 | 
					    filamentDoc["diameter"] = (payload["di"].is<String>() && payload["di"].as<String>().length() > 0) ? payload["di"].as<String>() : "1.75";
 | 
				
			||||||
    filamentDoc["weight"] = String(weight);
 | 
					    filamentDoc["weight"] = String(weight);
 | 
				
			||||||
    filamentDoc["spool_weight"] = payload["spool_weight"].as<String>();
 | 
					    filamentDoc["spool_weight"] = payload["sw"].as<String>();
 | 
				
			||||||
    filamentDoc["article_number"] = payload["artnr"].as<String>();
 | 
					    filamentDoc["article_number"] = payload["an"].as<String>();
 | 
				
			||||||
    filamentDoc["settings_extruder_temp"] = payload["extruder_temp"].is<String>() ? payload["extruder_temp"].as<String>() : "";
 | 
					    filamentDoc["settings_extruder_temp"] = payload["et"].is<String>() ? payload["et"].as<String>() : "";
 | 
				
			||||||
    filamentDoc["settings_bed_temp"] = payload["bed_temp"].is<String>() ? payload["bed_temp"].as<String>() : "";
 | 
					    filamentDoc["settings_bed_temp"] = payload["bt"].is<String>() ? payload["bt"].as<String>() : "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (payload["artnr"].is<String>())
 | 
					    if (payload["an"].is<String>())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        filamentDoc["external_id"] = payload["artnr"].as<String>();
 | 
					        filamentDoc["external_id"] = payload["an"].as<String>();
 | 
				
			||||||
        filamentDoc["comment"] = payload["url"].is<String>() ? payload["url"].as<String>() + payload["artnr"].as<String>() : "automatically generated";
 | 
					        filamentDoc["comment"] = payload["u"].is<String>() ? payload["u"].as<String>() + payload["an"].as<String>() : "automatically generated";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    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>()) {
 | 
					    if (payload["mc"].is<String>()) {
 | 
				
			||||||
        filamentDoc["multi_color_hexes"] = payload["multi_color_hexes"].as<String>();
 | 
					        filamentDoc["multi_color_hexes"] = payload["mc"].as<String>();
 | 
				
			||||||
        filamentDoc["multi_color_direction"] = payload["multi_color_direction"].is<String>() ? payload["multi_color_direction"].as<String>() : "";
 | 
					        filamentDoc["multi_color_direction"] = payload["mcd"].is<String>() ? payload["mcd"].as<String>() : "";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    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;
 | 
					    String filamentPayload;
 | 
				
			||||||
@@ -883,17 +870,14 @@ uint16_t createSpool(uint16_t vendorId, uint16_t filamentId, JsonDocument& paylo
 | 
				
			|||||||
    String spoolsUrl = spoolmanUrl + apiUrl + "/spool";
 | 
					    String spoolsUrl = spoolmanUrl + apiUrl + "/spool";
 | 
				
			||||||
    Serial.print("Create spool with URL: ");
 | 
					    Serial.print("Create spool with URL: ");
 | 
				
			||||||
    Serial.println(spoolsUrl);
 | 
					    Serial.println(spoolsUrl);
 | 
				
			||||||
    //String currentDate = getCurrentDateISO8601();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Create JSON payload for spool creation
 | 
					    // Create JSON payload for spool creation
 | 
				
			||||||
    JsonDocument spoolDoc;
 | 
					    JsonDocument spoolDoc;
 | 
				
			||||||
    //spoolDoc["first_used"] = String(currentDate);
 | 
					 | 
				
			||||||
    //spoolDoc["last_used"] = String(currentDate);
 | 
					 | 
				
			||||||
    spoolDoc["filament_id"] = String(filamentId);
 | 
					    spoolDoc["filament_id"] = String(filamentId);
 | 
				
			||||||
    spoolDoc["initial_weight"] = weight > 10 ? String(weight-payload["spool_weight"].as<int>()) : "1000";
 | 
					    spoolDoc["initial_weight"] = weight > 10 ? String(weight - payload["sw"].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["spool_weight"] = (payload["sw"].is<String>() && payload["sw"].as<String>().length() > 0) ? payload["sw"].as<String>() : "180";
 | 
				
			||||||
    spoolDoc["remaining_weight"] = (payload["weight"].is<String>() && payload["weight"].as<String>().length() > 0) ? payload["weight"].as<String>() : "1000";
 | 
					    spoolDoc["remaining_weight"] = spoolDoc["initial_weight"];
 | 
				
			||||||
    spoolDoc["lot_nr"] = (payload["lotnr"].is<String>() && payload["lotnr"].as<String>().length() > 0) ? payload["lotnr"].as<String>() : "";
 | 
					    spoolDoc["lot_nr"] = (payload["an"].is<String>() && payload["an"].as<String>().length() > 0) ? payload["an"].as<String>() : "";
 | 
				
			||||||
    spoolDoc["comment"] = "automatically generated";
 | 
					    spoolDoc["comment"] = "automatically generated";
 | 
				
			||||||
    spoolDoc["extra"]["nfc_id"] = "\"" + uidString + "\"";
 | 
					    spoolDoc["extra"]["nfc_id"] = "\"" + uidString + "\"";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -942,13 +926,15 @@ uint16_t createSpool(uint16_t vendorId, uint16_t filamentId, JsonDocument& paylo
 | 
				
			|||||||
    // Create optimized JSON structure with sm_id at the beginning for fast-path detection
 | 
					    // Create optimized JSON structure with sm_id at the beginning for fast-path detection
 | 
				
			||||||
    JsonDocument optimizedPayload;
 | 
					    JsonDocument optimizedPayload;
 | 
				
			||||||
    optimizedPayload["sm_id"] = String(createdSpoolId);  // Place sm_id first for fast scanning
 | 
					    optimizedPayload["sm_id"] = String(createdSpoolId);  // Place sm_id first for fast scanning
 | 
				
			||||||
 | 
					    optimizedPayload["b"] = payload["b"].as<String>();
 | 
				
			||||||
 | 
					    optimizedPayload["cn"] = payload["an"].as<String>();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Copy all other fields from original payload (excluding sm_id if it exists)
 | 
					    // Copy all other fields from original payload (excluding sm_id if it exists)
 | 
				
			||||||
    for (JsonPair kv : payload.as<JsonObject>()) {
 | 
					    //for (JsonPair kv : payload.as<JsonObject>()) {
 | 
				
			||||||
        if (strcmp(kv.key().c_str(), "sm_id") != 0) {  // Skip sm_id to avoid duplication
 | 
					    //    if (strcmp(kv.key().c_str(), "sm_id") != 0) {  // Skip sm_id to avoid duplication
 | 
				
			||||||
            optimizedPayload[kv.key()] = kv.value();
 | 
					    //        optimizedPayload[kv.key()] = kv.value();
 | 
				
			||||||
        }
 | 
					    //    }
 | 
				
			||||||
    }
 | 
					    //}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    String payloadString;
 | 
					    String payloadString;
 | 
				
			||||||
    serializeJson(optimizedPayload, payloadString);
 | 
					    serializeJson(optimizedPayload, payloadString);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										750
									
								
								src/nfc.cpp
									
									
									
									
									
								
							
							
						
						
									
										750
									
								
								src/nfc.cpp
									
									
									
									
									
								
							@@ -23,6 +23,7 @@ bool tagProcessed = false;
 | 
				
			|||||||
volatile bool pauseBambuMqttTask = false;
 | 
					volatile bool pauseBambuMqttTask = false;
 | 
				
			||||||
volatile bool nfcReadingTaskSuspendRequest = false;
 | 
					volatile bool nfcReadingTaskSuspendRequest = false;
 | 
				
			||||||
volatile bool nfcReadingTaskSuspendState = false;
 | 
					volatile bool nfcReadingTaskSuspendState = false;
 | 
				
			||||||
 | 
					volatile bool nfcWriteInProgress = false; // Prevent any tag operations during write
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct NfcWriteParameterType {
 | 
					struct NfcWriteParameterType {
 | 
				
			||||||
  bool tagType;
 | 
					  bool tagType;
 | 
				
			||||||
@@ -408,49 +409,212 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  Serial.println("✓ Payload passt in den Tag - Schreibvorgang wird fortgesetzt");
 | 
					  Serial.println("✓ Payload passt in den Tag - Schreibvorgang wird fortgesetzt");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // STEP 1: Read current tag content for debugging
 | 
					  // STEP 1: NFC Interface Reset and Reinitialization
 | 
				
			||||||
  Serial.println();
 | 
					  Serial.println();
 | 
				
			||||||
  Serial.println("=== SCHRITT 1: AKTUELLER TAG-INHALT ===");
 | 
					  Serial.println("=== SCHRITT 1: NFC-INTERFACE RESET UND NEUINITIALISIERUNG ===");
 | 
				
			||||||
  uint8_t currentContent[64]; // Read first 16 pages
 | 
					 | 
				
			||||||
  memset(currentContent, 0, 64);
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  for (uint8_t page = 4; page < 20; page++) {
 | 
					  // First, check if the NFC interface is working at all
 | 
				
			||||||
    uint8_t pageData[4];
 | 
					  Serial.println("Teste aktuellen NFC-Interface-Zustand...");
 | 
				
			||||||
    if (nfc.ntag2xx_ReadPage(page, pageData)) {
 | 
					  
 | 
				
			||||||
      memcpy(¤tContent[(page-4)*4], pageData, 4);
 | 
					  // Try to read capability container (which worked during detection)
 | 
				
			||||||
      Serial.print("Seite ");
 | 
					  uint8_t ccTest[4];
 | 
				
			||||||
      Serial.print(page);
 | 
					  bool ccReadable = nfc.ntag2xx_ReadPage(3, ccTest);
 | 
				
			||||||
      Serial.print(": ");
 | 
					  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++) {
 | 
					      for (int i = 0; i < 4; i++) {
 | 
				
			||||||
        if (pageData[i] < 0x10) Serial.print("0");
 | 
					        if (testData[i] < 0x10) Serial.print("0");
 | 
				
			||||||
        Serial.print(pageData[i], HEX);
 | 
					        Serial.print(testData[i], HEX);
 | 
				
			||||||
        Serial.print(" ");
 | 
					        Serial.print(" ");
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      Serial.println();
 | 
					      Serial.println();
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      Serial.print("Fehler beim Lesen von Seite ");
 | 
					      Serial.println("❌ - Nicht lesbar");
 | 
				
			||||||
      Serial.println(page);
 | 
					      if (testPage >= 3 && testPage <= 6) { // Critical pages for NDEF
 | 
				
			||||||
 | 
					        basicPagesReadable = false;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    vTaskDelay(10 / portTICK_PERIOD_MS); // Small delay between reads
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  Serial.println("=========================================");
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // STEP 2: Simple write test - write one test page
 | 
					  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();
 | 
				
			||||||
  Serial.println("=== SCHRITT 2: SCHREIBTEST ===");
 | 
					  Serial.println("=== SCHRITT 3: SCHREIBBEREITSCHAFTSTEST ===");
 | 
				
			||||||
  uint8_t testPage[4] = {0xAA, 0xBB, 0xCC, 0xDD}; // Test pattern
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if (!nfc.ntag2xx_WritePage(10, testPage)) { // Use page 10 for test
 | 
					  // Test write capabilities before attempting the full write
 | 
				
			||||||
    Serial.println("FEHLER: Einfacher Schreibtest fehlgeschlagen!");
 | 
					  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");
 | 
					    Serial.println("Tag ist möglicherweise schreibgeschützt oder defekt");
 | 
				
			||||||
    oledShowMessage("Tag write protected?");
 | 
					    
 | 
				
			||||||
 | 
					    // 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);
 | 
					    vTaskDelay(3000 / portTICK_PERIOD_MS);
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // Verify test write
 | 
					  // Verify test write
 | 
				
			||||||
  uint8_t readBack[4];
 | 
					  uint8_t readBack[4];
 | 
				
			||||||
 | 
					  vTaskDelay(20 / portTICK_PERIOD_MS); // Wait for write to complete
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  if (!nfc.ntag2xx_ReadPage(10, readBack)) {
 | 
					  if (!nfc.ntag2xx_ReadPage(10, readBack)) {
 | 
				
			||||||
    Serial.println("FEHLER: Kann Testdaten nicht zurücklesen!");
 | 
					    Serial.println("FEHLER: Kann Testdaten nicht zurücklesen!");
 | 
				
			||||||
 | 
					    oledShowMessage("Test verify failed");
 | 
				
			||||||
 | 
					    vTaskDelay(3000 / portTICK_PERIOD_MS);
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
@@ -477,12 +641,20 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  Serial.println("✓ Schreibtest erfolgreich - Tag ist beschreibbar");
 | 
					  // Restore original content
 | 
				
			||||||
  Serial.println("================================");
 | 
					  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");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // STEP 3: NDEF initialization with verification
 | 
					  Serial.println("✓ Schreibtest erfolgreich - Tag ist voll funktionsfähig");
 | 
				
			||||||
 | 
					  Serial.println("======================================================");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // STEP 4: NDEF initialization with verification
 | 
				
			||||||
  Serial.println();
 | 
					  Serial.println();
 | 
				
			||||||
  Serial.println("=== SCHRITT 3: NDEF-INITIALISIERUNG ===");
 | 
					  Serial.println("=== SCHRITT 4: NDEF-INITIALISIERUNG ===");
 | 
				
			||||||
  if (!initializeNdefStructure()) {
 | 
					  if (!initializeNdefStructure()) {
 | 
				
			||||||
    Serial.println("FEHLER: Konnte NDEF-Struktur nicht initialisieren!");
 | 
					    Serial.println("FEHLER: Konnte NDEF-Struktur nicht initialisieren!");
 | 
				
			||||||
    oledShowMessage("NDEF init failed");
 | 
					    oledShowMessage("NDEF init failed");
 | 
				
			||||||
@@ -513,6 +685,42 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
 | 
				
			|||||||
  Serial.println("✓ NDEF-Struktur initialisiert und verifiziert");
 | 
					  Serial.println("✓ NDEF-Struktur initialisiert und verifiziert");
 | 
				
			||||||
  Serial.println("==========================================");
 | 
					  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
 | 
					  // Allocate memory for the complete TLV structure
 | 
				
			||||||
  uint8_t* tlvData = (uint8_t*) malloc(totalTlvSize);
 | 
					  uint8_t* tlvData = (uint8_t*) malloc(totalTlvSize);
 | 
				
			||||||
  if (tlvData == NULL) {
 | 
					  if (tlvData == NULL) {
 | 
				
			||||||
@@ -573,7 +781,7 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
 | 
				
			|||||||
  uint16_t totalBytes = offset + 1;
 | 
					  uint16_t totalBytes = offset + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Serial.println();
 | 
					  Serial.println();
 | 
				
			||||||
  Serial.println("=== SCHRITT 4: SCHREIBE NEUE NDEF-DATEN ===");
 | 
					  Serial.println("=== SCHRITT 6: SCHREIBE NEUE NDEF-DATEN ===");
 | 
				
			||||||
  Serial.print("Schreibe ");
 | 
					  Serial.print("Schreibe ");
 | 
				
			||||||
  Serial.print(totalBytes);
 | 
					  Serial.print(totalBytes);
 | 
				
			||||||
  Serial.print(" Bytes in ");
 | 
					  Serial.print(" Bytes in ");
 | 
				
			||||||
@@ -597,8 +805,26 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
 | 
				
			|||||||
    // Copy data to page buffer
 | 
					    // Copy data to page buffer
 | 
				
			||||||
    memcpy(pageBuffer, &tlvData[bytesWritten], bytesToWrite);
 | 
					    memcpy(pageBuffer, &tlvData[bytesWritten], bytesToWrite);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Write page to tag
 | 
					    // Write page to tag with retry mechanism
 | 
				
			||||||
    if (!nfc.ntag2xx_WritePage(pageNumber, pageBuffer)) {
 | 
					    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.print("FEHLER beim Schreiben der Seite ");
 | 
				
			||||||
      Serial.println(pageNumber);
 | 
					      Serial.println(pageNumber);
 | 
				
			||||||
      Serial.print("Möglicherweise Page-Limit erreicht für ");
 | 
					      Serial.print("Möglicherweise Page-Limit erreicht für ");
 | 
				
			||||||
@@ -623,35 +849,52 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
 | 
				
			|||||||
    Serial.print("... ");
 | 
					    Serial.print("... ");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    uint8_t verifyBuffer[4];
 | 
					    uint8_t verifyBuffer[4];
 | 
				
			||||||
    vTaskDelay(10 / portTICK_PERIOD_MS); // Small delay before verification
 | 
					    vTaskDelay(20 / portTICK_PERIOD_MS); // Increased delay before verification
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (nfc.ntag2xx_ReadPage(pageNumber, verifyBuffer)) {
 | 
					    // Verification with retry mechanism
 | 
				
			||||||
      bool writeSuccess = true;
 | 
					    bool verifySuccess = false;
 | 
				
			||||||
      for (int i = 0; i < bytesToWrite; i++) {
 | 
					    for (int verifyAttempt = 0; verifyAttempt < 3; verifyAttempt++) {
 | 
				
			||||||
        if (verifyBuffer[i] != pageBuffer[i]) {
 | 
					      if (nfc.ntag2xx_ReadPage(pageNumber, verifyBuffer)) {
 | 
				
			||||||
          writeSuccess = false;
 | 
					        bool writeMatches = true;
 | 
				
			||||||
          Serial.println();
 | 
					        for (int i = 0; i < bytesToWrite; i++) {
 | 
				
			||||||
          Serial.print("VERIFIKATIONSFEHLER bei Byte ");
 | 
					          if (verifyBuffer[i] != pageBuffer[i]) {
 | 
				
			||||||
          Serial.print(i);
 | 
					            writeMatches = false;
 | 
				
			||||||
          Serial.print(" - Erwartet: 0x");
 | 
					            Serial.println();
 | 
				
			||||||
          Serial.print(pageBuffer[i], HEX);
 | 
					            Serial.print("VERIFIKATIONSFEHLER bei Byte ");
 | 
				
			||||||
          Serial.print(", Gelesen: 0x");
 | 
					            Serial.print(i);
 | 
				
			||||||
          Serial.println(verifyBuffer[i], HEX);
 | 
					            Serial.print(" - Erwartet: 0x");
 | 
				
			||||||
 | 
					            Serial.print(pageBuffer[i], HEX);
 | 
				
			||||||
 | 
					            Serial.print(", Gelesen: 0x");
 | 
				
			||||||
 | 
					            Serial.println(verifyBuffer[i], HEX);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (writeMatches) {
 | 
				
			||||||
 | 
					          verifySuccess = true;
 | 
				
			||||||
          break;
 | 
					          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 (!writeSuccess) {
 | 
					    if (!verifySuccess) {
 | 
				
			||||||
        Serial.println("❌ SCHREIBVORGANG FEHLGESCHLAGEN!");
 | 
					      Serial.println("❌ SCHREIBVORGANG/VERIFIKATION FEHLGESCHLAGEN!");
 | 
				
			||||||
        free(tlvData);
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        Serial.println("✓");
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      Serial.println("❌ Kann Seite nicht zur Verifikation lesen!");
 | 
					 | 
				
			||||||
      free(tlvData);
 | 
					      free(tlvData);
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      Serial.println("✓");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Serial.print("Seite ");
 | 
					    Serial.print("Seite ");
 | 
				
			||||||
@@ -668,7 +911,7 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
 | 
				
			|||||||
    pageNumber++;
 | 
					    pageNumber++;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    yield();
 | 
					    yield();
 | 
				
			||||||
    vTaskDelay(5 / portTICK_PERIOD_MS); // Small delay between page writes
 | 
					    vTaskDelay(10 / portTICK_PERIOD_MS); // Slightly increased delay between page writes
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  free(tlvData);
 | 
					  free(tlvData);
 | 
				
			||||||
@@ -695,12 +938,72 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
 | 
				
			|||||||
  Serial.println("%");
 | 
					  Serial.println("%");
 | 
				
			||||||
  Serial.println("✓ Bestehende Daten wurden überschrieben");
 | 
					  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("==================================================================");
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  // CRITICAL: Verify the write by reading back the data
 | 
					  // CRITICAL: Verify the write by reading back the data
 | 
				
			||||||
  Serial.println();
 | 
					  Serial.println();
 | 
				
			||||||
  Serial.println("=== WRITE VERIFICATION ===");
 | 
					  Serial.println("=== WRITE VERIFICATION ===");
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // Wait a moment for tag to stabilize
 | 
					  // Wait a moment for tag to stabilize
 | 
				
			||||||
  vTaskDelay(100 / portTICK_PERIOD_MS);
 | 
					  vTaskDelay(200 / portTICK_PERIOD_MS); // Increased stabilization time
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Only proceed with verification if interface is responsive
 | 
				
			||||||
 | 
					  if (!interfaceResponsive) {
 | 
				
			||||||
 | 
					    Serial.println("SKIPPING VERIFICATION: Interface not responsive");
 | 
				
			||||||
 | 
					    Serial.println("❌ WRITE COMPLETED but VERIFICATION SKIPPED");
 | 
				
			||||||
 | 
					    Serial.println("❌ Cannot guarantee data integrity");
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // Read back the written data to verify
 | 
					  // Read back the written data to verify
 | 
				
			||||||
  uint8_t verifyBuffer[totalBytes];
 | 
					  uint8_t verifyBuffer[totalBytes];
 | 
				
			||||||
@@ -712,7 +1015,27 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
 | 
				
			|||||||
  
 | 
					  
 | 
				
			||||||
  while (verifyBytesRead < totalBytes && verifyPage <= maxWritablePage) {
 | 
					  while (verifyBytesRead < totalBytes && verifyPage <= maxWritablePage) {
 | 
				
			||||||
    uint8_t pageData[4];
 | 
					    uint8_t pageData[4];
 | 
				
			||||||
    if (!nfc.ntag2xx_ReadPage(verifyPage, pageData)) {
 | 
					    
 | 
				
			||||||
 | 
					    // Verification read with retry mechanism
 | 
				
			||||||
 | 
					    bool pageReadSuccess = false;
 | 
				
			||||||
 | 
					    for (int readAttempt = 0; readAttempt < 3; readAttempt++) {
 | 
				
			||||||
 | 
					      if (nfc.ntag2xx_ReadPage(verifyPage, pageData)) {
 | 
				
			||||||
 | 
					        pageReadSuccess = true;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        Serial.print("Verification read attempt ");
 | 
				
			||||||
 | 
					        Serial.print(readAttempt + 1);
 | 
				
			||||||
 | 
					        Serial.print("/3 for page ");
 | 
				
			||||||
 | 
					        Serial.print(verifyPage);
 | 
				
			||||||
 | 
					        Serial.println(" failed");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (readAttempt < 2) {
 | 
				
			||||||
 | 
					          vTaskDelay(50 / portTICK_PERIOD_MS);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!pageReadSuccess) {
 | 
				
			||||||
      Serial.print("VERIFICATION FAILED: Cannot read page ");
 | 
					      Serial.print("VERIFICATION FAILED: Cannot read page ");
 | 
				
			||||||
      Serial.println(verifyPage);
 | 
					      Serial.println(verifyPage);
 | 
				
			||||||
      verificationSuccess = false;
 | 
					      verificationSuccess = false;
 | 
				
			||||||
@@ -725,6 +1048,8 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    verifyBytesRead += bytesToCopy;
 | 
					    verifyBytesRead += bytesToCopy;
 | 
				
			||||||
    verifyPage++;
 | 
					    verifyPage++;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    vTaskDelay(10 / portTICK_PERIOD_MS); // Small delay between verification reads
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if (verificationSuccess && verifyBytesRead >= totalBytes) {
 | 
					  if (verificationSuccess && verifyBytesRead >= totalBytes) {
 | 
				
			||||||
@@ -799,6 +1124,8 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
 | 
				
			|||||||
      if (!jsonFound) {
 | 
					      if (!jsonFound) {
 | 
				
			||||||
        Serial.println("WARNING: No valid JSON found in verified data!");
 | 
					        Serial.println("WARNING: No valid JSON found in verified data!");
 | 
				
			||||||
        verificationSuccess = false;
 | 
					        verificationSuccess = false;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        Serial.println("✓ JSON extracted and validated successfully");
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@@ -1040,7 +1367,7 @@ bool decodeNdefAndReturnJson(const byte* encodedMessage, String uidString) {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      // Brand Filament not registered to Spoolman
 | 
					      // 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"] == "")))
 | 
					      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
 | 
					        doc["sm_id"] = "0"; // Ensure sm_id is set to 0
 | 
				
			||||||
        // If no sm_id is present but the brand is Brand Filament then
 | 
					        // If no sm_id is present but the brand is Brand Filament then
 | 
				
			||||||
@@ -1065,65 +1392,208 @@ bool decodeNdefAndReturnJson(const byte* encodedMessage, String uidString) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool quickSpoolIdCheck(String uidString) {
 | 
					bool quickSpoolIdCheck(String uidString) {
 | 
				
			||||||
    // Fast-path: Read only first 2-3 pages to check for sm_id pattern
 | 
					    // Fast-path: Read NDEF structure to quickly locate and check JSON payload
 | 
				
			||||||
    // This dramatically speeds up known spool recognition
 | 
					    // 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 ===");
 | 
					    Serial.println("=== FAST-PATH: Quick sm_id Check ===");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Read first 3 pages (12 bytes) after NDEF header (pages 4-6)
 | 
					    // Read enough pages to cover NDEF header + beginning of payload (pages 4-8 = 20 bytes)
 | 
				
			||||||
    uint8_t quickData[12];
 | 
					    uint8_t ndefData[20];
 | 
				
			||||||
    memset(quickData, 0, 12);
 | 
					    memset(ndefData, 0, 20);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    for (uint8_t page = 4; page < 7; page++) {
 | 
					    for (uint8_t page = 4; page < 9; page++) {
 | 
				
			||||||
        if (!nfc.ntag2xx_ReadPage(page, quickData + (page - 4) * 4)) {
 | 
					        if (!nfc.ntag2xx_ReadPage(page, ndefData + (page - 4) * 4)) {
 | 
				
			||||||
            Serial.print("Failed to read page ");
 | 
					            Serial.print("Failed to read page ");
 | 
				
			||||||
            Serial.println(page);
 | 
					            Serial.println(page);
 | 
				
			||||||
            return false; // Fall back to full read
 | 
					            return false; // Fall back to full read
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Convert to string for pattern matching
 | 
					    // Parse NDEF structure to find JSON payload start
 | 
				
			||||||
    String quickCheck = "";
 | 
					    Serial.print("Raw NDEF data (first 20 bytes): ");
 | 
				
			||||||
    for (int i = 0; i < 12; i++) {
 | 
					    for (int i = 0; i < 20; i++) {
 | 
				
			||||||
        if (quickData[i] >= 32 && quickData[i] <= 126) {
 | 
					        if (ndefData[i] < 0x10) Serial.print("0");
 | 
				
			||||||
            quickCheck += (char)quickData[i];
 | 
					        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;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    Serial.print("Quick data (first 12 bytes): ");
 | 
					    if (tlvOffset == -1) {
 | 
				
			||||||
    Serial.println(quickCheck);
 | 
					        Serial.println("✗ FAST-PATH: No NDEF TLV found");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Look for sm_id pattern at the beginning
 | 
					    // Parse NDEF record to find JSON payload
 | 
				
			||||||
    if (quickCheck.indexOf("\"sm_id\":\"") >= 0 && quickCheck.indexOf("\"sm_id\":\"0\"") < 0) {
 | 
					    int ndefRecordStart;
 | 
				
			||||||
        Serial.println("✓ FAST-PATH: sm_id found in first bytes - known spool detected!");
 | 
					    if (ndefData[tlvOffset + 1] == 0xFF) {
 | 
				
			||||||
 | 
					        // Extended length format
 | 
				
			||||||
 | 
					        ndefRecordStart = tlvOffset + 4;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        // Standard length format
 | 
				
			||||||
 | 
					        ndefRecordStart = tlvOffset + 2;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
        // Extract sm_id from quick data if possible
 | 
					    if (ndefRecordStart >= 20) {
 | 
				
			||||||
        int smIdStart = quickCheck.indexOf("\"sm_id\":\"") + 9;
 | 
					        Serial.println("✗ FAST-PATH: NDEF record starts beyond read data");
 | 
				
			||||||
        int smIdEnd = quickCheck.indexOf("\"", smIdStart);
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
        if (smIdEnd > smIdStart) {
 | 
					    // Parse NDEF record header
 | 
				
			||||||
            String quickSpoolId = quickCheck.substring(smIdStart, smIdEnd);
 | 
					    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.print("✓ Quick extracted sm_id: ");
 | 
				
			||||||
            Serial.println(quickSpoolId);
 | 
					            Serial.println(quickSpoolId);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // Set as active spool immediately
 | 
					            // Only process known spools (sm_id != "0") via fast path
 | 
				
			||||||
            activeSpoolId = quickSpoolId;
 | 
					            if (quickSpoolId != "0" && quickSpoolId.length() > 0) {
 | 
				
			||||||
            lastSpoolId = activeSpoolId;
 | 
					                Serial.println("✓ FAST-PATH: Known spool detected!");
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
            oledShowProgressBar(2, octoEnabled?5:4, "Known Spool", "Quick mode");
 | 
					                // Set as active spool immediately
 | 
				
			||||||
            Serial.println("✓ FAST-PATH SUCCESS: Known spool processed quickly");
 | 
					                activeSpoolId = quickSpoolId;
 | 
				
			||||||
            return true; // Skip full tag reading!
 | 
					                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 quick patterns
 | 
					    // Check for other patterns that require full read
 | 
				
			||||||
    if (quickCheck.indexOf("\"location\":\"") >= 0) {
 | 
					    if (quickJson.indexOf("\"location\":\"") >= 0) {
 | 
				
			||||||
        Serial.println("✓ FAST-PATH: Location tag detected");
 | 
					        Serial.println("✓ FAST-PATH: Location tag detected");
 | 
				
			||||||
        return false; // Need full read for location processing
 | 
					        return false; // Need full read for location processing
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (quickCheck.indexOf("\"brand\":\"") >= 0 && quickCheck.indexOf("\"sm_id\":\"0\"") >= 0) {
 | 
					    if (quickJson.indexOf("\"brand\":\"") >= 0) {
 | 
				
			||||||
        Serial.println("✓ FAST-PATH: New brand filament detected (sm_id:0)");
 | 
					        Serial.println("✓ FAST-PATH: Brand filament detected - may need full processing");
 | 
				
			||||||
        return false; // Need full read for brand filament creation
 | 
					        return false; // Need full read for brand filament creation
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@@ -1139,14 +1609,11 @@ void writeJsonToTag(void *parameter) {
 | 
				
			|||||||
  Serial.println(params->payload);
 | 
					  Serial.println(params->payload);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  nfcReaderState = NFC_WRITING;
 | 
					  nfcReaderState = NFC_WRITING;
 | 
				
			||||||
 | 
					  nfcWriteInProgress = true; // Block high-level tag operations during write
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // IMPORTANT: Do NOT suspend reading task during writing!
 | 
					  // Do NOT suspend the reading task - we need NFC interface for verification
 | 
				
			||||||
  // We need to be able to read during write verification
 | 
					  // Just use nfcWriteInProgress to prevent scanning and fast-path operations
 | 
				
			||||||
  // Just set the state to WRITING to prevent scan conflicts
 | 
					  Serial.println("NFC Write Task starting - High-level operations blocked, low-level NFC available");
 | 
				
			||||||
  Serial.println("NFC Write Task starting - Reader remains active for verification");
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  // Small delay to ensure any ongoing operations complete
 | 
					 | 
				
			||||||
  vTaskDelay(100 / portTICK_PERIOD_MS);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //pauseBambuMqttTask = true;
 | 
					  //pauseBambuMqttTask = true;
 | 
				
			||||||
  // aktualisieren der Website wenn sich der Status ändert
 | 
					  // aktualisieren der Website wenn sich der Status ändert
 | 
				
			||||||
@@ -1205,13 +1672,80 @@ void writeJsonToTag(void *parameter) {
 | 
				
			|||||||
        }else{
 | 
					        }else{
 | 
				
			||||||
          oledShowProgressBar(1, 1, "Write Tag", "Done!");
 | 
					          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;
 | 
					        uint8_t uidLength;
 | 
				
			||||||
        yield();
 | 
					        int tagRemovalChecks = 0;
 | 
				
			||||||
        esp_task_wdt_reset();
 | 
					        
 | 
				
			||||||
        while (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 400)) {
 | 
					        Serial.println("Warte bis Tag entfernt wird...");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Monitor tag presence
 | 
				
			||||||
 | 
					        while (tagRemovalChecks < 10) {
 | 
				
			||||||
          yield();
 | 
					          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);
 | 
					        vTaskResume(RfidReaderTask);
 | 
				
			||||||
        vTaskDelay(500 / portTICK_PERIOD_MS);        
 | 
					        vTaskDelay(500 / portTICK_PERIOD_MS);        
 | 
				
			||||||
    } 
 | 
					    } 
 | 
				
			||||||
@@ -1234,9 +1768,8 @@ void writeJsonToTag(void *parameter) {
 | 
				
			|||||||
  sendWriteResult(nullptr, success);
 | 
					  sendWriteResult(nullptr, success);
 | 
				
			||||||
  sendNfcData();
 | 
					  sendNfcData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Since we didn't suspend reading, we don't need to re-enable it
 | 
					  // Only reset the write protection flag - reading task was never suspended
 | 
				
			||||||
  // Just reset the state back to IDLE
 | 
					  nfcWriteInProgress = false; // Re-enable high-level tag operations
 | 
				
			||||||
  Serial.println("NFC Write Task completed - Reader was never suspended");
 | 
					 | 
				
			||||||
  pauseBambuMqttTask = false;
 | 
					  pauseBambuMqttTask = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  free(params->payload);
 | 
					  free(params->payload);
 | 
				
			||||||
@@ -1271,8 +1804,8 @@ void startWriteJsonToTag(const bool isSpoolTag, 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
 | 
					    // Skip scanning during write operations, but keep NFC interface active
 | 
				
			||||||
    if (nfcReaderState != NFC_WRITING && !nfcReadingTaskSuspendRequest && !booting)
 | 
					    if (nfcReaderState != NFC_WRITING && !nfcWriteInProgress && !nfcReadingTaskSuspendRequest && !booting)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      nfcReadingTaskSuspendState = false;
 | 
					      nfcReadingTaskSuspendState = false;
 | 
				
			||||||
      yield();
 | 
					      yield();
 | 
				
			||||||
@@ -1417,8 +1950,17 @@ void scanRfidTask(void * parameter) {
 | 
				
			|||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      nfcReadingTaskSuspendState = true;
 | 
					      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();
 | 
					    yield();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,7 @@ extern String activeSpoolId;
 | 
				
			|||||||
extern String lastSpoolId;
 | 
					extern String lastSpoolId;
 | 
				
			||||||
extern volatile nfcReaderStateType nfcReaderState;
 | 
					extern volatile nfcReaderStateType nfcReaderState;
 | 
				
			||||||
extern volatile bool pauseBambuMqttTask;
 | 
					extern volatile bool pauseBambuMqttTask;
 | 
				
			||||||
 | 
					extern volatile bool nfcWriteInProgress;
 | 
				
			||||||
extern bool tagProcessed;
 | 
					extern bool tagProcessed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user