http://www.ulisp.com/ * Home * Reference * Forum Logo uLisp [ ] [Search] Getting started * Lisp for microcontrollers * Performance * Using uLisp * Using uLisp from a terminal * Debugging in uLisp * Using the program editor * SD card interface * I2C and SPI serial interfaces * Lisp Library * Download uLisp * uLisp Sensor Library * Forum Self-contained Lisp computers * Tiny Lisp Computer * Lisp Badge * Pocket Op Amp Lab 8/16-bit platforms * Arduino Uno * Arduino Mega 2560 * ATmega1284 * ATmega4809 boards * AVR DA and DB series boards 32/64-bit platforms * Arduino Zero * Arduino MKRZero * Adafruit M0 boards * Adafruit M4 boards * Adafruit PyGamer and PyBadge * Adafruit nRF52840 boards * BBC Micro:bit * Calliope mini * ESP32 boards * ESP8266 boards * Maxim MAX32620FTHR * Sipeed MAiX RISC-V boards * Teensy 4.0 and 4.1 Platforms also supported * Arduino Due * STM32 boards * MSP430 F5529 LaunchPad * MSP430 FR5969 LaunchPad * MSP430 FR5994 LaunchPad * MSP430 FR6989 LaunchPad Simple examples * Blinking primes * Mood light * LED 8x8 dot-matrix display * Simon game * I2C clock * Data logging * Ringing the changes * Driving DotStar RGB LEDs * LCD character display * DDS signal generator * Temperature sensor * Simple data plotter * Thermocouple interface * Benchmarks Larger examples * Tweetmaze * Animals * Route finder * Calculating with fractions * Infinite precision arithmetic * Scrolling text display * Dot-matrix clock * Graphics display interface in Lisp * Plotting to a colour TFT display * Ray tracing with uLisp * GPS mapping application * Eliza chatbot * Bulls & Cows game * Query language * uLisp GSM server * A LoRaWAN node using uLisp * Solving resistor networks * Fast Fourier Transform * Sudoku solver * Prime number spiral * Wi-Fi examples * Automatic uLisp to C converter * Simple object system * Mini text adventure game Assemblers * AVR assembler overview New! * AVR assembler examples New! * ARM assembler overview * ARM assembler instructions * ARM assembler examples * RISC-V assembler overview * RISC-V assembler instructions * RISC-V assembler examples * NeoPixel driver using assembler New! * Mandelbrot set using assembler * Returning a floating-point result Tutorials * Getting started * Lists * Expressions * Defining functions * Variables * Strings * Testing a result * Manipulating lists * Processing items in a list * Recursion * Returning functions * Lisp for C programmers * Thinking in a Lispy way Reference * Language reference * Floating-point extensions * Graphics extensions * Wi-Fi extensions * Error messages * Adding useful functions to uLisp Implementation * Implementation * Objects * Built-in symbols * Arbitrary symbol names * Strings * Arrays * Read, Evaluate, Print * Garbage collection * Tail-call optimization * Saving and loading images * Assembler and defcode * Debugging uLisp * Adding your own functions * Converting between C and uLisp * Porting uLisp to a new platform * uLisp Builder * uLisp Zero Other information * About me * Contact * Legal stuff RSS Feed uLisp news! Lisp for microcontrollers Lisp for Arduino, Adafruit M0/M4, Micro:bit, ESP8266/32, RISC-V, and Teensy 4.x boards. News! AVR Version 3.6 of uLisp now includes an AVR assembler AVR Version 3.6 of uLisp now includes an AVR assembler which allows you to generate machine-code functions, integrated with Lisp, written in AVR assembler mnemonics. For more information see AVR assembler overview. All versions of uLisp 3.6 now also automatically turn off echo when pasting a program into the Serial Monitor. This allows you to use uLisp with a minimal Serial buffer, freeing up RAM, without the risk of errors due to buffer overflows. uLisp(r) is a version of the Lisp programming language specifically designed to run on microcontrollers with a limited amount of RAM, from the Arduino Uno based on the ATmega328 up to the Teensy 4.0/4.1. You can use exactly the same uLisp program, irrespective of the platform. Because uLisp is an interpreter you can type commands in, and see the effect immediately, without having to compile and upload your program. This makes it an ideal environment for learning to program, or for setting up simple electronic devices. Lisp is also an ideal language for learning about fundamental programming concepts. It incorporates string handling, list processing, and garbage collection, and so is also an excellent language for expressing complex ideas, such as teaching a robot to solve mazes or finding the shortest route on a map. As well as supporting a core set of Lisp functions uLisp includes Arduino extensions, making it ideal as a control language for the Arduino. You can download the current version of uLisp free from the Download uLisp page. uLisp projects NeoPixelsSmall.jpgDriving NeoPixels using assembler ClueRayTrace2.jpgRay tracing with uLisp LispBadgeHand2.jpgLisp Badge DotMatrixClock2.jpgDot-matrix clock GPSPlotter2.jpgGPS mapping application MAX6675b.jpgThermocouple interface Requirements RAM: At least 2 Kbytes. Program memory: At least 32 Kbytes. EEPROM, flash, or FRAM memory: If available, used for saving and loading the uLisp workspace. 8/16-bit platforms The versions of uLisp for 8-bit and 16-bit platforms support integers between -32768 and 32767. AVR version The AVR version of uLisp supports the following boards: Arduino Uno or other ATmega328-based cards. These will give you enough memory for a simple uLisp application using short symbol names. All the Simple examples will run on the Arduino Uno. Arduino Mega 2560 or other ATmega2560-based boards. These will give you enough memory for a fairly complex application; for examples see Animals, Tweetmaze, Route finder, and Infinite precision arithmetic. ATmega1284. Although there isn't an official Arduino board based on it, the ATmega1284 is easy to wire up on a prototyping board, and provides a generous 16 Kbytes RAM. ATmega4809 boards. The Arduino Nano Every and Microchip Curiosity Nano evaluation board are low-cost platforms based on the ATmega4809. 32/64-bit platforms The versions of uLisp for 32-bit platforms support integers between 2147483647 and -2147483648, and 32-bit floating-point numbers. ARM version The ARM version of uLisp supports the following boards: Arduino Zero. This board is based on the SAMD21 ARM Cortex-M0+ core and provides 256 Kbytes of flash and 32 Kbytes of RAM. Arduino MKRZero. This is similar to the Arduino Zero, based on the SAMD21 ARM Cortex-M0+ core and with 256 Kbytes of flash and 32 Kbytes of RAM. It incorporates an SD-card socket, allowing you to use an SD card for saving and loading uLisp images. Adafruit M0 boards. The Adafruit Gemma M0, Adafruit ItsyBitsy M0, and Adafruit Feather M0 are each based on the ATSAMD21 48 MHz ARM Cortex M0+ microcontroller. They have similar features and performance; the main difference is the form-factor of each board. Adafruit M4 boards. The Adafruit Metro M4 Grand Central, Adafruit Metro M4, Adafruit ItsyBitsy M4, and Adafruit Feather M4 are each based on the ATSAMD51 120 MHz ARM Cortex M4 microcontroller. Adafruit PyGamer and PyBadge. The Adafruit PyGamer and PyBadge are handheld game platforms based on the ATSAMD51 120 MHz ARM Cortex M4 microcontroller and incorporating a 160x128 colour TFT display. Adafruit nRF52840 boards. The Adafruit CLUE and Adafruit ItsyBitsy nRF52840 are each based on the Nordic Semiconductor nRF52840 64 MHz ARM Cortex-M4 microcontroller, with 1 Mbyte of flash program memory and 256 Kbytes of RAM. BBC Micro:bit. This is based on a Nordic Semiconductor nRF51822 ARM Cortex-M0 microcontroller. It runs at 16 MHz and provides 256 Kbytes of flash program memory and 16 Kbytes of RAM. Maxim MAX32620FTHR. This is based on a Maxim MAX32620 ARM Cortex-M4F microcontroller running at 96 MHz, with 2048 Kbytes of flash memory and 256 Kbytes of RAM. Teensy 4.0 and 4.1. These are based on the NXP iMXRT1062 ARM M7 processor running at 600 MHz, and with 1 Mbytes of RAM. ESP8266/ESP32 version The ESP8266/ESP32 version of uLisp supports the following boards: ESP8266 boards. These boards are based on the 32-bit Tensilica Xtensa L106 microprocessor running at 80 MHz, with 4 Mbytes of flash and 80 Kbytes of RAM. They include integrated Wi-Fi. ESP32 boards. These boards are based on the 32-bit Tensilica Xtensa LX6 microprocessor running at 160 or 240 MHz, with 4 Mbytes of flash and 520 Kbytes of RAM. They include integrated Wi-Fi and dual-mode Bluetooth. RISC-V version The RISC-V version of uLisp supports the following boards: Sipeed MAiX RISC-V boards. These boards are based on the Kendryte K210 RISC-V Dual Core 64 bit 400 MHz processor and provide 8 Mbytes RAM and 16 Mbytes flash. They are similar in performance. Other platforms These boards are supported by earlier versions of uLisp: Arduino Due. This board is based on the AT91SAM3X8E ARM Cortex-M3 core and provides 512 Kbytes of flash, 96 Kbytes of RAM, and an 84 MHz clock. STM32 version STM32 boards. The STM32 Maple Mini and Blue Pill boards are based on the STM32F103 ARM Cortex-M3 processor running at 72 MHz, with 128 Kbytes of flash and 20 Kbytes of RAM. MSP430 version The MSP430 version of uLisp supports the following boards: MSP430 F5529 LaunchPad. This uses the flash memory for saving images, and provides enough memory for a fairly complex application. MSP430 FR5969 LaunchPad. This version uses the FRAM for the workspace, and for saving images, giving a generous amount of memory. MSP430 FR5994 LaunchPad. This version uses the FRAM for the workspace, and for saving images, giving a generous amount of memory. MSP430 FR6989 LaunchPad. This version uses the FRAM for the workspace, and for saving images, and supports writing text to the on-board LCD display. Performance See Performance. Specification The language is generally a subset of Common Lisp, and uLisp programs should also run under Common Lisp. But note that there is one namespace for functions and variables; in other words, you cannot use the same name for a function and a variable. The 8/16 bit platforms provide lists, symbols, integers, characters, strings, (32-bit platforms), and streams. In addition the 32-bit platforms provide floating-point numbers and arrays, including bit-arrays. An integer is a sequence of digits, optionally prefixed with "+" or "-". On the 8/16-bit platforms integers can be between -32768 and 32767. On the 32-bit platforms integers can be between 2147483647 and -2147483648. You can enter integers in hexadecimal, octal, or binary with the notations #x2A, #o52, or #b101010, all of which represent 42. On platforms with more than 2 Kbytes of RAM arbitrary user-defined symbol names are supported. Any sequence that isn't an integer can be used as a symbol; so, for example, 12a is a valid symbol. On platforms with only 2 Kbytes symbol names can have up to three characters consisting of a-z, 0-9, or $, *, or -. uLisp provides tail-call optimization, so applications written using recursive functions can be as efficient as using iteration. Strings can consist of an arbitrary sequence of ASCII characters. Strings can be unlimited length, and are automatically garbage-collected. uLisp includes a mark and sweep garbage collector. Garbage collection takes under 1 msec on an Arduino Uno or under 3 msec on an Arduino Mega 2560 (see Performance). uLisp also includes a simple program editor (see Using the program editor), a trace facility, and a pretty printer (see Debugging in uLisp). Example The following example illustrates how you might use uLisp. After uploading uLisp to your microcontroller board you can communicate it via by typing or pasting commands into the Serial Monitor, or using a serial terminal. For more information see Using uLisp. Suppose you have a red LED connected to the analogue output pin 9 on an Arduino Uno. Then you can type in the Lisp command: (analogwrite 9 128) to set the LED to 128, which corresponds to half brightness. To save having to write this command every time you want to set the red LED you can define a function called red: (defun red (x) (analogwrite 9 x)) Now you can achieve the same effect simply by writing: (red 128) In each case the LED changes immediately, as soon as you type in the command. Suppose you've got a potentiometer connected to vary the voltage on the analogue input A0. You could define a function dim to make the potentiometer adjust the brightness of the LED with: (defun dim () (loop (red (/ (analogread 0) 4))) and run it by typing: (dim) Finally, you could save the uLisp image to EEPROM, and specify that dim should be run on load, by entering: (save-image 'dim) When you reset the Arduino dim will now load and run automatically. This is a simple example showing how uLisp allows you to build up complex programs from simpler components, testing each of the components as you go along. --------------------------------------------------------------------- Next: Performance Copyright 2021