Garagentoröffner mit RFID und Keypad bauen für Dauerbetrieb

Ich habe seit gestern ein Arduino Uno R3 starterkit und schon fleißig rumprobiert. :smiley:

Als erstes Projekt will ich einen Garagentoröffner bauen mit RFID und Zahlencodeeingabe über ein Keypad.

Bislang hab ich einen Schlüsselschalter der einfach nur 2 Kabel verbindet damit das Tor sich öffnet.
Für diese 2 Kabel hab ich bereits ein Relais bestellt mit 5V das diese beiden Kabel für ca. 1s verbindet damit das Tor öffnet. Zum testen hab ich im momentanen Sketch eine LED verwendet die für 5s leuchtet.

Für das eigentliche Projekt werde ich ein Arduino Nano verwenden sobald alles läuft.

Ich hab mich schon ordentlich eingelesen im Internet und einen Sketch geschrieben der soweit gut funktioniert und nur noch ein bisschen abgeändert werden muss für das Relais und den Arduino Nano.

Meine Frage ist nur, ist mein Sketch für den Dauerbetrieb geeignet und welches Netzteil sollte ich dafür verwenden?
Ich habe Angst das was passiert wenn das dauerhaft läuft und evtl. fehler im Sketch sind oder das Netzteil abfackelt...
Hab leider 0 Ahnung von Mikrocontrollern und kaum Ahnung vom programmieren :frowning:

Zumindest im Versuchsaufbau klappt soweit alles wunderbar, aber das ganze soll ja Jahrelang durchlaufen....

#include <SPI.h>
#include <MFRC522.h>
#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {15, 14, 7, 6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad keypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
char KEY[4] = {'1','2','3','4'}; // default secret key
char attempt[4] = {0,0,0,0};
int z=0; //end of keypad


#define RST_PIN   9     // Configurable, see typical pin layout above
#define SS_PIN    10    // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance

/* Set your new UID here! */
#define NEW_UID {0xDE, 0xAD, 0xBE, 0xEF}

MFRC522::MIFARE_Key key;
int led = 8;

void setup() // Beginn des Setups:

{

Serial.begin(9600); // Serielle Verbindung starten (Monitor)

SPI.begin(); // SPI-Verbindung aufbauen

mfrc522.PCD_Init(); // Initialisierung des RFID-Empfängers

pinMode(led, OUTPUT);

}



void correctKEY() // do this if the correct KEY is entered
{
    Serial.print("Correct key!");
    digitalWrite (led, HIGH); // ...dann soll die LED an Pin 2 leuchten...

    delay (5000); // für 5 Sekunden

    digitalWrite (led, LOW); // … und danach wieder aus gehen.

}
void incorrectKEY() // do this if an incorrect KEY is entered
{
   Serial.println("KEY REJECTED!");    
   for (byte o = 0; o<3; o++)
  {
  digitalWrite(led, HIGH);
  delay(200);
  digitalWrite(led, LOW);
  delay(200);
  }
}
void checkKEY()
{
   int correct=0;
   int i;
   for ( i = 0; i < 4 ; i++ )
   {
      if (attempt[i]==KEY[i])
      {
         correct++;
      }
   }
   if (correct==4)
   {
      correctKEY();
   }
   else
   {
      incorrectKEY();
   }
   for (int zz=0; zz<4; zz++) // clear previous key input
   
   {
      attempt[zz]=0;
   }
}
void readKeypad()
{
   char key = keypad.getKey();
   if (key != NO_KEY)
   {
      switch(key)
      {
      case '*':
         z=0;
         break;
      case '#':
         delay(100); // added debounce
        checkKEY();
         break;
      default:
         attempt[z]=key;
         z++;
      }
   }
}



void loop() // Hier beginnt der Loop-Teil

{
   readKeypad();


  

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.
}





long code=0; // Als neue Variable fügen wir „code“ hinzu, unter welcher später die UID als zusammenhängende Zahl ausgegeben wird. Statt int benutzen wir jetzt den Zahlenbereich „long“, weil sich dann eine größere Zahl speichern lässt.

for (byte i = 0; i < mfrc522.uid.size; i++)
{
code=((code+mfrc522.uid.uidByte[i])*10); // Nun werden wie auch vorher die vier Blöcke ausgelesen und in jedem Durchlauf wird der Code mit dem Faktor 10 „gestreckt“. (Eigentlich müsste man hier den Wert 1000 verwenden, jedoch würde die Zahl dann zu groß werden.
}

Serial.print("Die Kartennummer lautet:"); // Zum Schluss wird der Zahlencode (Man kann ihn nicht mehr als UID bezeichnen) ausgegeben.
Serial.println(code);

if (code==1088910) // 

{ 

digitalWrite (led, HIGH); 

delay (5000); 

digitalWrite (led, LOW); 

} 
else {
  for (byte o = 0; o<3; o++)
  {
  digitalWrite(led, HIGH);
  delay(200);
  digitalWrite(led, LOW);
  delay(200);
  }
  }


Serial.println(); // Mit dieser Zeile wird auf dem Serial Monitor nur ein Zeilenumbruch gemacht.
delay(500);

}

Hi

delay() ist Gift, wenn die Kiste JEDERZEIT bedienbar sein soll.
Ider willst Du 5 Sekunden warten müssen, bis Du die Erlaubnis vom Arduino bekommst, nun endlich Deinen RFID-Chip erfassen zu lassen?
Während des delay() macht Der nämlich ... Nichts (ok, aber zumindest nicht viel).

Auch das 'return' in den RFID-Abfragen wäre eine Überlegung wert - solange in dem Sketch 'dahinter' Nichts passieren soll, wenn eben kein neuer RFID-Kontakt erschlossen wurde - auch eine Lösung, damit loop() neu anfängt.
Wenn der Arduino aber vll. später Mal die Beleuchtung der Garage, einen Abstand-Messer zur Garagenwand oder sonstigen Tinnef machen soll, war's Das schon an dieser Stelle.

Zu Deinen Ängsten:
Lädst Du Dein Handy Nachts?
DAS ist um Längen gefährlicher, als ein laufender Arduino.
Nicht nur, weil in so einem Handy wirklich gut brennbares Lithium verbaut ist (im Akku) - je nach Technologie vll. nicht mehr ganz so gefährlich, aber mindestens sehr ungesund bleibt der Kram.
Der Arduino kann vll. hängen bleiben/ausfallen aufgrund ausgefallenem Netzteil oder so Zeug.

Als Netzteil würde ich ein USB-Ladenetzteil für's Handy nehmen - die gaaanz Billigen, Die beim Wegwerf-Handy beiliegen, schaffen mindestens 400mA - für den Arduino dicke genug.
Wenn's mehr ist, schadet's nicht, ist aber auch nicht nötig.

Ernst gemeinter Tip(p):
Fange klein an - spiele mit den Beispielen der IDE, den Beispielen der Library's der Module, Die Du verwendest.
Werfe delay() raus und lies Dich in millis() ein (Nachtwächter-Erklärung, combie hatte dazu Mal eine Liste, Die ich aber vom Forum her nicht verlinken kann/darf).

Wenn's bei Dir fertig ist - Das plane ich auch schon einige Monate ... bei mir sind's 2+ Türen und ein Garagentor (werde selber aber eine Art Zentrale im Haus einsetzen, Außen sind dann nur dumme Slaves, Die nicht selber entscheiden, ob Jemand rein darf, oder nicht - so erhoffe ich mir eine bessere/einfachere Verwaltung der RFID-Tags/Pin-Nummern - Verbunden via CAN-Bus-Modulen, 2-Draht).

MfG

Ich hab mich mal in millis() eingelesen aber irgendwie funktioniert das bei mir nicht... :o
Wahrscheinlich weil ich den Code zum öffnen in einer if Bedingung laufen habe und dieser nur ein mal aufgerufen wird wenn die Bedingung zutrifft.

In meinen Test ging die LED erst wieder aus wenn ich den RFID chip dauerhaft hingehalten habe, was ja nicht der Sinn sein soll.

Der Arduino soll nichts weiter machen, da sogut wie alle Anschlüsse belegt sind wird das sowieso schwierig noch mehr damit zu machen.
Für alles weitere würde ich einfach einen zweiten besorgen, die sind ja nicht sooo teuer :wink:

Werde noch ein bisschen rumspielen, vll schaff ich es ja doch noch.^^

So, habe meine Relais heute bekommen und festgestellt das sie auf GND schalten.

Hab das auf den einfachsten Weg nun gelöst indem ich sie bei Setup direkt auf HIGH schalte und auf LOW beim Schaltvorgang.
Ist das so üblich oder sollte ich mir da einen besseren Weg ausdenken? Sry für die Newbiefrage. :slight_smile:

Zweite frage:
Wenn das Ding mal im Dauerbetrieb geht, sollte ich da die Serial-Befehle alle löschen oder können die so stehen bleiben?

Die kosten nur minimale Ausführzeit und die kannst du stehen lassen, oder über eine "debug-Anweisung" bei Bedarf ein bzw. ausschalten.

Ja, das ist der normale Weg für LOW-aktive Relaismodule.

Das Ausschalten im "Produktivmodus" könntest Du z.B. über derartige Macros realisieren:

// 0 = aus, 1 = ein
#define DEBUG 0

#if (DEBUG == 0)
  #define sprint(...)
  #define sprintln(...)
  #define sbegin(...)
#else
  #define sprint(...) Serial.print(__VA_ARGS__)
  #define sprintln(...) Serial.println(__VA_ARGS__)
  #define sbegin(...) Serial.begin(__VA_ARGS__); while(!Serial)
#endif

Gruß Tommy