Using interrupts

There is now a version of AVR uLisp 2.7 with interrupt handling, to allow you to detect events independently of the execution of your Lisp program.

Download it from GitHub at: uLisp AVR Interrupts

Example

As a simple example, connect a push button between the following two pins on an Arduino Uno or Arduino Mega 2560 board:

  • Arduino Uno: between pin 2 and GND.
  • Arduino Mega 2560: between pin 21 and GND.

Define the interrupt pin with a pullup, and pin 13 as an output: on the Arduino Uno:

(pinmode 2 2)
(pinmode 13 t)

or on the Arduino Mega 2560:

(pinmode 21 2)
(pinmode 13 t)

Now upload the following tog function:

(defun tog (n) (digitalwrite 13 (not (digitalread 13))))

This simply toggles the LED on pin 13 of the Arduino board.

To attach an interrupt to the interrupt pin evaluate:

(attach-interrupt 0 tog)

This uses the default trigger mode, on the rising edge of the signal; ie when you release the pushbutton.

Now pressing the push button will toggle the LED on and off. Note that this happens even when you are running a Lisp program.

Counting interrupts

The above simple example ignores the argument returned by the interrupt routine. However, this is useful when you need to count the exact number of interrupts that have occurred.

For example, if the interrupt was from an optical encoder you could use the parameter to increment a counter:

(defvar c 0)
(defun inc (n) (incf c n))
(attach-interrupt 0 inc)

Now, even if two interrupts are received in quick succession, so the interrupt handler does not have time to respond to both, the counter will still reflect the correct interrupt count.

attach-interrupt Arduino function

Syntax: (attach-interrupt interrupt function [mode])

Attaches a function to an interrupt; the function is evaluated when the interrupt occurs. Note that the interrupt parameter should be the interrupt number, not the Arduino pin number.

The function should be a function of one argument; it will be called with the number of interrupts that have occurred since the last evaluation of the interrupt handling function; this will normally be 1, but may be more if the interrupt handling function took longer than the rate of interrupts. The maximum value is 65535; this indicates that some interrupts may have been lost. For more information see the above examples.

The mode argument specifies how the interrupt is triggered:

Mode Effect
0 Triggered on a low input
1 Triggered on a change in input
2 Triggered on a falling input
3 Triggered on a rising input (default)

Give attach-interrupt with just one argument to detach the interrupt function from a specified interrupt.

The following table shows the available interrupt numbers, followed by the Arduino pin number in brackets:

Processor Arduino pin Typical Boards
ATmega328 0 (2), 1 (3) Arduino Uno
ATmega2560 0 (21), 1 (20), 2 (19), 3 (18), 4 (2), 5 (3), 6 (*), 7 (*) Arduino Mega 2560
ATmega1284 0 (10), 1 (11), 2 (2)  

* Not accessible on Arduino board.