I want to put my arduino UNO to deep sleep (PWR_DWN_MODE) and wake it up when it receives a character from the PC (through the Arduino IDE console). Here is my code:
#include <avr/sleep.h>
#include <avr/interrupt.h>
volatile uint8_t MeasReceived=0;
ISR(PCINT2_vect){
MeasReceived=1;
PCIFR = bit (PCIF2);
digitalWrite(LED_BUILTIN, HIGH);
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
Serial.flush();
Serial.print("Hello PC");
delay(1000);
Serial.flush();
delay(1000);
cli();
PCMSK2 = bit (PCINT16); // turn on pins PD0 , PCINT16
PCIFR = bit (PCIF2);
PCICR = bit (PCIE2); // turn on port d
sei();
}
void loop() {
if(MeasReceived==1){
cli();
MeasReceived=0;
sei();
delay(1000);
Serial.print('S');
delay(1000);
}
delay(1000);
cli();
set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Set power down mode
sleep_bod_disable(); //disable brown-out detection
digitalWrite(LED_BUILTIN, LOW);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
delay(1000);
}
The problem is that, when I send one character from my PC, the arduino wakes up from sleep, but the ISR is never fired! How is it possible to wake up and at the same time not access the ISR? Should that not occur naturally?
Furthermore, if I send two characters together from the console, then the arduino does wake up and it accesses the ISR normally. Can somebody explain what exactly is happening?
It appears that there is some delay between the waking up of the CPU and the time it is ready to process Pin Change interrupts. I don't know why.
I ran a sketch similar to yours on my Arduino UNO and (at 115200. baud) it took about 14 characters (140 bits. about 1.2 milliseconds) between the first bit that woke up the processor and the Pin Change Interrupt ISR starting to be called.
Something about sleeping the processor screws up the serial input. If the processor isn't actually put to sleep (that part of the sketch commented out) the Serial input arrives without problems, even when the Pin Change Interrupt is enabled and occuring. If the processor is put to sleep and awakened with the Pin Change Interrupt, the first 15 characters are lost and the remaining characters are garbled. Here is the output when sending the following strings with a Newline: