Electronics Software Development

Getting Started With CircuitPython On Raspberry Pi With Blinka

CircuitPython On Raspberry Pi Graphic
Written by John Woolsey

Last Updated: December 17, 2022
Originally Published: September 29, 2020

Skill Level: Intermediate

Table Of Contents

Introduction

This tutorial will teach you how to get up and running with CircuitPython on a Raspberry Pi using the Blinka library.

We will cover the following topics:

  • What CircuitPython and Blinka are and why you may want to use them in your projects.
  • How to install the Blinka library to add CircuitPython hardware support to your Python programs.
  • How to invoke and use the Read-Evaluate-Print-Loop (REPL) to run individual lines of code.
  • How to install and use libraries in your CircuitPython program.

A basic understanding of electronics and programming is expected along with some familiarity with the Raspberry Pi platform. If you are new to Raspberry Pi or would just like to refresh your knowledge, please see our Blink: Making An LED Blink On A Raspberry Pi tutorial before proceeding with this one. In addition, this tutorial will use a solderless breadboard to build a circuit from a schematic diagram. The All About Circuit’s Understanding Schematics, SparkFun’s How to Read a Schematic, Core Electronics’ How to Use Breadboards, and Science Buddies’ How to Use a Breadboard guides are good resources for learning how to translate a schematic to a breadboard.

What Is Needed

Background Information

My development board is the Raspberry Pi 3 Model B running the Raspberry Pi OS operating system. If you are using a different Raspberry Pi model or a different OS that is similar to Raspberry Pi OS, the vast majority of this tutorial should still apply, however, some minor changes may be necessary.

A list of all single board computers (SBCs) currently supported by Blinka, and the CircuitPython API, is available on the CircuitPython Blinka page.

If you need assistance with your particular setup, post a question in the comments section below and I, or someone else, can try to help you.

What Is CircuitPython

If you are a fan of the Python programming language and enjoy tinkering with electronics, you will certainly love CircuitPython. It is an open source programming language developed and maintained by Adafruit. According to Adafruit, it was “designed to simplify experimenting and learning to code on low-cost microcontroller boards”. It is “the easiest way to program microcontrollers”.

CircuitPython is based on MicroPython which itself is based on Python. CircuitPython adds strong hardware support to the Python language. It also provides a multitude of libraries and drivers to support sensors, breakout boards, and other external hardware components. This makes CircuitPython an incredibly powerful ally in quickly developing your own hardware interfaced projects.

What Is Blinka

CircuitPython was originally developed to run on small microcontroller boards using a simplified Python interpreter. However, the Raspberry Pi and other SBCs are full-fledged computers running their own operating systems. Blinka is a Python library that provides the CircuitPython hardware API compatibility layer for SBCs, like the Raspberry Pi, so that they can run CircuitPython programs using the standard Python interpreter.

Blinka translates the CircuitPython hardware API to whatever libraries the Linux board provides. On the Raspberry Pi, for instance, the RPi.GPIO library is used for GPIO access, the spidev library is used for SPI, and ioctl messaging is used for I2C. This allows us to use the CircuitPython built-in libraries, e.g. board, microcontroller, digitalio, etc. so that our CircuitPython programs can be agnostic to the hardware they are running on and just work as expected.

CircuitPython adds hardware support to the Python language along with a large selection of hardware libraries. With Blinka, we can take advantage of those fantastic libraries developed for CircuitPython and use them in our SBC based projects.

Building The Circuit

Before connecting any circuitry to your Raspberry Pi, shutdown and disconnect it from power. This avoids accidental damage during wiring.

Using a breadboard and jumper wires, connect a red LED in series with a 330 Ω resistor to GPIO21 (physical pin 40) of the Raspberry Pi according to the schematic diagram shown below.

Schematic Diagram Of Raspberry Pi & LED Circuit
Schematic Diagram Of Raspberry Pi & LED Circuit

Once the circuit is built, connect power to your Raspberry Pi and boot it up.

Installing Blinka

I assume you are already comfortable installing and using Raspberry Pi OS so I won’t go into those details, but it is safe to say, you should be running a very recent and stable OS version. You should also make sure the I2C and SPI interfaces are enabled on your Raspberry Pi.

Python 3 is required to support Blinka and CircuitPython, so use python3 and pip3 in your commands. With the deprecation recently of Python 2, this may change in the near future.

Open a terminal window on your Raspberry Pi and install Blinka, which also installs various supporting libraries, using the following command.

$ pip3 install adafruit-blinka

Now let’s verify Blinka was installed correctly. Open your favorite text editor and create a Python program named blinkatest.py with the code shown below that I retrieved from Adafruit’s learning guide.

import board
import digitalio
import busio

print("Hello blinka!")

# Try to great a Digital input
pin = digitalio.DigitalInOut(board.D4)
print("Digital IO ok!")

# Try to create an I2C device
i2c = busio.I2C(board.SCL, board.SDA)
print("I2C ok!")

# Try to create an SPI device
spi = busio.SPI(board.SCLK, board.MOSI, board.MISO)
print("SPI ok!")

print("done!")

Run the program to test the hardware interfaces used by Blinka.

$ python3 blinkatest.py

You should see the following printed to your screen if everything passed.

Hello blinka!
Digital IO ok!
I2C ok!
SPI ok!
done!

Writing Your First CircuitPython Program

Now let’s write that old-time standard first program, blinking an LED, that covers the basics for what you need to run a very simple CircuitPython program. Create a file named blink.py with the code shown below.

from time import sleep
import board
from digitalio import DigitalInOut, Direction
import RPi.GPIO as GPIO

print("Hello, CircuitPython!")

red_led = DigitalInOut(board.D21)
red_led.direction = Direction.OUTPUT

print("Press CTRL-C to exit.")
try:
    while True:
        red_led.value = True
        sleep(1)
        red_led.value = False
        sleep(1)
finally:
    GPIO.cleanup()

Lines 1-4 import the libraries we are using in our program. We don’t actually import the Blinka library directly, but its embedded libraries, e.g. board and digitalio. All CircuitPython programs should import the board module. This module defines the specifics of the development board you are using and is necessary for CircuitPython programs to access the board’s GPIO pins and hardware. The digitalio library is used to interface to the GPIO pins of the Raspberry Pi. The time library provides access to the sleep() method in order to create timing delays. We are also importing the RPi.GPIO library to take advantage of its cleanup() method.

Line 6 of the program welcomes us to CircuitPython.

Lines 8 and 9 utilize the digitalio library to set the red_led variable to point to pin GPIO21 and define it as an output in order to drive our LED.

The infinite while loop, beginning on line 13, repeatedly turns on and off the LED with one second delays in between.

Lines 18 and 19 define an exception block finally clause containing the RPi.GPIO library’s cleanup()method that when used with the while loop in the try clause (line 12), will reset all GPIO pins back to their default (input) states and exit the program cleanly when CTRL-C is pressed on the keyboard.

Run our new blink program

$ python3 blink.py

and you should see the LED on your breadboard now blinking. Press CTRL-C to exit the program.

Using The REPL

Since CircuitPython programs are really just running the standard Python interpreter using the Blinka library for hardware support on the Raspberry Pi, we can still use Python’s standard Read-Evaluate-Print-Loop (REPL) functionality.

Enter the REPL by simply executing the python3 command without any arguments.

$ python3

Let’s try some CircuitPython specific constructs by typing them in at the >>> REPL prompt.

Start with importing CircuitPython’s board library and printing the board’s ID.

>>> import board
>>> board.board_id
'RASPBERRY_PI_3B'

As you can see, I am running on a Raspberry Pi 3 Model B.

We can also list all of the Raspberry Pi’s pins known by CircuitPython, along with some other items.

>>> dir(board)
['CE0', 'CE1', 'D0', 'D1', 'D10', 'D11', 'D12', 'D13', 'D14', 'D15', 'D16', 'D17', 'D18', 'D19', 'D2', 'D20', 'D21', 'D22', 'D23', 'D24', 'D25', 'D26', 'D27', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9', 'I2C', 'MISO', 'MISO_1', 'MOSI', 'MOSI_1', 'RX', 'RXD', 'SCK', 'SCK_1', 'SCL', 'SCLK', 'SCLK_1', 'SDA', 'SPI', 'TX', 'TXD', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'ap_board', 'board_id', 'detector', 'pin', 'sys']

Want to update the LED manually from the REPL? Enter the digitalio statements from our program we wrote earlier.

>>> import digitalio
>>> led = digitalio.DigitalInOut(board.D21)
>>> led.direction = digitalio.Direction.OUTPUT
>>> led.value = True
>>> led.value = False

When you are done playing with the REPL, press CTRL-D to exit.

Working With Libraries

The ability to access and utilize a vast collection of hardware-specific libraries is one of the core tenets of the CircuitPython ecosystem. All of the currently available libraries can be viewed from the Adafruit_CircuitPython_Bundle GitHub repository.

Let’s utilize one of the libraries to demonstrate how this all works. So you don’t need an extra piece of hardware, I selected a library that just converts between binary (ASCII) and hexadecimal representations.

On microcontroller boards solely running the simplified CircuitPython interpreter, libraries are installed by simply copying the necessary libraries from the bundle. However, on the Raspberry Pi running the standard Python interpreter, we install CircuitPython libraries in the usual Python fashion with pip3.

Install the adafruit_binascii library by running the following command.

$ pip3 install adafruit-circuitpython-binascii

Create a file named binascii.py with the code shown below.

from adafruit_binascii import hexlify, unhexlify

# Binary data.
data = b"CircuitPython is Awesome!"
print("Original Data: ", data)

# Get the hexadecimal representation of the binary data
hex_data = hexlify(data)
print("Hex Data: ", hex_data)

# Get the binary data represented by hex_data
bin_data = unhexlify(hex_data)
print("Binary Data: ", bin_data)

This is a modified program that I retrieved from the example listed in the adafruit_binascii library’s GitHub repository. It converts binary based ASCII characters to their hexadecimal representation and then back again.

Run the program

$ python3 binascii.py

and you should see the following printed to the screen.

Original Data:  b'CircuitPython is Awesome!'
Hex Data:  b'43697263756974507974686f6e20697320417765736f6d6521'
Binary Data:  b'CircuitPython is Awesome!'

That’s all there is to it.

Additional Resources

The following is a list of additional resources you may find helpful.

I recommend reviewing the above resources. They provide a wealth of information for learning more about CircuitPython.

If you run into any problems, the CircuitPython on Linux and Raspberry Pi guide by Adafruit goes into much more detail than what I have covered here and may provide just the information you need to resolve your issues.

In addition, the CircuitPython Essentials learning guide is an excellent resource for learning about the built-in libraries.

Summary

In this tutorial, we learned how to get started using Blinka to run CircuitPython programs on a Raspberry Pi.

Specifically, we learned

  • what CircuitPython and Blinka are and why you may want to use them in your projects,
  • how to install the Blinka library to add CircuitPython hardware support to your Python programs,
  • how to invoke and use the Read-Evaluate-Print-Loop (REPL) to run individual lines of code, and
  • how to install and use libraries in your CircuitPython program.

Hopefully, you have discovered that CircuitPython, by way of the Blinka library, can be an invaluable part of your next Raspberry Pi project. In future articles, we will explore some of the hardware-specific libraries to interface various components with our boards. This, in my opinion, is where CircuitPython really shines.

Thank you for joining me in this journey and I hope you enjoyed the experience. Please feel free to share your thoughts in the comments section below.

This tutorial is provided as a free service to our valued readers. Please help us continue this endeavor by considering a donation.

About the author

John Woolsey

John is an electrical engineer who loves science, math, and technology and teaching it to others even more.
 
He knew he wanted to work with electronics from an early age, building his first robot when he was in 8th grade. His first computer was a Timex/Sinclair 2068 followed by the Tandy 1000 TL (aka really old stuff).
 
He put himself through college (The University of Texas at Austin) by working at Motorola where he worked for many years afterward in the Semiconductor Products Sector in Research and Development.
 
John started developing mobile app software in 2010 for himself and for other companies. He has also taught programming to kids for summer school and enjoyed years of judging kids science projects at the Austin Energy Regional Science Festival.
 
Electronics, software, and teaching all culminate in his new venture to learn, make, and teach others via the Woolsey Workshop website.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.