Elektronisches Codeschloss mit Gültigkeitsablauf

Hallo liebe Freunde des Microcontrollers,

da ich wie schon in einem anderen Thread erwähnt, bei mir die Hausrenovierung ansteht, möchte ich ein Zahlenschloss zum öffnen der Haustüre.
Das verzwickte an der Situation ist diese, dass ich oft und lange nicht zuhause bin und anderen Menschen den Zugangscode geben muß.
Deswegen dachte ich an einen Gültigkeitszeitraum wo danach dieser Code ungültig wird.
Quasi ein Mastercode für mich und ein zeitlich begrenzt gültiger Code, den ich auch generieren können muß?

Der momentane Source von meinem Zahlenschloss sieht so aus:

#include <Keypad.h>

char* secretCode = "123456";
int position = 0;

const byte rows = 4;
const byte cols = 3;
char keys[rows][cols] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};

byte rowPins[rows] = {4, 5, 6, 7};
byte colPins[cols] = {1, 2, 3};

Keypad keypad = Keypad(makeKeymap(keys), 
                       rowPins, colPins,
                       rows, cols);

int redPin = 8;
int greenPin = 9;
int relais = 10;

void setup()
{
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(relais, OUTPUT);
  setLocked(true);
}
void loop()
{
  char key = keypad.getKey();
  if (key == '*' || key == '#') {
    position = 0;
    setLocked(true);
  }
  if(key >= '0' && key <= '9')
{
  if (key == secretCode[position]) {
    position++;
  }
  else
  {
     position=0;
  }
  digitalWrite(greenPin, HIGH);
  delay(100);
  digitalWrite(greenPin, LOW);
}
  if (position == 6) {
    setLocked(false);
    delay(2000);
    setLocked(true);
    position = 0;
  }
  delay(50);
}

void setLocked(int locked)
{
  if (locked) {
    digitalWrite(redPin, HIGH);
    digitalWrite(greenPin, LOW);
    digitalWrite(relais,LOW);
  }
  else {
    digitalWrite(redPin, LOW);
    digitalWrite(greenPin, HIGH);
    digitalWrite(relais,HIGH);
  }
}

Ich hätte eine Möglichkeit, habe sie bislang auf Arduino noch nicht programmiert. Habe es bei einem größeren SPS-Hersteller so gelöst in der Software, das ich mit der Zeit einen Code errechnet.

Code = Jahr * Monat / 1012

Ist nur ein einfaches Beispiel. Dafür müsstest du aber ein RTC mit einbinden, sollte aber nicht zwingend das Problem sein.
Was der RTC nun alles ausser Tag, Monat, Jahr kann, hab ich gerade nicht im Kopf. Aber KW oder ähnliches war glaub auch dabei.

Wobei, ich würde es so nicht zwingend machen!

Andere Lösung für dich:
Code nach Tag oder Stunde machen. Nur wenn mal jemand in die unvorhersehbar in Wohnung muss. Ansonsten, wenn du länger weg bist -> Schlüssel jemanden hinterlegen. Die Software kann auch ausfallen.

Wenn mal die Zeit falsch ist dann bleibst Du draußen. :wink: :wink:

Wennschon Zahlenschloß dann lange Zahl/Wort (Tastatur wie bei Händy) und nach 3 Fehleingaben ist das Schloß für eine bestimmte Zeit zB eine halbe Stunde gesperrt. So ist es unmöglich einfach alle Zahlenkombinationen durchzuprobieren. Einen Masterkey in Form eines Mechanischen Schlüssels würde ich dennoch vorsehen. Was passiert wenn der Strom ausfällt? Willst Du dann Einbrecher spielen damit Du zum Sicherungskasten kommst und die Sicherung armieren kannst?

Grüße Uwe

Er sprach davon, einen Mastercode zu haben. Der muss nicht zwingend auf der Uhr basieren :wink:

Den Mastercode sehe ich als Sicherheitsleck. Wenn der normale Kode nur bestimmte Zeit gültig ist, der Mastercode aber immer dann ist der Mastercode der das System unsicherer macht.
Grüße Uwe

Zahlenschlösser finde ich schon wieder etwas veraltet.

Wie wäre es mit sowas ? Finger print sensor with Arduino | Arduino Blog

Wobei auch es natürlich auch damit eine Möglichkeit geben sollte die Türe mit einen mechanischen Schlüssel öffnen zu können.

Fr33l4nc3r:
Deswegen dachte ich an einen Gültigkeitszeitraum wo danach dieser Code ungültig wird.
Quasi ein Mastercode für mich und ein zeitlich begrenzt gültiger Code, den ich auch generieren können muß?

Die Lösung liegt darin, dass der Programmcode nicht Stelle für Stelle den Zahlencode vergleicht und bei Nichtübereinstimmung abbricht, sondern es muß der gesamte eingegebene Code zwischen Startzeichen * und Fertigzeichen # eingesammelt werden, und erst bei Eingabe von # werden die Codes und ggf. die Gültigkeitsbedingungen geprüft.

Codevorschlag:

#include <Keypad.h>

#define LED 13

char masterCode[] = "123456";
char limitedCode[]= "112233";

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte colPins[COLS] = {2, 3, 4}; //connect to the row pinouts of the keypad
byte rowPins[ROWS] = {6,7,8,9}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );


boolean validCode()
{
  static byte counter = 0;
  static char code[sizeof(masterCode)];
  char key = keypad.getKey();
  if (!key) return false; // keine Taste gedrückt, kann nicht gültig sein
  if (counter==0) memset(code,0,sizeof(code)); // clear code string
//  Serial.println(key); // comment out if not needed for debugging
  switch (key)
  {
    case '*': counter=0; // start new code
              break; 
    case '#': if (strcmp(code,masterCode)==0) // maybe correct code?
              {
                counter=0;
                return true; // correct masterCode was entered
              }
              if (true==true) // hier die limitierende Bedingung einsetzen
              {
                if (strcmp(code,limitedCode)==0) // mayby the limitedCode?
                {
                  counter=0;
                  return true; // yes, the limitedCode is correct
                }
              } 
              break;
    default : code[counter]=key; // just add the keystroke to the code
              if (counter<sizeof(code)-1) counter++;
   
  }
  return false; // es wurde kein gültiger Code eingegeben  
}


void setup(){
  Serial.begin(9600);
  pinMode(LED,OUTPUT);
  digitalWrite(LED,LOW);
}
  
void loop(){
  if (validCode())  
  { 
    Serial.println("VALID CODE");
    for (int i=0;i<5;i++) // do some blinking LED
    {
      digitalWrite(LED,HIGH);
      delay(500);
      digitalWrite(LED,LOW);
      delay(500);
    }
  }
}

Sowas ließe sich natürlich noch aufbohren, etwa wenn zwischen Eingabe der verschiedenen Codes unterschieden werden soll, und daraufhin unterschiedliche Aktionen ablaufen sollen, z.B. Protokollierung auf SD-Karte:

  • hh:mm:ss ==> Mastercode wurde erfolgreich eingegeben
  • hh:mm:ss ==> falscher Code
  • hh:mm:ss ==> limited Code wurde erfolgreich eingegeben
    etc. pp.

Oder man sieht noch einen speziellen "EditCode" vor, mit dem nicht die Tür geöffnet wird, sondern mit dem das Schloss in einen Eingabemodus versetzt wird, z.B. blinkt eine grüne EditMode-LED und man hat dann die Möglichkeit, den limitedCode und seine Gültigkeitsdauer neu einzugeben.

Kann man ja alles programmieren, wie man es möchte.

Will nur mal etwas einwerfen... mit einer RTC und einem RFID/NFC-Modul kann man sehr gut eine Zugangsverwaltung aufbauen.

Innerhalb einer bestimmten Zeitspanne sind nur von dir freigegebene NFC-Chips gültig, welche nach der Zeit wertlos werden.
Dein Chip kann dauerhaft gültig bleiben...

Vielen Dank für die vielen Antworten, ich konnte nicht Antworten weil ich eben wieder nicht zuhause war.

Das bei der Codeeingabe * und # fehlt ist beabsichtigt, weil dadurch, wenn Besuch hinter mir steht und zusieht, ich die ganze Tastatur abrackern kann und erst am Schluß die Fünft oder Sechste Stelle interessant wird.

Vielleicht weiß jemand wie man den obigen Quelltext mit einem Algorithmus ergänzt.
Am besten wär der Mastercode der ohne * und # auskommt und ein OTP (One Time Password) das dann mit * und # beginnt bzw. endet, aber dazu bräuchte ich eine Computerprogramm wo ich den Zeitraum festlegen kann um den Code zu generieren. Beispielsweise der Zugang am 13.8.2013 - 27.8.2013 ein Passwort generiert das nur in diesem Zeitraum gültig ist.

Schlüssel wird es an meinem Haus keinen mehr geben, da die alle Türen über eine Motorverriegelung verfügen und EINE Türe werde ich aber für den Fall der Fälle, per USV gegen Stromausfall absichern.

Von Fingerprint halte ich nichts

Oder noch einfacher, weiß jemand wie der Quellcode aussehen müsste das der "Gastcode" von einer SD Karte gelesen wird? Dann müsste ich bei längerer Abwesenheit nur die SD Karte einstecken und bei Ankunft diese entfernen?