Intelligent Blink


#1

Here for fun is an updated uLisp version of the classic Aduino Blink program, traditionally used to verify that your Arduino board is working correctly.

This one blinks out the series of prime numbers, starting with 2, 3, 5, 7, 11, etc, up to the largest integer that uLisp can represent, 32767. You could also use this to demonstrate the existence of intelligent life to visiting aliens.

First, the routine pri returns t if its argument is prime, and nil if it’s composite:

(defun pri (n)
  (let ((d 2))
    (loop
     (when (> (* d d) n) (return t))
     (when (zerop (mod n d)) (return nil))
     (incf d))))

Here’s the Blink program:

(defun bli (pin)
  (pinmode pin t)
  (dotimes (x 32767)
     (when (and (> x 1) (pri x))
         (dotimes (f (* x 2))
           (digitalwrite pin (evenp f))
           (delay 250))
         (delay 1500))))

Call it with the pin number corresponding to the LED on your board; for example, on an Arduino Uno:

(bli 13)

It will run on any uLisp platform.

If anyone can improve it or shorten it let me know!


#2

Note that if you’re running this on my Lisp Badge use:

(bli 7)

#3

Hi,

Unfortunatelly this version crashes on Uno (x becomes undefined after it reaches 8, I assume it’s stack overwriting data or something like this).

Here is my improved version - pri is now based on fdv (find divisor) and both are tail call recursive (no loops).

(defun fdv (n td)
  (cond ((< n (* td td)) n)
        ((= 0 (mod n td)) td)
        (t (fdv n (+ td 1)))))

(defun pri (n)
  (if (< n 2)
      nil
      (= n (fdv n 2))))

(defun bli (pin)
  (pinmode pin t)
  (dotimes (x 32767)
    (when (pri x)
      (dotimes (b (* x 2))
        (digitalwrite pin (not (digitalread pin)))
        (delay 250))
      (delay 1500))))

#4

You’re right! This works fine on uLisp 2.6, but one of the changes in 2.7 seems to have broken it. I’ll investigate.

Thanks for reporting this (and for providing the better version).