Use PD0 (UART RX) as pin change interrupt

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:

1234567890
12345678901234567890
123456789012345678901234567890
1234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890
123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890

(Note: the interrupt count is a byte so it wraps to 0 at 256 interrupts.)

Sleeping...  Interrupts: 0		Characters received: 0	
Sleeping...  Interrupts: 38	Characters received: 6	ͳ3⸮⸮
Sleeping...  Interrupts: 96	Characters received: 16	ͳ3⸮&6FVfv⸮⸮⸮
Sleeping...  Interrupts: 152	Characters received: 26	3⸮3⸮&6FVfv⸮⸮&6FVfv⸮⸮⸮
Sleeping...  Interrupts: 212	Characters received: 36	ͳ3⸮&6FVfv⸮⸮&6FVfv⸮⸮&6FVfv⸮⸮⸮
Sleeping...  Interrupts: 14	Characters received: 46	ͳ3⸮&6FVfv⸮⸮&6FVfv⸮⸮&6FVfv⸮⸮&6FVfv⸮⸮⸮
Sleeping...  Interrupts: 72	Characters received: 56	3⸮3⸮&6FVfv⸮⸮&6FVfv⸮⸮&6FVfv⸮⸮&6FVfv⸮⸮&6FVfv⸮⸮⸮
Sleeping...

My sketch:

#include <avr/sleep.h>
#include <avr/interrupt.h>


volatile uint8_t InterruptCount = 0;


ISR(PCINT2_vect)
{
  InterruptCount++;
}


void setup()
{
  Serial.begin(115200);
  Serial.flush();
  Serial.println("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()
{
  delay(1000);
  Serial.print("Sleeping...  ");
  Serial.flush();


  cli();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);    //Set power down mode
  sleep_bod_disable();  //disable brown-out detection
  sleep_enable();
  sei();


  sleep_cpu();
  sleep_disable();


  delay(1000);
  Serial.print("Interrupts: ");
  Serial.print(InterruptCount);
  Serial.print("\tCharacters received: ");
  Serial.print(Serial.available());
  Serial.print('\t');
  while (Serial.available())
    Serial.print((char)Serial.read());
  Serial.println();
  Serial.flush();
  InterruptCount = 0;
}