damellis / attiny

ATtiny microcontroller support for the Arduino IDE
717 stars 224 forks source link

Support pin change interrupts once they're supported in the Arduino AVR core. #14

Open Schtrudel opened 11 years ago

Schtrudel commented 11 years ago

AttachInterrupt() is not in the supported list, but pin interrupt is supported by the chip itself. Is it possible to add it?

damellis commented 11 years ago

Access to the pin change interrupts is something that should be added to the Arduino core: https://github.com/arduino/Arduino/issues/248. We'd then pick it up for the ATtiny.

Schtrudel commented 11 years ago

What do you mean by "should be added to the Arduino core"? It's part of the Arduino API, isn't it? (At least, it's working for mine :-) )

NicoHood commented 9 years ago

Are you talking about pin interrupts or pin change interrupts?

eried commented 8 years ago

Hey Schtrudel, what it is working? I cant attach interrupts on my tiny85 :/

Schtrudel commented 8 years ago

Hi eried.

I love these discussions with 3 messages in 3 years... :-) Reminds me of this joke: http://jokesareawesome.com/joke/869

Anyway, I don't remember how I solved it then, but later, I switched to another approach: I don't use attachInterrupt at all and use a few lines with the "native" mechanism. In my case, it detects the change on any of 2 buttons, and I detect which one in the ISR. Quick and dirty, but works very well for my use. Most of it shamelessly copied and adapted from https://bigdanzblog.wordpress.com/2014/08/10/attiny85-wake-from-sleep-on-pin-state-change-code-example/ [Thanks Big Dan] For reference, the relevant parts of the code. I hope it can help. ////////////////////////////////////////////////////////////////////////////////////////////

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

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

const int button1 = 4;    
const int button2 = 3;
//...

volatile byte button2Pressed = 0;     // Don't forget to declare your global handled in ISR as volatile

ISR(PCINT0_vect) {
    if (digitalRead(button2))
      button2Pressed = 1;        
}

void setup()
{
//...
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
//...
}

void loop(){
     //...
     sleep();
     if (button2Pressed) {
       run_fun2();
     }
     else{
      run_fun1();
     }
    //...
}

void sleep() {
    GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts
    PCMSK |= _BV(button1);                   // Use button1 as interrupt pin
    PCMSK |= _BV(button2);                  // Use button2 as interrupt pin

    ADCSRA &= ~_BV(ADEN);                   // ADC off
    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

    cli();                                  // Disable interrupts
   PCMSK &= ~_BV(button1);
   PCMSK &= ~_BV(button2);
    sleep_disable();                        // Clear SE bit
    ADCSRA |= _BV(ADEN);                    // ADC on

    sei();                                  // Enable interrupts
} // sleep
eried commented 8 years ago

Hahaha! I was thinking to reply in 1 more year but I am going to forget to do that, so thanks for the code! I´ll use it that way too, it was 3 am and I was very frustrated led debugging the tiny85