Hallo in die Runde,
ich beschäftige mich grad mit dem EEPROM vom Arduino Mega2560.
Es gibt ja den Befehl:
EEPROM.get(addr, value);
EEPROM.get(addr, value);
So wie es es bisher verstanden habe, brauch ich mir bei dem Befehl "fast" einerlei Gedanken machen bezüglich der Speicherplatzverwaltung. Mein plan wäre eine long Zahl (4 Byte) in den EEPROm zu schreiben und zu lesen.
Damit würde ich bei einer Zahl bei Speicherstelle 0 anfangen und in der Theorie bei Speichertstelle 3 enden. Falls eine weitere Zahl geschrieben werden soll, müsste ich dann mit Speicherstelle 4 weiter machen. Ist das so korrekt wie ich es verstanden habe?
Ein konkretes Codebeispiel wäre besser, weil deine Aussagen
Interpretations-spielraum lassen. Wenn du es so gedacht hast, wie ich dich verstehe, dann lautet die Antwort: Ja ist korrekt.
Ein konkretes Codebeispiel wäre besser, weil deine Aussagen
Interpretations-spielraum lassen.
Was wäre denn hier falsch interpretierbar? Ist doch eigentlich alles klar - er will die Bytes aller Zahlen entsprechend ihrer auf-/absteigenden Endianness bzw. Wertigkeit sequentiell im Speicher ablegen, und alle 4 Bytes kommt die nächste Zahl dran. Er muß sich nur noch entscheiden, welche Endianness er umsetzen will (little/big endianness).
Also ja, richtig verstanden ...
Hallo und nochmal Danke für das zahlreiche Feedback.
Es wurde nach Code verlangt..
In diesem Progrämmlein wird nach jedem Neustart eine Zahl um +5 höher als vorher angezeigt. Außer beim ersten Mal, da wird 0 angezeigt, da der EEPROM Inhalt leer ist.
Korrekt ?
Leider hab ich keinen Arduino hier zum grad mal schnell testen.
Danke.
1
#include<EEPROM.h>
2
3
longWegstrecke=2100000000;//-2.147.483.648 bis +2147483648. Ein Long benötigt 32 Bits/4 Bytes Speicherplatz
4
byteAdresse=0;// 0 bis 255
5
boolZahl=0;
6
7
voidsetup()
8
{
9
// put your setup code here, to run once:
10
}
11
12
voidloop()
13
{
14
15
if(Zahl==0)
16
{
17
EEPROM.get(Adresse,Wegstrecke);
18
Serial.println(Wegstrecke);//nach den ersten Mal wir hier 0 angezeigt, dann später 2100000005 usw.
In diesem Progrämmlein wird nach jedem Neustart eine Zahl um +5 höher
als vorher angezeigt. Außer beim ersten Mal, da wird 0 angezeigt, da der
EEPROM Inhalt leer ist.
Korrekt ?
Leeres bzw. gelöschtes Eeprom enthält 0xFF. Also wird wohl beim ersten Mal -1 angezeigt.
Bei dir ist die Adresse vom Typ byte. Das funktioniert nur für den vorderen Bereich des Eeproms. Der Atmega2560 hat 4K Eeprom, die Adressen laufen also bis 4095.
Die Größe einer Variablen in byte liefert sizeof(). Damit kannst du die die Adressen deiner Daten im Eeprom ausrechnen anstatt sie hart zu codieren. Oder du benutzt, noch eleganter, das EEMEM-Konstrukt des gcc wie oben von arduinof schon beschrieben.
Bist seit neun Jahren hier angemeldet und schaffst es nicht
deinen Code in entsprechende Code-Tags einzurahmen?
Ja, leider nicht aber ich Probier mich mal hier
<
#include <EEPROM.h>
long Wegstrecke = 2100000000; //-2.147.483.648 bis +2147483648. Ein Long benötigt 32 Bits/4 Bytes Speicherplatz
byte Adresse = 0; // 0 bis 255
bool Zahl =0;
void setup()
{
// put your setup code here, to run once:
}
void loop()
{
if (Zahl == 0)
{
EEPROM.get(Adresse, Wegstrecke);
Serial.println(Wegstrecke); //nach den ersten Mal wir hier 0 angezeigt, dann später 2100000005 usw.
Wegstrecke ++;
Wegstrecke ++;
Wegstrecke ++;
Wegstrecke ++;
Wegstrecke ++;
EEPROM.put(Adresse, Wegstrecke);
Zahl = 1;
}
}
Ich vermeide es prinzipiell von überall her auf den EEPROM zuzugreifen.
Ein einziges long zu schreiben, kostet auf dem AVR schon 32ms, das ist aus CPU-Sicht eine elend lange Zeit. Und wenn dabei die Spannung absackt, ist der Wert ungültig.
Ich lege daher alle zu speichernden Variablen im RAM in einer Struct an und arbeite nur darauf. Und wenn dann die Struct gespeichert werden soll, erfolgt das per Polling oder Interrupt im Hintergrund, d.h. keine CPU-Zeit wird verwartet.
Damit die Daten als gültig erkannt werden, kommt noch eine CRC16 dran. Entweder wird bei ungültiger CRC die Werksinitialisierung des RAM behalten oder noch eine 2. Kopie auf gültige CRC geprüft.
RAM-Variablen lassen sich ja ganz einfach vorbelegen. Bei EEPROM-Variablen kann das aber recht knifflig werden.
Der Hinweis, wie es geht, steht immer oberhalb des Textfeldes, in welchem Du einen neuen Beitrag erfasst. Ich habe mal einen Screenshot davon angefügt.
P.S.
Im zweiten Screenshot siehst Du, wie Dein C-Code auf Mobilgeräten aussieht, wenn Du keine C-Tags verwendest.
Ich vermeide es prinzipiell von überall her auf den EEPROM zuzugreifen.
Ein einziges long zu schreiben, kostet auf dem AVR schon 32ms, das ist
aus CPU-Sicht eine elend lange Zeit. Und wenn dabei die Spannung
absackt, ist der Wert ungültig.
Ich lege daher alle zu speichernden Variablen im RAM in einer Struct an
und arbeite nur darauf. Und wenn dann die Struct gespeichert werden
soll, erfolgt das per Polling oder Interrupt im Hintergrund, d.h. keine
CPU-Zeit wird verwartet.
Damit die Daten als gültig erkannt werden, kommt noch eine CRC16 dran.
Entweder wird bei ungültiger CRC die Werksinitialisierung des RAM
behalten oder noch eine 2. Kopie auf gültige CRC geprüft.
RAM-Variablen lassen sich ja ganz einfach vorbelegen. Bei
EEPROM-Variablen kann das aber recht knifflig werden.
Danke für das Feedback. Plan ist den km vom Tacho der Simme bei Zündung oder der Motor wird ausgemacht 1x zu schreiben. Dazu soll über einen analog Eingang die Spannung (12 V) überwacht werden und bei unter X V wird er Wert 1x geschrieben. Hierzu wird Controller und Display entkoppelt und mit genügend Kondensatoren am uC dafür gesorgt, dass die Spannung hält bis das Schreiben abgeschlossen ist. So der Plan.
kann ich mit Program/Sketch X in den Eeprom Speicher 0 = 100 erstmals Schreiben und mit dem 2. Programm/Sketch Y was ich übertrage dann die 100 auslesen oder wird mit dem zweiten Programm der Eeprom Inhalt verändert?
Sollte eigentlich nicht so sein … ich frage aber trotzdem mal 🙈
Ich vermeide es prinzipiell von überall her auf den EEPROM zuzugreifen.
Ein einziges long zu schreiben, kostet auf dem AVR schon 32ms, das ist
aus CPU-Sicht eine elend lange Zeit. Und wenn dabei die Spannung
absackt, ist der Wert ungültig.
Ich lege daher alle zu speichernden Variablen im RAM in einer Struct an
und arbeite nur darauf. Und wenn dann die Struct gespeichert werden
soll, erfolgt das per Polling oder Interrupt im Hintergrund, d.h. keine
CPU-Zeit wird verwartet.
Damit die Daten als gültig erkannt werden, kommt noch eine CRC16 dran.
Ein absolut sinnvolles Vorgehen.
Kann man Richtung "fail safe" noch etwas aufblasen, aber das ist dann sehr oft unter dem Aspekt der konkreten Anwendung bzw. des konkreten Wertes dieser Anwendung zu sehen. Sprich: das läßt sich nicht wirklich abstrahieren.