Passwörter im Eeprom speichern und abrufen

Hallo, Arduino-Community! :slight_smile:
Ich habe Probleme mit folgendem Projekt:
Beschreibung:
Ein Aufbau von 8 Schließfächern, von denen jedes seinen individuellen Öffnungscode erhält.
Öffnet man ein Schließfach, wird der Code resettet (ist also nur 1x benutzbar) und das Schließfach kann neu belegt werden (nur vom Service-Personal) und erhält einen neuen Code.
Technischer Aufbau:
Arduino Uno, Keypad (0-9,,#), i2c-Expander MCP23017 (Bank A als Input für Elektroschloß-Schalter, Bank B als Output für Elektroschlösser), i2c-1602-LED-Display und ein Schlüsselschalter für die Service-Funktionen.
Was bisher funktioniert:
der ganze Ablauf ohne Eeprom-Funktionen (Fach befüllen, Abhol-Code vergeben, Abholen und Code resetten, Belegte Fächer anzeigen), lediglich noch ein paar kosmetische Dinge sind noch zu erledigen (z.B. darf „
“ und „#“ nicht eingegeben werden)…
Zur Überprüfung einfach alles auskommentieren, was mit Eeprom zu tun hat.
Was nicht funktioniert:
Ich würde gerne alle Abhol-Codes(Passwörter) im Eeprom ablegen, aber das will mir nicht so recht gelingen. Irgendwie ist das, was oder wie ich es im Eeprom speichere nicht richtig.
Gibt es für „password.h“ irgendeine Möglichkeit, die gesetzten Passwörter (hier: was mit passwordArray[index].set(eeprompassword); festgelegt wurde) sich im seriellen Monitor anzeigen zu lassen? Dann käme ich vielleicht selbst weiter..

...der Code ist leider zu lang, um ihn in Code-Tags zu posten,...
...bis ich ihn gekürzt habe hier so lange die ino-Datei... :frowning:

WSF_10_Eeprom_01.ino (14.2 KB)

evtl. hilft dir dieses ja

combie:
evtl. hilft dir dieses ja

...während ich mir das mal genauer durchlesen (beim Überfliegen hats noch nicht 'klick' gemacht) hier solange mal mein stark gekürzter sketch:

#include <EEPROM.h>
byte PWadd = 0;       //adress for storing Eeprom-passwords

#include <Password.h> 
#include <Keypad.h> 

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
byte rowPins[ROWS] = {9, 4, 5, 7};
byte colPins[COLS] = {8, 10, 6};
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS );

const byte maxbox = 8;        // first 8 Passwords are the Pickup-Codes
const byte maxcommand = 9;    // next 9 Passwords are the Service-Codes
Password passwordArray[maxbox + maxcommand] = {
  Password( "1111" ),     //Pickup-Code for Box #1
  Password( "2222" ),     //Pickup-Code for Box #2
  Password( "3333" ),     //Pickup-Code for Box #3
  Password( "4444" ),     //Pickup-Code for Box #4
  Password( "5555" ),     //Pickup-Code for Box #5
  Password( "****" ),     //Pickup-Code for Box #6
  Password( "7777" ),     //Pickup-Code for Box #7
  Password( "****" ),     //Pickup-Code for Box #8
  //Service-codes
  Password( "1201" ),     //Open Box#1
  Password( "1202" ),     //Open Box#2
  Password( "1203" ),     //Open Box#3
  Password( "1204" ),     //Open Box#4
  Password( "1205" ),     //Open Box#5
  Password( "1206" ),     //Open Box#6
  Password( "1207" ),     //Open Box#7
  Password( "1208" ),     //Open Box#8
  Password( "9999" ),     //Open empty and unused Box to fill
};

byte boxstate[maxbox];          // 0 = empty/no PW  1 = full/PW set
byte sesam, codelength;         // length of entered password
byte sesammax = 4;              // max length of password
String passwordinput;           // the entered password for output on lcd-display
byte menu;                      // menu value for info on LCD-Display
byte index;                     // global counter variable
boolean setnewpassword = false; // true, if a new password is to set

byte boxtoopen;       // Box# for LCD-Display

#define KeySW A0      // Keyswitch-Input for Master-Key
boolean keystate;     // true when Masterkey ON => service menu
boolean keylaststate;


void setup() {
  Serial.begin(9600);

  resetEeprom();

  delay(50);

  readEeprom();

  delay(50);

  pinMode(KeySW, INPUT_PULLUP);

  keypad.addEventListener(keypadEvent); //add an event listener for this keypad

  codelength = sesammax;
}

void loop() {

  boxtoopen = 0;

  while (sesam < codelength) {
    if (sesam < 1) {
      CheckMasterKey();
    }
    ShowDisplay();
    keypad.getKey();
  }
  delay(200);

  //evaluate Passwords
  CheckAllPasswords();

  //Is a box to open?
  if (boxtoopen > 0) {
    OpenTheBox();
  }

  //reset entered Password
  ResetAllPasswords();

}

void ShowDisplay() {
}


void keypadEvent(KeypadEvent eKey) {
  switch (keypad.getState()) {
    case PRESSED:
      passwordinput += eKey;
      Serial.print ("passwordinput : ");
      Serial.println(passwordinput);
      AppendAllPasswords(eKey);
      break;
    case HOLD:
      break;
    case RELEASED:
      sesam++;
      break;
  }
}

void AppendAllPasswords(KeypadEvent eKey) {
  switch (keystate) {
    //Service-Mode
    case true:
      if (menu == 1) {                                //new pickup-code
        for (index = 0; index < maxbox; index++) {
          passwordArray[index].append(eKey);
        }
      }
      else {                                          //expect password for service
        for (index = maxbox; index < (maxcommand + maxbox); index++) {
          passwordArray[index].append(eKey);
        }
      }
      break;
    //Customer-Mode
    case false:                                       //expect pickup-code
      for (index = 0; index < maxbox; index++) {
        passwordArray[index].append(eKey);
      }
      break;
  }
}


void CheckAllPasswords() {
  byte cmdindex;
  switch (keystate) {
    case true:
      //check service-passwords, creating command list starting from 0
      for (cmdindex = maxbox; cmdindex < (maxcommand + maxbox); cmdindex++) {
        Serial.print ("Evaluation of Command #");
        Serial.print (cmdindex - maxbox + 1);
        Serial.print (" ... ");
        if (passwordArray[cmdindex].evaluate()) {
          //Code is Command
          switch (cmdindex - maxbox) {
            case 0 ... 7:
              //Open Box 1-8
              Serial.print  ("Öffne Fach #");     //Oeffne Fach
              Serial.println(cmdindex - maxbox + 1);          //#
              boxtoopen = (cmdindex - maxbox + 1);
              break;
            case 8:
              //Fill empty Box
              byte fullboxcounter = 1;
              for (index = 0; index < maxbox; index++) {
                if (boxstate[index] == 1) {
                  fullboxcounter++;
                }
                else {
                  Serial.print  ("Befülle Fach #");   //Oeffne Fach
                  Serial.println(index + 1);          //#
                  boxtoopen = index + 1;
                  //FillBox();
                  break;
                }
              }
              if (fullboxcounter == maxbox) {
                //All Boxes full .. no Fill possible
                Serial.println("Alle Fächer voll!");     //show this on LCD
              }
              break;
          }
        }
        else {
          Serial.println("none!");
        }
        delay(5);
      }
      break;
    case false:
      //checking for right pick-up code
      for (index = 0; index < maxbox; index++) {
        Serial.print ("Evaluation Password for Box #");
        Serial.print (index + 1);
        Serial.print ("... ");
        if (passwordArray[index].evaluate()) {
          Serial.println ("correct!");
          boxtoopen = (index + 1);
          break;
        }
        else {
          Serial.println("wrong!");
        }
        delay(5);
      }
      //Pickup-Code-Check Result on LCD
      if (boxtoopen == 0) {
        menu = 11;        // "CODE UNBEKANNT"
        ShowDisplay();
        delay(2000);
        menu = 10;
      }
      break;
  }
}

void ResetAllPasswords() {
  for (index = 0; index < (maxbox + maxcommand); index++) {
    passwordArray[index].reset();
  }
  //reset other values
  sesam = 0;
  codelength = sesammax;
  passwordinput = "";
}

void CheckMasterKey() {
}

void OpenTheBox() {
  byte oldmenu;
  oldmenu = menu;
  menu = 20;
  ShowDisplay();
  //here will the box open, is temporarily deleted
  //menu = 30; and check for a closed door
  menu = oldmenu;
  if (keystate == false) {
    ResetPickupCode(boxtoopen);
  }
}

void ResetPickupCode(byte codetoreset) {
  codetoreset--;    // pointer=box-1
  passwordArray[codetoreset].set("****");
  // save new password to Eeprom
  for (byte j = 0; j < sesammax; j++)
  {
    EEPROM.write((PWadd + (codetoreset * 5) + j), '*');
  }
  EEPROM.write((PWadd + (codetoreset * 5) + sesammax), '\0');
}


void readEeprom() {
  char eeprompassword[5];
  for (index = 0; index < maxbox; index++) {
    for (byte j = 0; j < (sesammax+1); j++) {
      eeprompassword[j] = EEPROM.read(PWadd + (index * 5) + j);
    }
    passwordArray[index].set(eeprompassword);
    Serial.print  ("Eeprom-password for Box#");
    Serial.print  (index + 1);
    Serial.print  (" is_: ");
    Serial.println(eeprompassword);
  }
}

void resetEeprom() {
  //reset all Eeprom pickup-passwords to "****"
  String nullpassword = "****";
  for (index = 0; index < maxbox; index++) {
    for (byte j = 0; j < sesammax; j++)
    {
      EEPROM.write((PWadd + (index * 5) + j), nullpassword[j]);
    }
    EEPROM.write((PWadd + (index * 5) + sesammax), '\0'); //Add termination null character for String Data
    //EEPROM.commit();
  }
}

Gibt es für „password.h" irgendeine Möglichkeit, die gesetzten Passwörter (hier: was mit passwordArray[index].set(eeprompassword); festgelegt wurde) sich im seriellen Monitor anzeigen zu lassen? Dann käme ich vielleicht selbst weiter..

Ich kenne die Klasse nicht wirklich. Nur mal überflogen.
Warum erweiterst du sie nicht um die benötigten Methoden?

Oder anders:
Warum benutzt du sie, wenn sie doch deinen Ansprüchen nicht genügt?

combie:
Warum erweiterst du sie nicht um die benötigten Methoden?
Oder anders:
Warum benutzt du sie, wenn sie doch deinen Ansprüchen nicht genügt?

  1. Ich pfusche nicht in libraries rum, wenn ich mich damit nicht auskenne. Ich benutze sie einfach nur :wink:
  2. Wieso sollte sie meinen Ansprüchen nicht genügen? Das weiß ich doch noch gar nicht.. Erstmal gehe ich von einem Bedienerfehler aus.

Mittlerweile bin ich mal wieder 10 Schritte zurückgegangen und habe beim Reduzieren des Sketches ein ganz anderes Problem gefunden:

Wie gesagt, ich lege die Passwörter ja in einem Passwort-Array ab.
Also habe ich nun mal einen Sketch angelegt, in dem die Passwörter einmal einzeln vergeben werden müssen.
Bedingung, kein Passwort darf doppelt vorkommen, also muss nach jeder Eingabe eine Prüfung daraufhin erfolgen. Und genau das will irgendwie nicht so klappen, wenn man z.B. mal versucht, PW#1 für PW#3 zu verwenden, lässt das Programm das zu.. Und das ist erst die Routine im Setup. Die Abfrage in der Loop klappt ebensowenig.

Also vermute ich, daß meine Art, wie ich das Passwort zu setzen versuche, irgendwie falsch ist...

derGeppi:
Also vermute ich, daß meine Art, wie ich das Passwort zu setzen versuche, irgendwie falsch ist...

Mit Sicherheit, aber was sehen wir aus der Ferne nicht.

Gruß Tommy

Sorry, der Sketch war mal wieder zu lang und musste 5 min mit dem posten warten... bitteschön! :slight_smile:

#include <Password.h> 
#include <Keypad.h> 

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
byte rowPins[ROWS] = {9, 4, 5, 7};
byte colPins[COLS] = {8, 10, 6};
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS );

const byte maxbox = 8;        // first 8 Passwords are the Pickup-Codes
Password passwordArray[maxbox] = {
  Password( "****" ),     //Pickup-Code for Box #1  (empty)
  Password( "****" ),     //Pickup-Code for Box #2  (empty)
  Password( "****" ),     //Pickup-Code for Box #3  (empty)
  Password( "****" ),     //Pickup-Code for Box #4  (empty)
  Password( "****" ),     //Pickup-Code for Box #5  (empty)
  Password( "****" ),     //Pickup-Code for Box #6  (empty)
  Password( "****" ),     //Pickup-Code for Box #7  (empty)
  Password( "****" )      //Pickup-Code for Box #8  (empty)
};

byte boxstate[maxbox];          // 0 = empty/password is '****'  1 = full/PW set
byte sesam, codelength;         // length of entered password
byte sesammax = 4;              // max length of password
String passwordinput;           // the entered password for output on lcd-display
byte index;                     // global counter variable
boolean setnewpassword = false; // true, if a new password is to set

byte boxtoopen;       // Box# for LCD-Display


void setup() {
  Serial.begin(9600);

  keypad.addEventListener(keypadEvent); //add an event listener for this keypad

  codelength = sesammax;
  SetAllPasswords();
}

void loop() {

  boxtoopen = 0;

  CheckBoxesInUse();

  Serial.println ("OK, new enter the right code!");

  while (sesam < codelength) {
    keypad.getKey();
  }
  
  //evaluate Passwords
  CheckAllPasswords();

  //Is a box to open?
  if (boxtoopen > 0) {
    //OpenTheBox();
  }

  //reset entered Password
  ResetAllPasswords();

}

void keypadEvent(KeypadEvent eKey) {
  switch (keypad.getState()) {
    case PRESSED:
      passwordinput += eKey;
      Serial.print ("passwordinput : ");
      Serial.println(passwordinput);
      AppendAllPasswords(eKey);
      break;
    case HOLD:
      break;
    case RELEASED:
      sesam++;
      break;
  }
}

void AppendAllPasswords(KeypadEvent eKey) {
  //append to all passwords in array
  for (byte appendindex = 0; appendindex < maxbox; appendindex++) {
        passwordArray[appendindex].append(eKey);
      }
}

void CheckAllPasswords() {
  //check all passwords in array
  for (byte validindex = 0; validindex < maxbox; validindex++) {
    Serial.print ("Evaluate Password '");
    Serial.print (passwordinput);
    Serial.print ("' for Box #");
    Serial.print (validindex + 1);
    Serial.print ("... ");
    if (passwordArray[validindex].evaluate()) {
      Serial.println ("correct!");
      boxtoopen = (validindex + 1);
      break;
    }
    else {
      Serial.println("wrong!");
    }
    delay(5);
  }
}

void ResetAllPasswords() {
  for (byte resetindex = 0; resetindex < maxbox; resetindex++) {
    passwordArray[resetindex].reset();
  }
  //reset other values
  sesam = 0;
  codelength = sesammax;
  passwordinput = "";
}

void CheckBoxesInUse() {
  //Set all Passwords to "****" (empty Box has code "****")
  Serial.println("Now we're gonna check, which box has a already a password..!");
  ResetAllPasswords();
  for (byte setindex = 0; setindex < maxbox; setindex++) {
    for (byte j = 0; j < sesammax; j++) {
      passwordArray[setindex].append('*');
    }
  }
  //check if any set passwords are "****"
  for (byte checkindex = 0; checkindex < maxbox; checkindex++) {
    Serial.print ("Evaluate Password '****' for Box #");
    Serial.print (checkindex + 1);
    Serial.print ("... ");
    if (passwordArray[checkindex].evaluate()) {
      Serial.println ("correct, so it's empty!");
      boxstate[checkindex] = 0;
    }
    else {
      Serial.println("wrong, so it's full!");
      boxstate[checkindex] = 1;
    }
    delay(5);
  }
  ResetAllPasswords();
} 

void SetAllPasswords() {
  //set new passwords for all 8 elements of password array (boxes)
  for (byte setnewpw = 0; setnewpw < maxbox; setnewpw++) {
    CheckBoxesInUse();          //show all boxes that have a password
    Serial.print  ("Set new password for Box# ");
    Serial.println(setnewpw+1);
    //ask for new code
    boolean newpasswordset = false;
    while (newpasswordset == false) {
      ResetAllPasswords();
      while (sesam < codelength) {
        keypad.getKey();
      }
      //is new code already in use?
      byte usedpassword = false;          //is new password already in use?
      for (byte usedindex = 0; usedindex < maxbox; usedindex++) {
        Serial.print ("Is it Password for Box #");
        Serial.print (usedindex + 1);
        Serial.print ("? ... ");
        if (passwordArray[usedindex].evaluate()) {
          Serial.println ("yes!");
          usedpassword = true;
        }
        else {
          Serial.println("no!");
        }
      }
      if (usedpassword == false) {
        Serial.println("new password accepted!");
        newpasswordset = true;
      }
      else {
        Serial.println("new password is already in use!");
      }
    }
    //set and save the new password 
    char newpass[5];
    Serial.print ("The new password '");
    Serial.print (passwordinput);
    Serial.print ("' will be set for Box #");
    Serial.println(setnewpw+1);
    passwordinput.toCharArray(newpass, 5);
    passwordArray[setnewpw].set(newpass);    // save new password in array
  }
}
  1. Ich pfusche nicht in libraries rum, wenn ich mich damit nicht auskenne. Ich benutze sie einfach nur :wink:

Jedem sein Ding.....

Wieso sollte sie meinen Ansprüchen nicht genügen?

  • Sie arbeitet nicht mit dem EEPROM, das willst du aber.
  • Sie zeigt die Passwörter nicht an, das willst du aber.

Genügt sie deinen Ansprüchen?
Offensichtlich: Nein!

Bedingung, kein Passwort darf doppelt vorkommen, also muss nach jeder Eingabe eine Prüfung daraufhin erfolgen.

Ein Irrweg! ? !

Denn, wenn ein doppeltes Passwort abgelehnt wird, weiß man automatisch ein Passwort der vergebenen Boxen. Kann sie also öffnen.

Langsam bekomme ich den Eindruck, du möchtest mir nicht helfen, sondern mich nur belehren…

Wieso sollte ich wollen, daß die password-library schon alle Eeprom-funktionen beinhaltet? Wenn ich einen Datentyp im Eeprom ablegen und auslesen kann und außerdem einen Datentyp als Passwort setzen kann, dann sollte man das doch auch miteinander kombinieren können, ohne in die Passwort-Library einzugreifen. Aber lass uns doch mal den Eeprom-Teil ausklammern, da mein Problem ja schon ganz woanders wurzelt..

Die Ausgabe des gesetzten Passworts im seriellen Monitor ist kein Muss, sondern wäre -wenn es das denn GÄBE- nur ein Goodie, was mir beim Debuggen hilfreich WÄRE. Stichwort: Hilfe zur Selbsthilfe.

Desweiteren ist mein Vorgehen, alle Passwörter am Anfang manuell zu setzen auch kein Irrweg, sondern einfach nur ein reduzierter Sketch, um meine Methode der Vergabe neuer Passwörter auf Fehler zu überprüfen (die ja „offensichtlich“ vorhanden sind).
Im fertigen Programm werden Passwörter nicht userseitig vergeben sondern nur von Service-Personal (post#1). Also keine Gefahr, daß jemand das Vorhandensein eines existierenden Codes unerlaubterweise bemerkt.

In der Tat wäre die library ungeeignet, wenn ich die Passwörter nicht in einem Array ablegen (das klappt ja einmal am Anfang per Definition) und beliebig neu setzen könnte.

Deswegen: Ist sie geeignet und meine Methode ist einfach nur falsch/fehlerhaft? Oder hat jemand ähnlich Erfahrungen gemacht und kann deswegen eine andere Methode/Passwort-Library empfehlen, die zum Erfolg führt?

Ich würde ganz auf die Passwortlib verzichten. So ein Array mit Char-Arrays kann man doch problemlos selbst verwalten. Aber dass muss jeder selbst entscheiden. Falls Du Dich näher damit beschäftigen willst bzw. die Lib besser verstehen willst, kannst Du hier nachlesen.

Gruß Tommy

Ich glaube, der Begriff "Passwort" ist eher verwirrend. Du meinst eher einen "EinmalBenutzbarenÖffnungscode", der nach der Vergabe später eins der 8 Fächer öffnet ?
Deshalb darf kein aktuell belegtes nochmal vergeben werden.

Dieser Code ist immer 4 Ziffern lang?
Zusätzlich hat jedes Fach einen weiteren Code (auch 4 Ziffern) ?

Der neue Öffnungscode wird vom Operator vergeben und dem Benutzer mitgeteilt.
Der Operator probiert bei Bedarf so lange, bis er einen freien Code erwischt, denn wenn er aus Versehen ( Chance 15:1000 ) einen belegten Code zweimal vergeben könnte, ginge ja evtl. das falsche oder mehrere Fächer beim Öffnen auf.

Das Ganze ist sicher nur Spaß und erinnert mich eher an eine Theater-Garderobe, nur mit virtuellen Märkchen.

Und da besteht für die meisten hier der Spaß darin, sowas selber zu machen, und dafür
(wenn überhaupt, und eher um es hübsch aussehen zu lassen) eine passende Library zu machen.

"Hilfe", so wie du (Geppi) es wohl verstehst, entsteht da höchstens am Rande. Und eher, so wie hier, als Diskussion über Sinn und Grenzen des Ganzen.

Falls ich das Projekt falsch verstanden habe, kannst du deine Beschreibung gern anpassen, Geppi.

Wenn alles schon OK war, und du nur das Array noch im EEPROM sichern/wiederherstellen willst, brauchst du nur EEPROM.put / .get richtig zu verwenden.

Bevor wir dir dieses zweigeteilte Array auch noch zerreden :slight_smile:

Bevor wir dir dieses zweigeteilte Array auch noch zerreden :slight_smile:

Soweit war ich noch nicht!
:smiling_imp: :smiling_imp: :smiling_imp: :smiling_imp:

Wie auch immer, meine Hilfeversuche, oder eher Versuche zu verstehen, was da passieren soll, sind wohl inkompatibel mit dem Fragesteller.

Langsam bekomme ich den Eindruck, du möchtest mir nicht helfen, sondern mich nur belehren…

Ein guter Grund für mich, hier aufzugeben.

Tommy56:
Ich würde ganz auf die Passwortlib verzichten.

So langsam glaube ich auch, daß dort die Krux liegt.. Ich habe schon andere Projekte mit dieser Lib realisiert und hoffte, daß man, was mit einem Passwort funktioniert bequem auf ein Array erweitern kann, was aber nur bedingt funktioniert. Beim Aufbau meines mittlerweile doch recht komplexen Sketches habe ich dann aber doch wieder einiges über char-arrays und strings gelernt und gemerkt, daß man das Ganze ohne passwort-Lib auch irgendwie hinkriegen SOLLTE. Daher freue ich mich über Deinen schön zusammengestellten Lesestoff und arbeite mich mal noch tiefer in die Materie ein :slight_smile:

@michael_X:
Genau so hatte ich mir das vorgestellt: einmaliger Öffnungscode, der (hoffentlich) nur ein Fach öffnet und nach Öffnung verfällt. Gaderobenmärkchen trifft es ganz gut :slight_smile: ich hatte mir das eher als DIY-Paketabholstation vorgestellt, bei dem ja auch der Code operatorseitig vorgegeben und mitgeteilt wird.
Das Risiko durch Rumprobieren userseitig und unberechtigt einen richtigen Code zu treffen, sollte dann auch durch größere arrays (6-8stelliger Code?) oder kummulativer Wartezeiten zwischen den Eingaben zu minimieren sein.

Zu diesem ominösen Konstrukt des zweigeteilten Arrays (Danke, daß ihr euch die Mühe gemacht und den Sketch in Augenschein genommen habt),... ja, da bin ich nicht mehr so stolz drauf wie am Anfang:
"Hey, wenn ich Passwörter abfragen und vergleichen kann, dann kann ich doch auch Passwörter/Codes zur Programmierung der ganzen Geschichte nehmen. Türen öffnen, wenn sie jemand zu früh schließt,zum Befüllen oder zum Entleeren am Tagesende" .. Find ich mittlerweile sehr unelegant und wird beim nächsten mal anders gelöst. Versprochen :smiley:

Nichts für ungut - aber das Ablehnen eines schon vorhandenen Passwort zwingt Einen förmlich dazu, das soeben abgelehnte Passwort bei den verschlossenen Boxen zu versuchen - netter Nebeneffekt: Man bekommt was geschenkt und anschließend klappt sogar das eigene Passwort (mit der Gefahr, daß jemand gaaanz Anderes meine Sachen Da wieder raus nimmt).

Warum dem Passwort nicht noch mitgeben, für welches Fach Es ist?
1-0-0-0-0 ist das Passwort für das Fach '1'.

Oder springt einfach das Fach auf, zu Dem der 4-stellige Code passt?
Vll. solltest Du bei einer Bank anfangen und ich sinnlos irgendwelche Pins im Geldautomaten eingeben ...

MfG

postmaster-ino:
das Ablehnen eines schon vorhandenen Passwort zwingt Einen förmlich dazu, das soeben abgelehnte Passwort bei den verschlossenen Boxen zu versuchen.

Oder springt einfach das Fach auf, zu Dem der 4-stellige Code passt?

Ich scheine es echt zu kompliziert zu erklären, obwohl es das doch gar nicht ist,... sorry dafür :wink:

Also Ablauf wie folgt:
-Operator will freies Fach füllen (Schlüsselschalter + Operator-Code)
-Tür von irgendeinem leeren Fach springt auf oder bleibt zu ("alle Fächer voll!")
-jetzt Ware rein, Abhol-Code festlegen ("ist er doppelt vergeben? Dann neuer Code bitte")
-(Türe zumachen, fast vergessen)
-Code an User geben
-User gibt Code ein, das entsprechende Fach springt auf. Ware raus, Tür zu... der nächste, bitte :slight_smile:
-Gibt er einen unbekannten Code ein, passiert gar nichts
-Gibt er einen existierenden Code ein, der nicht zum eigenen Fach gehört, habe ich ein Problem :slight_smile:

Feinheiten wie "Tür ging nicht auf, weil jmd dagegen gelehnt hat" und "Rumprobieren schwer gemacht" kommen natürlich noch dazu :wink:

Wie gesagt, das Konstrukt im Groben steht ja schon (mechanisch wie programmtechnisch), lediglich dieser Krampf mit der Programmierung des Abhol-Codes ist die einzige Hürde, wo ich den Schubs in die richtige Richtung gebraucht habe.

Abgesehen davon, Menschen sind faul. Servicekräfte auch. Was hindert die daran, jedes Mal das gleiche Passwort für das gleiche Fach zu vergeben? Nichts.

Generiere das neue Passwort doch über den Zufallsgenerator und zeige es der Servicekraft an. Dann kann sie dieses weiter geben.

Gruß Tommy

Tommy56:
Abgesehen davon, Menschen sind faul. Servicekräfte auch. Was hindert die daran, jedes Mal das gleiche Passwort für das gleiche Fach zu vergeben?

Den Abhol-Code bekommen sie von anderer Stelle vorgegeben, da ist quasi schon der Zufallsgenerator drin. Musste ihnen bereits ausreden, fortlaufende Zahlen zu verwenden :wink: Aber gut mitgedacht..

Hi

Problem: Wie kommst Du an das Fach heran, wenn der Kunde (und die Service-Kraft) das Aktuelle vergessen haben?
Dann braucht's wieder einen Taster, damit man den Öffnungsmechanismus auch von Hand auslösen kann - da muß ich aber vorher noch prüfen, welches Fach dem Kunden nun wirklich ist ...

Umschwenken auf RFID?
Kunde leiht Sich einen RFID-Chip (5€ Pfand), schließt Seinen Kram ein, öffnet nach dem Einkauf wieder, tauscht den Chip gegen die abgegebenen 5 Euro.
Keine Nummern merken - wenn Chip weg, dann Pech - Inhalt am Monatsende zur Versteigerung (Koffer-Hoffer ...).

Nun gut - bin ja hier nur der blöde Entwickler und muß mir keinen Kopf über Sinn oder Dessen Fehlen machen.
8 Schließfächer = Array mit 8 Plätzen für den Code.
Beim 'Fach anfordern' schaut der Arduino nach, ob noch was frei ist - wenn JA, wird so lange eine Zahl ausgewürfelt, bis Diese noch nicht in den anderen Fächern vorhanden ist - der Einfachheit ist 0000 der 'Fach ist leer'-Code.
Sobald ein Code ausgewürfelt wurde, wird Dieser im Array gespeichert, das Fach geht auf, der Kunde bekommt den Zettel mit der Nummer.

MfG

Berechtigte Frage..
..bei allgemeinem Versagen geht halt nur der manuelle Weg. Fach für Fach öffnen und reinschauen. Die Funktion dafür ist bereits im Programm vorgesehen: Operator kann alle Fächer mit Schlüsselschalter plus Code einzeln öffnen.

RFID ist eine gute Lösung für das Schließfach als Lagerfach.

Ich würde es aber gerne als Warenausgabefach umsetzen, d.h. Fach wird befüllt, wenn der Kunde noch gar nicht vor Ort ist.

In Planung (wenn die einfache Version klappt) für Version 2.0 wäre dann das System mit Code-Scanner... ob als gedruckter Barcode oder QR-Code aufs Handy kann man dann frei entscheiden. Das würde dann auch den Missbrauch eliminieren.

So aber bin ich schon froh, wenn diese "primitve" Variante erstmal funktioniert :slight_smile:

..und genau so, wie du es machen würdest, habe ich es ja auch schoh hinbekommen, bis auf den Unterschied, daß der Code nicht vom Arduino erwürfelt wird. Jetzt nur noch den Code richtig im Array und Eeprom speichern, keine Speicherprobleme bekommen und gut ist :slight_smile: