Codeschloss

Hallo

Ich habe für meine Jungs jeweils einen Tresor mit Codeschloss gebaut
Die Grundfunktionen habe ich schon hin bekommen.
Sogar mit änderbarem pinCode.
Leider ist bei jedem neu Start ist wieder der alte Code drin.

Jetzt Wollte ich den neuen Code in den EEprom schreiben, dazu miss ich den CHAR STRING ja erst mal trennen.

Beides hab ich nach 2tagen versuchen nicht hin bekommen.

Ich hoffe mir kann jemand Helfen.

MFG Rocco

Codeschloss.ino (4.2 KB)

Setze Deinen Code bitte direkt ins Forum. Benutze dazu Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Hi

LESE den Pin-Code in setup() aus dem EEprom aus - und speichere Diesen, wenn Er geändert werden soll, im EEprom.
Vll. kurz davor den Code auch Mal anzeigen lassen (wird wohl 0xFF 0xFF 0xFF 0xFF oder 4x die Null) sein - von meinen EEprom-Schreibereien bin ich auch noch ein/zwei Tage entfernt.

Dann kannst Du initial den Müll-Code in 4x die Null ändern und Deine Jungs können ihren Eigenen Pin einstellen.
ACHTUNG: Nach 100.000 Änderungen könnte das EEprom ‘ausfransen’ … also bei täglicher Änderung nur 300 Jahre Laufzeit … :wink:

Du darfst Dein Projekt gerne in Zeigt her eure geilen Projekte ! hier im Forum vorstellen :slight_smile:

MfG

Edit
Im Code fiel mit unter Anderem die ‘magic number’ 48 auf.
Mir ist durchaus bewusst, daß Das die Null (der ASCII-Code) ist.
Du kannst im Code, wie bei den Buchstaben, die Null auch als Zeichen angeben, also ‘0’ <-> 48 <-> 0x30 (bei der HEX-Darstellung findet Sich die 0…9 ebenfalls an rechter Stelle wieder ;))

dazu miss ich den CHAR STRING ja erst mal trennen.

Nein

Du kannst EEPROM.put() und EEPROM.get() verwenden.

Siehe

Hallo

Auf grund der nachfrage hier noch mal der ganze code

#include <Keypad.h>
#include <Servo.h> 

// Pinlänge und Pincode festlegen
const byte PINLENGTH = 4;
char pinCode[PINLENGTH+1] = {'0','8','1','5'};

// Zwischenspeicher für Eingaben
char keyBuffer[PINLENGTH+1] = {'-','-','-','-'};

// Kompakter kann man das auch so schreiben:
// char pin[] = "0815";
// char keyBuffer[] = "----";

// Definition für das Keypad von Elegoo
const byte ROWS = 4; // vier Zeilen
const byte COLS = 4; // vier Spalten
// Symbole auf den Tasten
char hexaKeys[ROWS][COLS] = {
 {'1','2','3','A'},
 {'4','5','6','B'},
 {'7','8','9','C'},
 {'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 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

// Variablen Definieren und PINS zuweisen
const int greenPin = 12;
const int redPin = 13;
const int bluePin = 11;
const int servoPin = 10;
const int angleClosed = 160;
const int angleOpen = 10;
const int openDelay = 3000;
const int buttonO = A6;
int openSensor;
int progMode;

// Servo-Objekt erzeugen
Servo myservo;

// Instanz von Keypad erzeugen, Keymap und Pins übergeben
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

void setup(){
 //Serial.begin(9600);
 // LED Pins setzen
 pinMode(greenPin, OUTPUT);
 pinMode(redPin, OUTPUT);
 digitalWrite(greenPin, LOW);
 digitalWrite(redPin, LOW);
 digitalWrite(bluePin, LOW);
 // Servo auf Ausgangsposition
 myservo.attach(servoPin);
 myservo.write(angleClosed);
 progMode = 0;
}

void loop(){
   // Endschalter abfragen
 openSensor = analogRead(buttonO);
 
 // Gedrückte Taste abfragen
 char customKey = customKeypad.getKey();

 if (customKey) {
   // Check, ob ASCII Wert des Char einer Ziffer zwischen 0 und 9 entspricht
   if ((int(customKey) >= 48) && (int(customKey) <= 57)){ 
         addToKeyBuffer(customKey); 
   }
 // oder Code überprüfen, falls Raute gedrückt wurde nur wenn Tür geschlossen
   else if ((customKey == '#') and (openSensor < 1000) and (progMode == 0)) { 
     checkKey(); 
   }
// Schliesen wenn "C" betätigt
   else if ((customKey == 'C') and (progMode == 0)){
    Dclose();
    } 
// Progamierebene betreten wenn "A" betätigt
    else if ((customKey == 'A') and (openSensor > 1000)and (progMode == 0)){ 
    Prog();    
    } 
// Progamierebene verlassen Code Speichern wenn "B" betätigt
    else if ((customKey == 'B') and (openSensor > 1000)and (progMode ==1)){ 
    Change();    
    }
 }
}
 

void addToKeyBuffer(char inkey) { 
//Serial.print(inkey); 
//Serial.print(" > ");
 // Von links nach rechts Zeichen um eins weiterkopieren = ältestes Zeichen vergessen
 for (int i=1; i<PINLENGTH; i++) {
   keyBuffer[i-1] = keyBuffer[i];
 }
 // in ganz rechter Stelle die letzte Ziffer speichern
 keyBuffer[PINLENGTH-1] = inkey;
 //Serial.println(keyBuffer);
}

void checkKey() {
 // Eingabe mit festgelegtem Pincode vergleichen
 if (strcmp(keyBuffer, pinCode) == 0) {
  //Serial.println("CORRECT");
   // Aktion für richtigen Pin ausführen
   pinCorrect();
 }
 else {
  //Serial.println("WRONG!");
   // Aktion für falschen Pin ausführen
   pinWrong();
 }

 // Nach Überprüfung Eingabe leeren
 for (int i=0; i < PINLENGTH; i++) {
   keyBuffer[i] = '-'; 
 }
}

// Aktion für korrekten Pincode
void pinCorrect() {
 myservo.write(angleOpen);
 digitalWrite(greenPin, HIGH);
 openSensor = analogRead(buttonO);
 if (openSensor < 1000){ 
   pinCorrect();}
   else {digitalWrite (greenPin, LOW);
 }
}
// Aktion Tür schliessen
void Dclose() {
//Serial.print (customKey);
//Serial.println ("schliessen");
    myservo.write(angleClosed);
    digitalWrite(greenPin, LOW);
    
}

// Aktion für falschen Pincode
void pinWrong() {
 for (int i=0; i<3; i++) {
   digitalWrite(redPin, HIGH);
   delay(50);
   digitalWrite(redPin, LOW);  
   delay(50);
   
 }
}
// Aktion Programmieren
void Prog(){
 digitalWrite (bluePin, HIGH);
 progMode = 1;
 }
// Aktion neuenPin Speichern 
void Change(){
 strcpy (pinCode,keyBuffer);
 digitalWrite (bluePin, LOW); 
 progMode = 0;
 
}

Und warum verwendest du keine Code-Tags ?
Dann wird dieser besser lesbar

Hallo

Was sind Code-Tags ?

@HotSystems

Ich hab nen LOOP der entscheidet was gemacht werden soll und dann in die einelnen bereiche springt.

Damit komme ich sehr gut klar.

Den Begriff Code-Tags hab ich so noch nicht gehört

MFG

Ist aus dem: How to use this forum - please read.

So jetzt mit den Code Tags

Jetzt auch die Aktuelle version

#include <Keypad.h>
#include <Servo.h> 
 
// Pinlänge und Pincode festlegen
const byte PINLENGTH = 4;
char pinCode[PINLENGTH+1] = {'0','8','1','5'};
 
// Zwischenspeicher für Eingaben
char keyBuffer[PINLENGTH+1] = {'-','-','-','-'};
 
// Kompakter kann man das auch so schreiben:
// char pin[] = "0815";
// char keyBuffer[] = "----";
 
// Definition für das Keypad von Elegoo
const byte ROWS = 4; // vier Zeilen
const byte COLS = 4; // vier Spalten
// Symbole auf den Tasten
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 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
 
// Variablen Definieren und PINS zuweisen
const int greenPin = 12;
const int redPin = 13;
const int bluePin = 11;
const int servoPin = 10;
const int angleClosed = 160;
const int angleOpen = 10;
const int openDelay = 3000;
int openSensor;
int progMode;
int l = 0; 
int d = 0;
// Servo-Objekt erzeugen
Servo myservo;
 
// Instanz von Keypad erzeugen, Keymap und Pins übergeben
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
 
void setup(){
  Serial.begin(9600);
  // LED Pins setzen
  pinMode(greenPin, OUTPUT);
  pinMode(redPin, OUTPUT);
  digitalWrite(greenPin, LOW);
  digitalWrite(redPin, LOW);
  digitalWrite(bluePin, LOW);
  // Servo auf Ausgangsposition
  myservo.attach(servoPin);
  myservo.write(angleClosed);
  progMode = 0;
}
 
void loop(){
  if (l==0){Serial.print (" LOOP ");}
  l = 1; 
     // Gedrückte Taste abfragen
  char customKey = customKeypad.getKey();
  Serial.print (customKey);
 
  if (customKey) {
    // Check, ob ASCII Wert des Char einer Ziffer zwischen 0 und 9 entspricht
    if ((int(customKey) >= 48) && (int(customKey) <= 57)){ 
          addToKeyBuffer(customKey); 
    }
  // oder Code überprüfen, falls Raute gedrückt wurde nur wenn Tür geschlossen
    else if ((customKey == '#') and (d == 0) and (progMode == 0)) { 
      checkKey(); 
    }
 // Schliesen wenn "C" betätigt
    else if ((customKey == 'C') and (d == 1)and (progMode == 0)){
     Dclose();
     } 
 // Progamierebene betreten wenn "A" betätigt
     else if ((customKey == 'A') and (d == 1)and (progMode == 0)){ 
     Prog();    
     } 
 // Progamierebene verlassen Code Speichern wenn "B" betätigt
     else if ((customKey == 'B') and (d ==1)and (progMode ==1)){ 
     Change();    
     }
  }
}
  
 
void addToKeyBuffer(char inkey) { 
 Serial.print(inkey); 
 Serial.print(" > ");
  // Von links nach rechts Zeichen um eins weiterkopieren = ältestes Zeichen vergessen
  for (int i=1; i<PINLENGTH; i++) {
    keyBuffer[i-1] = keyBuffer[i];
  }
  // in ganz rechter Stelle die letzte Ziffer speichern
  keyBuffer[PINLENGTH-1] = inkey;
 Serial.println(keyBuffer);
 l = 0; 
}
 
void checkKey() {
  // Eingabe mit festgelegtem Pincode vergleichen
  if (strcmp(keyBuffer, pinCode) == 0) {
   Serial.println("CORRECT");
    // Aktion für richtigen Pin ausführen
    pinCorrect();
  }
  else {
   Serial.println("WRONG!");
    // Aktion für falschen Pin ausführen
    pinWrong();
  }
 
  // Nach Überprüfung Eingabe leeren
  for (int i=0; i < PINLENGTH; i++) {
    keyBuffer[i] = '-'; 
  }
  l = 0; 
}
 
// Aktion für korrekten Pincode
void pinCorrect() {
  myservo.write(angleOpen);
  digitalWrite(greenPin, HIGH);
  delay(1000);
  digitalWrite (greenPin, LOW);
  d = 1;
  l = 0; 
}
// Aktion Tür schliessen
void Dclose() {
 //Serial.print (customKey);
 Serial.println ("schliessen");
     myservo.write(angleClosed);
     digitalWrite(greenPin, LOW);
     delay(50);
     d = 0;
 l = 0;     
}
 
// Aktion für falschen Pincode
void pinWrong() {
  for (int i=0; i<3; i++) {
    digitalWrite(redPin, HIGH);
    delay(50);
    digitalWrite(redPin, LOW);  
    delay(50);
    }
  l = 0; 
}
// Aktion Programmieren
void Prog(){
  digitalWrite (bluePin, HIGH);
  progMode = 1;
  l = 0; 
  }
// Aktion neuenPin Speichern 
void Change(){
  strcpy (pinCode,keyBuffer);
  digitalWrite (bluePin, LOW); 
  progMode = 0;
  l = 0; 
  
}

Man kann eine Post auch editieren und dort die CODE TAGs einfügen (was ich Dir in diesem Fall schon getan habe).
Grüße Uwe

Cabriofahrer-RG:
Was sind Code-Tags ?

Das hat dir Tommy doch in Post #1 schon geschrieben.

ja da hab ich wohl nicht genau genug gelesen. Schreibe ja auch zum ersten mal was in irgend ein Forum.

Das Thema ist jetzt erledigt ich weis das nächste mal wie es geht und werde es besser machen.

Jetzt zurück zu meinem Problem.

wie bekomme ich den pinCode in den EEProm geschrieben und wie lese ich ihn wieder aus.

MFg Rocco

Schau Dir EEPROM.put und /.get an.

Gruß Tommy

Das habe ich auch schon probiert....
Ist aber resonanzlos verpufft.

Aber wer weiß, vielleicht kommst du ja damit durch.

Habe mich letztens mit einem ganz ähnlichen Projekt beschäftigt und hier eine hilfreiche Erklärung (auf deutsch) der Syntax und zwei Beispielen gefunden.
Viel Erfolg!

derGeppi:
Habe mich letztens mit einem ganz ähnlichen Projekt beschäftigt und hier eine hilfreiche Erklärung (auf deutsch) der Syntax und zwei Beispielen gefunden.
Viel Erfolg!

Da sind ein paar Dinger drin, welche ich für kritisch halte.

#define EESIZE 1024

Da sollte man doch besser die EEPROM Instanz fragen, als das Konstant anzunageln.

int adresse = 0;              /* EEPROM-Startadresse */

Ja, wohl wahr....
Aber auch so selbstverständlich, dass die Not einer Erwähnung gering ist.

adresse += sizeof(float);

Händische (relative) berechnungen der Adresse.
Nicht hier, nicht heute, aber irgendwann schleichen sich da schwer zu findende Wartungsfehler ein.
Ich rate davon ab und empfehle solcher Art Berechnungen dem Kompiler zu überlassen.
Der irrt sich nicht, und übersieht nix.

Ansonsten:
Durchaus brauchbar., die Anleitung.

Hi

Zum 'den Compiler den Kram berechnen lassen' versuche ich mich gerade, Alles, was ich im EEprom haben will, in eine Struktur zu pappen und Diese ins EEprom zu 'put'en.
(bisher gette ich nur und benutze den eingelesenen Inhalt noch nicht, da die Grundfunktion noch nicht läuft ... außerdem steht die 'Speichere die aktuellen Daten im EEprom'-Funktion ebenfalls noch nicht - wobei Das wirklich nur 1 .put sein dürfte)

So richtig gangbar erscheint mir dieser Weg allerdings nicht - täuscht mich hier mein Bauchgefühl?

MfG

So richtig gangbar erscheint mir dieser Weg allerdings nicht - täuscht mich hier mein Bauchgefühl?

Wir haben 3 Speicherorte, wo Daten landen können!
RAM, Flash und EEPROM

Ich mache mir immer gerne eigene Typen.
Dann habe ich einen passenden Bezeichner, und einen zuverlässigen "Anfass"

using  Passwort  = char[4+1];

Dann kann ich Variablen in dem gewünschten Speicherbereich anlegen und auch vorbesetzen.

Passwort imRam  {"1234"};  // vergänglich
const Passwort imFlash PROGMEM {"1234"}; // dauerhaft
Passwort imEeprom EEMEM {"1234"};  // persistent

Das Passwort im Ram wird "hier" aus dem Flash initialisiert.

Das Passwort im Flash, bleibt auch erstmal da. ReadOnly. Spezielle Leseroutinen sind nötig.
(soll hier kein Thema sein)

Das Passwort im EEPROM kann aus dem Programm überschrieben und gelesen werden. Die Initialisierungsdaten landen in der *.eep Datei, und können per ISP ins EEPROM übertragen werden.

Das lesen vom EEPROM in den vergänglichen Speicher.

EEPROM.get((int)&imEeprom,imRam);

Das schreiben vom vergänglichen Speicher ins EEPROM.

EEPROM.put((int)&imEeprom,imRam);

Alles, was ich im EEprom haben will, in eine Struktur zu pappen und Diese ins EEprom zu 'put'en.

Auch eine Variante.
Wobei man dann auch einzelne Strukturelemente lesen kann.
offsetof() ist dabei Gold wert.

Hallo

Ich möchte mich bedanken.

Mit eurer Hilfe habe ich es hin bekommen.

meine Jungs sind WAHNSINNIG DANKBAr das der andere jetzt nicht mehr in seinem Tresor kommt.

für den Notfall hab ich mir die möglichkeit gelassen den Code aus zu lesen.

MFG Rocco