ATMega: EEPROM Inhalt zerschossen, warum?

OP #1931360
Lesenswert?

Hallo,

in meinem doch etwas komplexerem Projekt tritt hin und wieder eine sehr 
komische Eigenart auf:

Unter noch nicht geklärten Umständen reagiert mein Controller nicht mehr 
und nach Reset ist der Speicherinhalt des EEPROMS komplett mit 
unbrauchbaren Werten überschrieben. Dies wirkt sich natürlich gravierend 
auf die Funktion aus und ist natürlich so nicht hinzunehmen.

Wie würdet Ihr am Besten vorgehen um den Fehler einzukreisen?

Wie kann man tendenziell herausfinden, ob das eher ein Softwarefehler 
oder eher ein Hardwarefehler (EMV) - Problem sein könnte?

Das Problem ist: Dieses Verhalten ist derzeitig noch nicht 
reproduzierbar.

Gruß
Bernhard N.
#1931383
Lesenswert?

Moin,

ich würde einen Pin freischaufeln und jeweils am Anfang und am Ende der 
EEPROM-Routinen toggeln lassen. Dann kann man schon mal sagen, ob die 
eigenen EEPROM-Routinen daran schuld sind, oder nicht.

Wenn ja, dann sollte das Problem zuerst im Call-Stack gesucht werden. 
Wenn nein, dann ??...??. Helfen kann eine externe Brown-Out-Schaltung 
die einen Reset erzeugt, wenn die Spannung zu niedrig ist. Dann sollte 
man EEPROM Adresse 0 aber nicht benutzen. (War zumindest bei den alten 
ATmega103s so.)

Ich hatte mit einem ATmega103 vor Jahren das Problem, daß mir mitten im 
Schreibvorgang die Versorgung weggebrochen ist. Das hat auch zu einem 
zerschossenen EEPROM geführt. War damals aber auch ein Problem mit Bugs 
im Chip.

Gruß
Carsten
Gast #1931425
Lesenswert?

Da es aber leider nicht immer nur Zelle 0 betrifft, ist das Ergebnis 
ggf. trotzdem verheerend - neben der Brown out Geschichte (hat bei mir 
mal das Problem beseitigt) hilft dann nur noch eine Prüfsumme über den 
EEPROM-Inhalt und ggf. das Rückschreiben aus einer Kopie.

Viele Grüße,

Mirko
Gast #1931440
Lesenswert?

Wie schon geschrieben: BrownOut detection einschalten.
Ich such mit zusätzlich oft noch ein Dummy-Eeprom Byte (z.B. gleich das 
erste).

Nach jeder EEProm-Operation mach ich nochmal ein Read auf das 
Dummy-Byte. Nachher stehen die Adress-register alle auf 0, und, wenn 
wirklich (trotz BrownOut-Schutz) Blödsinn passiert, erwischt es ziemlich 
sicher die Dummy-Speicherzelle.

also:
1
...
2
uint8_t uint32_t EEMEM dummy=0x42;
3
...
4

5
eeprom_read_block(irgendwas);
6
(void)eeprom_read_byte(&dummy); // set EEProm Pointer to dummy

Denselben Effekt erreicht man vermutlich auch durch einfaches Setzen der 
EEAR - Register, wenn einem der extra "read_byte"-Aufruf zuviel ist.
OP #1931447
Lesenswert?

Hi,

ich habe jetzt mal die interne BrowmOut Detection aktiviert (Fuse 
gesetzt und Level auf 4V).


Ich werde das weiter beobachten..

Wobei ich schon ein stabilisiertes Netzteil verwende, das auch viel zu 
stark ausgelegt ist um so etwas zu vermeiden.

Das Problem ist wirklich gravierend, denn es werden in einer 
Produktionsanlage Befeuchtungsventile ein / ausgeschaltet 
(Feuchreregelung) und die Zuweisungen Ventil-> Regelungsbereiche und 
alle Parameter sind im EEPROM.

EDIT:

Bei mir war übrigens der komplette Speicherinhalt unbrauchbar.

Hier mal der Inhalt in ASCII, wie der in einer üblichen Konfiguration 
aussehen sollte und wie der zerschossen aussieht:

======================================================================

 Unbenutzt         d dUnbenutzt         d dUnbenutzt         d dS hleife 
Keller øddFlur AB          ôd!dDraussen         öd
dSchleifen II     ùd
dCNC or07         ùddProduktion       ôd&dTrommelraum      øddLager 10 
d
dSensor11          d dSensor12          d dSensor13          d dSensor14 
d dSensor15          d dLager nnt00
 È  2   Schleifen 1       , 2    Schleifen 2      ú  2    CNC uktion 
, 2    Trommelraum        d  2   Produktion        X 2    Flur AB aum 
, 2    Flur Neubau     c d  2    Unbekannt08     cc ,  2    Unbekannt09 
c ,  2    Unbekannt10
c ,  2    Unbekannt11     c ,  2    Draussen 12     c , 2    Unbekannt13 
cc ,  2    Unbekannt14     cc ,  2    Unbekannt15     cc ,  2    Altbau 
e0       Neubau e1        ÿÿ Xÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ


======================================================================



Zerschossen:

======================================================================


 2cMò1½W/ʆµ' B¡ ÛÁ_ d ;1T 81Tcc2c ò1½W/ʆµ' B¡¾ÛÁ_ d ; T 
82Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d ;3T 83Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d ;4T 
84Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d ;5T 85Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d ;6T 
86Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d ;7T 87Tcc2cMò1½W/ †µ' B¡¾ÛÁ_ d ;8T 88T 
cc2cMò1½W/ʆµ' B¡¾ Á_ d ;9T 89Tcc2cM 1½W/ʆµ' B¡¾ÛÁ_ d <0 
90Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d <1T 91Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d <2T 
92Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d <3T 93Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d <4T 
94Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d <5T 95Tcc2cMò1½W/ʆµ' Bµ' B¡¾ÛÁ_ d 96T 
66Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d 97T 67Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d 98T 
68Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d 99T 69Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d :0T 
70Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d :1T 71Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d :2T 
72Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d :3T 73Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d :4T 
74Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d :5T 75Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d :6T 
76Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d :7T 77Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d :8T 
78Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d :9T 79Tcc2cMò1½W/ʆµ' B¡¾ÛÁ_ d ;0T 80Tc


======================================================================

Hmm, gerade beim Pasten fällt mir doch die relative Gleichmässigkeit des 
"Rauschens" auf...



Gruß
Bernhard
Gast #1931464
Lesenswert?

Du kannst das ja mal testen -> so 10 mal schnell Strom an/Strom 
aus(richtig wild den Schalter hin und her jackeln), ohne Brown out ist 
dein EEprom spätestens nach dem dritten Versuch verändert.

Viel Erfolg,

Mirko
Gast #1931471
Lesenswert?

> 2) EEPROM-Schreibroutinen aus dem Code entfernen
> 3) Testen, ob EEPROM immer noch zerschossen wird.
Gute Idee,zu 98%
Nun würde ich trotzdem noch behaupten, daß Masseprobleme und 
Spannungsspitzen manchmal wunderliche Blüten treiben. Evtl. tritt es nur 
auf wenn der Aufzugmotor startet?

Ein paar Prüfpunkte im Programm vorsehen und irgendwas anzeigen?
#1931486
Lesenswert?

Auch wenn ich denke, dass BOD das Problem erledigt, sollte man immer 
dran denken, dass ein Brownout nur dafür sorgt, dass noch das letzte 
Byte korrekt im EEPROM landet. Bei Werten größer 1 Byte hilft das auch 
nicht wirklich.

Beispiel: von einem 16-Bit Wert wird nur das Low-Byte geschrieben, 
High-Byte hat aber noch den ursprünglichen Wert. Um das zu verhindern, 
schreibe ich jeden Eintrag 2mal wie folgt:

Seq# - Daten - Seq# - Daten - Seq#

Seq# = 1 Byte und für jeden Schreibvorgang um 1 erhöht.

Damit weiß ich, dass Daten  zwischen identischen Seq# vollständig 
geschrieben wurden. Falls das für die erste Kopie der Daten nicht der 
Fall ist, wurde wahrscheinlich der Schreibvorgang im ersten Datensatz 
abgebrochen. Dann nehme ich die alten Daten aus dem zweiten Datensatz. 
Falls auch deren Seq# nicht gleich ist, werden die Daten neu 
initialisiert.
Gast #1931490
Lesenswert?

Bernhard N. schrieb:
>> Ein paar Prüfpunkte im Programm vorsehen und irgendwas anzeigen?
> Was meinst Du damit?

Lass irgendeine Leuchtdiode blinken oder zeig nach jedem Schritt ein 
Sternchen oder eine Zahl an, damit man eher merkt in welchem Moment der 
Absturz auftritt. Daraus könnte man dann überlegen ob es immer am Punkt 
17 oder nur wenn der Motor 56 einschaltet passiert.
OP #1931499
Lesenswert?

Hallo,

ich nutze ja schon ein Frontend für C Sharp, dass permanent mit 
Zustandsdaten, Mess und Stellwerten vom Controller gefüttert wird, die 
auch alle aktuellen Schaltzustände anzeigen. Diese gesendeten Rohdaten 
schreibe ich jetzt schon in eine CSV -Logdatei. (mit Datum / Uhrzeit) 
Nur leider war zu diesem Zeitpunkt die Logfunktion nicht aktiv. Diese 
wurde jetzt aktiviert.
So hoffe ich, dass das Problem in naher Zukunft mal auftritt und ich so 
in die "Logs" gucken kann..

Gruß
Bernhard,

der sich echt freut dass so viele sich um mein Problem kümmern. ;)
OP #1931503
Lesenswert?

@ Klaus 2m5:

Ich werde nochmals nachschauen ob die wenigen 16bit EEPROM Werte 
irgendeine Fehlfunktion auslösen könnten. Wahrscheinlich nicht und wenn 
doch, wird der Wert beim Auslesen nachgeprüft und limitiert, so dass 
zumindest gültige Werte innerhabl der Grenzen verwendet werden (z.B. 
sinnvolle Grenzwerte der Regelung etc.)

Strings, also Beschreibungen können ruhig manipuliert sein, dass merkt 
der Nutzer sofort und kann sie einfach neu benennen.
#1931535
Lesenswert?

Ich denke auch das irgend ein Verbraucher dir diesen Effekt beschert, 
schau mal ins Datenblatt des ATTiny26 dort ist für die 
Spannungsversorgung des ADCs eine kleine Filterschaltung LC abgebildet, 
diese setze ich z.B. auch vor die reguläre VCC, mein AVR läuft damit im 
Abstand von wenigen cm neben einer Zündkerze ohne Probleme, mein PC 
hingegen spuckt manchmal Töne weil sich die USB Geräte ab und wieder 
anmelden obwohl hier mehrere Meter Abstand sind.

Denn Filter möglichst nach an die Blockkondensatoren.
Gast #1931587
Lesenswert?

Hi
Nur mal eine Anmerkung: Du beschreibst den EEProm aber nicht öfters? 
Damit meine ich in der Programmschleife. ( z.B. bei Werteänderung ...) 
Da könnte es denn sein, das dein EEProm "verbraucht" ist. Das Datenblatt 
redet von ca. 10000 schreibzyklen, danach ist's nicht mehr zuverlässig 
und irgendwann auch mal so richtig zerschossen.
Gruß oldmax
Gast #1931661
Lesenswert?

Nein, ich schreibe nur Werte in den Speicher, die sehr selten verändert 
werden. Benutzervorgaben z.B.

Laufvariablen wie die Reglerdifferenzengleichungswerte etc. werden nur 
im Speicher gehalten.
Gast #1932594
Lesenswert?

Wie werden die Magnetventile angesteuert? Ich hatte auch mal so ein 
Problem.
Es wurde gelöst durch Z-Dioden an den Spulen. Wenn die Enstörung an der 
LPL statt findet wirken die Kabel wie Antennen.
Da hilft nur systematisch vorgehen.
1. Schreib ein kleines Programm und Toggle so ein Ventil und schreibe 
den EEPROM- Inhalt über die Serielle Schnittstelle raus.
2. Beim Schaltvorgang  mit einen Scope mal alle möglichen Signal 
darstellen.
....
#1932653
Lesenswert?

schau dir das mal an
http://www.picoauto.com/waveforms/images/zoom/4_injectors.png
das stammt von einem KFZ-Einspritzventil

Das Ventil wird mit 14V betrieben beim Abschalten entsteht eine 
Spannungspitze von etwa 40V, beim Relais ist das genauso.

Deine "Galvanische Trennung" hilft also nur das der große Verbraucher 
keine Störungen über das Relais zu deinem µC zurückleitet, deine 
Relaisspule tut das aber trotzdem.

Du könntest aber eine galvanische Trennung mit Optokopplern machen, da 
diese im Gegensatz zu Relais keinen Dreck erzeugen dann sollte aber 
wieder drauf geachtet werden von wo die Relaisspule versorgt wird nciht 
das es von dieser Seite wieder reinhaut. Deswegen kann auch ein 
Filternetzwerk vor dem Spannungsregler ganz nützlich sein.

Oder wie gesagt eine Freilaufdiode verwenden wodurch sich diese 
Spannungsspitzen erst garnicht aufbauen.
OP #1932702
Lesenswert?

Ich nutze pro Ventil (Kugelhahnstellantrieb) ULN2803 
Darlingtontreiberstufen. Die Freilaufdiode dort wurde beschaltet. Die 
Relais (kleinere Finder Relais) werden mittels 12V, getrieben von 
ULN2803 angesteuert. Funktionierte eigentlich über ein halbes Jahr 
zuverlässig.


In der main- Schleife wird nur dann was geschrieben, wenn von Außen 
(über GUI) Stellwerte und Parameter verändert werden. Ich schließe aus, 
dass dort eine Abnutzung erfolgte.
Ein Aufspielen einer alten Konfigurationsdatei (entspricht Image des 
EEPROMs) über die GUI klappte einwandfrei, nichts war manipuliert.

Gruß

Bernhard
#1932728
Lesenswert?

nimmst du die 12V vor dem Spannungsregler ab? Kann es sein dass die 
Belastung beim Schalten von mehreren Ventilen gleichzeitig zuviel für 
den 12V-Zweig ist und dort die Spannung unter 7,5V abfällt(auch 
kurzzeitig)

Hast du ein Oszilloskop um das zu prüfen ein Spannungsmesser wäre zu 
langsam fall es nur sehr kurz runtergeht.

Du kannst auch mal testen ob der Fehler auch auftritt wenn der µC von 
einer Batterie oder externem Netzteil gespeist wird die etwas Reserven 
haben.
OP #1932784
Lesenswert?

Hi,

die 12V werden von einer anderen Netzteilrail gespeist. Auch weit 
überdimensioniert.

Controller arbeitet mit 5V, allerdings mit gemeinsaer Masse.

Netzteil ist so ein 5V + 12V Schaltnetzteilcombieinheit. (40 watt ca.)

Wenn Probleme durch Antennenwirkung auftreten sollten, kann dies eher 
durch meine Sensorplatine kommen. Dort sind digitale Sensoren 
angebracht, an langer Leitung angeschlossen, die über Multiplexer und 
RS485er Treiber angebunden sind.

Gruß
Bernhard
#1932818
Lesenswert?

könnte es vielleicht sein dass das EEPROM richtig beschrieben wird nur 
die Daten beim Übertragen von deiner Sensorplatine zum µC gestört werden 
und diese falschen Daten dann gebrannt werden. Hier wirst du mit dem 
Oszi mal ran müssen um zu sehen wo der Müll herkommt Datenleitungen oder 
Spannungsversorgung.

Komisch ist auch das dein µC hängen bleibt normal muss der doch einfach 
an der falschen Stelle weiterarbeiten und wenns gerade keine 
Endlosschleife ist sollte er doch auf irgendetwas reagieren.
Gast #1932821
Lesenswert?

Bernhard N. schrieb:
> an langer Leitung angeschlossen
... wie lang ist eine lange Leitung? cm m km ?

Verläuft sie näher als 50cm parallel zum Maschinenstrom?
Evtl. wird was von den Maschinen induziert? Es gab schon verrückte Fälle 
wo der Fahrdraht der Eisenbahn in 40m Entfernung im Büro störte ...
Gast #1934277
Lesenswert?

Mein erster Gedanke bei komplett zerstörtem EEPROM Inhalt und Absturz 
des Controllers ==> Stack-Overflow

Das System läuft unkontrolliert mit irgendwelchen zufälligen Parametern 
in die Routine die das EEPROM beschreibt.
Vielleicht mal einen Stack Monitor einbauen und kontinuierlich 
überprüfen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren