2

I have a digispark attiny85, and I am using SLEEP_MODE_PWR_DOWN to sleep, and wake-up with external interrupt on pin2. I am trying to count number of interrupts received with the code below.

Problem is on every LOW signal on pin2, attiny85 reset (restart) itself instead of processor wake-up and continue where it left. I can identify this by seeing led blink 3 times(as in setup()) on every LOW signal.

Is there a limitation on this hardware? How can I only wake-up from sleep and not reset? I appreciate if you direct me an example.

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

//modified from http://playground.arduino.cc/Learning/arduinoSleepCode

int ledPin = 0;            // LED connected to digital pin 0
int interruptPin = 1;      // LED to show the action of a interrupt
int wakePin = 2;            // active LOW, ground this pin momentary to wake up
unsigned int counter = 0;

void setup(){
  pinMode(ledPin, OUTPUT);         // sets the digital pin as output
  pinMode(interruptPin, OUTPUT);   // sets the digital pin as output
  pinMode(wakePin, INPUT_PULLUP);        // sets the digital pin as input
  digitalWrite(wakePin, HIGH);
  counter = 0;
  //do some blinks so we can identify boot & loop
     digitalWrite (interruptPin, HIGH);    // sets the digital pin as output
    delay(250);
     digitalWrite (interruptPin, LOW);    // sets the digital pin as output
    delay(250);
     digitalWrite (interruptPin, HIGH);    // sets the digital pin as output
    delay(250);
     digitalWrite (interruptPin, LOW);    // sets the digital pin as output
    delay(250);
     digitalWrite (interruptPin, HIGH);    // sets the digital pin as output
    delay(250);
     digitalWrite (interruptPin, LOW);    // sets the digital pin as output
    delay(250);
}


void sleepNow(){         

    set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // sleep mode is set here
    sleep_enable();                          // enables the sleep bit in the mcucr register so sleep is possible
    attachInterrupt(0, wakeUpNow, LOW);     // use interrupt 0 (pin 2) and run function wakeUpNow when pin 2 gets LOW
    digitalWrite(interruptPin, LOW); 

    sleep_mode();                          // here the device is actually put to sleep!!

    sleep_disable();                       // first thing after waking from sleep: disable sleep...
    detachInterrupt(0);                    // disables interrupton pin 3 so the wakeUpNow code will not be executed during normal running time.
    delay(250);                           // wait 2 sec. so humans can notice the interrupt LED to show the interrupt is handled
    digitalWrite (interruptPin, HIGH);       // turn off the interrupt LED

}



void wakeUpNow(){        // here the interrupt is handled after wakeup

  //execute code here after wake-up before returning to the loop() function
  // timers and code using timers (serial.print and more...) will not work here.
 digitalWrite(interruptPin, HIGH);
}


void loop(){
   digitalWrite(interruptPin, HIGH);
  //digitalWrite(ledPin, HIGH);            // sets the LED on
  counter++;
  delay(5000);                           // waits for a second
  sleepNow();                      // sleep function called here
}
ozkolonur
  • 121
  • 4

1 Answers1

0

I found this, I can confirm it is working. on digispark attiny85.

void sleepTillChg() {  // 0.02ma drain while sleeping here
    GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts
    PCMSK |= _BV(PCINT0);                   // Use PB0 (was PB3) as interrupt pin
    // Turn off unnecessary peripherals
    ADCSRA &= ~_BV(ADEN);                   // ADC off
    ACSR |= _BV(ACD); // Disable analog comparator

    set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // replaces above statement
    sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
    sei();                                  // Enable interrupts
    sleep_cpu();                            // sleep ... Zzzz

    cli();                                  // Disable interrupts
    PCMSK &= ~_BV(PCINT0);                  // Turn off PB0 (was PB3) as interrupt pin
    sleep_disable();                        // Clear SE bit
    sei();                                  // Enable interrupts
}

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

credits should go https://www.instructables.com/id/3-Minute-Game-Timer/

ozkolonur
  • 121
  • 4