MFRC522 Script hängt sich auf

Hallo zusammen,

ich habe mir einen Arduino als Türöffner gebaut (das haben sicher schon ganz viele gemacht). Allerdings hat meiner eine kleine Eigenheit. Den genauen "Auslöser" konnte ich bisher nicht feststellen. Aber den Workaround um Ihn wieder in gang zu bekommen.

IST-Zustand (Code folgt unten):
Hauseingangstüre mit elektrischem Schloss
Arduino Nano mit MFRC522
RFID Tag zum auslesen

Ich halte z.B. meinen Token an den MFRC522 und die Türe öffnet für eine Sekunde. Irgendwann funktioniert dies aber nicht mehr. EIne genaue Situation wann, kann wie gesagt bisher nicht genauer definiert werden. Einzig KANN es passieren das der Fehler auftritt wenn der Arduino mal neustartet weil z.B. der Strom weg war.

Die USB Verbindung beenden und somit einen Neustart des Arudinos erzwingen funktioniert leider nicht. Und jetzt kommt das, was ich nicht verstehe.

Ich muss den Arduino per USB an meinen Rechner stecken und einmal den Seriellen Monitor öffnen. Dann startet das Script ja automatisch neu und voilá es läuft wieder.

Ich stecke den Arduino ab und wieder in die USB Stromversorgung und er läuft wieder für mal nen Monat mal zwei/drei Monate.

Woran kann das liegen?
Was kann ich dagegen machen?
Ich habe überlegt die Serial Befehle auszukommentieren außer zum Debuggen oder hinzufügen eines neuen Token.

Alles andere funktioniert einwandfrei.
Den Arduino nur an meinen Rechner stecken brachte auch nichts. Es muss wirklich der Serielle Monitor aufgemacht werden.
Nochmal aufspielen um Aufspielfehler auszuschließen habe ich auch.

Ich freue mich auf eure Rückmeldungen.

Hier nun der Code:

#include <SPI.h> // SPI-Bibiothek hinzufügen
#include <MFRC522.h> // RFID-Bibiothek hinzufügen

#define SS_PIN 10 // SDA an Pin 10
#define RST_PIN 9 // RST an Pin 9
#define PIN_Tuermotor 8 // Türöffner an PIN 8

MFRC522 mfrc522(SS_PIN, RST_PIN); // RFID-Empfänger initialisieren

void setup(){
  Serial.begin(9600); // Serielle Verbindung starten (Monitor)
  SPI.begin(); // SPI-Verbindung aufbauen
  mfrc522.PCD_Init(); // Initialisierung des RFID-Empfängers
  pinMode(PIN_Tuermotor,OUTPUT);
  //digitalWrite(PIN_Tuermotor, HIGH);
  //delay(5000);
  digitalWrite(PIN_Tuermotor, LOW);
  Serial.println("Beginn des Scripts");
}

void loop(){
  String Token_ID;
  String Token_Byte;
  if ( ! mfrc522.PICC_IsNewCardPresent()) // Wenn keine Karte in Reichweite ist...
  {
    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
  {
    return; // ...springt das Programm zurück vor die if-Schleife, womit sich die Abfrage wiederholt.
  }
  
  Serial.print("Die ID des RFID-TAGS lautet:");
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    Token_Byte=(mfrc522.uid.uidByte[i]);
    Serial.print(mfrc522.uid.uidByte[i]); // Dann wird die UID ausgelesen, die aus vier einzelnen Blöcken besteht und der Reihe nach an den Serial Monitor gesendet.
    //Serial.print(mfrc522.uid.uidByte[i], HEX); // Dann wird die UID ausgelesen, die aus vier einzelnen Blöcken besteht und der Reihe nach an den Serial Monitor gesendet. Die Endung Hex bedeutet, dass die vier Blöcke der UID als HEX-Zahl (also auch mit Buchstaben) ausgegeben wird
    Serial.print(" ");
  Token_ID=Token_ID+Token_Byte;
  }
  Serial.println();
  delay(1000);

  //Serial.print("Die ID lautet:");
  //Serial.println(Token_ID);

  if(Token_ID == "XXX"){                                 // Smartwatch
    Serial.println("Token ist registriert. Tür wird geöffnet");
    digitalWrite(PIN_Tuermotor, HIGH);
    delay(1000);
    digitalWrite(PIN_Tuermotor, LOW);
    Serial.println("Tür wieder geschlossen");
  }
   if(Token_ID == "XXX"){                                 // Implantat
    Serial.println("Token ist registriert. Tür wird geöffnet");
    digitalWrite(PIN_Tuermotor, HIGH);
    delay(1000);
    digitalWrite(PIN_Tuermotor, LOW);
    Serial.println("Tür wieder geschlossen");
  }
}

Welchen Arduino ganz genau?
Bilder vom Aufbau?
Wie lang sind die SPI Leitungen?
Wie nah bist an 230V AC oder anderen Störquellen?

if(Token_ID == "XXX"){                                 // Smartwatch
    Serial.println("Token ist registriert. Tür wird geöffnet");
    digitalWrite(PIN_Tuermotor, HIGH);
    delay(1000);
    digitalWrite(PIN_Tuermotor, LOW);
    Serial.println("Tür wieder geschlossen");
  }
   if(Token_ID == "XXX"){                                 // Implantat
    Serial.println("Token ist registriert. Tür wird geöffnet");
    digitalWrite(PIN_Tuermotor, HIGH);
    delay(1000);
    digitalWrite(PIN_Tuermotor, LOW);
    Serial.println("Tür wieder geschlossen");
  }

Du hast 2x die gleiche abfrage drinnen. 1x reicht.

Das Modul läuft mit 3,3V. hängt es auch an 3,3V?

An welche Pins hast du das Modul angeschlossen? Ein Schaltplan oder Diagramm wäre hilfreich.

Ach ok war jetzt Denkfehler von mir, sehe gerade das eine ist für Smartwatch, das andere für Implantat. Ja das kann man so machen. Wird jetzt auch nix sein was den Fehler verursacht.

UNO, Nano Mega bei Start vom Serial Resetten. :wink:

So lange der Arduino separat versorgt wird, kannste stöpseln wie du willst, dadurch kommt kein resett, das bekommst du nur durch Stromunterbrechung oder Taster.

Sie vermissen dies am Ende der loop()

  rfid.PICC_HaltA();        // Halt PICC
  rfid.PCD_StopCrypto1();   // Stop encryption on PCD

Ein Arduino Nano...welchen genau weiß ich nicht. Hab hier über 20 rumfliegen und welche ich damals hatte weiß ich nicht.
die SPI Leitungen sind direkt gelötet maximal 10cm lang.
Die Stromleitung vom USB zu Arduino ist 1m lang.
Der Arduino wird direkt per USB versorgt.
Außer die USBleitung hat nichts Nähe zu 230V Leitungen.

Die Pins sind oben im Code definiert.
SDA => 10
RST => 9
MOSI => 11
MISO => 12
SCK => 13
Türöffner => 8 (Türöffner selbst wird geschaltet auf 12V Mittels MOSFET)

Von den Anfragen gibt es noch mehr habe aber exemplarisch mal die beiden mit reingenommen. Heute habe ich sogar darüber nachgedacht den Öffnugnsprozess in eine eigene Funktion zu packen. Aber das ist ja was anderes.

Der Arduino hängt an 5V per USB und das Modul wird vom Arduino mit 3,3V versorgt.

Schaltplan muss ich zuhause erstmal raussuchen. Bin leider auf der Arbeit.

Inwiefern resetten nach dem ich Serial gestartet habe? Und warum?

Die USB Verbindung IST zeitgleich die Stromversorgung.

Warum, gutteFrage, ist eben so.

Und wie?

Hallo,
ich denke das ist unglücklich gelöst. Du könntest die Strings als globale Variable anlegen. Ich könnte mir vorstellen das das so zu einem Speicherüberlauf kommt.

for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    Token_Byte=(mfrc522.uid.uidByte[i]);
    Serial.print(mfrc522.uid.uidByte[i]); // Dann wird die UID ausgelesen, die aus vier einzelnen Blöcken besteht und der Reihe nach an den Serial Monitor gesendet.
    //Serial.print(mfrc522.uid.uidByte[i], HEX); // Dann wird die UID ausgelesen, die aus vier einzelnen Blöcken besteht und der Reihe nach an den Serial Monitor gesendet. Die Endung Hex bedeutet, dass die vier Blöcke der UID als HEX-Zahl (also auch mit Buchstaben) ausgegeben wird
    Serial.print(" ");
  Token_ID=Token_ID+Token_Byte;
  }

Wenn ich das richtig sehe liest Du byteweise Zeichen aus und hängst sie an das String Objekt dran. Da wäre ein char Array "C- Zeichenkette" besser geeignet.

ich hab das noch nicht ganz verstanden, Wenn der Nano stromlos ist sollte er doch nach dem erneuten einstecken jungfräulich booten und auch starten ohne das was an der Seriellen ausgelesen wird.

schau Dir noch mal das Beispiel aus der Lib ab ReadNUID

globale String Objekte werden nicht gegen Speicher Defragmentierung helfen.

Wenn dann überhaupt keine String Objekte und die gültigen Tags/UIDs entweder

  • in ganz einfachen Byte Arrays halten und mit memcmp vergleichen oder
  • wenn es nur vierstellige UIDs sind, dann einfach in einem uint32_t halten

Vor einigen Monaten habe ich hier einen Sketch gezeigt:

war für einen ESP32 - aber sehr ähnlich (fast baugleich) auch auf einem Nano.

oder mit memcmp()

#include <SPI.h> // SPI-Bibiothek hinzufügen
#include <MFRC522.h> // RFID-Bibiothek hinzufügen

#define SS_PIN 10 // SDA an Pin 10
#define RST_PIN 9 // RST an Pin 9
#define PIN_Tuermotor 8 // Türöffner an PIN 8

MFRC522 mfrc522(SS_PIN, RST_PIN); // RFID-Empfänger initialisieren

const MFRC522::Uid bekannteUIDs[] = {
  {4, {0x00, 0x00, 0x00, 0x00}, 0},
  {4, {0x00, 0x00, 0x00, 0x00}, 0},
  {4, {0x00, 0x00, 0x00, 0x00}, 0},
};
const size_t bekannteUIDsAnzahl = sizeof bekannteUIDs / sizeof * bekannteUIDs;

void setup() {
  Serial.begin(115200); // Serielle Verbindung starten (Monitor)
  SPI.begin(); // SPI-Verbindung aufbauen
  mfrc522.PCD_Init(); // Initialisierung des RFID-Empfängers
  pinMode(PIN_Tuermotor, OUTPUT);
  digitalWrite(PIN_Tuermotor, LOW);
}

void loop() {
  if ( ! mfrc522.PICC_IsNewCardPresent()) return;
  if ( ! mfrc522.PICC_ReadCardSerial()) return;

  for (auto & uid : bekannteUIDs) {
    if ((mfrc522.uid.size == uid.size) && (memcmp(mfrc522.uid.uidByte, uid.uidByte, uid.size) == 0)) {
      digitalWrite(PIN_Tuermotor, HIGH);
      delay(1000);
      digitalWrite(PIN_Tuermotor, LOW);
      Serial.println("Tür wieder geschlossen");
      break;
    }
  }

  mfrc522.PICC_HaltA();        // Halt PICC
  mfrc522.PCD_StopCrypto1();   // Stop encryption on PCD
}

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