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? Danke an alle.
Daniel E. schrieb: > 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.
Stefan F. schrieb: > 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 ...
Stefan F. schrieb: > Ja ist korrekt. Nein ist sie nicht. Daniel E. schrieb: > EEPROM.get(addr, value); Da werden keine Values übergeben, sondern Referenzen auf Variablen. Daniel E. schrieb: > Falls eine weitere Zahl geschrieben > werden soll, müsste ich dann mit Speicherstelle 4 weiter machen. Das ist zawr richtig, aber dennoch eine gute Idee. Lass den Kompiler rechnen. Der ist da zuverlässiger als ein Mensch. Jens G. schrieb: > Er muß sich nur > noch entscheiden, welche Endianness er umsetzen will (little/big > endianness). Wenn him get und put verwendet, ist die Sache schon mal viel klarer, als du sie hier darstellst. Jens G. schrieb: > er will die Bytes aller Zahlen entsprechend ihrer > auf-/absteigenden Endianness bzw. Wertigkeit sequentiell im Speicher > ablegen, Nein, er möchte Long lesen und schreiben. Und genau das kann get und put Für Byte gibt es z.B. read write update und den Array Access. Und natürlich wäre ein testbares Beispiel das Mittel der Wahl hier.
:
Bearbeitet durch User
Adressvergabe übernimmt Compiler/Linker
1 | #include <EEPROM.h> |
2 | #include <Streaming.h> // die Lib findest du selber ;-) |
3 | Print &cout = Serial; // cout Emulation für "Arme" |
4 | |
5 | |
6 | // Arduino erstellt *.eep Datei
|
7 | unsigned long resetCount EEMEM {0}; |
8 | unsigned long wasAnderes EEMEM {4711}; |
9 | |
10 | byte test EEMEM {42}; // noch ein byte reset Counter |
11 | |
12 | |
13 | void setup() |
14 | {
|
15 | Serial.begin(9600); |
16 | cout << F("Start: ") << F(__FILE__) << endl; |
17 | |
18 | unsigned long resetCount {0}; |
19 | EEPROM.get(int(&::resetCount),resetCount); // read |
20 | ++resetCount; // modify |
21 | EEPROM.put(int(&::resetCount),resetCount); // write |
22 | |
23 | cout << F("resetCount: ") << resetCount << endl; |
24 | |
25 | // read modify write und ausgabe in einer Zeile
|
26 | cout << F("test: ") << ++EEPROM[int(&test)] << endl; |
27 | }
|
28 | |
29 | void loop() |
30 | {
|
31 | |
32 | }
|
Arduino F. schrieb: > Das ist zawr richtig, aber dennoch eine gute Idee. Da fehlt leider ein 'k' > Das ist zwar richtig, aber dennoch keine gute Idee.
:
Bearbeitet durch User
Hallo und Danke für das zahlreiche Feedback. Meinen Code muss ich noch mal ordnungsgemäß hier einstellen… Danke erstmal
:
Bearbeitet durch User
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 | long Wegstrecke = 2100000000; //-2.147.483.648 bis +2147483648. Ein Long benötigt 32 Bits/4 Bytes Speicherplatz |
4 | byte Adresse = 0; // 0 bis 255 |
5 | bool Zahl =0; |
6 | |
7 | void setup() |
8 | {
|
9 | // put your setup code here, to run once:
|
10 | }
|
11 | |
12 | void loop() |
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. |
19 | Wegstrecke ++; |
20 | Wegstrecke ++; |
21 | Wegstrecke ++; |
22 | Wegstrecke ++; |
23 | Wegstrecke ++; |
24 | EEPROM.put(Adresse, Wegstrecke); |
25 | Zahl = 1; |
26 | }
|
27 | }
|
[Mod: C-Code in C-Tags verpackt]
:
Bearbeitet durch Moderator
Daniel E. schrieb: > Wegstrecke ++; > Wegstrecke ++; > Wegstrecke ++; > Wegstrecke ++; > Wegstrecke ++; Wegstrecke += 5;
:
Bearbeitet durch User
Daniel E. schrieb: > Meinen Code muss ich noch mal ordnungsgemäß hier einstellen… Bist seit neun Jahren hier angemeldet und schaffst es nicht deinen Code in entsprechende Code-Tags einzurahmen?
Daniel E. schrieb: > 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. LG, Sebastian
:
Bearbeitet durch User
> 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; } } >
:
Bearbeitet durch User
Falsche Formatierung! Steht ja gleich obendran wie's geht! Gruss Chregu
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.
Daniel E. schrieb: > ich Probier mich mal hier Das hat nicht geklappt. 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.
:
Bearbeitet durch Moderator
Peter D. schrieb: > 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.
Beitrag #7513527 wurde vom Autor gelöscht.
Test 🙃
1 | #include <EEPROM.h> |
2 | long Wegstrecke = 2100000000; //-2.147.483.648 bis +2147483648. Ein Long benötigt 32 Bits/4 Bytes Speicherplatz |
3 | byte Adresse = 0; // 0 bis 255 |
4 | bool Zahl =0; |
5 | void setup() |
6 | {
|
7 | // put your setup code here, to run once:
|
8 | }
|
Got it 👍
:
Bearbeitet durch User
Noch eine „blöde Frage“ 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 🙈 Dankeschön
Daniel E. schrieb: > oder wird mit dem zweiten Programm der Eeprom Inhalt > verändert? Die EESAVE Fuse bestimmt, ob ein ChipErase das EEPROM löscht. Ansonsten bleibt der Inhalt erhalten! Damit die Konsistenz erhalten bleibt, geht die von mir vorgeschlagene Variante nicht zuverlässig, da der Linker die Adressen würfeln darf. Alternativ: Alle EEPROM Daten in eine Struktur stopfen und entweder in einem Rumms lesen, oder per offsetof() einzelne Daten.
Daniel E. schrieb: > So wie es es bisher verstanden habe, brauch ich mir bei dem Befehl > "fast" einerlei Gedanken machen bezüglich der Speicherplatzverwaltung. Naja, du musst sie halt komplett selber machen.
Peter D. schrieb: > 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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.