So I have started having some pretty weird issues with my Interrupt service routines. I have simplified the code to try testing for solutions without my entire program but the problem persists. In a nut shell I am placing the mcu into power down mode, setting a watch dog timer for 2 seconds, waking the device, in the real world I'm checking a sensor but in this simplified code I am just printing to the serial monitor. Long story short sometimes when it wakes up it throws some random characters, sometimes it crashes catastrophically, sometimes it just hangs forever, and sometimes it resets. Incidentally it works perfectly when the sleep mode is standby mode. Power down mode is where the issue is at. and until 3 days ago that was working fine to. I don't know what I changed and my backup isn't working any better. Somewhere I am making a simple and obvious mistake. So obvious that I simply cannot see it.
I have been staring at it for 3 days and trying every trick I know. Perhaps some fresh eyes can see the probably simple error I have made. I'm going to go ahead and answer the usual questions to save us all some time. Thank you all for any help that you can give.
Why am I putting it into power down mode? Because that's what I need to do, it's a power issue.
Why am I using a watchdog timer? I have an rtc as well and a button, the button interrupt works fine. The rtc interrupt is having the exact same issue as the WDT. My thought is that if I can figure out what is wrong with the WDT then I can solve the rtc issue as well.
Can you post the full project code? Believe me you don't want to sift through 1200 lines of code... Also the problem remains persistent in the simplified code so it is extremely probable that the error is inside the simplified code I have attached.
Why are you disabling the WDT after interrupt? It may take more than 2 seconds after waking up depending on what the sensor detects and I don't want it interrupting continuously during that process. The interrupt is only for waking the device from power down mode.
volatile uint8_t InterruptFlag=0;
char cmd=0;
int duh=0;
void setup() {
Serial.begin(9600);
delay(500);
Serial.println("Starting");
}
ISR(WDT_vect){
InterruptFlag=1;
}
void loop() {
cmd=0;
Serial.print("test number: ");Serial.println(duh++);
if(InterruptFlag==1){
delay(50);
Serial.println("watch dog");
Serial.print("MCUSR: ");Serial.println(MCUSR,BIN);
InterruptFlag=0;
WDTCSR=24;
WDTCSR=0;
}
delay(1000);
if(Serial.available()){
cmd=Serial.read();
if(cmd=='1'){
GoToSleep();
}
}
}
void GoToSleep(){
ADCSRA &= ~(1 << 7); // TURN OFF ADC CONVERTER
WDTCSR = (24); // Change enable and WDE - also resets
WDTCSR = (7); // Prescalers only to set time- get rid of the WDE and WDCE bit
WDTCSR |= (1<<6); // Enable interrupt mode
//SMCR |=(3<<2); // Standby Mode
SMCR |= (1 << 2); // power down mode
SMCR |= 1; // enable sleep
MCUCR |= (3 << 5); // set both BODS and BODSE at the same time
MCUCR = (MCUCR & ~(1 << 5)) | (1 << 6); // then set the BODS bit and clear the BODSE bit at the same time
__asm__ __volatile__("sleep"); // In line assembler to go to sleep
//SMCR |=(0<<0); // I DON'T REALLY REMEMBER WHY
ADCSRA |= (1 << 7); // TURN ON ADC CONVERTER
}
Thank you all for any guidance or assistance you can give.
sketch_mar08a.ino (1.49 KB)