RFID RC 522 Probleme

Hallo Arduino Gemeinde,

ich habe ein Problem, das mich schon lange nervt - ich aber keine Lösung finde.

ich habe einen Arduino Nano mit einem RFID RC522 und einem Relais Board als Schalter programmiert.
Nach dem Einschalten funtioniert das Auslesen und Schalten bei erkennen der freigegebenn Karten problemlos. Nach einiger Zeit reagiert die Steuerung aber nicht mehr. Nach einem wieder einschalten ist alles wieder OK - für eine Zeit.
Alle Versuche einen Fehler zu finden schlugen fehl.
Nun habe ich einen neuen Versuch mit einem Wemos gemacht und diesen per MQTT mit einen IOBroker verbunden. Zusätzlich habe ich noch ein paar Eingänge zur Überwachung hinzugefügt.

Auch hier habe ich das Problem, das die RFID Abfrage nach einer gewisssen Zeit nicht mehr reagiert. Die digitalen Eingänge funktionieren aber einwandfrei.

Hier der Code dazu:

#include <SPI.h> // SPI-Bibiothek hinzufügen
#include <MFRC522.h> // RFID-Bibiothek hinzufügen
#include <ESP8266WiFi.h> // ESP Wifi-Bibliothek hinzufügen
#include <PubSubClient.h> // MQTT-Bibiliothek hinzufügen

#define SS_PIN D8 // SDA an Pin D8  bei Wemos 
#define RST_PIN D3 // RST an Pin D3 Bei Wemos

String RFID;
String RFIDTAG;

const char* ssid = "xxx";
const char* password = "xxx";
const char* mqtt_server = "192.168.xxx";
const char* clientId = "Sensors/Garage";
const char* UserName = "xxx";
const char* UserPWd = "xxx";

long lastMsg = 0;

int Tor = D1 ;
int Licht = D2 ;
int Res3 = D4 ;
int Res4 = D0 ;
int In1, In2, In3, In4 ;
int Alt1, Alt2, Alt3, Alt4 = 0; 

MFRC522 mfrc522(SS_PIN, RST_PIN); // RFID-Empfänger benennen
WiFiClient espGarageClient;
PubSubClient client(espGarageClient);

void setup_wifi() {
   delay(100);
  // We start by connecting to a WiFi network
    //Serial.print("Connecting to ");
    //Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) 
    {
      delay(500);
      Serial.print(".");
    }
  randomSeed(micros());
  //Serial.println("");
  //Serial.println("WiFi connected");
  //Serial.println("IP address: ");
  //Serial.println(WiFi.localIP());
}

void reconnect() 
{
  // Loop until we're reconnected
  while (!client.connected()) 
  {
    //Serial.print("Attempting MQTT connection...");
    if (client.connect(clientId,UserName,UserPWd))
    {
     //Serial.println("connected");
     //once connected to MQTT broker, subscribe command if any
    } 
    else {
      //Serial.print("failed, rc=");
      //Serial.print(client.state());
      //Serial.println(" try again in 5 seconds");
      // Wait 6 seconds before retrying
      delay(6000);
    }
  }
}
void handle_inputs () {
  In1 = digitalRead(Tor) ;
  In2 = digitalRead(Licht) ;
  In3 = digitalRead(Res3) ;
  In4 = digitalRead(Res4) ;

  if (In1 != Alt1){ 
    Alt1 = In1 ;
    if (In1 == 0) 
      {client.publish("Sensors/Garage/Tor",("true")) ;}
    else 
      {client.publish("Sensors/Garage/Tor",("false")) ;}
  }
  if (In2 != Alt2){ 
    Alt2 = In2 ;
    if (In2 == 0) 
      {client.publish("Sensors/Garage/Licht",("true")) ;}
    else 
      {client.publish("Sensors/Garage/Licht",("false")) ;}
  } 
  if (In3 != Alt3){ 
    Alt3 = In3 ;
    if (In3 == 0) 
      {client.publish("Sensors/Garage/Res3",("true")) ;}
    else 
      {client.publish("Sensors/Garage/Res3",("false")) ;}
  }
  if (In4 != Alt4){ 
    Alt4 = In4 ;
    if (In4 == 0) 
      {client.publish("Sensors/Garage/Res4",("true")) ;}
    else 
      {client.publish("Sensors/Garage/Res4",("false")) ;}
  }
}

void setup() // Beginn des Setups:
{
Serial.begin(115200); // Serielle Verbindung starten (Monitor)
setup_wifi(); // Wifi Verbindung aufbauen
SPI.begin(); // SPI-Verbindung aufbauen
mfrc522.PCD_Init(); // Initialisierung des RFID-Empfängers
client.setServer(mqtt_server, xxxx);

pinMode(Tor,INPUT) ;
pinMode(Licht,INPUT) ;
pinMode(Res3,INPUT) ;
pinMode(Res4,INPUT) ;
}
void loop() 
{
if ( ! mfrc522.PICC_IsNewCardPresent()){     // Wenn keine Karte in Reichweite ist...
handle_inputs() ;
return; // ...springt das Programm zurück vor die if-Schleife, womit sich die Abfrage wiederholt.
}
if ( ! mfrc522.PICC_ReadCardSerial()){ // Wenn kein RFID-Sender ausgewählt wurde
handle_inputs() ;
return; // ...springt das Programm zurück vor die if-Schleife, womit sich die Abfrage wiederholt.
}
RFID = "";
RFIDTAG = "";
for (byte i = 0; i < mfrc522.uid.size; i++){
RFID += (mfrc522.uid.uidByte[i]);
RFID += " ";
RFIDTAG += (mfrc522.uid.uidByte[i]);
}
    if (!client.connected()) {
    reconnect();
  }
  client.loop();
  long now = millis();
  if (now - lastMsg > 2000)
  {
    lastMsg = now;
    String msg="";
    char MsgRFIDTag[25];
    msg = "";
    msg = String(RFIDTAG);
    msg.toCharArray(MsgRFIDTag,25);
    client.publish("Sensors/Garage/RFIDTag", MsgRFIDTag); 
    //Serial.println("MQTT gesendet");
    //Serial.print("RFID Tag: ");
    //Serial.println(RFIDTAG);
    //Serial.println(MsgRFIDTag);
  }
}

Bei der Suche habe ich bisher keine Lösung für diese Problem finden können.
Hat jemand hier vieleicht noch einen Denkanstoß für mich, um das Problem in den Griff zu bekommen.
Danke Markus

Hallo,

auf einem ESP8266 ist das bißchen String-Kram mit Sicherheit nicht das Problem.
Allerdings sieht das ganze Handling irgendwie seltsam aus. Ich finde meine alten Spielreien mit dem RC522 gerade nicht, um zu schauen, mit welchen Datentyp das eigentlich ankommt.

Das meiste vor
client.publish("Sensors/Garage/RFIDTag", MsgRFIDTag);
kann man sich z.B. sparen, dafür reicht ein
client.publish("Sensors/Garage/RFIDTag", RFIDTAG.c_str());

Wenn schon Stringklasse, dann richtig.

Gruß aus Berlin
Michael

Hallo nette Helfer,

ich habe meinen Code mal bereinigt.

Bei der Variablendeklaration bin ich bei noiasca.
Alleedings glaube ich, wie Michael, auch nicht, das die char String Schieberei die Ursache sein könnte.

Ein bischen Var Schieberei ist nötig, da ich die ID zur weiterverarbeitung als Dezimalzahl benötige.

Ich werde meinen bereinigten Code mal testen.

Danke erstmal für die Hilfe.
Markus

#include <SPI.h> // SPI-Bibiothek hinzufügen
#include <MFRC522.h> // RFID-Bibiothek hinzufügen
#include <ESP8266WiFi.h> // ESP Wifi-Bibliothek hinzufügen
#include <PubSubClient.h> // MQTT-Bibiliothek hinzufügen

#define SS_PIN D8 // SDA an Pin D8  bei Wemos 
#define RST_PIN D3 // RST an Pin D3 Bei Wemos

String RFID;
char MsgRFIDTag[25];

const char* ssid = "xxx";
const char* password = "xxx";
const char* mqtt_server = "192.168.xxx";
const char* clientId = "Sensors/Garage";
const char* UserName = "xxx";
const char* UserPWd = "xxx";

unsigned long now;
unsigned long lastMsg = 0;

int Tor = D1 ;
int Licht = D2 ;
int Res3 = D4 ;
int Res4 = D0 ;
int In1, In2, In3, In4 ;
int Alt1, Alt2, Alt3, Alt4 = 0;

MFRC522 mfrc522(SS_PIN, RST_PIN); // RFID-Empfänger benennen
WiFiClient espGarageClient;
PubSubClient client(espGarageClient);

void setup_wifi() {
  delay(100);
  // We start by connecting to a WiFi network
  //Serial.print("Connecting to ");
  //Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  randomSeed(micros());
  //Serial.println("");
  //Serial.println("WiFi connected");
  //Serial.println("IP address: ");
  //Serial.println(WiFi.localIP());
}

void reconnect()
{
  // Loop until we're reconnected
  while (!client.connected())
  {
    //Serial.print("Attempting MQTT connection...");
    if (client.connect(clientId, UserName, UserPWd))
    {
      //Serial.println("connected");
      //once connected to MQTT broker, subscribe command if any
    }
    else {
      //Serial.print("failed, rc=");
      //Serial.print(client.state());
      //Serial.println(" try again in 5 seconds");
      // Wait 6 seconds before retrying
      delay(6000);
    }
  }
}
void handle_inputs () {
  In1 = digitalRead(Tor) ;
  In2 = digitalRead(Licht) ;
  In3 = digitalRead(Res3) ;
  In4 = digitalRead(Res4) ;

  if (In1 != Alt1) {
    Alt1 = In1 ;
    if (In1 == 0) {
      client.publish("Sensors/Garage/Tor", ("true")) ;
    }
    else {
      client.publish("Sensors/Garage/Tor", ("false")) ;
    }
  }
  if (In2 != Alt2) {
    Alt2 = In2 ;
    if (In2 == 0) {
      client.publish("Sensors/Garage/Licht", ("true")) ;
    }
    else {
      client.publish("Sensors/Garage/Licht", ("false")) ;
    }
  }
  if (In3 != Alt3) {
    Alt3 = In3 ;
    if (In3 == 0) {
      client.publish("Sensors/Garage/Res3", ("true")) ;
    }
    else {
      client.publish("Sensors/Garage/Res3", ("false")) ;
    }
  }
  if (In4 != Alt4) {
    Alt4 = In4 ;
    if (In4 == 0) {
      client.publish("Sensors/Garage/Res4", ("true")) ;
    }
    else {
      client.publish("Sensors/Garage/Res4", ("false")) ;
    }
  }
}

void setup() // Beginn des Setups:
{
  Serial.begin(115200); // Serielle Verbindung starten (Monitor)
  setup_wifi(); // Wifi Verbindung aufbauen
  SPI.begin(); // SPI-Verbindung aufbauen
  mfrc522.PCD_Init(); // Initialisierung des RFID-Empfängers
  client.setServer(mqtt_server, 18xx);

  pinMode(Tor, INPUT) ;
  pinMode(Licht, INPUT) ;
  pinMode(Res3, INPUT) ;
  pinMode(Res4, INPUT) ;
}
void loop() // Hier beginnt der Loop-Teil
{
  if ( ! mfrc522.PICC_IsNewCardPresent()) {    // Wenn keine Karte in Reichweite ist...
    handle_inputs() ;
    return; // ...springt das Programm zurück vor die if-Schleife, womit sich die Abfrage wiederholt.
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) { // Wenn kein RFID-Sender ausgewählt wurde
    handle_inputs() ;
    return; // ...springt das Programm zurück vor die if-Schleife, womit sich die Abfrage wiederholt.
  }
  RFID = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    RFID += (mfrc522.uid.uidByte[i]);
  }
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  now = millis();
  if (now - lastMsg > 2000)
  {
    lastMsg = now;
    client.publish("Sensors/Garage/RFIDTag", RFID.c_str());
    //Serial.println("MQTT gesendet");
    //Serial.print("RFID Tag: ");
    //Serial.println(RFID);
    //Serial.print("RFID MSG ");
    //Serial.println(RFID.c_str());
  }
}

Warum brauchst Du die ID als Dezimalzahl? Wo wandelst Du sie um?

Gruß Tommy

Hallo,

@Tommy

RFID = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    RFID += (mfrc522.uid.uidByte[i]);
  }
...
    client.publish("Sensors/Garage/RFIDTag", RFID.c_str());

So wird die ID als Dezimalzahl übertagen. Wenn ich die Bytes nur in einen String schreibe kommen Sie beim MQTT als 4 ASCII Zeichen an.
Eine Dezimalzahl lässt sich im IOBroker einfacher auswerten und weiterverareiten als 4 ASCII Bytes.

Mein bereinigtes Programm funktioniert leider auch nicht.

Hat sonst noch jemand enie gute Idee.

Gruß
Markus

Hi

4 Zahlzeichen sind aber besser (für den Menschen) zu Lesen und Einzugeben.
Die 'Umwandlung' ist auch keine wirkliche Kunst.
Wenn das nächste Zeichen ein Zahlzeichen (0...9) ist, dann alte Zahl x 10 + Zahlzeichen -'0'.
Das auf HEX auszuweiten ist ebenfalls nicht weiter schwer.
Meine CAN-Sketche werten die serielle Eingabe aus und basteln daraus die Bytes der CAN-Nachricht, Die eingetragen und dann verarbeitet wird.
So kann ich mit dem einen Arduino, Der am PC hängt, mit Diesem schwätzen oder über Diesen auch mit den Anderen im Bus.

MfG

@TO: Das glaubst aber nur Du, dass das die dezimale Entsprechung der UID ist.

Nur mal zum Nachdenken:

Dezimalzahl 24 = 2 * 101 + 4 * 100 = 2 * 10 + 4
Hexadezimal: 0x3456 = 0x34 * 256 + 0x53

Das, was Du als Dezimalzahl betrachtest ist nicht eindeutig und kann evtl. für mehrere ID zum gleichen Ergebnis führen.

Gruß Tommy

Ja, eure Ausführungen bezüglich Umwandung und Sicherheit sind richtig.
Ich lese nur die Stelle aus und gebe Sie als dezimalzahl weiter ohne die Werigkeit zu berücksichtigen.

Mein Problem ist aber nicht die Umwandung der ID sondern, das die Erkennung der Karte nur eine kurze Zeit funktioniert und dann nicht mehr.
Wenn ich den MQTT sende Befehl für die ID herausnehme und hier nur ein Serial.print ausgebe läuft das Script länger. Die true/flase Signale die ich genereire wenn keine Karte erkannt wird, werden weiterhin problemlos übertragen.
Gibt es evtl. in der MQTT Routine eine Kleinigkeit, die ich übersehen habe?
Kann eigntlich nicht sein, da das Programm mit einem angesteuerten Relais auch schon hängengeblieben ist. In diesm PRg gab es noch kein MQTT.
Hat hierzu noch jemand eine Idee?

Gruß Markus

ich habe in meinem 1. Post geschrieben, dass die digitalen Eingänge einwandfrei funktionieren.

Das bedeutet meiner Meinung nach, das der Sketch bis auf die Erkennung der Karte bzw. das Senden der ID problemlos läuft.

Das mit der Life Bit LED habe ich mir verkniffen, da ich in der Test Phase in allen Programmteilen Serial.Print überwachungen eingebaut hatte.

Nur habe ich nicht tagelang getestet, sondern immer nur auf Funktion.
Wenn ein Programm einmal läuft, gehe ich eigentlich nicht davon aus, das es dies nicht nur eine kurze Zeit tut, sondern dauerhaft.

Die einzigste Möglichkeit, die mir noch einfällt, warum die Abfrage nur kurz funktioniert, wäre ein Registerüberlauf, den ich aber nicht feststellen kann.
Wäre das eine Möglichkeit? Hat jemand eine Idee wie ich sowas ausschließen kann?

So wie ich es sehe, wurde über die Spannungsversorgung bisher nicht geschrieben.

Mit welchem Netzteil versorgst du das Ganze und wie hast du Controller und RFID-Reader verkabelt ?

Wenn ein Programm einmal läuft, gehe ich eigentlich nicht davon aus, das es dies nicht nur eine kurze Zeit tut, sondern dauerhaft.

Witzige Sicht auf die Dinge!
Oder eher ein Irrtum?

Besser:

Je gemeiner der Fehler, desto länger hockt er in den Büschen, bis es knallt.

@Hot Systems
Ich habe ein 24V 5A Netzteil. Zur reduzierung der Spannung benutze ich einen Min DC-DC Wandler XM1584 Step Down Modul 3A 0,8-20V - eingestellt auf 3,314 V Spannung (Leerlauf und Last). Stromaufnahme habe ich nicht gemessen.
Sollte aber so in Ordnung sein.

Der D1 Mini und das DC DC Modul sitzten auf einer Platine, die ich mit Schraubklemmen zur Versorgung und Anschluß der Sensoren in ein Gehäuse montiert habe.
Am RFID habe ich ein Cat 5 Kabel (ca. 2m) angelötet und an die Schrabklemmen angeschlossen.

@combie
Warum witzige Sicht?
Ein Programm läuft oder nicht - aber nicht nur eine bestimmte Zeit. Es sei den irgendwo steckt ein Fehler, wie z.B. ein Overflow. deshalb meine Überlegung bzw. Frage in die Richtung.

Wieso 3,3V für einen Nano.
Da ist doch sicher irgendwo ein Fehler im Konzept !!

noiasca:
vermutlich ein Wemos:

gem. Code:

#include <ESP8266WiFi.h> // ESP Wifi-Bibliothek hinzufügen

bitte einen SCHALTPLAN und ein ECHTBILD von deinem Aufbau.

Ja, stimmt, aber der erste Anlauf war der Nano und der läuft eben nicht sicher mit 3,3Volt.

Wenn man dann noch ohne Konzept wieter “wurschtelt”, kann es nicht funktionieren.
Da steckt man dann einfach 3,3V an den 5Volt Pin.
Aber Schaltbild hast du ja angefordert.

Mawo94:
@combie
Warum witzige Sicht?
Ein Programm läuft oder nicht - aber nicht nur eine bestimmte Zeit. Es sei den irgendwo steckt ein Fehler, wie z.B. ein Overflow. deshalb meine Überlegung bzw. Frage in die Richtung.

Hast Du keinen Windows-PC?

Anders gesagt es kann alles mögliche passieren. Ein Programm kann auch so instabil laufen daß es meistens funktioniert wie es soll aber auch wiederholt probleme gibt.

Grüße Uwe

Mawo94:
@combie
Warum witzige Sicht?
Ein Programm läuft oder nicht - aber nicht nur eine bestimmte Zeit. Es sei den irgendwo steckt ein Fehler, wie z.B. ein Overflow. deshalb meine Überlegung bzw. Frage in die Richtung.

Erstmal: Ich kann in deinem Programm keinen offensichtlichen Fehler finden.
(das heißt aber nicht viel)

Zum "Warum?":

Die Beweisführung, ob ein Programm fehlerfrei ist, ist eins der schwierigsten Probleme in der Informatik.
Gerade im Fall C++ hat sich die Erkenntnis durchgesetzt, dass dieses kaum möglich ist.

Auszug aus Schulungsunterlagen zum Thema "Software in sicherheitsrelevanten Bereichen":

......
Daraus folgt, dass es keinen korrekten C++-Compiler geben kann, der jedes C++ Programm übersetzt, beziehungsweise nicht mehr allgemein entscheidbar ist, ob ein C++-Programm korrekt ist.
......

Für mich war das harter Tobak, als diese Kröte geschluckt werden musste.
Und wie mir scheint, steht diese Kröte evtl. gerade vor dir.

Mir fällt dazu folgender Spruch ein:

Wie bringt man den lieben Gott zum lachen?
Mach Pläne!

Alternativ:

Nimm an, dass dein Programm korrekt ist.

--

Dann gibts noch den Spruch:

Irren ist menschlich.
Im Irrtum verharren ist Dummheit.

Solange ich Mensch bin, werde ich niemals garantieren können, dass meine Programme Fehlerfrei sind.
Wenn andere meinen, fehlerfreie Programme schreiben zu können, dann finde ich das vor dem genannten Hintergrund "witzig".
8) Oder eben auch traurig, aber Traurigkeit macht weniger Spaß. 8)

Natürlich wurden in der Vergangenheit viele Verfahren entwickelt, wie man sich der Korrektheit nähern kann.
Modularisieren, die Komponenten einzeln testen.
Was so weit geht, dass man erst die Tests schreibt und danach die Module.

z.B. Unit tests , extreme progamming
( es gibt noch viel mehr interessante Vorgehensweisen)

Wie auch immer, es gibt viele ausgetretene Wege/Verfahren ein lauffähiges Programm zu erzeugen. Alle geben sich reichlich Mühe, möglichst fehlerfreien Code zu generieren.
Aber eine Garantie bietet kein einziges der Verfahren.

combie:
Mir fällt dazu folgender Spruch ein:

Wie bringt man den lieben Gott zum lachen?
Mach Pläne!

Oder auch

"Leben ist das, was passiert, während Du etwas anderes planst."

Gruß Tommy

Entschuldigung für die späte Antwort, ich habe zur Zeit ein wenig Stress mit anderen Dingen.

Zur Erklärung - ja der Nano war mit 5V versorgt und von hier habe ich die 3,3V für den RC522 abgegriffen.
Der Di Mini ist mit 3,3 V versorgt.

Ich habe ein Bild meines Aufbaus Ohne RC522 und ein Bild aus dem Nezt meiner Verschaltung angfügt.

@ Uwe
Ja leider bin ich, wie wir alle, Windows Tester.
@ combie
Ich kann in meinem Programm auch keinen Fehler finden, was wie du schon richtig geschrieben hast nicht viel heißt.
Deine bildliche Kröte habe ich schon lange verdaut. Jetzt nicht in bezug auf C++, sondern im Berrich PLC Programierung auf diversen Plattformen.
Mein Problem ist eben das anscheinend richtige Programm wird nach einer Weile vermutlich im RFID Lese oder Erkennungs Abschnitt nicht mehr richtig abgearbeitet. Ich kann aber keine Grund erkennen.
Deshalb die Frage in die Gemeinde.
Das Programm ist eigentlich nur ein abgewandeltes Standarprogramm aus dem Netz.

Zur Schaltung und dem Aufbau: Die Schaltung habe ich aus einer der vielen Standardschlatungen aus dem Netz nachgebaut. Zusätzlich habe ich 4 Eingänge über Pull Down Widerstände (10k) eingebaut, die einwandfrei funktionieren.
Beim Testaufbau auf einem Breadboard mit 10cm langen Jumpern besteht überigens das gleiche Problem.