I've looked into the sleep modes and from what I understood the analog comparator would need to be in IDLE mode, which is the least efficient.
So I replaced the PCI by a Watchdog Timer Interrupt that wake the IC every 125ms. It is also useful to receive data from the nrf24l01 without using the IRQ pin.
I cannot test the current consumption for the moment, but the timer behave as expected. I used MCUSR &= ~(1<<WDRF); from an example of the datasheet, but I have seen it set to 0 in others.
#define WDPS_16MS (0<<WDP3 )|(0<<WDP2 )|(0<<WDP1)|(0<<WDP0)
#define WDPS_32MS (0<<WDP3 )|(0<<WDP2 )|(0<<WDP1)|(1<<WDP0)
#define WDPS_64MS (0<<WDP3 )|(0<<WDP2 )|(1<<WDP1)|(0<<WDP0)
#define WDPS_125MS (0<<WDP3 )|(0<<WDP2 )|(1<<WDP1)|(1<<WDP0)
#define WDPS_250MS (0<<WDP3 )|(1<<WDP2 )|(0<<WDP1)|(0<<WDP0)
#define WDPS_500MS (0<<WDP3 )|(1<<WDP2 )|(0<<WDP1)|(1<<WDP0)
#define WDPS_1S (0<<WDP3 )|(1<<WDP2 )|(1<<WDP1)|(0<<WDP0)
#define WDPS_2S (0<<WDP3 )|(1<<WDP2 )|(1<<WDP1)|(1<<WDP0)
#define WDPS_4S (1<<WDP3 )|(0<<WDP2 )|(0<<WDP1)|(0<<WDP0)
#define WDPS_8S (1<<WDP3 )|(0<<WDP2 )|(0<<WDP1)|(1<<WDP0)
#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2
#include <avr/sleep.h>
#include <RHReliableDatagram.h>
#include <RH_NRF24.h>
#include <SPI.h>
RH_NRF24 driver;
RHReliableDatagram manager(driver, CLIENT_ADDRESS);
const byte XPIN = A1;
const byte YPIN = A2;
const byte ZPIN = A3;
const byte RFLED = 7;
const byte IRLED = 6;
ISR (WDT_vect) { sleep_disable(); }
void setup ()
{
pinMode(XPIN, INPUT);
pinMode(YPIN, INPUT);
pinMode(ZPIN, INPUT);
pinMode(RFLED, OUTPUT);
digitalWrite(RFLED, LOW);
manager.init(); //nrf24
MCUSR &= ~(1<<WDRF); //Clear Watchdog System Reset Flag (WDRF) in MCU Status Register (MCUSR)
WDTCSR = (1<<WDCE)|(1<<WDE); //Set WD Change Enable (WDCE) and WD Enable (WDE) in WD Timer Control Register (WDTCSR) (enter configuration mode)
WDTCSR = (1<<WDIE)|WDPS_125MS; //Set WD Interrupt Enable (WDIE) and WD Pause
}
void loop ()
{
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_mode ();
rf_listen();
read_input();
}
void read_input()
{
if (digitalRead(ZPIN) == 0) { rf_sendString("Click"); }
else if (analogRead(YPIN) > 700) { rf_sendString("Up"); }
else if (analogRead(YPIN) < 400) { rf_sendString("Down"); }
else if (analogRead(XPIN) > 700) { rf_sendString("Left"); }
else if (analogRead(XPIN) < 400) { rf_sendString("Right"); }
}
void rf_sendString(char str[RH_NRF24_MAX_MESSAGE_LEN])
{
digitalWrite(RFLED, HIGH);
uint8_t rf_data[RH_NRF24_MAX_MESSAGE_LEN];
strcpy((char*)rf_data, str);
manager.sendtoWait(rf_data, sizeof(rf_data), SERVER_ADDRESS);
digitalWrite(RFLED, LOW);
}
void rf_listen()
{
if (manager.available())
{
uint8_t rf_buf[RH_NRF24_MAX_MESSAGE_LEN];
uint8_t len = sizeof(rf_buf);
uint8_t from;
if (manager.recvfromAck(rf_buf, &len, &from))
{
if (!strcmp((char*)rf_buf, "tv"))
{
//Blink IR LED
}
}
}
}