Sleep, interrupt and VirtualWire

My Arduino is put to sleep only to wake up when one of three buttons is pressed.

Only…it doesn’t work.

I receive the “Prêt” message from setup().
Then I connect pin 2 (interrupt 0) to ground: the led on pin 13 lights up but the Arduino doesn’t seem to send anything on pin 12 which is connected to the DATA pin of the RF emitter (my multimeter stays silent whereas it shows a few mA on startup when “Prêt” is sent). The pin never goes off.

#include <avr/sleep.h>
#include <VirtualWire.h>
#include <avr/interrupt.h>  // Do I need that? It was working without it with a previous RF library.


int pinPlaque = 2;
int pinPortes = 3;
int pinAv = 6;


void ouvrePlaque()
{
  sleep_disable();
  detachInterrupt(0);
  
  digitalWrite(13, HIGH);  //Debugging
  
//  vw_set_tx_pin(12);  //Doesn't work wether I place it here or in setup()
//  vw_setup(1000);
  
  const char *lettre = "lettre";
  vw_send((uint8_t *)lettre, strlen(lettre));
//  digitalWrite(13, LOW);  //Debugging
  vw_wait_tx();
  digitalWrite(13, LOW);  //Debugging
  
}


void ouvrePorte()
{
  sleep_disable();
  detachInterrupt(1);
  
  digitalWrite(13, HIGH);  //Debugging
  
  const char *av = "avant";
  const char *arr = "arrière";
    
  if(digitalRead(pinAv) == LOW){
    vw_send((uint8_t *)av, strlen(av));
    vw_wait_tx(); // Wait until the whole message is gone 
    }
  else
  {
    vw_send((uint8_t *)arr, strlen(arr));
    vw_wait_tx(); // Wait until the whole message is gone
  }
}


void setup()
{
  vw_set_tx_pin(12);
  vw_setup(1000);      //Vitesse en bps
  
  pinMode(13, OUTPUT);
  pinMode(pinPlaque, INPUT);
  pinMode(pinPortes, INPUT);
  pinMode(pinAv, INPUT);
  digitalWrite(pinPlaque, HIGH);
  digitalWrite(pinPortes, HIGH);
  digitalWrite(pinAv, HIGH);
  
  const char *set = "Prêt !";
  vw_send((uint8_t *)set, strlen(set));
  vw_wait_tx();
}


void loop()
{
//  ADCSRA = 0;
  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  
  sleep_enable();
  
  attachInterrupt(0, ouvrePlaque, FALLING);  // I tried with LOW as well.
  attachInterrupt(1, ouvrePorte, FALLING);
  
//  MCUCR = bit (BODS) | bit (BODSE);
//  MCUCR = bit (BODS); 
  
  interrupts();
  sleep_cpu();
}

Is it even possible to use the VirtualWire library inside an ISR?

EDIT: Maybe it isn’t, I got it working that way.

#include <avr/sleep.h>
#include <VirtualWire.h>
//#include <avr/interrupt.h>  // Do I need that? It was working without it with a previous RF library.


int pinPlaque = 2;
int pinPortes = 3;
int pinAv = 6;
volatile int int_flag = 0;

const char *lettre = "Lettre";
const char *av = "Colis";
const char *arr = "Relève";


void ouvrePlaque()
{
  int_flag = 1; 
}


void ouvrePorte()
{    
  if(digitalRead(pinAv) == LOW)
  {
    int_flag = 2;
  }
  else
  {
    int_flag = 3;
  }
}


void setup()
{
  vw_set_tx_pin(12);  //Pin d'émission
  vw_setup(1000);      //Vitesse en bps
  
  pinMode(pinPlaque, INPUT_PULLUP);
  pinMode(pinPortes, INPUT_PULLUP);
  pinMode(pinAv, INPUT_PULLUP);
  digitalWrite(pinPlaque, HIGH);
  digitalWrite(pinPortes, HIGH);
  digitalWrite(pinAv, HIGH);
  
  const char *set = "Prêt !";
  vw_send((uint8_t *)set, strlen(set));
  vw_wait_tx();
}


void loop()
{
  ADCSRA = 0;
  
  if(int_flag==1)
  {
    detachInterrupt(0);
    vw_send((uint8_t *)lettre, strlen(lettre));  //Sending via RF
    vw_wait_tx();  //Waiting for message to be sent
  }
  else if(int_flag==2)
  {
    detachInterrupt(1);
    vw_send((uint8_t *)av, strlen(av));
    vw_wait_tx(); // Wait until the whole message is gone 
  }
  else if(int_flag==3)
  {
    detachInterrupt(1);
    vw_send((uint8_t *)arr, strlen(arr));
    vw_wait_tx(); // Wait until the whole message is gone 
  }
  int_flag=0;
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  
  sleep_enable();
  
  attachInterrupt(0, ouvrePlaque, FALLING);
  attachInterrupt(1, ouvrePorte, FALLING);
  
  MCUCR = bit (BODS) | bit (BODSE);
  MCUCR = bit (BODS); 
  
  interrupts();
  sleep_cpu();
}

If an optimization/sleep guru could take a look at my code, I would really appreciate it :slight_smile: