Forum: Mikrocontroller und Digitale Elektronik Zähler im EEPROM


von Sören (Gast)


Lesenswert?

Hallo,

in einem Projekt benutze ich einen ATmega328P mit 1024 Bytes EEPROM.

Der Controller zählt Impulse und gibt die Gesamtzahl aus. Nach dem 
Einschalten des Systems soll nach dem alten Zählerstand weiter gezählt 
werden.
Es ist mit 1-10 Impulsen pro Sekunde zu rechnen.

Es wird angegeben, dass das EEPROM 100.000 Schreibzyklen aushält. Das 
reicht natürlich nicht lange.

Gibt es einen Unterschied, ob man in ein EE-Byte eine 0 oder eine 1 
schreibt? Sollte man deshalb einen bestimmten Code verwenden?

Kann man die Tatsache geschickt ausnutzen, dass es sich um einen Zähler 
handelt, d.h. der Wert immer größer wird?

Wenn ich einfach eine Zahl mit z.B. 4 Bytes abspeichere und dann hoch 
zähle, wird ja das unterste Byte viel öfter geschrieben als das oberste, 
das sich viel seltener ändert.
Gibt es einen Mechanismus, bei dem berücksichtigt wird, dass die untern 
Bytes häufiger geschrieben werden und diese auf mehrere EE-Zellen 
verteilt, nicht aber die oberen Bytes?

Danke schon mal für alle Ideen.
Gruß
Sören

von Einer K. (Gast)


Lesenswert?

Googletipp: "wear leveling"

Vielleicht möchtest du ja lieber ein FRAM verwenden.
Oder ein Batterie gestütztes SPI NVRAM

von HildeK (Gast)


Lesenswert?

Ich kenne leider die internen Vorgänge beim EEPROM nicht. Es kann aber 
durchaus sein, dass zuerst die Zelle gelöscht wird (->0xFF) und dann der 
neue Wert geschrieben. Es werden nur die Nullen geschrieben.
Aber da wissen sicher andere mehr.

Eine andere Idee:
Man könnte auch feststellen, wann die Spannungsversorgung weggenommen 
wird und einen Elko-Puffer für die Prozessorversorgung einbauen, so dass 
er genügend Zeit hat, den letzten Zählwert ins EEPROM zu schreiben. 
Damit reduziert sich die Schreibhäufigkeit dramatisch.

von Sören (Gast)


Lesenswert?

Unter Wear Leveling habe ich schon einiges gefunden, hauptsächlich 
Ringspeicher. Das eignet sich gut für zufällige Daten.

In diesem Fall hier mit einem inkrementierenden Zähler bin ich aber der 
Hoffnung, dass es da noch bessere Ansätze gibt.
Vor allem ist mir aber unklar, wir man die unterschiedliche 
Änderungshäufigkeit der niedrigsten und höchsten Stelle ausnutzen bzw. 
berücksichtigen kann.

Natürlich könnte man einen andern Speicher oder auch Batteriepuffer 
einsetzen. Aber wenn schon EEPROM mit dabei ist, lässt sich das Problem 
vielleicht auch einfach damit lösen.

von Michael B. (laberkopp)


Lesenswert?

Sören schrieb:
> Gibt es einen Mechanismus, bei dem berücksichtigt wird, dass die untern
> Bytes häufiger geschrieben werden und diese auf mehrere EE-Zellen
> verteilt, nicht aber die oberen Bytes?

Wenn man mehr Platz hat als die 4 bytes:

EEPROM löschen und bits setzen.

Ist eine bestzimmte Abzahl von bits gesetzt worden, z.B. 256,
als nächste Stellen normal bytes hochzählen, die werden dann auch nit 
öfter gelöscht alds die unteren bits.

Ob bits gesetzt oder gelöscht werden, hängt vom EEPROM Typen ab, EEPROM, 
NAND flash oder NOR flash

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


Lesenswert?

Sören schrieb:
> Gibt es einen Unterschied, ob man in ein EE-Byte eine 0 oder eine 1
> schreibt? Sollte man deshalb einen bestimmten Code verwenden?
Nein. Es wird sowieso gelöscht. Und das Löschen ist es, das das 
EEPROM-Bit im Laufe der Zeit kaputt macht.

Aber es wäre sowieso schlau, den Zähler auf mehrere EEPROM-Zellen 
aufzuteilen.
Stell dir vor, du verwendest 10 EEPROM-Zellen parallel für die "Einer" 
und zählst so:
1
Adr.   0  1  2  3  4  5  6  7  8  9    Zählschritt
2
Daten  0  0  0  0  0  0  0  0  0  0       0
3
       1  0  0  0  0  0  0  0  0  0       1
4
       1  1  0  0  0  0  0  0  0  0       2
5
       1  1  1  0  0  0  0  0  0  0       3
6
       1  1  1  1  0  0  0  0  0  0       4
7
       1  1  1  1  1  0  0  0  0  0       5
8
       1  1  1  1  1  1  0  0  0  0       6
9
       1  1  1  1  1  1  1  0  0  0       7
10
       1  1  1  1  1  1  1  1  0  0       8
11
       1  1  1  1  1  1  1  1  1  0       9
12
       1  1  1  1  1  1  1  1  1  1      10
13
       2  1  1  1  1  1  1  1  1  1      11
14
       2  2  1  1  1  1  1  1  1  1      12
15
       2  2  2  1  1  1  1  1  1  1      13
16
       2  2  2  2  1  1  1  1  1  1      14
17
       2  2  2  2  2  1  1  1  1  1      15
18
       2  2  2  2  2  2  1  1  1  1      16
19
       2  2  2  2  2  2  2  1  1  1      17
20
       2  2  2  2  2  2  2  2  1  1      18
21
       2  2  2  2  2  2  2  2  2  1      19
22
       2  2  2  2  2  2  2  2  2  2      20
23
       3  2  2  2  2  2  2  2  2  2      21
24
       3  3  2  2  2  2  2  2  2  2      22
25
       3  3  3  2  2  2  2  2  2  2      23
26
       :                                  :
27
       :                                  :
Das Auswerten dieses Zählers ist recht einfach: du musst nur die Stelle 
suchen, bei der der nachfolgende Wert kleiner als der aktuelle ist und 
dann den die Werte geschickt miteinander verrechnen.
Das Ganze geht natürlich auch mit 100 oder 1000 EEPROM-Bytes als 
"linearen Zähler".

Und/oder in das EEPROM nur alle paar Sekunden und bei Powerfail den 
Zählerstand schreiben. Dann musst du nur erkenne, dass die Spannung 
abfällt und ausreichend Energie zum einmaligen Schreiben des Zählers 
bereitstellen.

Sören schrieb:
> Vor allem ist mir aber unklar, wir man die unterschiedliche
> Änderungshäufigkeit der niedrigsten und höchsten Stelle ausnutzen bzw.
> berücksichtigen kann.
Das bringt nur was bei den höherwertigen Bytes des Zählers. Aber bei 
denen musst du dir dann oft gar keine Gedanken mehr machen. Oder 
bestenfalls noch zu einer evtl. redundanten Speicherhaltung dieser 
Bytes. Aber auch dort lässt sich das obige Verfahren anwenden, indem 
dafür dann z.B. 4 Bytes hergenommen werden. Dann kann man auch relativ 
einfach eine korrupte Speicherzelle erkennen, indem man diese Bytes 
miteinander vergleicht und bei Abweichung von mehr als 1 einen Fehler 
erkennt.

Richtiges Wearleveling brint nur was bei Flash-Speicher, der explizit 
und getrennt vom Schreiben gelöscht werden muss/kann.

: Bearbeitet durch Moderator
von Auf Merker (Gast)


Lesenswert?

Sören schrieb:
> Das reicht natürlich nicht lange.

Man schreibt auch nicht während des Betriebs dauernd ins
EEPROM. Sondern nach Tacho-Manier beim nächsten Ausschalten.
Dazu braucht es halt ein bisschen Zusatz-Logik damit man den
Ausschalt-Vorgang erkennt und erst später nach dem EEPROM
Schreiben den Controller ausschaltet.

Externe I2C oder SPI-EEPROMs können heutzutage übrigens
garantiert 1 Million Erase/Write Zyklen. Das hält ewig und
drei Tage wenn man es ein bisschen schlauer macht ....

von Vorschlag (Gast)


Lesenswert?

1) Beim Systemstart aus dem EEPROM lesen, Wert im RAM hochzählen, und 
beim Ausschalten ins EEPROM schreiben, so wird das im KFZ-Bereich 
gemacht.

2) Ganzes EEPROM ausnutzen, z.B. die 4 Byte Blöcke immer nacheinander 
in's EEPROM schreiben. Beim Systemstart den Block mit der höchsten Zahl 
(außer 0xFFFFFFFF) suchen und weiternutzen - es wird ja nur 
inkrementiert. Generische Methoden existieren auch für Datenflashs. Dort 
wird z.B. mit Valid-Flags für den zugehörigen Datenwert gearbeitet, die 
ebenfalls immer nacheinander geschrieben werden ohne den alten Wert zu 
löschen - der wird nur ungültig markiert (bis der Speicher voll ist, 
dann wird gelöscht).

von Safari (Gast)


Lesenswert?

Tut nichts zur eigentlichen Sache, aber vielleicht als Info nebenher 
interessant:

Ich habe mal das EEPROM eines mega8 und eines mega1284p "getestet".
Der mega8 machte nach 2,7x sovielen Zyklen schlapp und der mega1284p 
hielt sogar 8x so viele Zyklen aus, bevor die ersten Fehler auftauchten.
Interessanter wäre natürlich, verschiedene mega8/xxxx aus 
unterschiedlichen Chargen und Jahren zu testen.

von Gerhard O. (gerhard_)


Lesenswert?

Der Vollständigkeit halber könnte man auch noch die ERAMS erwähnen. Das 
sind SRAMS mit automatischer EEPROM Datensicherung. MC stellt die 
47C(L)04/16 her. Ein Stützkondensator sichert den SRAM Inhalt bei 
Absinken von Vcc automatisch und stellt den alten Zustand beim 
Einschalten automatisch wieder her. Bus ist I2C.

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


Lesenswert?

Safari schrieb:
> Der mega8 machte nach 2,7x sovielen Zyklen schlapp und der mega1284p
> hielt sogar 8x so viele Zyklen aus, bevor die ersten Fehler auftauchten.
Hast du die Versorgungsspannung da auch ab&zu abgeschaltet? Denn ich 
habe bei dauernd anliegender Versorgung auch schon mal mehr als das 
zehnfache geschafft.
Und als ich den Test wiedeholte und die Versorgung jede Minute mal 
abschaltete, da blieb dann bei µC aus der selben Charge nur noch der 
Faktor 1,2 bis 1,5 übrig...

von Safari (Gast)


Lesenswert?

Lothar M. schrieb:
> Hast du die Versorgungsspannung da auch ab&zu abgeschaltet? Denn ich
> habe bei dauernd anliegender Versorgung auch schon mal mehr als das
> zehnfache geschafft.
> Und als ich den Test wiedeholte und die Versorgung jede Minute mal
> abschaltete, da blieb dann bei µC aus der selben Charge nur noch der
> Faktor 1,2 bis 1,5 übrig...

Darauf kam ich leider nicht ...

Ich habe noch zwei ziemlich alte (~2000-2005) mega8 da und kann das mal 
testen. Aber auf die Schnelle wird das nix, weder Experimentierboard, 
noch ISP, ... da.
Noch nichtmal mehr einen Rechner mit Parport und auch kein Steckbrett 
grrr ;)

Den zerstörten mega1284p habe ich im Sommer 2012 gekauft.
Also letztendlich wären meine Werte, die ich dabei herausbekommen 
könnte, für Vergleiche mit aktuellen Chips sinnlos, wiedermal bei rein 
aus Interesse. Dann wieder bei kein Zubehör, ...

Hast du beim Zugriff auf das EEPROM abgeschaltet, oder wenn das grade 
Pause hatte?

von Sören (Gast)


Lesenswert?

Erst mal vielen Dank für all die hilfreichen Ideen!

Es ist tatsächlich sinnvoller nur dann zu speichern, wenn es wirklich 
nötig ist, d.h. wenn das Gerät abgeschaltet wird. Das kann man dann noch 
kombinieren mit einer Methode, die die Schreibzugriffe auf mehrere 
EEPROM-Zellen verteilt. Dann reicht das fast ewig.

Eine einfache Schaltung zur Erkennung von Stromausfall sollte genügen, 
ich habe das hier gefunden:
https://www.mikrocontroller.net/articles/Speicher#EEPROM_Schreibzugriffe_minimieren

Da ich einen Regler einsetze, geht es um das zweite dort gezeigte 
Schaltbild. Dazu eine Frage:
Die große Stützkapazität hätte ich nach dem Regler geschaltet, am 
Ausgang des Reglers noch eine Schottky-Diode eingebaut, damit im Fall 
des Spannungsverlusts nicht in den Regler gespeist wird.
Oder gibt es einen guten Grund, die Stützkapazität vor den Regler zu 
platzieren? Da hat man dann bei Stromausfall ja noch den Regler mit zu 
versorgen, oder?

An die Eingangsspannung vor dem Regler kommt ein Spannungsteiler, der 
zum Comparator des ATmega geführt ist, das sollte dann eine schnelle 
Erkennung der Situation mittels Interrupt ermöglichen.

von Sören (Gast)


Lesenswert?

Was ich noch zu den Tests der EEPROM-Lebensdauer gelesen habe:

Das Ein- und Ausschalten der Spannung hat Einfluss auf die Zahl der 
möglichen Zyklen, wie das oben auch Lothar M. erwähnt hat.

Außerdem scheint es so, dass irgendwann die "data retention time" nicht 
mehr gewährleistet wird. Die Zahlen weiß ich jetzt nicht mehr, aber z.B. 
werden bis zu den 100.000 Schreibzyklen 20 Jahre angegeben. Wenn man 
dann aber bei z.B. 200.000 Schreibzyklen ist - die Daten werden korrekt 
gelesen - kann es durchaus sein, dass diese nach 5 Jahren weg sind.

von Dietrich L. (dietrichl)


Lesenswert?

Sören schrieb:
> Oder gibt es einen guten Grund, die Stützkapazität vor den Regler zu
> platzieren?

Ja, denn dann bleibt die Ausgangsspannung länger stabil (hängt natürlich 
vom Regler und der Eingangsspannung ab).

> Da hat man dann bei Stromausfall ja noch den Regler mit zu
> versorgen, oder?

Das kann man ausrechnen, wie groß dieser Anteil ist, und einen Regler 
mit genügend kleinem Eigenverbrauch nehmen.

von Fpgakuechle K. (Gast)


Lesenswert?

Schreib nur in den EEPROM wenn der Controller ausgeschaltet wird. Dazu 
könnte man einen brownOut Detect IRQ nutzen und die PowerSupply für die 
paar us Schreiben entsprechend nachstützen. Nur mal so als Denkanregung.

von Sören (Gast)


Lesenswert?

Auch ein interessanter Vorschlag.

Reicht es, beim Regler einen mit kleiner Drop-out Spannung zu nehmen?
Als Eingangsspannung habe ich 5V, könnten auch 9V werden. Der Controller 
läuft mit 3,3V.
Ein LP2950 oder MCP1700 würde passen, oder?

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


Lesenswert?

Sören schrieb:
> Auch ein interessanter Vorschlag.
Der kam eigentlich schon ein paar Mal...

> Reicht es, beim Regler einen mit kleiner Drop-out Spannung zu nehmen?
Kommt auf deine Versorgung an. Und auf die Möglichkeit einer Pufferung 
vor oder nach dem Spanungsregler.

Ich lasse einfach einen AD-Wandler laufen und die Eingangsspannung 
messen. Und wenn die Spannung unter eine bestimmte Schwelle fällt, wird 
das EEPROM geschrieben.
Da muss man das Programm natürlich schon so "schlau" sein und dan ADC 
oft genug anschmeißen.

Man könnte natürlich auch einen Komparatoreingang nehmen.

Fpga K. schrieb:
> und die PowerSupply für die paar us Schreiben entsprechend nachstützen.
Das spielt sich pro Byte eher im ms-Bereich ab. Da lohnt es sich, für 
die Rechnung die Feder zu spitzen. Denn es müssen ja durchaus mehrere 
Bytes gespeichert werden...

von Sören (Gast)


Lesenswert?

OK, dann ziehe ich mich mal ins Bastelkämmerlein zurück und mache ein 
paar Versuche. Melde mich dann wieder.

von Johnny B. (johnnyb)


Lesenswert?

Arduino Fanboy D. schrieb:
> Vielleicht möchtest du ja lieber ein FRAM verwenden.

Kann ich auch empfehlen, das ist die einfachste Lösung. Sie sind 
kompatibel zu EEPROMS, ersetzen diese also ohne irgendwelche Änderungen 
in der Software/Hardware und die kriegt man mit schreiben nicht 
kaputt.Kosten tun sie etwas mehr, aber bei kleinen bis mittleren 
Stückzahlen immernoch billiger als Tagelang an einer Lösung mit EEPROMS 
tüfteln.

Edit: Aha sorry, Du benutzt ja das interne EEPROM des uC, dann ist es 
natürlich schon merklich teurer mit einem FRAM als wenn Du eh schon 
einen externen Chip benutzt hättest.

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


Lesenswert?

Johnny B. schrieb:
> Arduino Fanboy D. schrieb:
>> Vielleicht möchtest du ja lieber ein FRAM verwenden.
> Kann ich auch empfehlen ... die kriegt man mit schreiben nicht kaputt.
Das ist schon richtig, aber leider nur 1 Seite der Medaille.
Denn das Problem das auch hier bleibt, ist, dass im "Abschaltfall" ein 
gerade begonnener Schreibvorgang (der ja aus mehreren Bytes bestehen 
wird) z.B. nach 2 Bytes abgebrochen wird. Denn wenn der Zähler vorher 
auf
hex 00 00 ff ff stand und jetzt auf
hex 00 01 00 00 wechselt,
und dieser Zähler vom niederwertigen Byte aus geschrieben wird, dann 
steht hinterher
hex 00 00 00 00 im Speicher.

Auch wenn man beginnend vom höchstwertigen Byte schreibt, bleibt das 
Problem und es steht
hex 00 01 ff ff im Speicher.

Mit ein wenig Nachdenken kommt man also auch in diesem Fall nicht um ein 
Pufferung des Schreibvorgangs herum. Der Witz dabei ist: es ist ein 
belibter Fehler. Jeder kennt solche Geräte, wo sich Parameter nach dem 
Abschalten ab&zu selber verstellt haben...  ;-)

: Bearbeitet durch Moderator
von HildeK (Gast)


Lesenswert?

Sören schrieb:
> Die große Stützkapazität hätte ich nach dem Regler geschaltet, am
> Ausgang des Reglers noch eine Schottky-Diode eingebaut, damit im Fall
> des Spannungsverlusts nicht in den Regler gespeist wird.

Sören schrieb:
> Da hat man dann bei Stromausfall ja noch den Regler mit zu
> versorgen, oder?

Je nach Regler und Spannung macht dem die Rückspeisung nichts aus --> 
Datenblatt. Z.B. der 7805 verträgt das.

Wenn du sie doch verwenden willst / benötigst: baue auch eine Diode in 
den GND-Anschluss des Reglers (z.B. beim 7805) ein, dann kompensiert 
sich der Spannungsverlust an deiner Diode weitgehend.

von Safari (Gast)


Lesenswert?

Fpga K. schrieb:
> paar us Schreiben

Da liegst du um den Faktor 1000 daneben, das bewegt sich im paar ms 
Bereich.

@Lothar
Safari schrieb:
> Hast du beim Zugriff auf das EEPROM abgeschaltet, oder wenn das grade
> Pause hatte?

von Safari (Gast)


Lesenswert?

Ich habe heute morgen noch einen uralt Laptop von ~2005, ein Lauflicht 
mit m8, sowie einen SUB-D 25 Stecker ausgegraben. Das dürfte sich gut 
als ISP und durch die vielen LEDs gut für Status-Ausgaben machen.
Ich hoffe, ich komme auch dazu, die beiden m8 "zu verheizen".

von Johnny B. (johnnyb)


Lesenswert?

Lothar M. schrieb:
> Johnny B. schrieb:
>> Arduino Fanboy D. schrieb:
>>> Vielleicht möchtest du ja lieber ein FRAM verwenden.
>> Kann ich auch empfehlen ... die kriegt man mit schreiben nicht kaputt.
> Das ist schon richtig, aber leider nur 1 Seite der Medaille.
> Denn das Problem das auch hier bleibt, ist, dass im "Abschaltfall" ein
> gerade begonnener Schreibvorgang (der ja aus mehreren Bytes bestehen
> wird) z.B. nach 2 Bytes abgebrochen wird. Denn wenn der Zähler vorher
> auf
> ...
> Mit ein wenig Nachdenken kommt man also auch in diesem Fall nicht um ein
> Pufferung des Schreibvorgangs herum.

Wenn mans klever macht, kommt man schon darum herum. Man muss halt nur 
schauen, dass beim abschalten sich der uC vor dem FRAM Chip 
verabschiedet.
z.B. der Cypress FM24CL16B läuft bis 2.7V. Jetzt muss man schauen, dass 
sich der uC halt schon bei einer höheren Spannung als 2.7V resettet. 
Allenfalls den FRAM Chip über eine Diode und etwas grösseren 
Buffer-Kondensator speisen. Das ist wirklich sehr einfach umzusetzen.
Du darfst nicht vergessen, dass ein FRAM die Daten sehr schnell 
wegschreibt und wenn man nur einen Zähler Schreibt, also ein paar Bytes, 
dies ruckzuck geht.

Aus dem Datenblatt:
These capabilities make the FM24CL16B ideal for nonvolatile
memory applications, requiring frequent or rapid writes.
Examples range from data logging, where the number of write
cycles may be critical, to demanding industrial controls where the
long write time of EEPROM can cause data loss.

Hier hat Cypress auf eine Frage im Supportforum geantwortet, dass jedes 
vollständig übertragene Byte auch garantiert geschrieben wird:
https://community.cypress.com/thread/32811

: Bearbeitet durch User
von Bauform B. (bauformb)


Lesenswert?

Johnny B. schrieb:
> z.B. der Cypress FM24CL16B läuft bis 2.7V. Jetzt muss man schauen, dass
> sich der uC halt schon bei einer höheren Spannung als 2.7V resettet.

Das nützt leider nichts, wenn der uC die ersten zwei Bytes geschrieben 
hat und dann resettet wird. Wir trauen dem FRAM schon zu, das es 
empfangene Bytes korrekt schreibt, aber in dem Fall hat der uC ja keine 
Chance die letzten Bytes zu senden.

Der uC darf den Schreibvorgang nur beginnen, wenn er sicher ist, dass 
die Elko-Ladung für alle Bytes ausreicht. Und wenn das funktioniert, 
kann man auch externes NOR-Flash verwenden (na gut, das braucht einen 
dickeren Elko).

: Bearbeitet durch User
von Fpgakuechle K. (Gast)


Lesenswert?

Lothar M. schrieb:

> Fpga K. schrieb:
>> und die PowerSupply für die paar us Schreiben entsprechend nachstützen.
> Das spielt sich pro Byte eher im ms-Bereich ab. Da lohnt es sich, für
> die Rechnung die Feder zu spitzen. Denn es müssen ja durchaus mehrere
> Bytes gespeichert werden...

Ich denke da an einen grösseren C der extra für das abschalten 
zugeschaltet wird.der C könnte auch mit einer Spannung am oberen Ende 
des Zulässigen aufgeladen werden um noch etwas reserve zu bieten.

Oder eine bufferbatterie LR11. Hat D10x16mm und bietet ca. 40 mAh

von Einer K. (Gast)


Lesenswert?

Bauform B. schrieb:
> aber in dem Fall hat der uC ja keine
> Chance die letzten Bytes zu senden.

Das (oder besser mein) übliches Verfahren wäre einen Zähler und eine 
Checksumme zu nutzen.

z.B.
struct
{
   int counter;
   int checksumm;
}

Dieser Datensatz wird 2 mal nacheinander an verschiedene Stellen des 
Fram geschrieben.
Also Redundant.

Wenn der erste Satz als kaputt erkannt wird, also die Prüfsumme nicht 
stimmt, ist der zweite, der letzte gültige.

Z.B. bei der Aufgabenstellung hier, dürfen keine Impulse verloren gehen.
Also weiß man, dass, wenn der erste Satz kaputt ist, dass man den Zähler 
des zweiten+1 verwenden kann.

von foobar (Gast)


Lesenswert?

Man kann auch mal überlegen, wie hoch man im besten Fall überhaupt 
zählen kann. Wenn man 2^13 = 8192 Bits hat, die jeweils 2^17 = 131072 
mal geändert werden können und beim Hochzählen nur immer ein Bit 
geändert wird und das optimal verteilt (Gray-Code?), kann man maximal 
2^13 * 2^17 = 2^30 mal zählen. Nix mit 32-Bit-Zähler.

Oder hab ich da nen Denkfehler?

von Norbert (Gast)


Lesenswert?

foobar schrieb:
> Man kann auch mal überlegen, wie hoch man im besten Fall überhaupt
> zählen kann. Wenn man 2^13 = 8192 Bits hat, die jeweils 2^17 = 131072
> mal geändert werden können und beim Hochzählen nur immer ein Bit
> geändert wird und das optimal verteilt (Gray-Code?), kann man maximal
> 2^13 * 2^17 = 2^30 mal zählen. Nix mit 32-Bit-Zähler.
>
> Oder hab ich da nen Denkfehler?

Tja, ich hasse es der Überbringer schlechter Nachrichten zu sein... ;-)

Wo zählst du denn wie oft du den Bit-Teppich rasiert hast um es mal 
blumig auszudrücken.

Da das jedoch mindestens 100.000 mal passiert brauchen wir einen drei 
Byte breiten Zähler. Damit haben wir noch 8168 Bits zur freien 
Verfügung.
Bei schnellstmöglicher Taktfrequenz (der Zählimpulse) lebt das Ding 
jetzt noch 2,6 Jahre. Wenn das lang genug ist, dann passt's.

von georg (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Z.B. bei der Aufgabenstellung hier, dürfen keine Impulse verloren gehen.

Diese Forderung ist weitgehend sinnlos, denn während das Gerät 
ausgeschaltet ist, gehen die Impuls ja auch verloren. Und ob ein Impuls 
der genau beim Ausschalten anliegt gezählt werden soll oder nicht ist 
rein willkürlich - am Ende müsste man prüfen ob es mehr als ein halber 
Impuls ist und weiteren Unsinn. Im übrigen kann ein Impuls ja auch beim 
Einschalten anliegen, rechnet man dann 2 halbe Impulse ergeben einen 
ganzen? Es lohnt sich garnicht darüber nachzudenken.

Georg

von foobar (Gast)


Lesenswert?

> Wo zählst du denn wie oft du den Bit-Teppich rasiert hast um es mal
> blumig auszudrücken.

Ich denke, du hast das falsch verstanden. Beim Zählerstand 8192 ist, 
durch Auswahl eines passenden Codes, jedes Bit exakt einmal geändert 
worden, bei 16384 zweimal, usw.

> Da das jedoch mindestens 100.000 mal passiert brauchen wir einen drei
> Byte breiten Zähler. Damit haben wir noch 8168 Bits zur freien
> Verfügung.

Du zählst also die ersten drei Bytes hoch, bei 100000 nimmst du die 
nächsten 3 Bytes, usw. Macht bei 1024 Bytes (1024/3)*100000 = 34100000 
~= 2^25 als maximalen Zählerstand. Widerlegt meine 2^30 nicht ;-)

von Norbert (Gast)


Lesenswert?

foobar schrieb:
> Ich denke, du hast das falsch verstanden. Beim Zählerstand 8192 ist,
> durch Auswahl eines passenden Codes, jedes Bit exakt einmal geändert
> worden, bei 16384 zweimal, usw.

Exakt. Und wo merkst du dir wie oft du diese Prozedur bereits 
abgearbeitet hast?

von Peter D. (peda)


Lesenswert?

Du kannst bei Deinem ATmega328P die interne Band-Gap Spannung messen mit 
VCC als Referenz. Wird der ADC nicht weiter benötigt, bietet sich der 
Free-Running Mode an, d.h. nach der Initialisierung kannst Du ihn 
fortlaufend auslesen.
Den Wert fragst Du im Timerinterrupt alle 1ms ab. Wenn er steigt, heißt 
das, die VCC bricht ein und dann schreibst Du den Zählwert vom RAM in 
den EEPROM.
Der Elko muß für 4ms je Byte die Spannung noch über dem Brownoutreset 
halten. Man kann aber auch vorher löschen, dann reichen 2ms je Byte.

von Nachgerechnet (Gast)


Lesenswert?

Um eine sichere Spannungsausfallerkennung mit Zeitreserve
für den Schreibvorgang kommt man nicht herum. Lässt sich
aber mit Bordmitteln (Analog-Komparator, interne Uref und
etwas "Hühnerfutter") machen.

- Aber wozu sich dann noch mit F-RAM, Batteriestützung
oder sonstigem Firlefanz belasten?

Mit 4 Byte kannst du die Zahl 4.294.967.295 darstellen.
Du kannst also bis zu 4.294.967.294 Pulse zählen, da die
0xFFFFFFFF für unbeschriebene Zellen reserviert ist.

4.294.967.294 /   10 (Pulse/s) = 429.496.729 s
  429.496.729 / 3600 (s/h)     =     119.304 h
      119.304 /   24 (h/d)     =       4.971 d
        4.971 /  365 (d/y)     = 13,6 y

Mit 4 Byte kann man also 13,6 Jahre lang 10 Pulse/s zählen.
Sind es im Mittel nur 5 Pulse/s geht es auch über 25 Jahre.

1024 Byte / 4 = 256 Speicherplätze

Werden die rollierend benutzt, kommt man auf
256 * 100.000 = 25.600.000 Zyklen.
In 25 Jahren kannst du also regelmäßig 100 mal pro Stunde
abschalten - das EEPROM wird innerhalb der Spezifikation
genutzt.

von S. R. (svenska)


Lesenswert?

Nachgerechnet schrieb:
> Mit 4 Byte kannst du die Zahl 4.294.967.295 darstellen.
> Du kannst also bis zu 4.294.967.294 Pulse zählen, da die
> 0xFFFFFFFF für unbeschriebene Zellen reserviert ist.

Und wenn du 4.294.967.294 mal den Zählerstand aktualisiert hast, sind 
deine 4 Bytes schon 4293 mal kaputt.

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.