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();
}