Frage zu meinem 'Sicherheitsschloss' Sketch/Question about my 'Safety Lock' Sketch

Deutsch:

Hallo liebe Arduino Community,
ich habe mithilfe des Arduino vor eine Art Sicherheitsschloss für eine Garagentür zu machen. Bisher habe ich es geschafft dass man die Tür per RFID-Chip sowie über einen Code über das Keypad aufmachen kann. Das Problem was ich jetzt habe, hängt mit der simulierten Alarmanlage zusammen. (Den habe ich nochmal zusätzlich mit Sternen markiert)
Mein Ziel ist, dass ich nach der Passworteingabe/RFID-Chip 5 Sekunden Zeit habe die Tür zu öffnen und nach den 5 Sekunden geguckt wird ob die Tür weiterhin offen ist (blaue led) oder die Tür geschlossen wurde (rote led). Ohne den markierten part im Sketch funktioniert das sogar, aber mit der Alarmfunktion wird diese direkt nach den 5 Sekunden eingeschaltet und bleibt solange wie die Kontakte getrennt sind.

Wenn sonst noch was offen steht einfach nachfragen
Jaimy

English:

Hello dear Arduino community,
I plan on doing some sort of Safety Lock for a garagedoor (the door for humans not for cars^^).
What I got to work so far is that you are allowed to open the door after using the rfid-tag oder the password. You got 5 seconds time for it to open the door. If you opened it and let it open blue led will light up, if you didnt open it or closed it after those 5 seconds it will light up red. Current issue is with the alert function of it (stars surrounded function in the code bracket). In theory I only want it to work when there is no password or tag given before opening the door. Practically it currently alerts immediately after the 5 second timer(opened door) and when the door is open without a password.

If you got any questions feel free to ask
Jaimy

#include <Keypad.h>
char P1 = '0'; char P2 = '2'; char P3 = '0'; char P4 = '9'; char P5 = '9'; char P6 = '8';           // Hier werden die sechs Zeichen für das Passwort festgelegt / 6 signs that will be the password. 
char C1, C2, C3, C4, C5, C6;                                                                        // Unter C1 bis C6 werden im Loop die eingegebenen Zeichen gespeichert / Under C1 to C6 the signs will be saved.

const int Schalter = 8;                                                                             // Der Magnetkontakt ist an Pin 8 angeschlossen / Magnetic contact is connected to Pin 8
const int roteLED = 7;                                                                              // Die rote LED ist an Pin 7 angeschlossen / Red LED is connected to Pin 7
const int blaueLED = 6;                                                                             // Die blaue LED wird an Pin 6 angeschlossen / Blue LED is connected to Pin 6

//Hier wird die größe des Keypads definiert
const byte COLS = 4;                                                                                             
const byte ROWS = 4;                                                                                             
int z1 = 0, z2, z3, z4, z5, z6, z7, z8, z9;                                                                      // Diese Variablen werden verwendet um für die einzelnen Zahlencodes die Eingabe freizuschalten. Damit wird im Sketch verhindert, dass eine einzelne Codeziffer einer falschen Position zugeordnet wird.

char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte colPins[COLS] = {2, A4, A5, A2};                                                           // Definition der Pins für die 4 Spalten
byte rowPins[ROWS] = {5, 4, 3, A3};                                                             // Definition der Pins für die 4 Zeilen
char Taste;                                                                                     // Taste ist die Variable für die jeweils gedrückte Taste.
Keypad Tastenfeld = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);                 // Das Keypad kann absofort mit "Tastenfeld" angesprochen werden

#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);

void setup() {
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  pinMode(Schalter, INPUT_PULLUP);
  pinMode(roteLED, OUTPUT);
  pinMode(blaueLED, OUTPUT);
}

void loop() {

  if (digitalRead(Schalter) == HIGH) {
    digitalWrite(roteLED, HIGH);
    digitalWrite(blaueLED, LOW);
    goto Anfang;
  }
  **else if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial() || Taste != '#' && blaueLED != HIGH) {**
**    Serial.println ("ALARM!");**
**    digitalWrite(roteLED, HIGH);                           // Die rote LED leuchtet**
**    digitalWrite(blaueLED, LOW);                           // Die blaue LED is aus**
**    delay(300);**
**    digitalWrite(roteLED, LOW);                            // Die rote LED pulsiert symbolisch für einen Alarm**
**    delay(300);**

  } else {
    z1 = 0; z2 = 1; z3 = 1; z4 = 1; z5 = 1; z6 = 1;
  }

Anfang:                                                                                       // Dies ist eine Markierung, zu der per "goto-"Befehl gesprungen werden kann.
  Taste = Tastenfeld.getKey();                                                                //Mit Unter der Variablen pressedKey entspricht der gedrückten Taste
  if (Taste) {                                                                                // Wenn eine Taste gedrückt wurde...
    if (Taste == '*') {                                                                       // Wenn die "*" Taste gedrückt wurde...
      Serial.println("Tür verriegelt");
      digitalWrite(roteLED, HIGH);                                                            // rote LED einschalten
      digitalWrite(blaueLED, LOW);                                                            // blaue LED einschalten
      z1 = 0; z2 = 1; z3 = 1; z4 = 1; z5 = 1; z6 = 1; z7 = 1; z8 = 1; z9 = 1;                 // Zugang zur ersten Zeicheneingabe freischalten
      goto Anfang;                                                                            // An dieser Stelle springt der Sketch zur Eingabe der Taste zurück, damit das Zeichen "*" nicht im folgenden Abschlitt als Codeeingabe gewertet wird.
    }

    if (Taste == '#') {                                                                       // Wenn die Rautetaste gedrückt wurde...
      if (C1 == P1 && C2 == P2 && C3 == P3 && C4 == P4 && C5 == P5 && C6 == P6) { // wird gepüft, ob die eingaben Codezeichen (C1 bis C6) mit den Zeichen des Passwortes (P1 bis P6) übereinstimmen. Falls der eingegebene Code richtig ist...
        Serial.println ("Code korrekt, Schloss offen");                                       // Ausgabe im seriellen Monitor
        if (1 == 1) {
          digitalWrite(roteLED, LOW);                                                         // rote LED leuchtet nicht..
          digitalWrite(blaueLED, HIGH);                                                       // blaue LED leuchtet..
          C1 = " "; C2 = " "; C3 = " "; C4 = " "; C5 = " "; C6 = " "; // C7=" ";/* C8=" "; C9=" ";*/
          delay(5000);
          return;
          if (digitalRead(Schalter == LOW)) {
            digitalWrite(blaueLED, HIGH);
            digitalWrite(roteLED, LOW);
            z1 = 1; z2 = 1; z3 = 1; z4 = 1; z5 = 1; z6 = 1;
            return;
          }
        }

      } else {                                                  // ist das nicht der Fall, bleibt das Schloss gesperrt
        Serial.println ("Code falsch, Schloss gesperrt");
        digitalWrite(roteLED, HIGH);                           // Die rote LED leuchtet
        digitalWrite(blaueLED, LOW);                           // Die blaue LED is aus
        delay(300);
        digitalWrite(roteLED, LOW);                            // Die rote LED pulsiert symbolisch für einen Alarm
        delay(300);
        digitalWrite(roteLED, HIGH);
        delay(300);
        digitalWrite(roteLED, LOW);
        delay(300);
        digitalWrite(roteLED, HIGH);
        delay(300);
        digitalWrite(roteLED, LOW);
        delay(300);
        digitalWrite(roteLED, HIGH);
        delay(300);
        digitalWrite(roteLED, LOW);
        delay(300);
        digitalWrite(roteLED, HIGH);
        delay(300);
        digitalWrite(roteLED, LOW);
        delay(300);
        digitalWrite(roteLED, HIGH);
        z1 = 0; z2 = 1; z3 = 1; z4 = 1; z5 = 1; z6 = 1; //z7 = 1; z8 = 1; z9 = 1; // Der Zugang für die erste Zeicheneingabe wird wieder freigeschaltet
        goto Anfang;                                           // An dieser Stelle springt der Sketch zur Eingabe der Taste zurück, damit das Zeichen "#" nicht im folgenden Abschlitt als Codeeingabe gewertet wird.
      }
    }
    // Ab hier werden die 6 Code-positionen unter den Variablen C1 bis C6 abgespeichert. Damit die eingegebenen Zeichen auch an der richtigen Position des Passwortes gespeichert werden, wird mit den Variablen z1 bis  der Zugang zu den einzelnen Positinen freigegeben oder gesperrt.
    if (z1 == 0) {                                             // Wenn das erste Zeichen noch nicht gespeichert wurde...
      C1 = Taste;                                              // Unter der Variablen "C1" wird nun die aktuell gedrückte Taste gespeichert
      Serial.print("Die Taste ");                              // Teile uns am Serial Monitor die gedrückte Taste mit
      Serial.print(C1);
      Serial.println(" wurde gedrueckt");
      z1 = 1; z2 = 0; z3 = 1; z4 = 1; z5 = 1; z6 = 1; //z7 = 1; z8 = 1; z9 = 1; // Zugang zur zweiten Zeicheneingabe freischalten
      goto Anfang;
    }

    if (z2 == 0) {
      C2 = Taste;
      Serial.print("Die Taste ");
      Serial.print(C2);
      Serial.println(" wurde gedrueckt");
      z1 = 1; z2 = 1; z3 = 0; z4 = 1; z5 = 1; z6 = 1; //z7 = 1; z8 = 1; z9 = 1;
      goto Anfang;
    }

    if (z3 == 0) {
      C3 = Taste;
      Serial.print("Die Taste ");
      Serial.print(C3);
      Serial.println(" wurde gedrueckt");
      z1 = 1; z2 = 1; z3 = 1; z4 = 0; z5 = 1; z6 = 1; //z7 = 1; z8 = 1; z9 = 1;
      goto Anfang;
    }

    if (z4 == 0) {
      C4 = Taste;
      Serial.print("Die Taste ");
      Serial.print(C4);
      Serial.println(" wurde gedrueckt");
      z1 = 1; z2 = 1; z3 = 1; z4 = 1; z5 = 0; z6 = 1; //z7 = 1; z8 = 1; z9 = 1;
      goto Anfang;
    }

    if (z5 == 0) {
      C5 = Taste;
      Serial.print("Die Taste ");
      Serial.print(C5);
      Serial.println(" wurde gedrueckt");
      z1 = 1; z2 = 1; z3 = 1; z4 = 1; z5 = 1; z6 = 0; //z7 = 1; z8 = 1; z9 = 1;
      goto Anfang;
    }

    if (z6 == 0) {
      C6 = Taste;
      Serial.print("Die Taste ");
      Serial.print(C6);
      Serial.println(" wurde gedrueckt");
      z1 = 1; z2 = 1; z3 = 1; z4 = 1; z5 = 1; z6 = 1; //z7 = 0; z8 = 1; z9 = 1;
      goto Anfang;
    }
  }


  if (!mfrc522.PICC_IsNewCardPresent()) {                                         // Wenn keine Karte in Reichweite ist...
    return;                                                                       // kehrt an den anfang dieser if anweisung zurück
  }

  if (!mfrc522.PICC_ReadCardSerial()) {                                           // Wenn kein RFID-Sender ausgewählt wurde
    return;
  }



  Serial.println ("RFID Erkannt");
  digitalWrite(roteLED, LOW);                                                     // rote LED leuchtet nicht..
  digitalWrite(blaueLED, HIGH);                                                   // blaue LED leuchtet..
  delay(5000);                                                                    // ..für 5 Sekunden
  if (digitalRead(Schalter == LOW)) {
    digitalWrite(blaueLED, HIGH);
    digitalWrite(roteLED, LOW);
    return;
  } else if (digitalRead(Schalter == HIGH)) {
    digitalWrite(roteLED, HIGH);
    digitalWrite(blaueLED, LOW);
  }
  goto Anfang;
}

Hi Jaimy,

delay(5000) means your Arduino does nothing else for 5 seconds than delaying. This means your program is blocked completely.

in a functional programming-language you should’nt use gotos
there are a lot of goto Anfang in your code which means the part above Anfang: don’t get executed anymore

Such a timing should be programmed in a NON-blocking way based on millis();

millis(); works like if your using your watch. You are looking how much time has passed by since midnight ( 0:00 )

Your description is not detailed enough that I would understand what your code should do.
Example:

What is “it” in this case. Name all things in every sentence. Even if this means to repeat words. You want help so help your helpers through making yourself easy to understand.

best regards Stefan

Good morning Stefan,

so my plan with the goto Anfang was only usable for the situation with the keypad and the rfid tag. Sadly the task was made by my trainee and he completely wants it without millis(); .

So what I want with the alert part of the code is that it only triggers when the magnets are not together and there is no rfid tag used or no password from the keypad. What it does rn is that after the delay(5000); it immediately goes into the alert function without checking if there was a password or tag used.
Without the alert function the code works as supposed. Which means: Password given → 5 seconds time to open the door → closing it (redLED) or letting it open (blueLED) when the magnets arent together after the 5 seconds. Same goes for the rfid part.

hard to believe that he wants it to have without millis(). Seems your trainee must have a lot of training too to become an advanced programmer.

using goto is IMHO bad programming style.

Sorry, I decide to not support a solution without millis()
best regards Stefan

it’s rather him needing it for private things. And since he doesn’t understand how to work around millis() he wants it without it.

But anyway thanks for reading through it tho!
-Jaimy