ATTINY85 not properly waking from sleep on Interrupt

Hello,

I spent a lot of time troubleshooting this problem and I can't seem to figure it out.

What is happening is that when I put the chip to sleep, and then try to wake it up from a button press, it won't wake up unless I hold the button down for more than 4 seconds. HOWEVER, if I remove the one line of code, which is sei(); in the sleep method which executes after it wakes up, then I can wake it up with a simple quick button press. However, without that line of code, my timers don't work and my loop method can never call the sleep method again after it wakes up.

Here is where I got the code for the sleep() method.

Here is my full code:

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

#define BUTTON 3
#define P0 0
#define P1 1
#define P2 2

#define BUTTON_PRESSED digitalRead(BUTTON) == HIGH

ISR(PCINT0_vect) {
    // This is called when the interrupt occurs, but I don't need to do anything in it
}

void setPins() {
    pinMode(BUTTON,INPUT);
    pinMode(P0, OUTPUT);
    pinMode(P1, OUTPUT);
    pinMode(P2, OUTPUT);
}

void sleep() {
    GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts
    PCMSK |= _BV(PCINT3);                   // Use PB3 as interrupt pin
    ADCSRA &= ~_BV(ADEN);                   // ADC off
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
    sei();                                  // Enable interrupts
    sleep_cpu();                            // sleep
    cli();                                  // Disable interrupts
    PCMSK &= ~_BV(PCINT3);                  // Turn off PB3 as interrupt pin
    sleep_disable();                        // Clear SE bit
    ADCSRA |= _BV(ADEN);                    // ADC on
    sei();                                  // Enable interrupts <---THIS IS THE PROBLEM
    setPins();
}

void allOff(){
    digitalWrite(P0, LOW);
    digitalWrite(P1, LOW);
    digitalWrite(P2, LOW);
    delay(10);
}

void pin0() {
    digitalWrite(P0, HIGH);
}

void pin1() {
    digitalWrite(P1, HIGH);
}

void pin2() {
    digitalWrite(P2, HIGH);
}

void setup() {
    setPins();
    allOff();
}

void loop() {
    static int pin = -1;
    if (BUTTON_PRESSED) {
        unsigned long start = millis();
        delay(100);
        while(BUTTON_PRESSED) {
            if ((millis() - start) > 3000) {
                allOff();
                delay(3000);
                sleep();
                pin = -1;
            }
        }
        pin ++;
        allOff();
        if (pin >= 3) pin = 0;
        switch(pin) {
            case 0:
                pin0();
                break;
            
            case 1:
                pin1();
                break;
            
            case 2:
                pin2();
                break;
            
            default:
                break;
        }
        delay(1000);
    }
}

I'm stumped. I should be able to wake this chip just by a quick press of the button with this code the way it is, but obviously, I'm missing something.

Any input would be appreciated.

Thank you,

Mike

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.