Forum: Mikrocontroller und Digitale Elektronik Arduino C-Classe EEprom endurance, wie am besten ?


von Chris S. (schris)


Lesenswert?

Wie implementiert man am einfachsten in C++ eine Klasse welche EEprom 
Endurance macht ohne richtig bloated zu sein ? Siehe unten.
Hier die etwas groessere Beschreibung, einfach runterscrollen zu
-----------------------------------------------------------------
Hallo, ich habe eine Applikation, einen Flowmeter welcher von einem 
Generator die Kraftstoffmenge anzeigt und loggt. Der Code ist von 
Internet runtergeladend und modifiziert, Flow Meter using 4-Digit 
7-segment Display 
von Circuits4you.com . Daten werden zusaetzlich ins EEprom geloggt, als 
circular buffer und dabei muss der Index jedesmal geupdated werden.
Was ich habe,fuer den Index, also im Prinzip ein Write jede 2 Stunden.
1
#define ENDURANCE_5m    24                                                                                            #define ENDURANCE_20m    6                                                                                            #define ENDURANCE_1h     2                                                                                            #define ENDURANCE_1d     1                                                                                            #define ENDURANCE_DATA  33      // total
Im Ram habe ich einen Log von 1 Minuten Inteval fuer eine Stunde und
danach 8 Stunden im 15 Minuten Interval.
Hingegen Im Eeprom:
 4 Stunden im 5Minuten Interval, danach
20 Stunden im 20 Minuten Interval, danach
 9 Tage im 1 Stunden Interval , danach
92 Tage im 24 Stunden Interval.
Zweck der Sache ist das Logging und optimierung des Verbrauchs eines 
Generators zur Unterstuetzung einer Off-Grid Solaranlage.
Geloggt werden 16bit Variablen, Einheit ml , bzw ml/25 bei 24Stunden 
Eintraegen, was 40ml gleichkommt, angezeigt wird lt/h im Display.
1
------------------------------------------------------------------
Zur Erklaerung,
ee(uint addr) sowie ee_(uint addr) sind einfach
~eeprom_read_byte((unsigned char*)addr); und ee_() ist das write,
bei leerem EEprom (0xff) wird 0 zurueckgeliefert. und ein 0 resultiert 
in 0xff.
C code zu eeprom endurance:
1
NOINLINE byte ee_idx_byte(word start, byte cnt) {       // 0=illegal or unitialized                                           byte i,t,ret; word j;                                                                                                 ret=-1;                                                                                                               for(i=0;i<cnt;i++)                                                                                                            if(t=ee(start++)) ret=i; else break;                                                                          return ret;                                                                                                   }                                                                                                                     NOINLINE byte ee_get_byte(word start, byte cnt) {       // 0=illegal or unitialized                                           byte i;                                                                                                               i=ee_idx_byte(start,cnt);                                                                                             if(i==-1) return ~0;                                                                                                  cnt=ee(start+i);                                                                                                      if(!cnt) cnt--;                                                                                                       return ret;                                                                                                   }                                                                                                                     NOINLINE void ee_set_byte(word start, byte cnt, byte val) {     // 0=illegal !!                                               byte i; word j,t,ret;                                                                                                 i=ee_idx_byte(start,cnt);                                                                                             if(i==--cnt) for(i=cnt;i--;ee_(start+i,0));                                                                           ee_(start + ++i,val);                                                                                         }
Ich habe aehnlichen Code fuer 16bit variable.
Nun moechte ich in Arduino einfach eine Classe haben , wo ich sage
EE_Endurance_byte  idx_5m(ENDURANCE_START,24);
und dann einfach idx_5m sowie idx_5m++ oder idx_5m=idx_5m+1 verwenden 
kann,
ohne dass mir die Klasse zuviel Ram und Flash hernimmt, was fuer einen 
Ansatz wuerdet ihr da nehmen oder koennt ihr mir Beispiele geben wie 
dies einfach gemacht werden koennte. Ich habe RingEEprom angesehen, aber 
das ist mir zuviel.
Danke im Voraus.

von Sherlock 🕵🏽‍♂️ (rubbel-die-katz)


Lesenswert?

Ich würde FRAM benutzen

von Frank K. (fchk)


Lesenswert?


von Chris S. (schris)


Lesenswert?

Eeorom ist bereits vorhanden und es funktioniert, nur sind es etliche 
und undurchsichtige define welche generell durch eine Classe, wenn man 
wüsste wie, (bin eben kein besserer cpp Programmierer) einfacher und 
übersichtlicher gemacht werden könnte, vielleicht auch optional 
selbständig EEPROM Verwaltung bei mehreren Variablen dieser Art.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Chris S. schrieb:
> was fuer einen
> Ansatz wuerdet ihr da nehmen oder koennt ihr mir Beispiele geben wie
> dies einfach gemacht werden koennte.

Schaue dir doch mal die Arduino Klasse an!
https://github.com/arduino/ArduinoCore-avr/blob/master/libraries/EEPROM/src/EEPROM.h

: Bearbeitet durch User
von Chris S. (schris)


Lesenswert?

Danke, damit komme ich weiter. Wieso habe ich nicht selbst daran 
gedacht,
vielen Dank.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Chris S. schrieb:
> Wie implementiert man am einfachsten in C++ eine Klasse welche EEprom
> Endurance macht ohne richtig bloated zu sein ?
Mal ehrlich: ich bin technisch nicht ganz unbeleckt und war beim 
Studienabschluss einer der besten im Semester, aber deine Beschreibung 
kann ich nicht in ein reales Problem umsetzen.

Was ist denn die grundlegende Aufgabe?

Chris S. schrieb:
> Zweck der Sache ist das Logging und optimierung des Verbrauchs eines
> Generators
Du willst eigentlich nur den Verbrauch des Generators speichern?

Chris S. schrieb:
> Im Ram habe ich einen Log von 1 Minuten Inteval fuer eine Stunde und
> danach 8 Stunden im 15 Minuten Interval.
> Hingegen Im Eeprom:
> 4 Stunden im 5Minuten Interval, danach
> 20 Stunden im 20 Minuten Interval, danach
> 9 Tage im 1 Stunden Interval , danach
> 92 Tage im 24 Stunden Interval.
Irgendwie höllisch umständlich...

Warum loggst du nicht einfach alle 5 Minuten diese Milliliter als 
unsigned long ins EEPROM? Da passen dann 4294967295 ml = 4294967,295 
Liter in diese 4 Bytes.

Wenn du diesen Wert dann alle 5 Minuten ins EEPROM speicherst und das 
EEPROM nur 100.000 Schreibzyklen hat, dann überlebt das EEPROM schon mal 
ohne was zu tun ein ganzes Jahr. Wenn du dann noch einen simplen 
Ringpuffer mit 32 Worten machst, dann überlebt das EEPROM 32 Jahre.

Und wenn das unbekannte EEPROM eher zeitgemäße 1 Mio Speicherzyklen hat, 
dann hält es mit dem 32 Byte Ringpuffer sogar bei einer Speicherung jede 
Minute über 60 Jahre...

Und ich würde dann zusätzlich noch einen etwas größeren Elko vor den µC 
stezen und den Wert einfach nur beim Powerfail speichern. Dann würde 1 
EEPROM-Zelle für viele tausend Jahre reichen.

: Bearbeitet durch Moderator
von Falk B. (falk)


Lesenswert?

Lothar M. schrieb:
> Und ich würde dann zusätzlich noch einen etwas größeren Elko vor den µC
> stezen und den Wert einfach nur beim Powerfail speichern. Dann würde 1
> EEPROM-Zelle für viele tausend Jahre reichen.

NEIN! Dann wäre es doch viel zu einfach und unsere ADHS geschädigten 
Hipster-Coder könnten nicht wochenlang an einer hochkomplexen, 
fehleranfälligen "Lösung" arbeiten!

von Chris S. (schris)


Lesenswert?

Zugrundeliegende Aufgabe: Messung und Logging eines Generators welcher 
die Batterie einer Offgrid Solaranlage aufladen soll in Zeiten wenn die 
Solaranlage es nicht schafft.
Auch sollte herausgefunden werden bis zu welcher Ladespannung der 
Generator effizient ist. Die Schaltung wird am Generator fix verbaut und 
bleibt dort als Anzeige von lt/h Momentanverbrauch.
Ja, der Code ist etwas komplexer da das interne EEPROM verwendet werden 
sollte, und 2Monate Logging sein sollten.
Der Generator geht so 3-4 Stunden am Stück. Es ist ein Haus wo man 
evaluieren will wie man am besten die Anlage erweitert.

von Falk B. (falk)


Lesenswert?

Hipstergefasel. Lothar hat alle sinnvollen Optionen nahezu idiotensicher 
beschrieben. Im Zeitalter der Terabyte-Micro-SD Karten was von "nur 
interner EEPROM" zu faseln ist grenzdebil. Ich höre immer wieder, vor 
allem von Softwerkern, "Hardware kostet nix". Stimmt leider und zum 
Glück. Also NIMM passende, SPOTTBILLIGE Hardware, schreib die Daten 
einfach rein und fertig!

KISS!

https://de.wikipedia.org/wiki/KISS-Prinzip

von Rainer W. (rawi)


Lesenswert?

Lothar M. schrieb:
> Mal ehrlich: ich bin technisch nicht ganz unbeleckt und war beim
> Studienabschluss einer der besten im Semester, aber deine Beschreibung
> kann ich nicht in ein reales Problem umsetzen.

Das wird wohl an dem Sprachwirrwarr liegen - geht mir genauso ;-)

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
Noch kein Account? Hier anmelden.