RFID Reader Problem

Hallo zusammen,

folgender Aufbau:

  • Arduino Giga R1
  • Arduino Ethernetschield 2
  • RC522 RFID Reader

Folgende Funktion hat das Programm
Das Programm wartet bis ein neuer Chip am RFID erkannt wird und schreibt via ModbusTCP an eine S7-1200 die RFID in ein Modbusregister, zusätzlich schreibt er eine Variable das die SPS erkennt das eine neue RFID eingelesen wurde.

zum Problem:
Soweit funktioniert das System auch, das Problem ist das sich das Programm oder der RFID Reader nach einer Zeit (3-10min) gefühlt aufhängt und keine neue RFID liest, bzw. der Reader keine neun Chip erkennt sobald er an den Leser gehalten wird.
Drücke ich den RESET Knopf funktioniert das Programm wieder tadellos.

#include <Ethernet.h>
#include <Mudbus.h>
#include <MFRC522.h>

// ---------------------------------------------------------------------
// Hardware-Definitionen
// ---------------------------------------------------------------------
#define W5100_SS 10     // Ethernet-Modul (W5100)
#define RFID_SS 9       // RFID-Modul (MFRC522)
#define RST_PIN 8       // RFID Reset-Pin

MFRC522 mfrc522(RFID_SS, RST_PIN);

// ---------------------------------------------------------------------
// Netzwerk- & Modbus-Konfiguration
// ---------------------------------------------------------------------
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 50);  // Feste IP-Adresse
EthernetServer server(502);
Mudbus Mb;  

// ---------------------------------------------------------------------
// Modbus-Register-Konfiguration
// ---------------------------------------------------------------------
#define STRING_REG_START 0   // Startregister (entspricht Modbus-Register 40001)
#define STRING_REG_COUNT 8   // 8 Register (je 16 Bit) für den String
#define BOOL_REG 9           // Boolean-Register (z. B. 40010)

// ---------------------------------------------------------------------
// Debug & Timing
// ---------------------------------------------------------------------
#define DEBUG true

unsigned long lastRFIDCheck = 0;
const unsigned long RFID_INTERVAL = 100; // RFID-Abfrage alle 100 ms

unsigned long boolTimestamp = 0;
bool resetBoolFlag = false;

const unsigned long modbusTimeout = 2000; // Maximale Bearbeitungsdauer eines Modbus-Clients (ms)

// Globaler initialer String, der in die Modbus-Register geschrieben wird
String initialString = "Hallo Modbus!";

// ---------------------------------------------------------------------
// Debug-Funktion
// ---------------------------------------------------------------------
void debugPrint(String message) {
  if (DEBUG) {
    Serial.println(message);
  }
}

// ---------------------------------------------------------------------
// Schreibt einen Arduino-String in die Modbus-Register  
// Es werden jeweils 2 Zeichen pro Register gespeichert; falls weniger Zeichen vorhanden sind, 
// wird der Rest mit 0 aufgefüllt.
// ---------------------------------------------------------------------
void stringToModbusRegisters(String str, int startRegister) {
  for (int i = 0; i < STRING_REG_COUNT; i++) {
    int index = i * 2;
    uint16_t regValue = 0;
    if (index < str.length()) {
      regValue = ((uint16_t)str.charAt(index) << 8);
    }
    if ((index + 1) < str.length()) {
      regValue |= (uint8_t)str.charAt(index + 1);
    }
    Mb.R[startRegister + i] = regValue;
    debugPrint("Register " + String(40001 + i) + " = " + String(Mb.R[startRegister + i], HEX));
  }
}

// ---------------------------------------------------------------------
// Formatiert die RFID UID als Hex‑String  
// Beim ersten Byte wird keine führende Null ausgegeben; für alle folgenden Bytes wird ggf. 
// eine führende Null ergänzt.
// ---------------------------------------------------------------------
String getRFID_UID() {
  String uid = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    if (i == 0) {
      uid += String(mfrc522.uid.uidByte[i], HEX);
    } else {
      if (mfrc522.uid.uidByte[i] < 16) uid += "0";
      uid += String(mfrc522.uid.uidByte[i], HEX);
    }
  }
  uid.toUpperCase();
  return uid;
}

// ---------------------------------------------------------------------
// Verarbeitung der RFID-Abfrage (nicht-blockierend)
// ---------------------------------------------------------------------
void processRFID() {
  if (millis() - lastRFIDCheck >= RFID_INTERVAL) {
    lastRFIDCheck = millis();
    // Den SPI-Bus freigeben, da Ethernet denselben Bus nutzt:
    digitalWrite(W5100_SS, HIGH);
    
    if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
      String uid = getRFID_UID();
      debugPrint("RFID erkannt: " + uid);
      
      // Schreibe die UID in die Modbus-Register
      stringToModbusRegisters(uid, STRING_REG_START);
      
      // Setze das Boolean-Register auf 1 und starte den Timer zum späteren Zurücksetzen
      Mb.R[BOOL_REG] = 1;
      boolTimestamp = millis();
      resetBoolFlag = true;
      
      mfrc522.PICC_HaltA(); 
      mfrc522.PCD_StopCrypto1();
    }
    
    // Automatischer Reset des Boolean-Registers nach 1,5 Sekunden
    if (resetBoolFlag && (millis() - boolTimestamp >= 1500)) {
      Mb.R[BOOL_REG] = 0;
      debugPrint("BOOL Register 40010 auf 0 zurückgesetzt.");
      resetBoolFlag = false;
    }
  }
}

// ---------------------------------------------------------------------
// Verarbeitung der Modbus-Verbindung  
// Ein neu verbundener Client wird maximal für modbusTimeout ms bearbeitet, um Blockierungen zu vermeiden.
// Gleichzeitig wird auch die RFID-Verarbeitung fortgeführt.
// ---------------------------------------------------------------------
void processModbus() {
  EthernetClient client = server.available();
  if (client) {
    debugPrint("Neuer Modbus-Client verbunden...");
    unsigned long modbusStart = millis();
    while (client.connected() && (millis() - modbusStart < modbusTimeout)) {
      if (client.available() > 0) {
        Mb.Run();
        modbusStart = millis(); // Timeout bei Aktivität zurücksetzen
      }
      processRFID();  // Gleichzeitig RFID-Verarbeitung durchführen
      delay(1);       // Kurze Pause zur Entlastung
    }
    client.stop();
    debugPrint("Modbus-Client getrennt.");
  }
}

// ---------------------------------------------------------------------
// setup()
// ---------------------------------------------------------------------
void setup() {
  Serial.begin(115200);
  debugPrint("Starte System...");
  
  // Ethernet initialisieren
  pinMode(W5100_SS, OUTPUT);
  digitalWrite(W5100_SS, HIGH);
  Ethernet.begin(mac, ip);
  server.begin();
  // IP-Adresse manuell zusammensetzen, da ip.toString() auf dem Due nicht verfügbar ist:
  String ipStr = String(ip[0]) + "." + String(ip[1]) + "." + String(ip[2]) + "." + String(ip[3]);
  debugPrint("Ethernet gestartet. IP: " + ipStr);
  
  // RFID-Modul initialisieren
  pinMode(RFID_SS, OUTPUT);
  digitalWrite(RFID_SS, HIGH);
  SPI.begin();
  mfrc522.PCD_Init();
  debugPrint("RFID Modul gestartet.");
  
  // Schreibe den initialen String in die Modbus-Register
  stringToModbusRegisters(initialString, STRING_REG_START);
}

// ---------------------------------------------------------------------
// loop()
// ---------------------------------------------------------------------
void loop() {
  // Zuerst eventuelle Modbus-Verbindungen bearbeiten
  processModbus();
  
  // Falls kein aktiver Modbus-Client vorliegt, reguläre RFID-Abfrage
  processRFID();
  
  // Ethernet-Verbindung aktiv halten
  Ethernet.maintain();
  
  yield();
}

Formatiere einmal den Code mit STRG-T in der IDE.

Was siehst du auf dem seriellen Monitor? Bleibt er immer an der gleichen Stelle hängen?

soweit wie ich es herausfinden konnte "hängt" er in folgendem Programmabschnitt:

void processRFID() {
  if (millis() - lastRFIDCheck >= RFID_INTERVAL) {
    lastRFIDCheck = millis();
    // Den SPI-Bus freigeben, da Ethernet denselben Bus nutzt:
    digitalWrite(W5100_SS, HIGH);
    
    if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
      String uid = getRFID_UID();
      debugPrint("RFID erkannt: " + uid);

Dann mach doch da noch ein paar debug prints hinein.

Lass das Millis() WEG.

Die Routine des Lesen reagiert eh erst wenn man ihm eine neue Karte vor den Reader hält.
Selbst wenn man eine Karte auf den Reader liegen lässt, juckt ihn das nicht.

tested by me

Geprüft wird das durch die Funktion :

mfrc522.PICC_IsNewCardPresent()

Gruß

Pucki

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.