ATtiny85 Interrupt Barebones Example

11,860

10

6

Introduction: ATtiny85 Interrupt Barebones Example

This example code and simple wiring demonstrated how to setup an AVR ATtiny85 processor to react to external interrupts. Whenever the voltage changes on the chosen input pin (pin 6 / PB1), it executes the interrupt service routine (ISR), checks the current voltage, and sets the output pin (pin 3 / PB4) to match. This is visible because of an LED (with current limiting resistor) attached to the output pin.

I needed this setup because examples of how to configure an ATtiny85 to enable interrupts are often complex or incomplete. After reading several sites, processor documentation, and learning more about the platform, I was able to clean up and distill down a couple of examples I found into one single nearly-barebones code and circuit example.

Supplies

AVR ATtiny85 (PDIP package in this example)

breadboard

LED

Resistor (any value 300 to 2.5k ohms should work fine)

Momentary switch

Jumper wires

5v power supply (I was using a USB power supply)

Step 1: Program the ATtiny85 and Wire the Board

The key piece of code to enable the interrupts lives here:

// Requires headers for AVR defines and ISR function
#include <avr/io.h>
#include <avr/interrupt.h>


#define INTERRUPT_PIN PCINT1 // This is PB1 per the schematic
#define INT_PIN PB1 // Interrupt pin of choice: PB1 (same as PCINT1) - Pin 6
#define LED_PIN PB4 // PB4 - Pin 3
#define PCINT_VECTOR PCINT0_vect // This step is not necessary - it's a naming thing for clarit
void setup() {
pinMode(LED_PIN, OUTPUT);
cli(); // Disable interrupts during setup
PCMSK |= (1 << INTERRUPT_PIN); // Enable interrupt handler (ISR) for our chosen interrupt pin (PCINT1/PB1/pin 6)
GIMSK |= (1 << PCIE); // Enable PCINT interrupt in the general interrupt mask
pinMode(INT_PIN, INPUT_PULLUP); // Set our interrupt pin as input with a pullup to keep it stable
sei(); //last line of setup - enable interrupts after setup
}

// This is the interrupt handler called when there is any change on the INT_PIN
// ISR is defined in the headers - the ATtiny85 only has one handler

ISR(PCINT_VECTOR) { if( digitalRead(INT_PIN) == HIGH ) { digitalWrite(LED_PIN, HIGH); }else{ digitalWrite(LED_PIN, LOW); } }

That code alone will run, but the attached .ino file has more comments, features and setup information.

Be the First to Share

    Recommendations

    • Robots Contest

      Robots Contest
    • Tinkercad Student Design Contest

      Tinkercad Student Design Contest
    • Space Contest

      Space Contest

    6 Comments

    0
    tytower
    tytower

    2 years ago

    I meant to add that I have found for price and convenience an arduino pro board costs $2-$3 also. Same price as an ATTiny85 and is much more powerful so using the 85 is really labouring . Here is an extract from one of the links you supplied .

    ATtiny45/85 vs. an Arduino Board
    The ATtiny45 or 85 is a great option for running simple Arduino
    programs: it’s small, cheap and relatively easy to use. It does,
    however, have some limitations relative to the ATmega328P on an Arduino
    Uno. There are fewer pins, meaning you can’t connect as many components.
    There’s less flash memory (4KB or 8KB instead of 32KB), meaning your
    programs can’t be as big. There’s less RAM (256 or 512 bytes instead of
    2KB), meaning you can’t store as much data. And there’s no hardware
    serial port or I2C port (Wire library), making communication trickier.
    (There are workarounds, like the SoftwareSerial library or the TinyWire
    library, but they’re not as robust and flexible.)

    In short, then, if your project requires only a few simple inputs
    and/or outputs, you’re probably fine using an ATtiny. If you’re trying
    to hook up more components or do more complex communication or data
    processing, though, you’re probably better off with something like the
    ATmega328P on an Arduino Uno. If you want something smaller and cheaper
    than a full Arduino board, you might try using an Arduino Mini Pro $2 instead.

    0
    ManoelG3
    ManoelG3

    Reply 5 months ago

    ATTiny 85 can run as a standalone chip with 6 peripherals pins. It is a good option for small projects where an Arduino would be overkill. Of course the user whas to do more work to use it sometimes.
    Sometimes convenience means the size and simplicity of a ATTiny.

    0
    l8gravely-pro
    l8gravely-pro

    1 year ago

    This is a nice simple example, but it could use some expansion I feel.

    1. You should mention up front that you're using the Arduino IDE for the example, and that you need to install the extra module(s) for programming the ATTiny85.

    2. What about your main() function? You don't explain that the code will just loop madly while waiting for various interrupts. Is there any way to put the ATtiny85 into a sleep mode to save power? This is key when you're on battery.

    Otherwise thanks for the instructable, very nice and clear explanation!

    0
    tytower
    tytower

    2 years ago

    She says that to all the boys.
    Nice job to simplify a darn difficult subject .
    I guess the line runs from neg on left side to neg on right but you used a red wire which is confusing because we can't see it. For Aus neg black red pos is the norm.

    Question Can I run this on a pro mini ? The code does not compile offhand but I guess it would need changes for an Arduino Pro board.
    I get "exit status 1
    'PCMSK' was not declared in this scope
    I guess GIMSK will go the same way.

    I had no ATTiny85's left to play with.

    0
    tytower
    tytower

    Reply 2 years ago

    Seems like you don't intend to try to answer this . So I post a normal interupt example used on an arduino board . Would you comment on what this is doing then?
    const byte ledPin = 9; //Defines the pin the LED is on
    const byte interruptPin = 2; //Defines the pin the button is on
    const byte potPin = 0; //Defines the pin the potentiometer is on

    volatile int level; //Keeps the brightness level of the LED

    void setup() {
    pinMode(ledPin, OUTPUT); //Sets the LED pin to OUTPUT
    pinMode(interruptPin, INPUT_PULLUP); //Sets the button pin to INPUT_PULLUP
    pinMode(potPin, INPUT); //Sets the potentiometer pin to INPUT
    attachInterrupt(digitalPinToInterrupt(interruptPin), brightness, RISING); //Attaches the interrupt to the input pin and brightness method and set it to rising
    }

    void loop() {
    analogWrite(ledPin, level); //Sets the LED to the set brightness
    }

    void brightness() {
    level = analogRead(potPin); //Reads in the value from the potentiometer
    level = map(level, 0, 1023, 0, 255); //Maps those values to value for LED brightness
    }