- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 15

Thema: wieder mal unerklärliche Resets

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521

    wieder mal unerklärliche Resets/Programmfehler

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo zusammen,

    Ich kämpfe wieder mit unerklärlichen Resets, und je mehr ich versuche Fehler zu vermeiden, desto weniger funktioniert. Mal fährt er 5 Minuten richtig, mal 2h, zuletzt hatte ich alle Arrays global definiert, und dann stürzt er nach 1 Minute ab.
    Sieht nach Stacküberlauf oder falschen Array Index aus, ich seh aber einfach den Fehler nicht.

    Verwendet wird ein Atmega1284P mit 16Mhz, sollte also mit 16kB mehr als genug RAM vorhanden sein da zuvor ein 644 mit 4kB verwendet wurde. Speicherbedarf der Arrays + globale Variablen derzeit bei knapp 4kb, dazu die einzelnen Funktionen mit in Summe ca 100Byte.
    Die Änderungen gegenüber dem Code für den 644er sind: Entfall von UART, Entfall vom LCD, und dafür mehr am TWI (Fleury lib), mehr Sensoren/Bumper ausgewertet. Also im Prinzip den alten Code genommen, UART und LCD gegen TWI Routinen getauscht, und Auswertung von 4 statt 1 Bumper. Arrays sind schon extra größer als notwendig definiert. Und ich bekomme das ehemals stabile Programm nicht mehr zum laufen.



    Ich poste hier mal den Code der am ehesten für die Fehler verantwortlich ist:

    die Arrays (für A* testweise global, ansonsten in der Funktion definiert)
    Code:
    #define grund_x 23 // 23 Anzahl Felder W-O
    #define grund_y 42 //42 Anzahl Felder S-O
    unsigned char Karte[grund_x+1][grund_y+1];
    
    #define kartenfeld 100 // Größe eines Kartenfeldes in 1cm Einheit= 1m X 1m
    #define pos_x_max (grund_x*kartenfeld-1)
    #define    pos_y_max (grund_y*kartenfeld-1)
    
    // A*: Rand wird nicht berücksichtigt, daher um 2 kleiner
    #define max_x_karte     grund_x-2
    #define max_y_karte     grund_y-2
    #define max_x             max_x_karte-1
    #define max_y             max_y_karte-1
    
    unsigned char x_vor_l_punkt[max_x_karte+1][max_y_karte+1]; // l_punkt <100, 100, 200, x_vor 0-99
    unsigned char y_vor[max_x_karte+1][max_y_karte+1];
    unsigned char g_wert[max_x_karte+1][max_y_karte+1];
    für die Karte gibts eigene Routinen um Fehler auszuschließem:
    Code:
    unsigned char Karte_lesen(unsigned char x, unsigned char y)
    {
    unsigned char wert;
    wert=150;
    if ((x<grund_x)&&(y<grund_y))
          {
            wert=Karte[x][y];
          }
    return(wert);
    }
    
    void Karte_schreiben(unsigned char x, unsigned char y, unsigned char wert)
    {
    if ((x<grund_x)&&(y<grund_y)&&(x>=0)&&(y>=0)) 
          {
            if (wert==0)
                { 
                 if (Karte[x][y]<100) Karte[x][y]++;
                }
            else 
                {
                if (Karte[x][y]<besetzt) Karte[x][y]=wert;
                if (wert==besetzt) Karte[x][y]=besetzt; // für initialsierung der Karte notwendig
                }
          }
    }
    im A* sieht es so aus:
    Code:
    for (xt=0;xt<=max_x;xt++)// niedrigsten f-Wert ermitteln
                    {
                    for (yt=0;yt<=max_y;yt++)
                        {
                        if ((x_vor_l_punkt[xt][yt]>=100)&&(x_vor_l_punkt[xt][yt]<200))  // Punkte auf open List vergleichen
                        
                            {
                               
                            ff=2*((abs(xt-x_ziel))+(abs(yt-y_ziel)));
                            fwert=g_wert[xt][yt]+ff;// f=g+ h-Wert
                                for (ii=0;ii<8;ii++)
                                    {
                                        if (ii==0) {xx=xt;yy=yt+1;}
                                        if (ii==1) {xx=xt;yy=yt-1;}
                                        if (ii==2) {xx=xt+1;yy=yt;}
                                        if (ii==3) {xx=xt-1;yy=yt;}
                                        if (ii==4) {xx=xt+1;yy=yt+1;}
                                        if (ii==5) {xx=xt+1;yy=yt-1;}
                                        if (ii==6) {xx=xt-1;yy=yt+1;}
                                        if (ii==7) {xx=xt-1;yy=yt-1;}
            
                                        if (xt<=0) {xx=0;}
                                        if (yt<=0) {yy=0;}
                                        if (xx>max_x) {xx=max_x;}
                                        if (yy>max_y) {yy=max_y;}    
            
                                        if (Karte_lesen(xt,yt)>=blockiert) fwert=fwert+2;    
                                    }    
                        
                            if (fwert>512) fwert=512;
                        
                            if (fwert<temp)
                                {temp=fwert;xf=xt;yf=yt;}
                            }
                        }
                    }

    In Verdacht habe ich auch die ISR, da diese doch länger ist:

    Code:
    /*+++++++Timer2++++++++++++++++*/
        TCCR2A = (1<<WGM21);// CTC Mode
    
    
            TCCR2B = (1<<CS22); // Prescaler 64
            TIMSK2 = (1<<OCIE2A); //Interupt compare match enable
            OCR2A=23; // alle 0,1ms 1 Interrupt
            
            
        /*+++ Interrupt Messer +++++++++*/
        EICRA |= (1<<ISC20) | (1<<ISC21); // steigende Flanke
        EIMSK |= (1<<INT2); // Int enable
    
        /*+++ Interrupt Vorderrad +++++++++*/
        PCICR |= (1<<PCIE3); // Int 31-24 enable
        PCMSK3 |= (1<<PCINT24); // Pin D0
    
        /*+++ Interrupt Odo Links +++++++++*/
        EICRA |= (1<<ISC10) ; // jede Flanke
        EIMSK |= (1<<INT1); // Int enable
        /*+++ Interrupt Odo Rechts +++++++++*/
        EICRA |= (1<<ISC00); // jede Flanke
        EIMSK |= (1<<INT0); // Int enable
    
    
    
    
    /********** Interrupts ***********************************/
    
    volatile unsigned char timecount,odo_li,odo_re,timer_zwei, mowerspeed;
    volatile short i_summe,v_alt;
    volatile unsigned short drehzahl_ist;
    volatile unsigned short radcount, messer_zeit;
    
    ISR(ISR_Timer2)
    {
    timer_zwei++;
    messer_zeit++ ; if (messer_zeit>14000) messer_zeit=14000;
    if (timer_zwei>100) 
        {timer_zwei=0;
        timecount++; 
        radcount++;
        }
    
    
    
    }
    
    ISR(INT0_vect) //Odo_re
    {
    odo_re++;
    
    }
    
    ISR(INT1_vect) // Odo_li
    {
    odo_li++;
    
    }
    
    
    ISR(INT2_vect) // Messerdrehzahl
    {
    short mowersp,v;
    
    
        drehzahl_ist= (unsigned short)(300000L/messer_zeit);
    
            v = (short)(drehzahl_soll-drehzahl_ist);                    //Vergleich
            i_summe = i_summe + v/10;    //(i_summe*9)/10 + v;    //Integration I-Anteil
            if (i_summe < -1000) i_summe = -1000;            //Begrenzung I-Anteil
            if (i_summe > 1000) i_summe = 1000;
    
    
            mowersp=(3*v+15*((i_summe))+8*((v -v_alt)))/80; 
            v_alt=v;
    
            if (mowersp < 77) mowersp = 77;            //Begrenzung Stellgröße
            if (mowersp > 255) mowersp = 255;    
            mowerspeed=(unsigned char)(mowersp);
            Mower=mowerspeed;
            messer_zeit=0;
    
    
    }
    
    
    ISR(PCINT3_vect) // Vorderrad
    {
    radcount=0;
    }
    die Messerdrehzahl, bzw PWM Wert für den Motor wird 2x pro Umdrehung berechnet, dh bei 2 Impulse pro Umdrehung und 2500U/min ca alle 12ms.

    Pointer gibt es im Programm ausser den Arrays keine, was sonst kann den Code noch ruinieren?

    Kämpfe mich mit Zeit und Schlafmangel schon wochenlang durch den Code, bin für jeden Hinweis dankbar!

    LG!
    Geändert von damfino (31.08.2011 um 11:14 Uhr) Grund: Titel ausgebessert
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  2. #2
    Benutzer Stammmitglied Avatar von KR-500
    Registriert seit
    26.12.2007
    Alter
    29
    Beiträge
    91
    Hi,

    also nurmal so ein paar Ideen um den Fehler einzugrenzen, ich nehme an das du einen Rasenmäherroboter bauen willst Und wenn Motoren im Spiel sind würde ich auf jeden Fall gucken ob der Reset nicht durch einen Spannungseinbruch zu Stande kommt, wenn zum Beispiel die Motoren auf einmal mehr Strom ziehen. Du kannst es ja einfach mal testen indem du ein Rad probeweise belastest. Das musst du natürlich nur probieren wenn Motor und µc aus der selben Batterie gespeist werden.
    Eine weitere Idee wäre einfach mal über die USART zu debuggen und Probeweise alle Variablen ausgeben lassen, so kannst du gucken ob irgendwelche Indexe zu weit gehen.

    Viele Grüße
    KR-500

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521
    Hi,
    die Versorgung der Kontroller ist über Dioden von den Motoren getrennt, und mit 470µF Elko (nach der Diode) gepuffert. Der 2. Kontroller, ein Atmega32, funktioniert immer.
    Aber der Hauptkontroller hat irgendwann Fehler in der Programmausführung, bzw wenn aktiviert spricht der Watchdog an.

    Bisher gab es auch keine Resets wenns den Mäher im hohen Gras gewürgt hat, die Akkus haben mittlerweile wieder volle Leistung und könnten 50A liefern, daher vermute ich den Fehler in der Software.

    LG!
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  4. #4
    Benutzer Stammmitglied Avatar von KR-500
    Registriert seit
    26.12.2007
    Alter
    29
    Beiträge
    91
    Hi,

    ok dann kann man die Stromversorung ja auschließen. Aus deinem ersten Post entnehme ich das der Fehler eher sporadisch auftritt, was es natürlich noch mal schwieriger macht den Fehler asufindig zu machen

    Und ich bekomme das ehemals stabile Programm nicht mehr zum laufen.
    Hast du denn mal Probiert ob deine alte stabile Version des Programms überhaupt noch läuft auf dem Atmega1284P? Wäre sicher gut zu wissen, ob der Controller funktioniert.

    Ich hatte mal ein ähnliches Problem bei dem sich der Controller immer wieder sporadisch resettet hat, dabei hatte ich versehentlich den USART Empfangsinterrupt aktiviert aber keine entsprechende ISR-Routine dazu gehabt, mit anderen Worten, immer wenn etwas über die Serielle Schnittstelle an den Atmega gesendet wurdem stürzte er ab. Vielleicht hast du auch irgendwo einen interrupt aktiviert aber keine ISR Definiert, dann dürfte der Controller ja irgendwo hinspringen bzw sogar an die Addresse Null, und würde sich somit resetten. (Ich hoffe das war jetzt richtig^^)

    KR-500

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521
    Das alte Programm kann leider nicht 1:1 verwendet werden. Grund für den Umbau war der Mangel an I/O Pins, deswegen sind das LCD und GPS (UART) auf den 2. Kontroller gewandert, und die Kommunikation erfolgt über TWI.
    Die aufwändigen Berechnungsroutinen von Navigation und Karten Arrays sind identisch, die Ausgaben fürs LCD mussten natürlich geändert werden. TWI wurde aber schon vorher verwendet.

    Letztes Jahr nur kurz in Betrieb war die ISR für die Messerdrehzahl, hier gab es noch einige Änderungen bis der PID Regler verlässlich funktionierte.

    Wegen fehlgeleiteter ISR ist das eingebaut:
    Code:
    ISR (__vector_default) // falsche Interrupt erkennen, abbrechen
    {cli();PORTC &= ~( (1<<DDC2) | (1<<DDC3) );PORTC &= ~( (1<<DDC4) | (1<<DDC5) );PORTC |= (1<<DDC6) | (1<<DDC7);
    ;LED_rot_ein;Anzeige_Sonder(18);
    while(1) {wdt_reset();}
    Schaltet alle Motoren ab und ich bekomme eine entsprechende Anzeige am LCD.

    Ich hatte letztes Jahr ganz ähnliche Aussetzer, damals war das Karten Array schuld.

    Der Fehler ist einigermaßen reproduzierbar, seitdem ich die A* Arrays global definiert hab:
    Er stürzt nach 1 Umdrehung bei der Spiralfahrt ab. Dabei wird A* aber nicht verwendet. Das Kartenarray wird verwendet, über die oben angeführten Routinen die dafür sorgen sollen dass die Array Grenzen eingehalten werden.

    Ein Variablenüberlauf kann dafür sorgen dass eine Berechnung falsch ausgeht, zB wird aus 18000 wegen Überlauf -14000. Falsch berechnete Positionen sollten die Kartenroutinen abfangen. Aber das stört doch nicht den normalen Programmablauf mit unberechenbarem Verhalten, oder?

    Oder was kann noch alles den Stack durcheinander bringen?

    LG!
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Versuch Mal, nach und nach Programmkomponenten zu deaktivieren (zum Beispiel besagten A*), vielleicht lässt sich so die Problemzone eingrenzen. Debug-Ausgaben über den Aufruf einzelner Routinen können ebenfalls helfen, um (ungewollt) aufgerufene Programmteile zu identifizieren.

    mfG
    Markus

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521
    Ich konnte jetzt wieder mal testen:
    .) A* und Navigation deaktiviert (Funktionen gelassen, Inhalt auskommentiert): Absturz innerhalb 1 min.
    .) alle Inline Funktionen wieder normal eingebunden: wieder viele Abstürze
    .) den ganzen Code auf Fehler durchsucht, wieder mal nichts gefunden.
    .) Brownout aktiviert, jetzt gibt es eher das Problem dass dieser gleich beim einschalten aktiviert wird.
    .) ebenso versucht das Register vom Power on Reset auszuwerten, aber damit bekommt man den Kontroller gleich gar nicht zum laufen. Wollte damit einen eventuellen schlechten Kontakt der Steckverbindungen erkennen.

    Derzeit verwende ich die letzte halbwegs stabile Version, nur die ISR vom PID Regler ist inzwischen etwas optimiert. Einmal löste der Watchdog nach ein paar Minuten aus, jetzt ist er grade >2h ohne Fehlfunktion gefahren.
    Ich hatte auch mal den Watchdog deaktiviert, aber dann macht im Fehlerfall das Programm was es will, da ist es besser wenn der Watchdog mal die Notbremse zieht. Ist mit 4s auch großzügig einstellt.

    Sieht also nach Stackproblem aus, nur wie findet man den Fehler?

    LG!
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    49
    Beiträge
    2.253
    Zum Einen sind Variablennamen wie xx xy yyxx etc. nur sehr übel zu debuggen,
    eindeutigere Namen helfen da mitunter schon den Baum im Wald besser zu sehen ...
    ich verwende z.B. in Variablennamen auch häufig gleich das jeweilige Format mit im Namen z.B.
    x_pos_1_byte,
    dann kann ich in Rechenoperationen gleich
    "abschätzen" ob der Wert oder die Berechnung in die Variable passen kann.
    Vor den Erfolg haben die Götter den Schweiß gesetzt

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    A* und Navigation deaktiviert (Funktionen gelassen, Inhalt auskommentiert): Absturz innerhalb 1 min.
    Wunderbar, das ist eine brauchbare Grundlage für den später beschriebenen Test.

    Brownout aktiviert, jetzt gibt es eher das Problem dass dieser gleich beim einschalten aktiviert wird.
    Doch Spannungsprobleme? So wie die eingestellte Spannung überschritten wird, sollte der AVR loslaufen ...

    ebenso versucht das Register vom Power on Reset auszuwerten, aber damit bekommt man den Kontroller gleich gar nicht zum laufen. Wollte damit einen eventuellen schlechten Kontakt der Steckverbindungen erkennen.
    Warum läuft er da nicht an? Da würde ich mich Mal dahinter klemmen, das klingt ... komisch.

    Sieht also nach Stackproblem aus, nur wie findet man den Fehler?
    Es gibt einen Trick um die Speichernutzung zu betrachten: Den kompletten Speicher mit einem bestimmten Wert beschreiben und dann später nachsehen, wieviel von diesem Wert/Muster noch vorhanden ist. Sieh dir Mal den RN-Wissen Artikel Speicherverbrauch bestimmen mit avr-gcc an.
    Mit der o.g. Variante die schon nach einer Minute abschmiert kannst du so schnell rauskriegen, wie sich der Speicherverbrauch entwickelt.

    mfG
    Markus

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521
    Hi,

    die uninspiriten Variablennamen wie xx werden nur als einfache Zähler innerhalb einer Funktion verwendet, wichtige Zwischenergebnisse haben normalerweise sinnvolle Bezeichnungen.
    Ein Überlauf könnte aber nur ein falsches Ergebnis, aber keine fehlerhafte Ausführung des Programmes bewirken, oder? Wenn die Positionsbestimmung falsch läuft, muss er zB trotzdem die Bumper beachten.

    Die Speichernutzung habe ich eingebaut, wird laufend statt der Pos_x im LCD angezeigt, es gibt also keine größere Änderung im Programmablauf. Morgen Abend kann ich wieder testen.

    Die Einschaltprobleme könnten vom Stepdown Regler kommen, ich muss die 5V Seite schalten und nicht die 12V damit die Kontroller richtig starten. Aber ohne Oszi wird eine Diagnose schwierig. Vorm Wandler ist ein 470µF Elko, die Kontroller haben alle Abblockkondensatoren und 10k Pullup am Reset. Der 1284 hat zusätzlich einen 100nF am Reset. Der Atmega32 fürs GPS und Display läuft ohne Probleme, die größeren 644 und 1284 sind anscheinend empfindlicher, das musste ich letztes Jahr schon feststellen. Deshalb auch der 2A Step down Regler anstatt eines heisslaufenden 7805.

    LG!
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Ich werd noch Irre - unerklärliche Taktverdoppelung
    Von vajk im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 8
    Letzter Beitrag: 11.11.2010, 21:30
  2. Unerklärliche Programmfehler
    Von damfino im Forum C - Programmierung (GCC u.a.)
    Antworten: 31
    Letzter Beitrag: 07.09.2010, 19:07
  3. Unerklärliche Spannung
    Von triti im Forum Elektronik
    Antworten: 14
    Letzter Beitrag: 06.11.2007, 06:48
  4. unerklärliche Spannung am ADC Eingang
    Von Johnny6 im Forum AVR Hardwarethemen
    Antworten: 16
    Letzter Beitrag: 31.07.2006, 12:40
  5. Mal wieder PWM
    Von Olle_Filzlaus im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 22.05.2006, 22:57

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad