LED 8x8 dot-matrix display
This article describes how to drive an I2C 8x8 dot matrix display from uLisp. It is ideal for providing a clear, bright display for representing data, such as analogue values, temperatures, or for playing games.
This code is compatible with displays that use an HT16K33 I2C driver chip . Suitable displays are available from Adafruit  and Keyestudio . You can choose one of four I2C addresses for each display, allowing you to drive up to four displays simultaneously.
The photograph shows the program running on uLisp on an ATtiny3216, but the code should work with any of the uLisp platforms.
Initialising the display
The variable ads is used to specify the I2C address of the display; by default this is 112:
(defvar adr 112)
The routine set initialises the display and sets the brightness, from 0 (off) to 15 (maximum):
(defun set (bri) (with-i2c (s adr) (write-byte #x21 s) (restart-i2c s) (write-byte #x81 s) (restart-i2c s) (write-byte (+ #xe0 bri) s)))
The routine clr clears the display by setting each column to zero:
(defun clr () (with-i2c (s adr) (dotimes (x 16) (write-byte #x00 s))))
Plotting a point
The plt routine treats the display as an 8x8 graphics display, and allows you to toggle one LED on or off by specifying its coordinates:
(defun plt (x y) (let (b) (with-i2c (s adr) (write-byte (* x 2) s) (restart-i2c s 1) (setq b (read-byte s)) (restart-i2c s) (write-byte (* x 2) s) (write-byte (logxor b (ash 1 (logand (+ y 7) 7))) s))))
For example, to toggle the LED in the bottom left-hand corner, give the command:
(plt 0 0)
(logand (+ y 7) 7)
is designed to compensate for the fact that for some reason the rows are numbered 7, 0, 1, 2, 3, 4, 5, 6 from bottom to top.
Finally here's a simple demo that randomly toggles LEDs on the display to give a changing series of patterns:
(defun ran () (clr) (set 2) (loop (plt (random 8) (random 8)) (delay 125)))
To run the demo give the command:
Here's the whole program: Dot-matrix display program.