ATtiny85 interrupts, programming with the UNO

I need help with programming an ISR with the one and only external interrupt on the ATtiny85. I have tried MANY things and nothing works. I have read through the ATtiny85 datasheet about 700 times. The only thing it gives me is how to set up the registers, which I have done below. I can't find any tutorials on how to do this except for a couple people have done a little bit of stuff on the Pin Change Interrupt. I cannot use the PCINT because that interrupt watches for rising and falling edges and is not changeable. I only need rising edge (my project involves interpreting the frequency of pulses (a tachometer on my motorcycle)). The ATtiny85 does not have an input capture timer channel apparently (only an output compare I could see in the data sheet). So, my only option is using an external interrupt to calculate the frequency or buy a frequency to voltage converter IC which I'd have to order and wait.

So, if anyone knows how to program an external interrupt on the ATtiny85 using the UNO as an ISP then I will worship you...

This is all I have anymore. I know the registers are set right. I do not know how to create the ISR itself and/or 'attach' it to the program. I tried using the Arduino attachInterrupt() and that didn't work either and I tried every pin.

Thanks a lot!

int pinLed = 0;

void setup()
{
  pinMode(pinLed,OUTPUT);

  MCUCR |= B00000011;    //watch for rising edge
  GIMSK |= B01000000;    //enable external interrupt
  SREG |= B10000000;     //global interrupt enable
}

void loop()
{
  ;
}

void beast_isr(void)
{
  digitalWrite(pinLed,HIGH);
  delay(1000);
  digitalWrite(pinLed,LOW);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
}

Let's take a step back and discuss some of your incorrect assumptions to make certain External Interrupts are the best choice.

I cannot use the PCINT because that interrupt watches for rising and falling edges and is not changeable. I only need rising edge (my project involves interpreting the frequency of pulses (a tachometer on my motorcycle)).

It is fairly easy to get CHANGE, RISING, and FALLING from a pin change interrupt...
http://code.google.com/p/arduino-tiny/downloads/detail?name=PinChangeInterrupt-0001.zip&can=2&q=
http://code.google.com/p/arduino-tiny/source/browse/#svn%2Ftrunk%2Flibraries%2FPinChangeInterrupt

Using pin change interrupts in this way has an advantage, a price, and a risk. The advantage is that you can use any pin. The price is several machine instructions to determine what happened. The risk is that a very very fast transition (e.g. low-->high-->low) will be missed.

The ATtiny85 does not have an input capture timer channel apparently (only an output compare I could see in the data sheet).

Correct. But the processor does have two Timer/Counters that can be driven from an external pulse stream #. In the Arduino world the Timer/Counters are strictly used as timers but nothing prevents you from using them as you please. I've used a Timer/Counter with an External Clock Source to measure frequency and it works well.

# Update: Only timer 0 on the ATtiny85 has support for an external Clock Source.

So, if anyone knows how to program an external interrupt on the ATtiny85 using the UNO as an ISP then I will worship you...

Finally, if you are using the Tiny Core... Google Code Archive - Long-term storage for Google Code Project Hosting. ...attachInterrupt works exactly the same as it does with the Standard Core. There is no need for you to fiddle with registers.

vikingbush:
I need help with programming an ISR with the one and only external interrupt on the ATtiny85. I have tried MANY things and nothing works. I have read through the ATtiny85 datasheet about 700 times. The only thing it gives me is how to set up the registers, which I have done below. I can't find any tutorials on how to do this except for a couple people have done a little bit of stuff on the Pin Change Interrupt. I cannot use the PCINT because that interrupt watches for rising and falling edges and is not changeable. I only need rising edge (my project involves interpreting the frequency of pulses (a tachometer on my motorcycle)). The ATtiny85 does not have an input capture timer channel apparently (only an output compare I could see in the data sheet). So, my only option is using an external interrupt to calculate the frequency or buy a frequency to voltage converter IC which I'd have to order and wait.

So, if anyone knows how to program an external interrupt on the ATtiny85 using the UNO as an ISP then I will worship you...

This is all I have anymore. I know the registers are set right. I do not know how to create the ISR itself and/or 'attach' it to the program. I tried using the Arduino attachInterrupt() and that didn't work either and I tried every pin.

Thanks a lot!

The part in red is incorrect, you can trigger on either edge or on a change. EDIT: OOPs, INT0 will let you pick the edge you want, sorry. Of course without the ICF, your timing will be a bit jittery but plenty good enough for an engine tach.

You don't have your interrupt handler assigned to the vector. This means it will never run. When the vector is triggered due to the register settings, the CPU will reset.

You can't call delay() in an ISR. The idea of an ISR is to get in and out as fast as possible. If you need to do more work, then move it to main level and trigger it with a flag set in the ISR.

You need to set up your ISR something like this:

ISR(INT0_vect) {
  
//  Put your ISR code here

}

Thank you guys both! I have an external interrupt working now. Here, I just have an LED to turn on or off each time a rising edge has occurred. I still could not get the attachInterrupt(x,x,x) to work so I ended up doing it the other way. Oh, and all those mistakes you guys pointed out, thanks for that too. I read that datasheet so many times I guess I got mixed up. Now to calculate the frequency...

int pinLed = 0;
int state = HIGH;

void setup()
{
  pinMode(pinLed,OUTPUT);
  pinMode(1,INPUT);

  MCUCR |= B00000011;    //watch for rising edge
  GIMSK |= B01000000;    //enable external interrupt
  SREG |= B10000000;     //global interrupt enable
}

void loop()
{
  digitalWrite(pinLed,state);
  delay(1);
}

ISR(INT0_vect)
{
  state = !state;
}

You can try this for attachInterrupt().
Note you should be using the keyword volatile for the state variable.

int pinLed = 0;
volatile int state = HIGH;

void setup()
{
  pinMode(pinLed, OUTPUT);
  attachInterrupt(0, blink, RISING);
}

void loop()
{
  digitalWrite(pinLed, state);
}

void blink()
{
  state = !state;
}

This was really helpful but I think the code is slightly wrong: INT0 is on PB2, so you need
pinMode(2,INPUT);
(or INPUT_PULLUP);

This is quite a bit later but as this old post keeps popping up, I'd like to address this for clarity. (note, all this is also covered in Arduino documentation ( attachInterrupt() - Arduino Reference )

Goldminer is talking about interupt numbers, not pin numbers. It is not recommended but one can do an attachInterupt(interuptnumber, ISR, MODE) assignment. For the ATtiny85, chip pin 7 is PB2, and is also INT.0. These multiple ways to identify the same location/pin used to drive me nuts when I read sketches and pseudo code as the writer may have had one term in mind (interrupt number) while the reader might have another (pin number). so, reader BEWARE and consider your assumptions.

INT.0 = PB2 = chip pin 7

example of recommended method: (pseudo code)

byte interuptPin = 2; // for ATtiny85 pin assignments
attachInterupt(digitalPinToInterrupt(interruptPin),ISR,mode);