damfino
01.06.2015, 11:21
Verzeifle gerade mit meinem Roboter: alle Motoren getestet, läuft, Deckel rauf, in den Garten, der Start vom Messermotor entspricht schon nicht dem Code, dann gleich alles tot, läuft in den Watchdog rein.
Hab nach langem suchen Herausgefunden dass die Interrupts , bzw Timer nicht aufgerufen werden, aber warum ist mir ein Rätsel. Lief ja schon.
zB Timer3, der steuert den gesamten Programmablauf
Funktion init:
/*+++++++Timer3++++++++++++++++*/
//CTC Mode
TCCR3B = (1<<CS32)|(1<<CS30)|(1<<WGM32); // Prescaler 1024
TIMSK3 = (1<<OCIE3A);//Interupt compare match enable
OCR3A=154; // alle 10ms 1 Interrupt
ISR(TIMER3_COMPA_vect)
{
static unsigned char tasktimer,tasktimersek;
short v, mowersp,temp_mower,drehtemp;
static short i_summe; // Testen ob das passt
static short i_summe_spe_li,i_summe_spe_re;
short spe_li,spe_re;//,temp;
short v_li,v_re;
radcount++;
tasktimer++;
tasktimersek++;
.
.
.
}
grundsätzlich soll bei einer falschen ISR abgeschalten werden:
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;
flag_messer_aus=True;TCCR0B &= ~ (1<<CS01)|(1<<CS00);
Anzeige_Sonder(18);
while(1){wdt_reset();}
}
und so ist der Anfang der main:
int main(void)
{
short richtung_soll,richtung_temp,zeitstart,zeittemp;
char modus;//,v_min_count;
unsigned short felder; //,; //16Bit 65535
unsigned char x,y, z, sekunde, temp;
char bl,br,bv,s;//,bh
init(); //Porteinstellungen, Timer, PWM, LCD
lcd_gotoxy(0,0);lcd_puts_p(PSTR("einschalten"));
i2c_init();_delay_ms(10);
LED_gr_ein;LED_rot_aus;
Motor_li_stop();Motor_re_stop();Mower_stop();
// Watchdog
// Watchdog-Reset //Brown out // Power reset
if ((mcusr_mirror & (1 << WDRF)))//||(mcusr_mirror & (1 << BORF)))//||(mcusr_mirror & (1 << PORF)))
{
Anzeige_Sonder(LCD_WATCHDOGK1); // "!WATCHDOG! "
Motoren_stop();Mower_faststop();
}
wdt_enable(WDTO_4S);
sei(); //Interupt ein
wdt_reset();
Einlesen(); // letzten Stand der Karte lesen
Karte_init(); // Karte initializieren ( auch wenn im EEPROM => muss! damit besetzte Felder sicher eingetragen werden)
//----------------------------------- Funktionstest TWI ------------------------------
Anzeige_Sonder(LCD_Kontroller1OK); //"Kontroller 1 OK!"
Akkuspannunglesen();Akkuspannunglesen();Akkuspannu nglesen(); // gleich oft wie Werte gemittelt werden
Akkucheck();
//Warten();Warten();
richtung_kom =0;
if(i2c_start(Adresse_Kompass)==0)
{
i2c_write(1); // register
i2c_rep_start(Adresse_Kompass); // restart
richtung_kom = (short)i2c_readNak(); // read 1 byte //neuen Wert lesen;
i2c_stop();
if (richtung_kom!=0) Anzeige_Sonder(LCD_KompassOk); // "Kompass ok!
}
else {Anzeige_Sonder(LCD_FehlerKompass); // "Kompass Fehler!
//while(1);
}
//Warten();Warten();
Und wenn man die Funktion "Warten()" aktiviert hauts da das Programm raus, oder mit auskommentierter Funktion eben an einer anderen Stelle wo der Watchdog zuschlägt:
/*++++++++ Warten 0,5s +++++++++++++++++++++++++++++++++++++*/
static inline void Warten(void)
{
char x;
x=0;
while (x<2)
{
if (gps_str_complete>GPS_Receive_Complete) GPS();
if (Funk_Daten) RXFunk();
TX_Funk();
if (taskflag==taskdatenflag)
{
taskflag=taskflagclear;
DatatoSlave();
}
if (taskflag==task250msflag)
{ taskflag=taskflagclear;
Messercheck();
x++;
wdt_reset();
}
}
}
Verwendet wird ein Arduino Mega2560, aber nicht in Arduino Umgebung sondern normal mit Atmel Studio 6.2. Stromversorgung über DC Wandler direkt auf 5V, der Linearregler vom Arduino wird umgangen.
Programm funktioniert ansonsten normal, kann Bootloader raufgeben, über Bootloader flashen (via Bluettoth), die Anzeigen am LCD werden alle ausgegeben.
Hatte auch extra eine LED in der Timer ISR geschalten, nichts gesehen. Hatte die ISR auf Timer5 unbenannt, hätte im Programm die falsche ISR erkannt und abgebrochen werden müssen, aber nichts ist passiert.
Hab alles kontrolliert ob nicht irgendwo ein nicht erkanntes cli() versteckt ist.
Ist ja nicht das erste Mal dass ich ISR programmiere, die ersten Tests vom Code nach der Umstellung der Hardware liefen seit Jänner, und hatte keine Probleme.
Hatte schon früher mal eine Frage wegen Anzahl der ISR gestellt, und dabei extra ISR's eingebaut um den Ablauf zu testen, gab damals kein Problem
Kann man über Fuses die ISR /Timer abschalten?
Wie kann es sonst sein dass die ISR nicht mehr funktionieren?
Hab 3 Tage lang die PI Regler der Motoren optimiert (die auch in einer ISR ablaufen), die Akkuanzeigen kalibriert, alles lief normal.
Jetzt kommt man gar nicht mehr soweit dass die Motoren laufen würden...
Habe anstatt Timer 3 auch mal auf Timer 5 (Timer + ISR) umgestellt, exakt das gleiche.
Für einen Hardwaredefekt wäre das wohl zu selektiv, oder? Da müsste doch der ganze Programmablauf hinüber sein. Obwohl, die ersten Sekunden im Garten waren schon ein falscher Programmablauf, aber am Abend zuvor im Arbeitszimmer hatte es zu 100% funktioniert. Sollten die Motoren nach 3 Jahren in Betrieb auf einmal stören??. Aber warum geht es dann auch nicht ohne Motoren?
Ach ja, die Watchdog Ausgabe am LCD kommt nur wenn kein Bootloader drauf ist. Mit Bootloader wird einfach nach 4s das Programm neu gestartet. Dachte deswegen es liegt am Bootloader, aber egal, mit und ohne geht es nur bis der Watchdog zuschlägt
Keine Ahnung nach was ich suchen könnte, jede Idee wäre hilfreich.
LG!
Hab nach langem suchen Herausgefunden dass die Interrupts , bzw Timer nicht aufgerufen werden, aber warum ist mir ein Rätsel. Lief ja schon.
zB Timer3, der steuert den gesamten Programmablauf
Funktion init:
/*+++++++Timer3++++++++++++++++*/
//CTC Mode
TCCR3B = (1<<CS32)|(1<<CS30)|(1<<WGM32); // Prescaler 1024
TIMSK3 = (1<<OCIE3A);//Interupt compare match enable
OCR3A=154; // alle 10ms 1 Interrupt
ISR(TIMER3_COMPA_vect)
{
static unsigned char tasktimer,tasktimersek;
short v, mowersp,temp_mower,drehtemp;
static short i_summe; // Testen ob das passt
static short i_summe_spe_li,i_summe_spe_re;
short spe_li,spe_re;//,temp;
short v_li,v_re;
radcount++;
tasktimer++;
tasktimersek++;
.
.
.
}
grundsätzlich soll bei einer falschen ISR abgeschalten werden:
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;
flag_messer_aus=True;TCCR0B &= ~ (1<<CS01)|(1<<CS00);
Anzeige_Sonder(18);
while(1){wdt_reset();}
}
und so ist der Anfang der main:
int main(void)
{
short richtung_soll,richtung_temp,zeitstart,zeittemp;
char modus;//,v_min_count;
unsigned short felder; //,; //16Bit 65535
unsigned char x,y, z, sekunde, temp;
char bl,br,bv,s;//,bh
init(); //Porteinstellungen, Timer, PWM, LCD
lcd_gotoxy(0,0);lcd_puts_p(PSTR("einschalten"));
i2c_init();_delay_ms(10);
LED_gr_ein;LED_rot_aus;
Motor_li_stop();Motor_re_stop();Mower_stop();
// Watchdog
// Watchdog-Reset //Brown out // Power reset
if ((mcusr_mirror & (1 << WDRF)))//||(mcusr_mirror & (1 << BORF)))//||(mcusr_mirror & (1 << PORF)))
{
Anzeige_Sonder(LCD_WATCHDOGK1); // "!WATCHDOG! "
Motoren_stop();Mower_faststop();
}
wdt_enable(WDTO_4S);
sei(); //Interupt ein
wdt_reset();
Einlesen(); // letzten Stand der Karte lesen
Karte_init(); // Karte initializieren ( auch wenn im EEPROM => muss! damit besetzte Felder sicher eingetragen werden)
//----------------------------------- Funktionstest TWI ------------------------------
Anzeige_Sonder(LCD_Kontroller1OK); //"Kontroller 1 OK!"
Akkuspannunglesen();Akkuspannunglesen();Akkuspannu nglesen(); // gleich oft wie Werte gemittelt werden
Akkucheck();
//Warten();Warten();
richtung_kom =0;
if(i2c_start(Adresse_Kompass)==0)
{
i2c_write(1); // register
i2c_rep_start(Adresse_Kompass); // restart
richtung_kom = (short)i2c_readNak(); // read 1 byte //neuen Wert lesen;
i2c_stop();
if (richtung_kom!=0) Anzeige_Sonder(LCD_KompassOk); // "Kompass ok!
}
else {Anzeige_Sonder(LCD_FehlerKompass); // "Kompass Fehler!
//while(1);
}
//Warten();Warten();
Und wenn man die Funktion "Warten()" aktiviert hauts da das Programm raus, oder mit auskommentierter Funktion eben an einer anderen Stelle wo der Watchdog zuschlägt:
/*++++++++ Warten 0,5s +++++++++++++++++++++++++++++++++++++*/
static inline void Warten(void)
{
char x;
x=0;
while (x<2)
{
if (gps_str_complete>GPS_Receive_Complete) GPS();
if (Funk_Daten) RXFunk();
TX_Funk();
if (taskflag==taskdatenflag)
{
taskflag=taskflagclear;
DatatoSlave();
}
if (taskflag==task250msflag)
{ taskflag=taskflagclear;
Messercheck();
x++;
wdt_reset();
}
}
}
Verwendet wird ein Arduino Mega2560, aber nicht in Arduino Umgebung sondern normal mit Atmel Studio 6.2. Stromversorgung über DC Wandler direkt auf 5V, der Linearregler vom Arduino wird umgangen.
Programm funktioniert ansonsten normal, kann Bootloader raufgeben, über Bootloader flashen (via Bluettoth), die Anzeigen am LCD werden alle ausgegeben.
Hatte auch extra eine LED in der Timer ISR geschalten, nichts gesehen. Hatte die ISR auf Timer5 unbenannt, hätte im Programm die falsche ISR erkannt und abgebrochen werden müssen, aber nichts ist passiert.
Hab alles kontrolliert ob nicht irgendwo ein nicht erkanntes cli() versteckt ist.
Ist ja nicht das erste Mal dass ich ISR programmiere, die ersten Tests vom Code nach der Umstellung der Hardware liefen seit Jänner, und hatte keine Probleme.
Hatte schon früher mal eine Frage wegen Anzahl der ISR gestellt, und dabei extra ISR's eingebaut um den Ablauf zu testen, gab damals kein Problem
Kann man über Fuses die ISR /Timer abschalten?
Wie kann es sonst sein dass die ISR nicht mehr funktionieren?
Hab 3 Tage lang die PI Regler der Motoren optimiert (die auch in einer ISR ablaufen), die Akkuanzeigen kalibriert, alles lief normal.
Jetzt kommt man gar nicht mehr soweit dass die Motoren laufen würden...
Habe anstatt Timer 3 auch mal auf Timer 5 (Timer + ISR) umgestellt, exakt das gleiche.
Für einen Hardwaredefekt wäre das wohl zu selektiv, oder? Da müsste doch der ganze Programmablauf hinüber sein. Obwohl, die ersten Sekunden im Garten waren schon ein falscher Programmablauf, aber am Abend zuvor im Arbeitszimmer hatte es zu 100% funktioniert. Sollten die Motoren nach 3 Jahren in Betrieb auf einmal stören??. Aber warum geht es dann auch nicht ohne Motoren?
Ach ja, die Watchdog Ausgabe am LCD kommt nur wenn kein Bootloader drauf ist. Mit Bootloader wird einfach nach 4s das Programm neu gestartet. Dachte deswegen es liegt am Bootloader, aber egal, mit und ohne geht es nur bis der Watchdog zuschlägt
Keine Ahnung nach was ich suchen könnte, jede Idee wäre hilfreich.
LG!