Forum: Mikrocontroller und Digitale Elektronik ATmega328PB macht was er will


von Patrick A. (elektronik_garten)


Lesenswert?

Hallo zusammen,

ich habe aktuell ein Projekt, bei dem mit einem ATmega328PB zwei 
Schrittmotoren, ein Display und ein paar Taster angesteuert werden.
Geschrieben ist alles in C++ mit Atmel Studio

Jetzt ist das Programm soweit fertig und ich bin ausgiebig am Testen.
Dabei ist mir aufgefallen, dass manchmal einfach irgendein Programmteil 
ausgeführt wird. Zum Beispiel nimmt man eine Einstellung vor und 
plötzlich wird die programmierte Referenzfahrt durchgeführt.
Es schein mir so als wenn der Speicherbereich von Steuervariablen 
überschrieben wird. Aber nie reproduzierbar.
Das ganze Programm ist mit einer Vielzahl von Zustandsautomaten 
programmiert.

Was ich schon gemacht habe:
Alles mehrfach kontrolliert und Fehler gesucht.
Die Compiler Optimierung abgeschaltet. Es passiert zwar seltener aber 
immer noch hin und wieder.
Neuen Controller verbaut, aber gleiche Problematik.

Hat jemand von euch eine Idee woran es liegen könnte oder einen Tipp, wo 
ich nochmal schauen könnte?

Ich wünsche euch allen einen schönen sonnigen Nachmittag.

Beste Grüße
Patrick

von DerEinzigeBernd (Gast)


Lesenswert?

Patrick A. schrieb:
> Hat jemand von euch eine Idee woran es liegen könnte

An einem Fehler in Deinem Programm oder einem Problem mit Deiner 
Schaltung.

Der µC selbst hat keinen Fehler, jedenfalls keinen, der solch ein 
Verhalten hervorrufen könnte.

von Sebastian R. (sebastian_r569)


Lesenswert?

Motoren führen gerne entweder zu EMV-Problemen oder zu Problemen mit der 
Spannungsversorgung.

Kannst du die Störungen provozieren? Wie ist der Aufbau? Ist das Layout 
ausreichend gut? Wie erfolgt die Spannungsversorgung?

von Falk B. (falk)


Lesenswert?

Patrick A. schrieb:
> ich habe aktuell ein Projekt, bei dem mit einem ATmega328PB zwei
> Schrittmotoren, ein Display und ein paar Taster angesteuert werden.
> Geschrieben ist alles in C++ mit Atmel Studio

Wahrscheinlich eher C, aber das ist nebensächlich.

> Jetzt ist das Programm soweit fertig und ich bin ausgiebig am Testen.
> Dabei ist mir aufgefallen, dass manchmal einfach irgendein Programmteil
> ausgeführt wird. Zum Beispiel nimmt man eine Einstellung vor und
> plötzlich wird die programmierte Referenzfahrt durchgeführt.
> Es schein mir so als wenn der Speicherbereich von Steuervariablen
> überschrieben wird. Aber nie reproduzierbar.

Klingt nach Stacküberlauf. Wieviel RAM ist noch frei?

von Oliver S. (oliverso)


Lesenswert?

Patrick A. schrieb:
> Hat jemand von euch eine Idee woran es liegen könnte oder einen Tipp, wo
> ich nochmal schauen könnte?

Das Problem liegt an und in deiner Software, oder es ist ein Problem mit 
der Hardware, oder auch beides. Danach solltest du dann mal schauen.

Viel mehr lässt sich aus deiner Fehlerberschreibung "macht nicht, was es 
soll" nicht herauslesen.

Oliver

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


Lesenswert?

Patrick A. schrieb:
> Hat jemand von euch eine Idee woran es liegen könnte
Mit allergrößter Wahrscheinlichkeit an der Software. Oder an der 
Hardware.

> oder einen Tipp, wo ich nochmal schauen könnte?
du solltest versuchen, den Fehler systematisch zu suchen. Ist die 
Versorgung immer stabil? Passiert die Effekte nur, wenn die Motoren 
laufen? Oder reicht es aus, wenn du nur lange genug wartest?

> wo ich nochmal schauen könnte?
Du solltest schauen, ob du einen amoklaufenden Pointer hast. Z.B. das 
übliche Array, das 1 Element zu klein ist. Oder die serielle Schnitte, 
die geradeaus weiter in den Speicher schreibt.

: Bearbeitet durch Moderator
von Heiner (Gast)


Lesenswert?

Was passiert, wenn nur 1 Motor angesteuert wird?
Was passiert, wenn beide Motoren angesteuert werden, das Display aber 
nicht?

Auf deutsch - versuche, den Fehler systematisch einzugrenzen durch nicht 
ansteuern von Komponenten

Viel Glück

von Stefan F. (Gast)


Lesenswert?

Wenn man gar keinen Schimmer hat, kann man auch versuchen, Teile des 
Programms auszukommentieren. Man entfernt schrittweise immer mehr Teile, 
bis es wieder funktioniert. Dann schau man sich nochmal ganz genau den 
zuletzt entfernten Teil an.

von Christian S. (roehrenvorheizer)


Lesenswert?

Patrick A. schrieb:
> dass manchmal einfach irgendein Programmteil
> ausgeführt wird. Zum Beispiel nimmt man eine Einstellung vor und
> plötzlich wird die programmierte Referenzfahrt durchgeführt.

Sieht aus wie Stacküberlauf. Vermutlich gibt es zu viele verschachtelte 
Unterprogramme oder zu viele Variablen, die auf dem Stack gesichert 
werden müssen. Man untersuche auch, ob Interruptroutinen etliche 
Variablen auf dem Stack sichern müssen.

mfg

von Hiller (Gast)


Lesenswert?

Patrick A. schrieb:
> Hallo zusammen,
>
> ich habe aktuell ein Projekt, bei dem mit einem ATmega328PB zwei
> Schrittmotoren, ein Display und ein paar Taster angesteuert werden.
> Geschrieben ist alles in C++ mit Atmel Studio

Wird im Programm viel mit der String Klasse gemacht, oder mit "new" 
Objekte erzeugt und wieder gelöscht? Dann kann auch der Heap Bereich 
fragmentieren bzw. den Stack überschreiben.

von Stefan F. (Gast)


Lesenswert?

Wenn Verdacht auf Heap-Überlauf bzw Fragmentierung besteht, kann man 
sich in die Hauptschleife eine Ausgabe des freien Speichers einbauen und 
dass dann z.B. jede Sekunde machen.

Dazu mit malloc() antesten, wie viel Speicher man maximal bekommen kann.

Versuche zuerst 4 kB, dann 2 kB, dann 1 kB, dann 1/2 kB, dann 1/4 kB 
usw. zu belegen. Der erste erfolgreiche Aufruf zeigt dir grob an, wie 
viel Speicher frei ist. Wenn das im Laufe der Zeit immer wenig wird, 
hast du wahrscheinlich einen Heap Überlauf.

Nicht vergessen, diesen Testblock wieder frei zu geben.

von DerEinzigeBernd (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Versuche zuerst 4 kB, dann 2 kB, dann 1 kB, dann 1/2 kB, dann 1/4 kB
> usw. zu belegen.

Bei nur 4 kB RAM insgesamt wird der erste Versuch schiefgehen, denn 
irgendwo sollte ja auch der Stack liegen. Und wenn Stringkonstanten 
verwendet werden, belegen die auch gerne Platz im RAM (dank der 
Harvard-Architektur der AVRs).

von Falk B. (falk)


Lesenswert?

Stefan ⛄ F. schrieb:
> Wenn Verdacht auf Heap-Überlauf bzw Fragmentierung besteht, kann man
> sich in die Hauptschleife eine Ausgabe des freien Speichers einbauen und
> dass dann z.B. jede Sekunde machen.

https://rn-wissen.de/wiki/index.php/Speicherverbrauch_bestimmen_mit_avr-gcc

von Oliver S. (oliverso)


Lesenswert?

Falk B. schrieb:
> https://rn-wissen.de/wiki/index.php/Speicherverbrauch_bestimmen_mit_avr-gcc

Das ist nett bei so gut wie statischer Belegung des SRams, aber bei 
intensiverer Nutzung des heaps wenig bis gar nicht hilfreich.

Oliver

von Falk B. (falk)


Lesenswert?

Oliver S. schrieb:
> Das ist nett bei so gut wie statischer Belegung des SRams, aber bei
> intensiverer Nutzung des heaps wenig bis gar nicht hilfreich.

Einfach mal weiter lesen, Überschrift "Dynamischer RAM-Verbrauch"

von Oliver S. (oliverso)


Lesenswert?

Falk B. schrieb:
> Einfach mal weiter lesen, Überschrift "Dynamischer RAM-Verbrauch"

Eben. Das solltest du mal tun.
"Damit der Code den richtigen Wert liefert, darf keine dynamische 
Speicherallokierung mit malloc() etc. geschehen sein"

Oliver

von Stefan F. (Gast)


Lesenswert?

In einem embedded Webserver nutze ich diese Funktion innerhalb des HTTP 
Request Handlers:
1
// Show the largest available block of free memory
2
static unsigned short function_freememory(char* buffer) {
3
    void *p = 0;
4
    size_t size;
5
    for (size = RAMEND; size > 1; size -= 10) {
6
        p = malloc(size);
7
        if (p != 0) {
8
            break;
9
        }
10
    }
11
    if (p != 0) {
12
        free(p);
13
    }
14
    else {
15
        size=0;
16
    }
17
    return sprintf_P(buffer,PSTR("%5u"),size);
18
}

Die Funktion schreibt die das Ergebnis als Text in den Buffer und 
liefert die Anzahl der Zeichen zurück.

Fragt mich bitte nicht, von wo ich das kopiert habe. Habe ich vergessen. 
Es könnte dieses Forum gewesen sein.

Wenn es ein bisschen schneller gehen soll kann man die Schrittweite von 
10 auf 100 ändern. Für meine Zwecke passte das aber so, da ich sie eh 
manuell (per HTTP Request) aufrufen musste.

von Falk B. (falk)


Lesenswert?

Oliver S. schrieb:
> Eben. Das solltest du mal tun.
> "Damit der Code den richtigen Wert liefert, darf keine dynamische
> Speicherallokierung mit malloc() etc. geschehen sein"

Und wer sagt, daß der Op dieses verwendet? Bisher herrscht da Schweigen 
im Walde.

von Peter D. (peda)


Lesenswert?

Patrick A. schrieb:
> Es schein mir so als wenn der Speicherbereich von Steuervariablen
> überschrieben wird.

Klingt nach wildem Pointer. Entweder ein Array ist zu klein oder ein 
16Bit-Wert wird versucht, auf einen Pointer auf 8Bit zu schreiben.

Ein Stackproblem läßt sich schnell ausschließen. Man füllt den Stack 
z.B. mit 0x77 und schaut sich den RAM-Dump an. Oder eine Routine zählt, 
wieviel 0x77 noch übrig sind. Es sollten wenigstens noch 16 Byte sein.

von späh kulant (Gast)


Lesenswert?

Seltsam das auch die erfahrensten Leute hier nicht (jedenfalls
nicht öffentlich) darüber nachdenken dass es sich auch einfach
um massive Störungen auf der Stromversorgung handeln könnte.

von DerEinzigeBernd (Gast)


Lesenswert?

späh kulant schrieb:
> dass es sich auch einfach
> um massive Störungen auf der Stromversorgung handeln könnte.

Sieh mal hier (betreffende Stelle hervorgehoben):

DerEinzigeBernd schrieb:
> An einem Fehler in Deinem Programm *oder einem Problem mit Deiner*
> Schaltung.

Das schließt Störungen der Stromversorgung mit ein.

von Heiner (Gast)


Lesenswert?

Liest der TO ueberhaupt noch mit, da bislang keinerlei Rueckmeldung kam 
...

von späh kulant (Gast)


Lesenswert?

Heiner schrieb:
> Liest der TO ueberhaupt noch mit, da bislang keinerlei Rueckmeldung kam

Na wenn hier von Stack und Heap geredet wird und er noch
nicht mal weiss was das ist ...... kann man schon mal die
Flucht ergreifen.

von Stefan F. (Gast)


Lesenswert?

späh kulant schrieb:
> Seltsam das auch die erfahrensten Leute hier nicht (jedenfalls
> nicht öffentlich) darüber nachdenken dass es sich auch einfach
> um massive Störungen auf der Stromversorgung handeln könnte.

Haben sie doch! Seltsam dass manche Leute nicht lesen bevor sie andere 
kritisieren.

Sebastian R. schrieb:
> Motoren führen gerne entweder zu EMV-Problemen oder zu Problemen mit der
> Spannungsversorgung... Wie erfolgt die Spannungsversorgung?

Oliver S. schrieb:
> Das Problem liegt an und in deiner Software, oder es ist ein Problem mit
> der Hardware, oder auch beides. Danach solltest du dann mal schauen.

Heiner schrieb:
> Was passiert, wenn nur 1 Motor angesteuert wird?

Drei entsprechende Hinweise sollten reichen, oder wie viele 
Wiederholungen hättest du gerne gehabt?

von Christian S. (roehrenvorheizer)


Lesenswert?

Patrick A. schrieb:
> oder einen Tipp, wo
> ich nochmal schauen könnte?

vielleicht bei den beliebten Abblockkondensatoren?

mfg

von Keller (Gast)


Lesenswert?

Geduld

Noo net huudle!

von Heiner (Gast)


Lesenswert?

Obba  a Leemszeichn vom TO wäähr ned schlechd, odda 😉

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.