Building code for microcontrollers
Les Pounder introduces a version of Python that we can use on the Raspberry Pi and microcontroller boards.
This month we take a look at CircuitPython, a programming language designed to simplify experimenting with low-cost boards. On a fresh install of Raspberry Pi OS we need to open a terminal and run a few commands to ensure our system is up to date and ready to install CircuitPython:
$ sudo apt update
$ sudo apt upgrade
Then we install/upgrade setuptools, a Python toolkit to manage Python package installations:
$ sudo pip3 install --upgrade setuptools
Next we make sure we’re in our home directory (/home/pi), then we use the Python packaging tool, pip3 to install Adafruit’s Python Shell tool:
cd ~
$ sudo pip3 install --upgrade adafruit-python-shell
The final two installation steps are to download an installation script from Adafruit, and then run that script using Python 3:
$ wget https://raw. githubusercontent.com/adafruit/ Raspberry-Pi-Installer-Scripts/ master/raspi-blinka.py
$ sudo python3 raspi-blinka.py During the installation it may state that you’re using Python 2. It’ll prompt you to update – do so. After a few minutes CircuitPython will be installed and ready for use.
Project one – flash it baby!
The humble flashing LED is always the first test for a new electronics project. It enables us to be certain that our code is working and that our wiring is sound. For this project we shall wire up an LED to GPIO 17 via two jumper wires and a 330 Ohm resistor. Please refer to the circuit diagram in the download files for this project.
To write the CircuitPython code we’ll use the Thonny editor, found in the menu under Programming. We start by importing three libraries of code. The first is time and this is used to control the
PROJECT ONE
• A breadboard • LED • 330 Ohm resistor (orange-orangebrown-gold) • Two male-to-female jumper wires PROJECT TWO
• Adafruit MPR121 capacitive touch sensor pace of our code. The next two, board and digitalio, are CircuitPython specific libraries. Board enables us to interact with the GPIO, while digitalio is used to control the state of a GPIO pin.
import time import board import digitalio
To control our LED, we need to tell CircuitPython where it’s connected and that it’s an output device. Our LED is connected to GPIO 17, which in CircuitPython is board.D17.
led = digitalio. DigitalInOut(board.D17)
led.direction = digitalio. Direction.OUTPUT
Inside of a loop we change the value of the LED object to True and False, with a delay, created using time.sleep , between each change. When the value is True, the LED is on. When False the LED is off.
while True: led.value = True time.sleep(0.1) led.value = False time.sleep(0.1)
Save the code and click on Run to start the code. The LED should now flash on and off every 0.1 seconds.
Project two – bananas!
The next project requires a little more equipment, but it’s no more difficult than controlling an LED. In this project we’ll use an MPR121 capacitive touch sensor and a few crocodile clips to enable us to use conductive objects as inputs. The MPR121 is designed for microcontroller boards, but with a little ingenuity we can make it work on a Raspberry Pi. The classic MPR121 example is a banana piano, where touching a banana triggers a note to be played. For our simplified version we’ll have two pieces of fruit, and each will turn the LED from Project one
on and off.
To use the MPR121 touch sensor we’ll need to install an additional piece of software. Open a terminal and enter the following command:
$ sudo pip3 install adafruitcircuitpython-mpr121
The MPR121 board uses a StemmaQT connector. To attach it to a Raspberry Pi we need the breakout lead that gives us four jumper wires. They are colour coded as follows: red to 3V, black to GND, yellow to SCL (GPIO3) and blue to SDA (GPIO2). Please see the circuit diagram for a visual guide. Connect the MPR121 to the Raspberry Pi using female-tofemale jumper wires. Using crocodile clips, connect a banana to input 0 of the MPR121, attach the other banana to input 1. Any conductive objects will work – aluminium foil and card is a cheap and easy way to make fun touch interfaces. With the board and bananas connected and the software installed we can start writing some CircuitPython code.
We start in the same manner as Project one, by importing the time, board and digitalio libraries.
import time import board import digitalio
The next two libraries are for the MPR121. The first busio enables our code to access the I2C interface that the MPR121 uses for communication. The second enables the use of the MPR121 in our code.
import busio import adafruit_mpr121
We reuse the LED object from Project one.
led = digitalio. DigitalInOut(board.D17)
led.direction = digitalio.
Direction.OUTPUT
In order to use the I2C interface our code must know where to find the connection, in this case CircuitPython’s busio library can use board.SCL and board.SDA to instantly know their location. We then create an object mpr121 that instructs the code to look for the MPR121 on the I2C pins.
i2c = busio.I2C(board.SCL, board.SDA)
mpr121 = adafruit_mpr121. MPR121(i2c)
We now get to the part of the code that will check for input. In this case, has a banana been touched? The first banana is connected to input 0. Using MPR121’s is_touched() function we can set the input to 0 and use conditional logic (a question) to check if the banana is touched. If so the function returns True and we use that to trigger the indented code. In this case it prints a message to the Python shell, then sets the led.value to True.
while True: if mpr121.is_touched(0) == True:
print(“This banana turns light on”)
led.value = True
The second banana is our off switch, and using elif (elseif) we can check to see if this banana has been touched. The banana is connected to input 1 via a crocodile clip, and if it’s been touched a message is printed to the Python shell and led.value is set to False. Finally, outside of the conditional logic but still inside the main loop we have a half-second pause in the code to prevent accidental activation of the LED.
elif mpr121.is_touched(1) == True:
print(“This banana turns the light off”)
led.value = False time.sleep(0.5)
With the code complete we can save the file as touch-test.py and click Run to start the code. Now press the bananas to turn the LED on and off.