Lisp for microcontrollers
Lisp for Arduino boards, Adafruit M0 / M4, Micro: bit, ESP8266 / 32, RISC-V and Teensy 4.x.
ARM version 3.6b now supports save-image on all ATSAMD21 boards
With the latest ARM uLisp release, version 3.6b, you can save an image of your entire Lisp workspace to flash memory on ATSAMD21 boards that do not provide a separate DataFlash chip.
Thus, support save-image adds to Adafruit Neo Trinkey, Adafruit Gemma M0, Adafruit Feather M0, Arduino Zero, Arduino MKRZero and Seeedstudio Xiao M0.
uLisp is a version of the Lisp programming language specifically designed to run on microcontrollers with limited RAM, from the ATmega328 based Arduino Uno to Teensy 4.0 / 4.1. Regardless of the platform, you can use exactly the same program on uLisp.
Since uLisp is an interpreter, you can enter commands into it and immediately observe the result, without having to first compile the program and then load it. As such, this environment is ideal for teaching programming or getting ready to use simple electronic devices.
In addition, the Lisp language is ideal for learning fundamental programming concepts. It offers string manipulation, list processing, and garbage collection, and is great for expressing complex ideas, such as teaching a robot to get out of a maze or finding the shortest path on a map. uLisp not only supports a basic set of Lisp functions, but also contains extensions for Arduino, so this language is ideal for controlling Arduino.
The current version of uLisp can be downloaded for free from the page Download uLisp…
Controlling NeoPixels in assembler
Ray tracing with uLisp
GPS mapping app
RAM: at least 2 KB.
Memory for storing programs: at least 32 KB.
EEPROM, Flash or Ferroelectric Random Access Memory (FRAM): if available, used to save and load the uLisp workspace.
The 8-bit and 16-bit versions of uLisp support integers in the range -32768 to 32767.
The AVR version of uLisp supports the following boards:
Arduino Uno or other cards based on ATmega328. It has enough memory for a simple uLisp application using short symbolic names. Everything Simple examples will go to the Arduino Uno.
Arduino Mega 2560 or other boards based on ATmega2560. With them, you will have enough memory for a very complex application; see for example Animals, Tweetmaze, Route finder and Infinite precision arithmetic…
ATmega1284… Although the Arduino does not have an official board based on this, the ATmega1284 is easy to connect to a breadboard and provides a whopping 16K of RAM.
Boards ATmega4809… Arduino Nano Every and Microchip Curiosity Nano development board are budget ATmega4809-based platforms.
The 32-bit versions of uLisp support integers from 2147483647 to -2147483648, as well as 32-bit floating point numbers.
The ARM version of uLisp supports the following boards:
Arduino Zero… This board is based on the SAMD21 ARM Cortex-M0 + core and provides 256KB of flash and 32KB of RAM.
Arduino MKRZero… Similar to the Arduino Zero, based on the SAMD21 ARM Cortex-M0 + core and provides 256KB of flash and 32KB of RAM. It has an SD card slot, so the SD card can be used to save and load uLisp images.
Boards Adafruit M0… The Adafruit Gemma M0, Adafruit ItsyBitsy M0 and Adafruit Feather M0 boards are all based on the ATSAMD21 48 MHz ARM Cortex M0 + microcontroller. They have similar capabilities and performance; the main differences between these boards are in their aspect ratio.
Boards Adafruit m4… The Adafruit Metro M4 Grand Central, Adafruit Metro M4, Adafruit ItsyBitsy M4, and Adafruit Feather M4 boards are all based on the ATSAMD51 120 MHz ARM Cortex M4 microcontroller.
Adafruit PyGamer and PyBadge… Adafruit PyGamer and PyBadge are portable gaming platforms based on the ATSAMD51 120 MHz ARM Cortex M4 microcontroller, equipped with a 160×128 color thin film display.
Boards Adafruit nRF52840… The Adafruit CLUE and Adafruit ItsyBitsy nRF52840 are both based on the Nordic Semiconductor nRF52840 64 MHz ARM Cortex-M4 microcontroller, with 1 MB of flash memory for program storage and 256 KB of RAM.
BBC Micro: bit… This board is based on the Nordic Semiconductor nRF51822 ARM Cortex-M0 microcontroller. It operates at 16 MHz and provides 256 KB of flash memory for programs and 16 KB of RAM.
Maxim MAX32620FTHR… This board is based on the Maxim MAX32620 ARM Cortex-M4F microcontroller, clocked at 96 MHz, with 2048KB of flash memory and 256KB of RAM.
Teensy 4.0 and 4.1… They are based on the NXP iMXRT1062 ARM M7 processor, clocked at 600 MHz with 1 MB of RAM.
ESP8266 / ESP32 version
The uLisp version for ESP8266 / ESP32 supports the following boards:
Boards ESP8266 … These boards are based on a 32-bit Tensilica Xtensa L106 microprocessor running at 80 MHz, with 4 MB of flash memory and 80 KB of RAM. They have built-in Wi-Fi function.
Boards ESP32… These boards are based on the Tensilica Xtensa LX6 32-bit microprocessor, clocked at 160 or 240 MHz, with 4 MB of flash memory and 80 KB of RAM. They have built-in Wi-Fi and dual-mode Bluetooth.
The uLisp RISC-V version supports the following cards:
Boards Sipeed MAiX RISC-V… These boards are based on the Kendryte K210 RISC-V 400 MHz dual-core 64-bit processor, provide 8 MB of RAM and 16 MB of flash memory. They are similar in performance.
These boards are supported by earlier versions of uLisp:
Arduino Due… This board is based on the AT91SAM3X8E ARM Cortex-M3 core and provides 512KB of flash memory, 96KB of RAM and an 84MHz clock.
Boards STM32… The STM32 Maple Mini and Blue Pill boards are based on the STM32F103 ARM Cortex-M3 processor, clocked at 72 MHz, with 128KB of flash memory and 20KB of RAM.
The uLisp MSP430 version supports the following boards:
MSP430 F5529 LaunchPad… It uses flash memory to store images and provides enough memory for a very complex application.
MSP430 FR5969 LaunchPad… This version uses ferroelectric random access memory (FRAM) for workspace and for saving images, so you have plenty of memory at your disposal.
MSP430 FR5994 LaunchPad… This version uses ferroelectric random access memory (FRAM) for workspace and for saving images, so you have plenty of memory at your disposal.
MSP430 FR6989 LaunchPad… This version uses ferroelectric random access memory (FRAM) for the workspace and for saving images, and also supports text output to the built-in LCD display.
In general, this language is a subset of Common Lisp, and uLisp programs must also run under Common Lisp. But note: there is one namespace for functions and variables; in other words, you cannot use the same name for a function and a variable.
On 8/16-bit platforms, lists, character sequences, integers, characters, strings (on 32-bit platforms), and streams are provided.
In addition, floating point numbers and arrays, including bit arrays, are provided on 32-bit platforms.
An integer is a sequence of numbers, which can be preceded by a “+” or “-” sign. On 8/16 bit platforms, integers can range from -32768 to 32767. On 32-bit platforms, integers can range from 2147483647 to -2147483648. Integers can be entered in hexadecimal, octal, or binary using the notation # x2A, # o52, or # b101010, all of which are 42.
Arbitrary user-defined symbolic names are supported on platforms with more than 2KB of RAM. Any sequence that is not an integer can be used as a character sequence; so, for example, 12a is a valid character sequence. On platforms with only 2KB, the symbolic name can contain up to three characters from the sets az, 0-9, or $, *, or or -.
uLisp provides tail-call optimization, so applications written using recursive functions can be as efficient as using iteration.
Strings can be composed of arbitrary sequences of ASCII characters. The length of strings can be unlimited, strings are automatically garbage collected.
ULisp has a garbage collector that uses a mark and sweep algorithm. Garbage collection takes less than 1ms on the Arduino Uno or less than 3ms on the Arduino Mega 2560. Performance).
uLisp also contains a simple program editor (see Working with the program editor), a tracer, and a nice printer (see p. Debugging in uLisp).
The following example shows how uLisp can be used.
Having downloaded uLisp to your microcontroller board, you can establish communication with it by entering or inserting commands into the port monitor or using a serial terminal. For more details see Using uLisp…
Let’s say you connected a red LED to the analog pin 9 on the Arduino Uno. Then you can enter the command in Lisp:
(analogwrite 9 128)
to set the LED to 128, which is half brightness.
To avoid having to write this command whenever you want to set a red LED, you can write a function red:
(defun red (x) (analogwrite 9 x))
Now you can achieve the same effect as above by simply writing:
In both cases, the LED color will change as soon as you enter the command.
Let’s say you use the potentiometer you connected to the board to vary the voltage at analog input A0. You can define a function dimso that the potentiometer itself adjusts the brightness of the LED, like this:
(defun dim () (loop (red (/ (analogread 0) 4)))
and run by writing:
Finally, you can save the uLisp image to EEPROM and specify that dim should be executed at boot by typing:
After restarting Arduino dim will be loaded and executed automatically.
This is a simple example showing how uLisp can be used to compose complex programs from simpler components, testing each component as you go.
Cloud servers from Macleod fast and safe.
Register using the link above or by clicking on the banner and get a 10% discount for the first month of renting a server of any configuration!