EEPROM-Tutorital verwirrt

Hallo zusammen,

ich hab heute jetzt mal angefangen, die Code's für mein Projekt zusammen zu basteln. Ich bin gerade beim EEPROM und jetzt ein wenig verwirrt:

value: the value to write, from 0 to 255 (byte)

Heißt das jetzt, dass ich in eine Adresse eine Zahl von 0 bis 255 eintragen kann, oder ist das die Bit-"Verschlüsselung" für den ASCII- oder sonst einen Code?
Es geht darum, dass ich im EEPROM eine dreistellige Zahl speichern muss. Krieg ich die in eine Adresse? Oder brauch ich da eben 3 dafür?

Danke schonmal

LG

Fipsi

Hallo Fipsi,
Die Daten werden Byte-weise adressiert. Also pro Adresse 1 Byte - also Wertebereich 0-255.
Wenn Du Werte hast die größer 255 sind brauchst Du 2 Byte - dann geht 0-65535.

Grüße,
Jürgen

Also für die dreistellige Zahl benötige ich dann also drei Adressen. Und wie kann ich die dann zusammen fügen, dass aus drei wieder eine Zahl wird, bzw. wie kann ich die splitten?

Edit: Ach ne, schmarn.. also wenn meine drei Zahlen unter 255 bleiben, bekomm ich's in eine Adresse, oder..?

Wenn sie zwischen 0-255 liegt in ein Byte ansonsten musst du sie auseinander nehmen in Highbyte und Lowbyte.
In der Reference sind beide Begriffe beschrieben.
In das Eeprom sind pro Adresse nur 8 Bits zu speichern. Also 11111111 Bin FF in Hex öd eben 255 in Dez.
Gruß
DerDani

Okay.. also die Zahlen werden unter 255 bleiben, also bekomm ich die in eine Adresse rein.

Und das gibt dann auch keine Probleme, wenn ich die dreistellige Zahl am Display ausgeben will? Bzw. wenn ich über eine Tastatur die drei Ziffern eingegeben hab und dann im EEPROM steichern will?

Du musst die Werte halt entsprechend umwandeln.
Bzw bei der Ausgabe auf ein LCD macht dies die LCD-Library.

Kannst du mir bitte kurz erklären, wie das geht?

Also ich hab ne Tastatur-matrix, über die die Zahlen eingegeben werden können. Die stehen dann in ner variable und werden gleichzeitig auf dem Display ausgegeben werden. Über einen Serial-Befehl soll diese Nummer dann im EEPROM gespeichert werden.
Standardmäßig ist diese Zahl Null bei der Eingabe. Falls jedoch im EEPROM schon was gespeichert ist, soll diese Nummer vom Display ausgegeben und in der Variable gespeichert werden.

LG

Fipsi

Wie werden die Zahlen denn nach der Eingabe gespeichert?
Jede Stelle in einem Byte?
Oder werden sie umgerechnet?

Fipsi:
Also für die dreistellige Zahl benötige ich dann also drei Adressen. Und wie kann ich die dann zusammen fügen, dass aus drei wieder eine Zahl wird, bzw. wie kann ich die splitten?

Mit zwei einfachen Funktionen:

#include <EEPROM.h>
long Testvar1 = 123456;
const int Testvar1Adr = 0;
const int Testvar1Size = 4;
long Testvar2 = 7891011;
const int Testvar2Adr = 4;
const int Testvar2Size = 4;

void setup(){  
  Serial.begin(115200);  
Serial.println("Testvar1");
Serial.println(Testvar1);
EEPromSave((byte*) &Testvar1 , Testvar1Size,  Testvar1Adr );
Testvar1 = 99;
Serial.println(Testvar1);
EEPromLoad((byte*) &Testvar1 , Testvar1Size,  Testvar1Adr  ); 
Serial.println(Testvar1);
Serial.println("Testvar2");
Serial.println(Testvar2);
EEPromSave((byte*) &Testvar2 , Testvar2Size,  Testvar2Adr );
Testvar2 = -5;
Serial.println(Testvar2);
EEPromLoad((byte*) &Testvar2 , Testvar2Size,  Testvar2Adr  ); 
Serial.println(Testvar2);
}

void loop(){
}


/*******************************************************************************************
** Funktion EEPRomSave                                                                    **
** Schreibt die übergebene Variable ins EEProm                                            **
** input:                                                                                 **
**   wert: pointer to byte array which holds the value to save                            **
**   numbytes: number of bytes to be saved                                                **
**   eprom_offset: offset in EEPROM for saving bytes                                      **
** output: void (nothing)                                                                 **
*******************************************************************************************/
void EEPromSave(byte* wert, int numbytes, int eprom_offset)
{
  for (int i=0;i<numbytes;i++)
    EEPROM.write(eprom_offset+i, wert[i]);
}// end of funkion EEPromSave



/*******************************************************************************************
** Funktion EEPRomLoad                                                                    **
** holt  die übergebene Variable aus dem EEProm                                            **
** input:                                                                                 **
**   wert: pointer to byte array which holds the value to save                            **
**   numbytes: number of bytes to be saved                                                **
**   eprom_offset: offset in EEPROM for saving bytes                                      **
** output: void (nothing)                                                                 **
*******************************************************************************************/
void EEPromLoad(byte* wert, int numbytes, int eprom_offset)
{
  for (int i=0;i<numbytes;i++)
    wert[i] = EEPROM.read(eprom_offset+i);
}// end of funkion EEPromLoad

Du kannst auch mit Sizeof() arbeiten anstatt die Größe im Code festzulegen, aber bei viele Variablen ist das so einfacher, da du gleich einen Überblick hast, wo welche Variable liegt.

Äh... ja.. das sah im Tutorital jetzt ein wenig einfacher aus.

Hab jetzt ehrlich gesagt keine Ahnung, was genau ich mit diesem Code machen soll, wie ich ihn an meinen anpass.

Bei mir siehts in etwa so aus:

#include <EEPROM.h>

int scheibe_num = 0;
int befehl_status = 0;
[...]
void setup()
{
  if (scheibe_num == 0)
  {
    scheibe_num = EEPROM.read(1);
  }
  
  Serial.begin(9600);
}

void loop()
{
   char key = kpd.getKey();
  
  if (Serial.available())
  {
     befehl_status = Serial.read();
  }
  
  if (befehl_status == 1)
  {
    int befehl_2 = Serial.read();
     if (befehl_2 == 1)
     {
       lcd.clear();
       lcd.backlight();
       lcd.setCursor(0,0);
       lcd.print('Scheibe:');
       lcd.setCursor(0,1);
       lcd.print(scheibe_num_1);
       lcd.setCursor(1,1);
       lcd.print(scheibe_num_2);
       lcd.setCursor(2,1);
       lcd.print(scheibe_num_3);
       lcd.setCursor(scheibe_num_stelle - 1,1);
       
       if (key)
       {
         if ((key =>0) && (key =< 9))
         {
           if (scheibe_num_stelle == 1)
           {
             scheibe_num = key*100;
             lcd.setCursor(1,1);
           } else if (scheibe_num_stelle == 2) {
             scheibe_num = scheibe_num + key*10;
             lcd.setCursor(2,1);
           } else if (scheibe_num_stelle == 3) {
             scheibe_num = scheibe_num + key;
           }
         } else if (key == "Cl") {
                      if (scheibe_num_stelle == 1)
           {
             scheibe_num = scheibe_num - (key*100);
             lcd.setCursor(0,1);
             lcd.print(' ');
           } else if (scheibe_num_stelle == 2) {
             scheibe_num = scheibe_num - (key*10);
             lcd.setCursor(1,1);
             lcd.print(' ');
           } else if (scheibe_num_stelle == 3) {
             scheibe_num = scheibe_num - key;
             lcd.setCursor(2,1);
             lcd.print(' ');
           }
         }
         
       }
     }
     else if (befehl_2 == 2)
     {
       EEPROM.write(scheibe_num,1);
     }
  }

So in ungefähr soll es etwa ausschauen. Ob das jetzt so funktioniert, weiß ich auch nicht ganz, da ich auch auf n paar Bauteile warten muss, dass ich meine Platinen fertig löten und ausprobieren kann.

LG

Fipsi

Fipsi:
Äh... ja.. das sah im Tutorital jetzt ein wenig einfacher aus.

Das sieht nur so aufwändig aus, weil ich gleich einen ganzen Testsketch mitgeliefert habe.

Du hast in deinem Code ein Problem:
die Variable "scheibe_num" ist integer und damit 2 Bytes lang.

Der Befehl "EEPROM.write(scheibe_num,1);" funktioniert also nur, wenn scheibe_num < 256 ist.

Hab jetzt ehrlich gesagt keine Ahnung, was genau ich mit diesem Code machen soll, wie ich ihn an meinen anpass.

ganz einfach:

du hängst unten an deinen Sketch die Funktionsdeklarationen für "EEPRomSave()" und "EEPRomLoad()" dran.
Und schreibst du anstatt "scheibe_num = EEPROM.read(1);" einfach
EEPromLoad((byte*) &scheibe_num, 2, 1);
Und anstatt "EEPROM.write(scheibe_num,1);" einfach
EEPromSave((byte*) &scheibe_num, 2, 1);

Es funktioniert wie vorher, nur werden jetzt beide Bytes der Variablen scheibe_num geschrieben und gelesen. Also auch wenn scheibe_num den Wert 2000 hat, wird der Wert korrekt gespeichert und gelesen.

Das einzige, was du beachten mußt: du hast ja nun 2 Bytes im EEProm belegt. Wenn du noch eine Variable ablegen willst, dann muß die Adresse 2 byte höher sein, also z.B. "EEPromSave((byte*) &befehl_status, 2, 3); "

So in ungefähr soll es etwa ausschauen. Ob das jetzt so funktioniert, weiß ich auch nicht ganz, da ich auch auf n paar Bauteile warten muss, dass ich meine Platinen fertig löten und ausprobieren kann.

Nur 3 Sachen:
a) Wenn du im Serial-Monitor eine "1" eintipst, dann bekommst du eine "49" geliefert, den ASCII-Code für "1"
b) Beim 2. Serial.read() fragst du vorher nicht ab, ob ein Zeichen da ist.
c) lcd.clear() sollte man nur ausführen, wenn es sein muß. Wenn es ständig ausführt wird, dann flackert das Display fürchterlich.