1.20 Interactive embedded development with uLisp, Arduino and Emacs
===================================================================
2017-08-04
AS I MENTIONED IN MY *note 'POST ABOUT ADA': Arduino Programming with
Ada, LISP HAS A COMPLETELY DIFFERENT APPROACH in terms of... well, just
about everything, beginning with the type system. One important feature
of Lisp environments is the high degree if interaction they provide:
Lisp Systems allowed for interaction with every part of the system (OS,
applications, window manager...) and to a smaller degree this is what
the read-eval-print-loop approach (REPL) provides in, say, Emacs with
SLIME.
One interesting language I found recently was uLisp, a Lisp language
for the Arduino and MSP430 platforms. It is based on a subset of Common
Lisp and provides a different approach to development: it installs an
interpreter which is programmed via the serial interface, thus allowing
for a much more interactive development style (at a certain cost in
terms of available space).
The interaction is normally made with the Arduino IDE, via the Serial
Monitor; uLisp contains a minimal editor as well, but using Emacs makes
more sense and it's actually easy to configure to that end; before going
into the details this is the end result (zoom in the image if necessary
to start the animation).
++++++++++++=+++++++++++=+++++++++++++++++++++++++++++++++++++++++++++
::::::::.:::::.::::::.............:::::::::::::::::..................:
...........:.....................::..................................
::................................:::::::::::........................:
::::::::........:......:..........:-::::::::..:...::.................:
:-::.............................:::::-:-::::.::....................:
:::-::::::::::...................::.::::::.::.:.:.::................:
:.:::.....:.......................::.................................:
:.................................::.................................:
.................................::.................................:
:.................................::.................................:
:.................................::.................................:
:.................................::.................................:
:.................................::.................................:
:.................................::.................................:
:.................................::.................................:
.................................::..................................
:...::::.::::::::::::::::::.......::.....:........:::::::::::........:
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
The main thing to consider is that inferior-lisp-mode is actually
based on comint-mode, which simplifies things: we just need a way to
replace the buffer created by calling inferior-lisp with a buffer that
communicates via the serial port. This is, in turn, something which can
be done using Emacs term-mode.
Combining all of this the following Emacs Lisp code will connect to
the Arduino via the serial port, rename the resulting buffer and change
to line mode.
;; Arduino LED blink
;;
;; Based on the example at
http://www.ulisp.com/show?1LG8
;;
;; 2017, Frederico Munoz <fsmunoz@ sdf.org>
(defun b (x s d)
"Slowly increases and decreases the blinking interval in a loop"
(pinmode 13 t)
(digitalwrite 13 x)
(delay s)
(cond
((< s 100) (b (not x) (+ s 50) 50))
((> s 1000) (b (not x) (- s 50) -50))
(t (b (not x) (+ s d) d))))
(b t 500 50)
Gist
(
https://gist.github.com/fsmunoz/ef4a04c5f4eb117087a923d2555563af#file-arduino-serial-el)
Creating a new Lisp file (like test.lisp) will by default enter
lisp-mode; in this mode we can use C-x C-e to send the s-expression to
the uLisp interpreter and get the result, as seen in the previous
screencast
;; Arduino LED blink
;;
;; Based on the example at
http://www.ulisp.com/show?1LG8
;;
;; 2017, Frederico Munoz <
[email protected]>
(defun b (x s d)
"Slowly increases and decreases the blinking interval in a loop"
(pinmode 13 t)
(digitalwrite 13 x)
(delay s)
(cond
((< s 100) (b (not x) (+ s 50) 50))
((> s 1000) (b (not x) (- s 50) -50))
(t (b (not x) (+ s d) d))))
(b t 500 50)
I've put the Lisp code on Github as well (1))
---------- Footnotes ----------
(1) I've put the Lisp code on Github as well
(
https://gist.github.com/fsmunoz/424b052e1848cdda3bee043386bdc7bd#file-blink-lisp)