Mehrere Zahlenwerte eingeben und speichern

Hei alle Zusammen!!

ich habe ein kleines Problem bei einem Sketch und hoffe die Profis aus dem Forum können mir weiter helfen :slight_smile: .
Ich möchte eine Zeitschaltung für ein Kochfeld mit Temperaturregelung umsetzen (für eine kleine Brausteuerung). Die Umsetzung des ganzen ist an sich nicht das Problem. Allerdings möchte ich die Temperatur- & Zeitvorgabe manuell über ein 4x4 Keypad eingeben und abspeichern. Es sollen bis zu vier unterschiedliche Zeiten und Temperautren für den Kochvorgang speicherbar sein. Ich möchte also vor dem Kochen über ein Keypad und ein Display bis zu 4 Zeiten und Temperaturen eingeben und speichern und das Programm dann entsprechend ablaufen lassen. Mein Problem ist jetzt das Speichern mehrstelliger Zahlenwerte. Ich müsste mit einem Platz je Wert im EEPROM hinkommen (alle Werte < 200), schaffe es aber nicht eine mehrstelligen Zahlenwert zu speichern (bspw. 120). Es kommt bei der AUsgabe dann immer nur der erste eingegebene Wert (bspw. 1) zurück.
Hat vielleicht jemand von euch hier einen Tipp, wie ich das ganze angehen kann. Über eure Hilfe würde ich mich riesig freuen!!

Schonmal vielen Dank und Grüße!!

Matthias

Willkommen im Forum!

Es ist schwierig zu helfen, wenn dein Sketch unbekannt ist - poste also deinen Sketch.

Was mir generell dazu einfällt:
Wenn die einzelnen Werte unter 255 sind, dann belegen die ohnehin nur ein Byte, das sollte ja kein Problem sein, passt ja in eine "EEPROM-Speicherzelle".

Es hängt ein wenig von der Arduino-IDE-Version ab, die du verwendest, aber bei neueren Versionen gibt es "Funktionen" die mit unterschiedlichen Datentypen "automatisch" umgehen können z.B. "Put" und "Get"

Hast du dir die Beispiele von EEPROM schon angesehen? https://www.arduino.cc/en/Tutorial/EEPROMGet

BrauerM:
ich habe ein kleines Problem ...

Glücklicherweise schlägst Du damit hier auf :slight_smile: Bei der Telekom gibt es keine kleinen Probleme.

Könntest Du den Sketch zeigen, der fehlerhaft ist?

Gruß

Gregor

Hei!

Also zuerst mal: schön, dass ihr Interesse an meinem "kleinen Problem" habt :-D. Den Sketch habe ich im Moment nicht zur Hand, kann ihn aber später nachreichen. Habt ihr schonmal ein ähnliches Problem gelöst und könnt ihr mir vielleicht sagen wie ihr die Sache angehen würdet??

Dein Projekt ist durchaus komplex.

Ich sehe da:
4x4 Keypad
ein Display
EEPROM - Speichern und Auslesen von Werten
Zeitschaltung für ein Kochfeld (möglicherweise 230 V AC - oh!)
Temperaturregelung

Wir wissen nicht welche Vorkenntnisse du hast (Elekrtonik, Programmieren etc.), ob das vielleicht dein erstes Projekt ist, wie weit du schon gekommen bist etc.

Grundsätzlich würde ich dieses Projekt in sehr kleine Schritte zerlegen. Also etwa:

  1. 4x4 Keypad zum laufen bringen und die eingetippten Zahlen erst mal nur seriell ausgeben
    wenn das funktioniert
  2. Zahlen am Display darstellen
  3. mich mit EEPROM lesen und schreiben auseinandersetzen
  4. mich mit Zeitschaltung / Regelung (Stichwore:Zweipunktregler und Hysterese) beschäftigen
    etc.
    Erst wenn alle Einzelschritte (Hardware und Software) befriedigend gelöst sind, würde ich beginnen diese Schritt für Schritt zusammenzufügen.

Dabei ist das EVA-Prinzip sehr sinnvoll.
Trenne folgende Bereiche in geeigneter Weise auf:
Eingabe
Verarbeitung
Ausgabe

Dadurch lässt sich Code modular aufbauen und es ist meist relativ leicht mehrere Module zusammenzufügen.

Hei uxomm,

dann bin ich garnicht mal auf einem schlechten Weg :smiley: . Ich habe alles bisher in kleine Einzelschritte aufgeteilt. Also erstmal den Temperatursensor auslesen und das Relais zum laufen bringen. Funktioniert soweit auch beides zusammen, also ab x°C schaltet das Relais ein und ab y°C wieder ab. Momentan ist ein kleiner Motor am Relais angeschlossen. Wenn es an die 230V geht, werde ich einen Profi dazu nehmen ;-). Das Display fehlt bisher noch, ist aber unterwegs. Dazu kommt später noch ein Rühwerk, das ebenfalls über das Relais eingeschaltet wird (zu Beginn des Kochvorgangs an, am Ende wieder aus).
Durch mein Studium (Maschinenbau) habe ich ein kleines bisschen was über E-Technik und auch Mess- & Regelungstechnik gehört. Bei Programmieren haperts bei mir allerdings noch ziemlich (aber das wird auch noch kommen). Mit Ardiuno habe ich schon etwas "herumgespielt". Ein größeres Projekt habe ich allerdings noch nicht realisiert...

schaffe es aber nicht eine mehrstelligen Zahlenwert zu speichern (bspw. 120). Es kommt bei der AUsgabe dann immer nur der erste eingegebene Wert (bspw. 1) zurück.

Wie kann das passieren wenn du die einzelnen Ziffern in einen einzigen Integer umrechnest? Klappt die Konvertierung schon nicht?

BrauerM:
...Habt ihr schonmal ein ähnliches Problem gelöst und könnt ihr mir vielleicht sagen wie ihr die Sache angehen würdet??

Meine aktuelle Baustelle enthält einige Komponenten, von denen jede „Neuland“ für mich war. Ich kenne Arduino bzw. die ATmegas 168/328 seit inzwischen drei Jahren und kenne immer noch vieles nicht.

Was ich aber aus Erfahrung mit meinem aktuellen Arduino-Spielzeug sagen kann:

Implementiere die Dinge nacheinander, wobei Du die einzelnen Komponenten so weit „fertig“ machst, wie es geht. Und räume zwischendurch immer wieder Deinen Code auf. Ich komme beim Kennenlernen der Dinge oft so in Fahrt, dass ich irre vieles teste, wobei ein ziemlich unordentlicher Code zustande kommen kann.
Um Übersichtlichkeit zu schaffen, fasse ich dann zusammen gehörende Dinge in einer Funktion bzw. Datei zusammen. Nachdem ich mein derzeitiges Gebastel so weit hatte, dass alles funktioniert, wie ich will, habe ich den Code in loop() aufgeräumt und so organisiert, dass loop() nur noch ein paar Zeilen hat und locker auf eine Textseite (am Schirm!) passt.
Vor jeder Änderung speichere ich meine Sketches in einer neuen Datei, die eine neue Versionsnummer bekommt. Je komplexer ein Vorhaben ist oder wird, desto wichtiger ist IMO die Versionierung. Ich habe schon mehrmals erlebt, dass ich mich bei einer Änderung/Ergänzung „verrannt“ habe und froh war, dass ich immer zur letzten funktionierenden Version zurück konnte.

HTH

Gregor

Nachtrag: Wenn ich etwas lerne, lege ich häufig Merkzettel an. Die Merkzettel der letzten Wochen habe ich neulich zu dem hier aufgeblasen. Vielleicht ist da etwas Nützliches für Dich dabei.

Hallo alle zusammen,

danke für eure Tipps!! Ich komme leider frühestens am Wochenende wieder an den Sketch. Dann werde ich alles mal nochmal zerpflücken und neu aufbauen und anschließend hier posten.

Bis dahin wünsch ich allen schöne Feiertage!!

Grüße,

Matthias

BrauerM:
... leider ...

Ja, es kann schon frustrierend sein, was einem durch Weihnachten versaut wird..

Gruß

Gregor

PS: Schöne Weihnachten!

Hei zusammen,

hoffe ihr habt die Feiertage gut überstanden!! Wie versprochen hier mein Sketch zur Keypad-Abfrage. Wäre super wenn ihr euch das mal ansehen könntet!! :slight_smile:

#include “Keypad.h”
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] =
{{‘1’,‘2’,‘3’,‘A’},
{‘4’,‘5’,‘6’,‘B’},
{‘7’,‘8’,‘9’,‘C’},
{’*’,‘0’,’#’,‘D’}};
byte rowPins[ROWS] = {5, 4, 3, 2};
byte colPins[COLS] = {9, 8, 7, 6};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

//Keypad starten

#include <EEPROM.h>

//EEPROM starten

int i=0;

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

// seriellen Monitor starten
}

void readKeypad()
{
char key = keypad.getKey();

if(key != NO_KEY)
{
switch(key)
{
case ‘A’:
case ‘B’:
case ‘C’:
case ‘D’:
Serial.println(“A, B, C oder D wurde gedrueckt!”);
i=0;

// Wenn ‘A’, ‘B’, ‘C’ oder ‘D’ gedrueckt wurde, Meldung auf dem seriellen Monitor ausgeben und i=0 setzen um, readKeypad-Funktion erneut drei mal zu durchlaufen

case ‘*’:
EEPROM.write(0, 0);
EEPROM.write(1, 0);
EEPROM.write(2, 0);
Serial.print(EEPROM.read(0));
Serial.print(EEPROM.read(1));
Serial.println(EEPROM.read(2));
i=0;

// Wenn ‘*’ gedrueckt wurde, die Stellen im EEPROM zu Null setzen, ‘000’ auf dem seriellen Monitor ausgeben und i=0 setzen, um readKeypad-Funktion erneut drei mal zu durchlaufen

case ‘1’:
case ‘2’:
case ‘3’:
case ‘4’:
case ‘5’:
case ‘6’:
case ‘7’:
case ‘8’:
case ‘9’:
case ‘0’:
EEPROM.write(i, key);

// Wenn eine Zahl gedrueckt wurde, die eingegebene Zahl an der i-ten Stelle im EEPROM speichern

}

}
}

void loop()
{
char key = keypad.getKey();

for(i=0; i<3; i++)
{
readKeypad();
}

if(key == ‘#’)
{
Serial.print(EEPROM.read(0)-48);
Serial.print(EEPROM.read(1)-48);
Serial.println(EEPROM.read(2)-48);

// Wenn ‘#’ gedrueckt wurde, die im EEPROM gespeicherten Zahlen im seriellen Monitor ausgeben

}

}

Nun zu den Problemen :-(.

Da das Programm die Funktionen ständig aufs Neue durchläuft, werden die eingegebenen Zahlen entweder garnicht geschrieben oder wahllos an eine der drei EEPROM stellen gesetzt. Ich weiss, dass es keine Möglichkeit gibt das Programm an einer bestimmten Stelle anzuhalten und auf die nächste Taste zu warten. Wie schaffe ich es dennoch die Zahlen an der richtigen Stelle abzulegen und dort zu belassen bis sie mit ‘*’ überschrieben werden oder bis alle drei vorgesehenen Stellen ausgefüllt sind und man weitere Zahlen eingibt. Hat jemand einen Tipp oder bin ich mit dem Sketch völlig auf dem Holzweg?!?

Grüße,

Matthias

Warum setzt du den Code nicht in Code-Tags?
So ist er sehr schlecht lesbar.

BrauerM:
... Wäre super wenn ihr euch das mal ansehen könntet!! ...

Wie HotSystems schon schrieb, ist der Code so sehr schlecht lesbar (was der Grund dafür ist, dass ich ihn mir nicht näher angeguckt habe).

Gruß

Gregor

Hallo nochmal!!

Ja habe das selbst grade gemerkt. Hoffe es ist jetzt besser. Das Problem hat sich aber grade erledigt. Kleiner Geistesblitz :wink: . Funktioniert soweit wie ich mir das vorstelle. Kann ich diesen Sketch jetzt so verwenden um die drei Werte im EEPROM als Zeitangabe (z.B. delay(EEPROM-Werte 1, 2 und 3)) zu verwenden??

Grüße,

Matthias

#include "Keypad.h"
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = 
{{'1','2','3','A'},
 {'4','5','6','B'},
 {'7','8','9','C'},
 {'*','0','#','D'}};
byte rowPins[ROWS] = {5, 4, 3, 2};
byte colPins[COLS] = {9, 8, 7, 6};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

//Keypad starten

#include <EEPROM.h>

//EEPROM-Pluigin starten

int i=0;

void setup()
{
  Serial.begin(9600);
  
  // seriellen Monitor starten
}


void readKeypad()
{
  char key = keypad.getKey();
      
  if(key != NO_KEY)
  {
      switch(key)
      {          
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case '0':
         EEPROM.write(i, key);
                  
        
        case '#':
        case 'A':
        case 'B':
        case 'C':
        case 'D':
         break;
         
         // Wenn eine Zahl gedrueckt wurde, die eingegebene Zahl an der i-ten Stelle im EEPROM speichern
         // Anderenfalls i um eins zurücksetzen um in der nächsten Runde wieder die gleiche EEPROM-Stell zu bedienen
        
        case '*':
         EEPROM.write(0, 0);
         EEPROM.write(1, 0);
         EEPROM.write(2, 0);
         Serial.print(EEPROM.read(0));
         Serial.print(EEPROM.read(1));
         Serial.println(EEPROM.read(2));
         i=i-1;
         
        
      }
  }
  
  else
  {
    i=i-1;
    
    // Wenn nichts gedrueckt wird, i um eins zurücksetzen um in der nächsten Runde wieder die gleiche EEPROM-Stell zu bedienen
  }
}


void loop()
{
  char key = keypad.getKey();
  
  for(i=0; i<3; i++)
  {
    readKeypad();
  }
  
  Serial.print(EEPROM.read(0)-48);
  Serial.print(EEPROM.read(1)-48);
  Serial.println(EEPROM.read(2)-48);
    
}

Oh je. Da hast du noch viel vor dir. Eeprom haben nur eine begrenzte Anzahl Schreibzyklen. Deswegen schreibt man da nie direkt rein. Man speichert die Daten in Variablen und schreibt dann diese ins Eeprom, wenn die Eingabe korrekt erfolgt ist.

Aber wenn das Projekt fertig ist, hast du bestimmt viel Spaß gehabt und noch mehr gelernt.

Hei,

ok das klingt soweit logisch. Aber wie kann ich die einzeln eingegebenen Werte in eine Variable bekommen?? Kann ich das zuerst in drei einzelne Variablen stecken, also für jeden Durchgang der if-Schleife eine neue Variable festlegen, die ich dann später zu einer zusammenfasse?

Gruß,

Matthias

Normal macht man Variable = Variable * 10 + neue Ziffer

z.B. 243

1.) Variable = 0, Eingabe = 2
→ Variable = 10 * 0 + 2 = 2

2.) Variable = 2, Eingabe = 4
→ Variable = 10 * 2 + 4 = 24

3.) Variable = 24, Eingabe = 3
→ Variable = 10 * 24 + 3 = 243

BrauerM:
Ja habe das selbst grade gemerkt. Hoffe es ist jetzt besser. Das Problem hat sich aber grade erledigt. Kleiner Geistesblitz :wink: . Funktioniert soweit wie ich mir das vorstelle. Kann ich diesen Sketch jetzt so verwenden um die drei Werte im EEPROM als Zeitangabe (z.B. delay(EEPROM-Werte 1, 2 und 3)) zu verwenden??

Wieso Zeitangabe und wofür. Ich sehe kein RTC.
Und delay solltest du sowieso nicht im Sketch verwenden.

Ich glaube bei diesen Fragen ist es Zeit, dir einfach mal mitzuteilen, dass du dir unbedingt die Grundlagen genauer durchlesen solltest.
Die Basics sind ein unbedingtes Muss für dass programmieren mit dem Arduino.

Ich würde keine Zahlen einlesen, sondern char array, und nach jedem Zeichen dieses ins array eintragen, den Index inkrementieren und eine '0' reinschreiben. Dann z.B. mit * zurück (index--) und mit '0' die Stelle löschen, mit # beenden und weiterverarbeiten. Zwischendurch kann man das array ja immer zur Kontrolle aufs LCD ausgeben.
Das ganze natürlich blockierungsfrei.