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)
für die Karte gibts eigene Routinen um Fehler auszuschließem: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];
im A* sieht es so aus: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 } } }
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:
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.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; }
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!







Zitieren

Lesezeichen