Go Down

Topic: EEPROM-Tutorital verwirrt (Read 2125 times) previous topic - next topic

Fipsi

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:

Quote
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
Funktioniert bei mir was nicht, dann liegt es an dem Teil, den ich sowieso nicht versteh ;)

JuergenR

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

Fipsi

#2
May 03, 2014, 10:55 am Last Edit: May 03, 2014, 10:58 am by Fipsi Reason: 1
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..?
Funktioniert bei mir was nicht, dann liegt es an dem Teil, den ich sowieso nicht versteh ;)

volvodani

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
"Komm wir essen Opa!" - Satzzeichen retten Leben!

Fipsi

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?
Funktioniert bei mir was nicht, dann liegt es an dem Teil, den ich sowieso nicht versteh ;)

JuergenR

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

Fipsi

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
Funktioniert bei mir was nicht, dann liegt es an dem Teil, den ich sowieso nicht versteh ;)

JuergenR

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

guntherb


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:

Code: [Select]

#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.
Grüße
Gunther

Fipsi

Ä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:

Code: [Select]
#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
Funktioniert bei mir was nicht, dann liegt es an dem Teil, den ich sowieso nicht versteh ;)

guntherb


Ä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.

Quote
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); "

Quote
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.
Grüße
Gunther

Go Up