Tiny Lisp Computer 2
18th October 2016
My aim in designing the first Tiny Lisp Computer was to create the smallest practical self-contained computer, with its own display and keyboard interface, that you could use to program in Lisp.
This second version extends the original Tiny Lisp Computer with four improvements: it uses the ATmega1284 to give it more program space; it includes parenthesis matching to make it easier to enter programs; it allows you to connect it to a computer via the USB port, to enter programs from the Arduino IDE's serial monitor; and it includes a built-in program editor, to allow you to make changes to programs without having to enter them again:
The Tiny Lisp Computer 2 - an improved version of my self-contained computer programmed in Lisp.
The new version of the program is also compatible with the original hardware, allowing you to upgrade the ATmega328 version to add parenthesis matching and an editor.
For a PCB version of the Tiny Lisp Computer 2 see Tiny Lisp Computer 2 PCB.
New features
ATmega1284
The Tiny Lisp Computer 2 uses the larger ATmega1284 processor, which is available in a breadboard-friendly 40-pin PDIP package and provides 16Kbytes RAM, the largest RAM size of any ATmega chip. It also provides 4Kbytes of EEPROM and 128Kbytes of flash memory. It has two 8-bit timer/counters and a 16-bit timer/counter, allowing you to have 8 analogue PWM outputs, and it includes 8 analogue inputs.
Parenthesis matching
This new version automatically highlights matching brackets as you type in a program. This makes it much easier to enter a program correctly, and is especially helpful in telling you how many closing brackets to type at the end of defining a function:
Parenthesis matching in the Tiny Lisp Computer 2.
Serial Monitor interface
You can optionally connect the RX and TX pins on the internal USART to a computer's USB socket via a suitable serial-to-USB interface such as the FTDI Basic Breakout from Sparkfun [1], available from HobbyTronics in the UK [2]. This allows you to enter a program via the Arduino IDE Serial Monitor [3], save it using the Tiny Lisp Computer's save-image command, disconnect the computer, and then use the program from the Tiny Lisp Computer's keyboard and display.
Program editor
Once you've defined some functions, it's annoying to have to type them in again if you made a mistake, or want to change a parameter to try a different effect. This new version includes a program editor, that lets you step through a function definition, editing it a bit at a time, using a set of simple single-key editing commands you type at the keyboard.
For more information see Using the program editor below.
Tiny Lisp Computer 2 – Specification
Display: 21 characters x 8 lines.
Memory available: 3001 Lisp cells (12004 bytes).
EEPROM: 1024 Lisp cells (4K bytes).
Language: uLisp, a subset of Common Lisp, with 125 Lisp functions and special forms. For a full definition see uLisp Language Reference.
Types supported: list, symbol, and integer.
An integer is a sequence of digits, optionally prefixed with "+" or "-". Integers can be between -32768 and 32767. You can enter numbers in hexadecimal, octal, or binary with the notations #x2A, #o52, or #b101010, all of which represent 42.
User-defined symbol names can have up to three characters consisting of a-z and 0-9. Any sequence that isn't an integer can be used as a symbol; so, for example, 12a is a valid symbol.
There is one namespace for functions and variables; in other words, you cannot use the same name for a function and a variable.
Includes a mark and sweep garbage collector. Garbage collection takes under 11 msec.
Interfaces:- Analogue input using analogread: A0 to A7 (24 to 31)
- Analogue output using analogwrite: 3, 4, 6, 7 , and 12 to 15
- Digital input and output using pinmode, digitalread, and digitalwrite: 0, 3 to 19, A0 to A7 (24 to 31)
- I2C using with-i2c and restart-i2c: 16 and 17
- SPI using with-spi: 5, 6, 7
As on an Arduino Uno, pin 13 is connected to an LED.
Using the program editor
Here is a summary of the commands:
Command | Name | Description |
Enter | enter | Prints the current form. |
a | car | Takes the car of the current form. |
d | cdr | Takes the cdr of the current form. |
r | replace | Replaces the current form with what you type in. |
c | cons | Conses what you type in onto the front of the current form. |
x | delete | Deletes the car of the current form. |
b | back | Backs up the tree. |
q | quit | Quits from the editor. |
You run the editor by typing:
(edit 'fun)
where fun is the name of the function, or variable, you want to edit.
To edit the function you type a series of a or d commands to step through the function to the part you want to edit, use r, c, or x to make changes, type b to go back, or type q to exit from the editor.
At any stage you can press Enter to print the current part of the function you've reached.
If you type an invalid key the editor prints ?, and if you reach the end of the tree with a or d the editor prints !.
Program editor example
As an example of using the program editor, enter the following function b that blinks the LED on pin 13 once a second:
(defun b (x) (pinmode 13 t) (digitalwrite 13 x) (delay 500) (b (not x)))
Suppose we now want to change the delay parameter to 250 to make it blink twice as quickly. First give the command:
(edit 'b)
The editor prints the current context:
(lambda (x) (pinmode 13 t) (digitalwrite 13 x) (delay 500) (b (not x)))
where lambda is the internal representation for a function. Get to the delay command by typing:
dddd
The editor prints:
((delay 500) (b (not x)))
Now get to the 500 by typing:
ada
The editor responds:
500
Replace this with 250 by typing:
r250
The editor responds:
250
We can confirm that we've changed the correct value by backing up with:
bb
The editor responds:
(delay 250)
Quit from the editor with:
q
Finally run the program to confirm that the change has been made:
(b nil)
Construction
I built the Tiny Lisp Computer 2 on a small 30x12 hole prototyping board, which was just large enough to fit the display and processor with the end of the processor tucked under the display.
The circuit uses an external FTDI USB-to-serial converter to connect it to the USB port of a computer. This is used to upload the Tiny Lisp Computer 2 program to the ATmega1284 chip, and provides an alternative way to enter programs via the Arduino IDE's Serial Monitor. There are several alternative FTDI boards available; I used the FTDI Basic Breakout from Sparkfun [4], available from HobbyTronics in the UK [5]. If you don't want the ability to enter programs from the Arduino IDE's Serial Monitor you can disconnect the FTDI interface once you've programmed the ATmega1284. In this case compile the program with the serialmonitor option disabled, to save the space taken by the serial routines.
The display is based on my Text Display for the Arduino Uno. You can use a 1.3" 128x64 SPI OLED display based on the SSD1306 driver, available from Adafruit [6], or one using the SH1106 driver available from Aliexpress or Banggood [7]. In the program the constant SH1106 should be set to 0 for SSD1306 displays, and 1 for SH1106 displays.
The project uses a PS/2 keyboard, which is relatively easy to interface to an ATmega328; it is based on my Simple PS/2 Keyboard Interface. A miniature PS/2 keyboard is available from Adafruit [8].
When you enter text at the keyboard it is entered into a 165-character buffer, large enough to hold a full screen of text, and you can use the Backspace key to edit what you've typed. Pressing Enter then submits the line to Lisp. The Esc key can be used to interrupt a running program.
Circuit
Here's the circuit for the tiny Lisp computer:
Circuit for the Tiny Lisp Computer 2.
It uses ATmega1284 pins RXD0 (PD0) and TXD0 (PD1) for the FDTI serial interface, PC4 to PC7 for the display interface, and PB1 and PB2 for the keyboard interface. All the other I/O pins are available for use by uLisp programs. I power it from a 3.7V Lipo battery, but anything from 3V to 5V should be fine.
Uploading the program
The ATmega1284 is programmed via the FDTI interface, using a bootloader installed on the ATmega1284. The simplest way is to buy an ATmega1284 chip with a bootloader already installed. Alternatively use In-System Programming to install a bootloader, using an Arduino Uno as a programmer; for more information see Using the ATmega1284 with the Arduino IDE.
To upload the Tiny Lisp Computer 2 program to the ATmega1284 install a suitable core such as Jack Christensen's Mighty 1284P core, which works happily with version 1.6.x of the Arduino IDE [9]. and use the Arduino IDE to upload the program.
Here's the whole Tiny Lisp Computer 2 program: Tiny Lisp Computer 2 Program.
Or get it from GitHub at: https://github.com/technoblogy/tiny-lisp-computer.
Compile options
The program includes the following compile options; comment out the ones you don't want:
Option | Description |
checkoverflow | Includes checking for arithmetic overflow. |
resetautorun | Automatically runs a program image from EEPROM on reset. |
printfreespace | Prints the amount of free space available before the uLisp ">" prompt. |
serialmonitor | Includes the serial interface code. |
tinylispcomputer | Includes the Tiny Lisp Computer keyboard and display interfaces. |
For help with using uLisp on the Tiny Lisp Computer visit the uLisp Forum.
- ^ FTDI Basic Breakout on Sparkfun.
- ^ FTDI Basic Breakout on HobbyTronics.
- ^ See Using uLisp on www.ulisp.com.
- ^ FTDI Basic Breakout on Sparkfun.
- ^ FTDI Basic Breakout on HobbyTronics.
- ^ Monochrome 1.3" 128x64 SPI OLED Graphic Display on Adafruit.
- ^ 1.3 Inch 7 Pin White OLED 128x64 SPI Interface Display Module on Banggood.
- ^ Miniature Keyboard - Microcontroller Friendly PS/2 and USB on Adafruit.
- ^ Mighty 1284P core on Github.
blog comments powered by Disqus