IRMP-org / IRMP

Infrared Multi Protocol Decoder
GNU General Public License v3.0
274 stars 44 forks source link

Resuming from sleep #25

Closed Ircama closed 3 years ago

Ircama commented 3 years ago

When setting sleep mode to save power, also enabling pin change interrupt to wake up the device as soon as the IR receiver detects an IR stream, I wish to know which is the best way to resume IRMP from sleep, in order to reduce the IR detection time to the minimum.

In fact, I notice that after the device resumes from a sleep (waken up by the IR receiver), I need to keep the IR button of my remote pressed for some additional fractions of second to allow IRMP to detect the code. I expect this, but wish to reduce this detection time if possible. Should I call some IRMP function?

When putting the device to sleep (ATTINY85 at 16,5 Mhz, IR receiver connected to PB2), I use the following function (called after 0.5 seconds of inactivity time):

void sleep() {
    cli();                                  // Disable interrupts to set the configuration
    GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts for all pins
    PCMSK |= _BV(PCINT2);                   // Unmask Pin Change Interrupt for pin PB2
    ADCSRA &= ~_BV(ADEN);                   // ADC off (save power when sleeping)
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // Set sleep to the lowest power mode
    sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
    sei();                                  // Enable interrupts before sleeping
    sleep_cpu();                            // sleep
    cli();                                  // Disable interrupts after resuming from sleep
    PCMSK &= ~_BV(PCINT2);                  // Mask Pin Change Interrupt for pin PB2
    GIMSK &= ~_BV(PCIE);                    // Turn off Pin Change Interrupts for all pins
    sleep_disable();                        // Clear SE bit
    ADCSRA |= _BV(ADEN);                    // Restore ADC on
    sei();                                  // Enable interrupts again
}

EMPTY_INTERRUPT(PCINT0_vect)
ArminJo commented 3 years ago

See https://github.com/ukw100/IRMP#tips-and-tricks

Ircama commented 3 years ago

Thanks, I confirm that IRMP module performs well with ATTINY85 at 8 MHz and supports prompt IR recognition after resuming from sleep (also without setting IRMP in interrupt mode).

To change the clock from 16,5 to 8 MHz, I did this command using an Arduino Nano as ISP programmer:

<path>\avrdude -C<path>/avrdude.conf -v -pattiny85 -cstk500v1 -P<com port> -b<baud> -U lfuse:w:0xE2:m

(Note: after changing the fuse, the ATTINY85 micronucleus bootloader will not work; anyway, through the ISP the clock can be reverted to 16,5 Mhz with -U lfuse:w:0xf1:m to return using the micronucleus for USB uploading.)

ArminJo commented 3 years ago

Thanks for testing and confirmation 👍