An interrupt-driven approach to Arduino programming
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
atmega328p
attiny84
attiny85
examples
msp430fr5739
msp430g2553
src
.gitignore
LICENSE.md
README.md
TODO.md
library.json
library.properties

README.md

Interrupted

A new approach to building low-power, interrupt-driven, apps on Arduino:

  • The processor mostly sleeps in a low-power mode.
  • Devices wake the processor using interrupts, it services them before returning to sleep.
  • State-machines are easily implemented: devices may be temporarily disabled when not needed in the current state.

Note

  • The master branch of this library is mostly compatible with the Arduino IDE; however it currently requires uC-Makefile to build the examples.
  • The ATtiny parts of this require a new version of attiny which is based on damellis's attiny branch for Arduino 1.6.
  • This has been tested with Arduino 1.8.4 and Energia 1.6.10E18.

See blog articles.

Example

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

#define LED     13
#define SER_OUT 99
#define EXT0    2
#define EXT1    3
#define TIMER   1

SerialOut output(SER_OUT, 115200);
Watchdog timer(TIMER, WDTO_4S);
External int0(EXT0), int1(EXT1, RISING);
Port port(PB);
Pin led(LED, port);
Devices devices;

void setup(void)
{
  devices.add(timer);
  devices.add(int0);
  devices.add(int1);
  devices.add(led);
  devices.add(output);
  devices.begin();
	 
  pinMode(LED, OUTPUT);
  digitalWrite(LED, HIGH);
}

void loop(void)
{
  switch (devices.select()) {
  case EXT0:
    digitalWrite(LED, HIGH);
    break;
  case TIMER:
  case EXT1:
    digitalWrite(LED, LOW);
    break;
  case LED:
    int0.enable(!led.is_on());
    int1.enable(led.is_on());
    timer.enable(led.is_on());
    break;
  case SER_OUT:
    output.enable(false);
    return;
  }
  output.enable();
  output.write("awake!\r\n");
}

Remarks:

  • This sketch manages a configuration with pins #2 and #3 connected to GND via pushbuttons:
    • when the button on pin #2 is pressed the LED on pin #13 is lit,
    • when that on pin #3 is pressed and released, the LED is turned off,
    • if the timer elapses when the LED is on, it is turned off again.
  • Five devices:
    • a watchdog timer with id 1, interrupting every 5s,
    • two external interrupts on ports 2 and 3,
    • a pin-change interrupt watching the LED on pin #13,
    • hardware serial output device running at 115200 baud.
  • A device group ("devices") which manages them.
  • Selecting on the device group sends the CPU to sleep if no device is ready.
  • When a device is ready, select returns its id.
  • Change of state of the LED pin triggers a state-machine change:
    • if the LED has come on, the timer and external interrupt #1 are enabled,
    • if the LED has been switched off, external interrupt #0 is enabled.
  • Disabled interrupts don't wake the CPU and aren't "remembered".
  • The serial port acts like any other device except that the processor must sleep in an IDLE mode when it is in use.
  • The processor enters the deepest sleep allowed by the currently-enabled devices. When output is in progress, this is SLEEP_MODE_IDLE, when not, SLEEP_MODE_POWER_DOWN.

Credits