Circuit Playground Bluefruit
22nd May 2023
The Adafruit Circuit Playground Bluefruit  is a compact board based on the Nordic Semiconductor nRF52840 ARM Cortex-M4 microcontroller running at 64 MHz, with 1 Mbyte of flash program memory and 256 Kbytes of RAM:
It includes the following features:
- Ten mini RGB NeoPixels.
- An LIS3DH triple-axis accelerometer.
- A temperature sensor (thermistor).
- A light sensor (phototransistor).
- A sound sensor (MEMS microphone).
- A mini speaker with a class D amplifier.
- Two push buttons, labelled A and B.
- A slide switch.
- Eight alligator-clip friendly input/output pins.
- A green power LED, and a red LED on :led-builtin.
- A reset button.
It also include 2 Mbytes of DataFlash that uLisp uses to allow you to save and reload the Lisp image.
Other Circuit Playgrounds
Adafruit also offer the Circuit Playground Express  which is almost identical, but it's based on the ATSAMD21 rather than the nRF52840, and it provides an infrared receiver and transmitter instead of the Bluetooth on the Circuit Playground Bluefruit.
From the point of view of running uLisp I highly recommend choosing the Circuit Playground Bluefruit because it offers about ten times the amount of workspace for Lisp, and it's slightly faster.
Installing uLisp on the Adafruit Circuit Playground Bluefruit
You can install the ARM version of uLisp on a Circuit Playground Bluefruit using the Arduino IDE as follows:
- Download the ARM version of uLisp from the downloads page: Download uLisp.
- Open the Boards Manager… from the Board item on the Tools menu, search for nRF52, and install Adafruit nRF52 Boards.
- Connect the Circuit Playground Bluefruit to your computer using a USB cable.
- Select Adafruit Circuit Playground Bluefruit from the Adafruit nRF52 Boards section on the Board menu.
I recommend release 4.4d or later of the ARM version of uLisp.
- Download the latest ARM version of uLisp from the Download uLisp page.
- Select the board's USB port from the Port menu.
- Upload uLisp to the board.
- You may need to select the board's USB port from the Port menu again.
- Select Serial Monitor from the Tools menu.
- Enter Lisp commands.
The following diagram shows the Circuit Playground Bluefruit pin assignments:
Buttons and switch
The Circuit Playground Bluefruit provides two pushbuttons on pins 4 (left) and 5 (right) that connect to Vcc when pressed, and a slide switch on pin 7 that connects to GND when switched to the right. You can read these with the following program:
(defun buttons () (pinmode 4 :input-pulldown) (pinmode 5 :input-pulldown) (pinmode 7 :input-pullup) (loop (print (mapcar digitalread '(4 5 7))) (delay 1000)))
Run it by typing:
Digital inputs and outputs
The Circuit Playground Bluefruit provides 8 digital inputs/outputs, on pin numbers 0 to 3, 6, 9, 10, and 12.
The Circuit Playground Bluefruit has a red LED on pin 13. You can flash it with the following program:
(defun blink (&optional x) (pinmode 13 :output) (digitalwrite 13 x) (delay 1000) (blink (not x)))
Run it by typing:
Exit from the program by entering ~.
Any pin can also be used as an 8-bit PWM analogue output.
For example, you can pulsate the red LED slowly on and off with the program:
(defun pulse () (let (down) (loop (dotimes (x 256) (delay 5) (analogwrite 13 (if down (- 255 x) x))) (setq down (not down)))))
Run it by typing:
Exit from the program by entering ~.
There are six analogue inputs on pin 0 (A6), 2 (A5), 3 (A4), 6 (A1), 9 (A2), and 10 (A3). In addition, pins 22 (A8) and 23 (A9) are used for the light sensor and thermistor.
The Circuit Playground Bluefruit provides the following options for analogreference, the first five of which are multiples of the 0.6V internal reference:
|:ar-default or :ar-internal||Internal reference of 3.6 V|
|:ar-internal-3-0||Internal reference of 3.0 V|
|:ar-internal-2-4||Internal reference of 2.4 V|
|:ar-internal-1-8||Internal reference of 1.8 V|
|:ar-internal-1-2||Internal reference of 1.2 V|
|:ar-vdd4||Internal reference of VDD|
Analogue read resolution
The ADC resolution can be set to 8, 10 (default), 12, or 14 bits using analogreadresolution.
The Circuit Playground Bluefruit has one accessible serial port on pin numbers 1 (TX) and 0 (RX).
The Circuit Playground Bluefruit have one accessible SPI port on pin numbers 9 (MISO), 10 (MOSI), and 8 (SCK).
The Circuit Playground Bluefruit has one accessible I2C port on pin numbers 2 (SDA) and 3 (SCL). The on-board accelerometer is on port 1 which is on internal pins 28 (SDA) and 28 (SCL).
The Circuit Playground Bluefruit provides a Murata NCP15XH103F03RC thermistor on pin 23 (A9) which you can read with analogread.
The following program temperature gives the temperature in °C for the thermistor:
(defun temperature (pin series-res nom-res nom-temp b-coeff) (analogreference :ar-vdd4) (- (/ (+ (/ (+ nom-temp 273.15)) (/ (log (/ (* series-res (1- (/ 1023 (analogread pin)))) nom-res)) b-coeff))) 273.15))
With the Circuit Playground Bluefruit you can read the temperature with:
> (temperature 23 10000 10000 25 3380) 20.3813
For an explanation of these parameters see: NTC Thermistor.
The Circuit Playground Bluefruit provides an ALS-PT19 light sensor connected to analogue input pin 22 (A8). The following program demonstrates its use:
(defun light () (loop (print (analogread 22)) (delay 1000)))
The Circuit Playground Bluefruit has a tiny loudspeaker driven by a Class D amplifier on analogue output pin 12. The speaker amplifier can be disabled by making pin 11 a low output.
The following program plays a scale on the speaker:
(defun scale () (mapc (lambda (n) (note 12 n 4) (delay 500)) '(0 2 4 5 7 9 11 12)) (note))
The Circuit Playground Bluefruit includes ten NeoPixel RGB LEDs that you can control using the NeoPixel extension to uLisp. For more information see NeoPixel extension.
For example, the following program displays a rotating rainbow:
(defun rotate () (pixels-begin) (loop (dotimes (n 1000) (pixels-rainbow (* n 65) 1 255 50) (pixels-show))))
You can combine the NeoPixel functions with the other sensors, such as the temperature sensor, light sensor, or accelerometer. For example, using the accelerometer you could make displays that change as you tilt the Circuit Playground Bluefruit.
The Circuit Playground Bluefruit includes an LIS3DH  low power triple-axis accelerometer with 10-bit precision and selectable scaling. It is connected to I2C port 1, with address #x19, and has an optional interrupt output on pin 24.
The sensor provides a number of different operating modes for different applications, and a FIFO allowing you to buffer 32 10-bit readings. The following routines run the sensor in the default Normal Mode, which provides 10-bit accuracy, and FIFO Bypass mode, which ignores the FIFO.
Setting the sample rate
By default the sensor is in low-power mode, so to take readings you need to set the rate. The following routines lis3dh-rate takes a parameter from 0 to 9:
(defun lis3dh-rate (x) (with-i2c (s 1 #x19) (write-byte #x20 s) (write-byte (logior (ash x 4) 7) s)))
For example to set a 10Hz sample rate:
Reading the accelerometer
The following routine s16 returns a signed 16-bit integer from two bytes, LSB first:
(defun s16 (s) (let ((d (logior (read-byte s) (ash (read-byte s) 8)))) (- d (ash (logand d #x8000) 1))))
The following routine lis3dh-xyz then returns the acceleration data as a list of three signed integers:
(defun lis3dh-xyz () (with-i2c (s 1 #x19) (write-byte (+ #x28 #x80) s) ; Set top bit to read multiple bytes (restart-i2c s 6) (let (dat) (dotimes (i 3) (push (s16 s) dat)) (reverse dat))))
At the default full-scale sensitivity, 2g, a value of 32767 represents 2g and -32768 represents -2g.
(-448 -640 15808)
If the sensor is stationary the x and y figures will be close to zero, and the z value will be close to 16384, corresponding to 1g.
The following routine will return the values in units of g; it reads the currently selected full-scale sensitivity:
(defun lis3dh-g3d () (let ((fs (with-i2c (s 1 #x19) (write-byte #x23 s) (restart-i2c s 1) (logand 3 (ash (read-byte s) -4))))) (mapcar (lambda (i) (/ i (ash 16384 (- fs)))) (lis3dh-xyz))))
(-0.03125 -0.0234375 0.96875)
Setting the sensitivity
The following routine set sets the full-scale sensitivity of the accelerometer:
(defun lis3dh-set (x) (with-i2c (s 1 #x19) (write-byte #x23 s) (write-byte (ash x 4) s)))
The parameter can be 0 for ±2g, 1 for ±4g, 2 for ±8g, or 3 for ±16g.