Today we’ll take a look at CircuitPython, another way to program the Raspberry Pi Pico.  We’ll see how we can take advantage of Adafruit’s large base of CircuitPython libraries to build some great projects with our Pico.

If you aren’t familiar with the Pico please see my article Raspberry Pi Pico – How to Interface (almost) Everything to get all caught up.

Introduction

I’m writing this article about a month after the introduction of the Raspberry Pi Pico. It’s an important point to make note of, because as of this writing the Pico is the only RP2040-based board available. 

Because of the “newness” of the Raspberry Pi Pico, there is a lack of MicroPython software examples and no support (yet) for C++ development on popular IDEs like the Arduino IDE or PlatformIO.

This situation will obviously be changing very soon, with new boards from Adafruit, Sparkfun, and Arduino which should be released shortly.  With these boards will come more sample code and libraries for both C++ and MicroPython.  And with Arduino’s involvement, we should also see support for C++ development on our favorite IDEs.

But right now we have this wonderful microcontroller and would like to start building things with it to exploit its unique capabilities.

CircuitPython provides us with the ability to do this right now.

CircuitPython

CircuitPython is a “fork” of MicroPython and was first published by Adafruit in 2017.  

CircuitPython with Raspberry Pi Pico

Originally CircuitPython was only available for Adafruit SAMD21 (M0) boards, but it has grown to support over 175 boards from a number of different manufacturers.

Although CircuitPython lacks some of the features of MicroPython it has some advantages. One of the biggest advantages is the availability of libraries and drivers for a variety of boards and peripherals, as of this writing, there are over 300 of these available. Also, by making use of the Adafruit Blinka library you can also access virtually any Python 3 library.

CircuitPython is particularly great for beginners, as code in CircuitPython all run sequentially and multiple files are run one at a time. This lack of concurrency will cause issues with some more advanced applications, and combined with the lack of support for interrupts will make CircuitPython unsuitable for some applications.

But if you’re looking for an easy-to-use development language with a wealth of libraries and code samples it’s hard to beat.

Consider it as one more tool that you can use to build things with the Pico and other microcontrollers.

Installing CircuitPython on the Raspberry Pi Pico

Of course, the first thing you’ll need to do to start working with CircuitPython is to install it on your Pico. This is pretty easy.

Downloading CircuitPython

You can get the latest build of CircuitPython from the download page on the CircuitPython website.

The file you are downloading is a UF2 boot file, when mounted into the boot folder on the Pico it will start and load CircuitPython.

Raspberry Pi Pico CircuitPython Download Page

Let’s do that now.

Reset and BOOTSEL

In order to open up the Pico as a drive, you need to hold down the BOOTSEL key while plugging in the Pico USB cable. You’ll then be prompted about a new drive on your machine called “RPI-RP2”, this is the Pico “drive” that we will require to install CircuitPython.

Another way of accomplishing the same thing, without the need to unplug and plug in the USB cable, is by holding the Pico RUN pin (pin # 30) to ground , then pressing BOOTSEL and holding it down, releasing the RUN connection to Ground and then releasing BOOTSEL.

You can wire a pushbutton switch between pin 30 and Ground to make this easier, essentially you have just added a “Reset” key to your Pico.

Raspberry Pi Pico Reset Switch

Hold down “Reset”, keep it held down while holding down BOOTSEL, release Reset and then release BOOTSEL. You will see a RPI-RP2 “drive” added to your host computer.

CircuitPython Installation

Installing CircuitPython is simply a matter of copying the UF2 file you downloaded into the RPI-RP2 drive. The easiest way to do this is to drag the UF@ file into the RPI-RP2 folder.

As soon as the file is finished copying the RPI-RP2 drive will be ejected. After about a second a new drive will be mounted. This drive is called CIRCUITPY.

Testing the CircuitPython Installation

If you have a CIRCUITPY folder then you have probably succeeded in your task, and have installed CircuitPython on your Raspberry Pi Pico.  Let’s poke around and give it a test drive.

Raspberry Pi Pico CircuitPython Installation - Copy Files

CircuitPython Folder

When you plug your Pico into your host computer you’ll be greeted by a folder called CIRCUITPY. This is the folder that holds CircuitPython on your Raspberry Pi Pico.

You can only keep a maximum of about a megabyte in here, so don’t start storing non-essential files. Only the code, data, and library files that you need should be kept here.

You will see a folder labeled “lib”, this is your Library folder. We will be copying a few libraries into this folder a bit later.

You’ll also see two files:

  • boot_out.txt – A text file with information about the CircuitPython build.
  • code.py – The main Python file, the one that will run when the system is started.

We will be editing code.py throughout our experiments. With CircuitPython all we need to do is to edit the file and save it, the act of saving the file runs the program.  There is no compile or upload step.

Raspberry Pi Pico CircuitPython CIRCUITPY Folder

Installing the MU Editor

Before we start working with CircuitPython on our Raspberry Pi Pico we are going to install yet-another Python editor! 

While we can make use of any editor when working with CircuitPython, the MU Python Editor has many advantages, especially for beginners. MU has a mode specifically made for working with CircuitPython and it provides a simple interface that anyone can understand.

MU is available for Windows and Mac OS X systems, as well as for several distributions of Linux. I managed to install it on my Ubuntu 20.04 workstation with the command.

While the MU Editor Website also has a download for the Raspberry Pi, there is a much simpler installation method for users of the Raspberry Pi Operating System.

On the Raspberry Pi Desktop click the “Raspberry” in the top left corner and choose Preferences. From the sub-menu that appears choose Recommended Software.

In the Recommended Software dialog box search for “MU”. You should see a listing for MU in the results, “a Python IDE for Beginners”. 

Select the checkbox beside the application name ad click the Apply button. The MU Editor will be installed.

Using the MU Editor

The MU Editor is made for beginners, so it is very easy to use. Most of the controls are in the form of big buttons, on a toolbar across the top of the editor.

MU Python Editor

Here are a few of the ones you need to familiarize yourself with right away:

Mode – On the far left side is a button labeled Mode. This allows you to select (what else?) the mode that you are working in. Modes are development environments, and the Mode we are interested in is the “Adafruit CircuitPython” mode. When you plug in a Pico with CircuitPython on it this mode should be automatically selected, but if it isn’t you can select it here.

New – Click this to open a new, untitled, editor window.

Load – Let’s you load a file into the editor.

Save – Let’s you save a file. If you are working on code.py on the Pico then saving the file wil also cause it to run.

Serial – Toggles the serial port, REPL window below the editor.

With your Pico plugged into the USB port open up MU. Check the Mode to be sure you are in  “Adafruit CircuitPython” mode, if not then select it.

Next click the Serial button to open the REPL, which is an acronym for:

  • Read – Read the user input (the Python commands you type)
  • Evaluate – Send it to the computer to Evaluate what you typed
  • Print – Print the computer’s results.
  • Loop – Loop back to the first step and do it all over again.

Essentially this is the command line through which you’ll communicate with the computer.

MU Editor REPL Window

You should see a command prompt when you first open this, if not then hit your Enter key to get one. You can now type CircuitPython commands at the command line. Try the following:

The interpreter should run and print back “Hello”.

Now click the Load button. The file manager will open up in the CIRCUITPY folder on the Pico, and you’ll see code.py. Select this.

Remember, whatever is in code.py will run when the system is started, and changes saved to code.py will run immediately. 

The code currently in code.py is just another print statement, the standard “Hello World”. Edit it to say something else and then click the Save button while observing the Serial REPL screen.

You will see the code runs as soon as you save it, and will print your greeting message.

Today we will be opening up new files and using them to modify code.py. Once we do our code will run immediately.

Test Program – Python Blink

Before we get started with our experiments let’s practice loading some new code.  You can get all the code used in the article here, it’s a ZIP file that has all the Python code we are using today.

The first file we will use is pico-blink, which as you probably guessed is the Blink program.

This is a pretty simple program, we import some libraries to work with time and the hardware.

We define an LED as being an output, note how the syntax differs slightly from MicroPython but the principle is identical.  Also, note the “board.LED” defines the built-in LED on GPIO pin 25.

In the True loop, we make the LED value True, which turns on the LED. Then we sleep for half a second and make it FALSE to turn it off. Another half-second snooze and we do it all over again.

Copy this code over the existing code.py and save it. As soon as you do you should observe the LED on the Pico blinking.

Now that you have seen how we will edit our programs using the MU editor and modifying code.py let’s move on to some more interesting experiments.

Custom Keyboard Emulator

One of the features of the Raspberry Pi Pico is its ability to act as a USB device to a host computer. And a great use for this feature is a custom keyboard emulator.

Audacity Keypad

In this experiment, I’m going to create a custom keyboard emulator for the popular audio recording and processing program Audacity.  You could use the same technique to create a custom keypad for just about any application on any computer.

Audacity, for those who are not familiar with it, is a very popular open-source audio recording and processing application. It runs on Linux, Windows, and Mac OS X. You can also install it on a Raspberry Pi, which is what I did for this experiment.

In our experiment, I’ll only be using two keys, one for Record and another for Stop. But you can easily extend this to have multiple keys.

Installing the Adafruit HID Library

A keyboard is classified as a Human Interface Device, or HID. Adafruit has a CircuitPython library for these devices, allowing us humans to interface with our computers.

So before we create a program to emulate a keyboard we will need to install this library.

To obtain the library we will grab ALL of the CircuitPython libraries from the CircuitPython Library Download page.

 

Get the Library Bundle Version at the very top of the list, this will be a collection of the latest production CircuitPython libraries.

Once you have this list unzip it on your local computer. You’ll see dozens of libraries in the ”lib” folder.

The only one you need right now is the HID (Human Interface Device) Library, it is a folder called adafruit_hid. Copy this entire folder into the lib folder in the CIRCUITPY drive.

You have now installed the Adafruit HID library, which we need for both our keyboard and mouse emulators.

Hooking up the Keyboard Emulator

Here is the hookup of our simple keyboard emulator.

Raspberry Pi Pico Keyboard Emulator Hookup

As you can see all we have done is connected a couple of pushbutton switches to two of the GPIO pins. You could add more switches and use different pins, nothing here is critical. 

The other side of both pushbuttons is connected to 3.3-volts, so the switch will send the input HIGH when it is pressed.

In my experiment, I’m using the “red” pushbutton as my Record key and the ”black” one as the Stop button.

Keyboard Emulator Code

The CircuitPython code for the keyboard emulator is shown here:

The code is pretty simple, thanks to the power of the Adafruit HID library.

We start by importing libraries, including the CircuitPython USB HID library to allow our Pico to emulate a USB device.

Then we import elements from the Adafruit HID library that we just installed in our “lib” folder. We need both the keyboard and keycode elements, and we are defining our keyboard as a US ASCII.

If you need to emulate a different keyboard you can find details by reading the Adafruit HID Library documentation.

We then define our two pushbuttons, one for record and one for stop. Note how in both cases we specify the GPIO pin (not pin number) for each button, and then define that pin as an input. We also define a pull-down resistor for each input, to hold the input LOW until a button is pressed.

In the True loop, we look to see if a button is pressed. If it is, we do the following:

  • Use a keyboard.press to send a Keycode. You can use multiple Keycodes, separated by commas if you want to hold down multiple keys.
  • Wait a short time.
  • Use a keypad.release, again specifying the Keycode.

We do this for each button. We can make a single button correspond to multiple keys, or to a sequence of keys.  It’s all up to you, in this example Audacity just needs a “r” for Record and a Space character for Stop.

Load the code and then open a Text Editor to try it out. In my case, I successfully printed “r” and a space for my buttons.

Raspberry Pi Pico Keyboard Emulator Demo

I then tried it in Audacity and it works, starting my recording with my red button and stopping it with the black one.

I could extend this to have an advanced keyboard emulator with multiple keys. Al with CircuitPython and the Raspberry Pi Pico.

Mouse Emulator

Another very common “Human Interface Device” is a mouse (or trackball or trackpad).  And the Adafruit HID Library is also capable of emulating a pointing device.

This could be very useful in situations where you want to automate an operation, perhaps involving a web page, that requires a mouse or a mouse and keyboard.  If you know the screen coordinates you need to click you could program the Pico to go there and click it for you.

In this experiment, we will create our own “mouse” using a joystick. We will also use the two pushbuttons that we used in the last experiment as our left and right mouse buttons.

Mouse Emulator Hookup

Here is how we will hook up our Pico to the Joystick. Note that the two pushbutton connections remain as they were in the previous experiment.

Raspberry Pi Pico Mouse Emulator Hookup

The joystick we are using is a standard joystick that consists of two potentiometers. Don’t try using the type of joystick that uses pulses, it won’t work. The joysticks included in those “37-in-one” kits are the proper type.

The X-Axis and Y-Axis outputs are connected to two of the Pico’s analog to digital converter inputs, ADC0 and ADC1.

Our two switches are wired up as in the Keyboard emulator, only their functions have changed. The ”red” button is the left mouse button, while the “black” one is the right.

After you have the joystick hooked up we’ll need some code to run it. Fortunately, Adafruit has provided an example that is almost what we need, all that needs to be done is to modify it to use the two pushbuttons instead of the one built into the joystick.

Mouse Emulator Code

Here is the code we are using to emulate our mouse:

This is essentially the Adafruit sample code, modified to use a couple of pushbuttons instead of the built-in switch on the joystick.

We start by importing the required libraries, including sections of the Adaft=ruit HID library.

We define our two analog inputs and set up the pushbuttons exactly as we did in the keyboard emulator experiment.  In this experiment, our pushbuttons are the left and right mouse buttons.

We define a minimum and maximum value for our input voltage, based upon our use of 3.3-volt logic.  We then define steps based upon that range.

We create two functions, one to get the voltage at the analog pins and the other that maps that voltage to a discrete step.

In the True loop, we read the pot values and look to see if a button is being pressed. If a button is active, we execute a LEFT_BUTTON or RIGHT_BUTTON emulation.

We then check to see if our mouse pointer needs to move. We do this in two ranges so that we can vary the speed of the pointer at extremes of the joystick.   As we do this for each input for both the positive and negative direction we run through this step several times.

This ends the loop, so we do it all again from the top.

Raspberry Pi Pico Mouse Emulator Demo

Load the code and save code.py, once you do you should be able to control our mouse pointer using the joystick. The two pushbuttons should act as the left and right mouse buttons.

microSD Card

A microSD card is a great way to store large quantities of data gathered by a microcontroller like the Pico. You can use one as part of a data logging system.

microSD card interfaces are very inexpensive, and they make use of the SPI bus. If you’re unfamiliar with the operation of microSD cards, or how to use them with microcontrollers, check out the article SD Card Experiments with Arduino.

We will be doing a very basic experiment, simply writing some data to a microSD card and then reading it back.  As simplistic as this is, it does illustrate all of the essential operations you’ll require to add a microSD card to your Pico project.

microSD Hookup

The microSD board is connected using the SPI bus, as shown here:

microSD Card Hookup

The Raspberry Pi Pico has two SPI busses and multiple ways of connecting each one. We are using SPI bus 1 for our card.

One thing to note in the hookup is that the VCC of the card is connected to the VBUS output, not the 3.3-volt output. Although the microSD card is a 3.3-volt logic device it has its own internal linear 3.3-volt regulator, so it requires 5-volts to power it. The logic signals are all 3.3-volts and are perfectly safe for your Pico.

You will also need a microSD card or course, formatted using the FAT file system. Note that this may limit the capacity of some larger cards, use the smallest one you can find for this experiment as we will only be using a few bytes!

microSD Demo Code

Once you have everything wired up and a formatted microSD card in the board you can load the code.

Next, we define the pins that we are using for our SPI bus connections. Refer to the Raspberry Pi Pico pinout diagram to see how these GPIO pins correspond to SPI bus 1.

We create an object to represent our SD card and attach it to the SPI bus that we just defined.  And after that, we mount a storage location on the SD card.

In the next line, we use the microcontroller library to read the internal temperature sensor. This doesn’t have anything to do with the microSD card, of course, I’m just doing it so that we have something interesting to write to the card.

And after that we do four operations on the microSD card:

  • We open a file for writing, which either creates a new file or overwrites an existing one.
  • We open the same file to add something to it, this will appear on the next free line.
  • We open it again, this time to add the temperature.
  • We open the file for reading and read back its contents.

Run the program by copying it over the code.py file and saving it. Observe the output in the REPL area. Try changing the text around and see the results.

This was a very basic demo, but it does give you all the essentials you’ll need to work with files on a microSD card using CircuitPython and the Raspberry Pi Pico.

Addressable RGB LED Strip

Addressable RGB LEDs are great devices for building complex light displays that require lots of LEDS. These devices have input and output connections, as well as power connections, and can be “daisy-chained”. This allows you to make large displays that require only one data connection.

I covered these extensively in the article RGB LEDS – Colorful Arduino Experiments, you can check that out if you want more details.

Adafruit sells these devices under their trade name “neopixels”, and they provide many resources to work with them, including a CircuitPython library.

Installing the Adafruit Neopixel Library

Earlier on when we built our Keyboard and Mouse emulators we used the Adafruit HID library from the group of libraries we downloaded. We are going to need another library from this group for these experiments.

The Adafruit Neopixel Library is a single python file that is included with the group of libraries. Look for “neopixel.mpy” and copy it into the “lib” folder in your Pico’s CICRUITPY drive.

Addressable RGB LED Hookup

Here is how we will hook up our strip of addressable LEDs to our Pico:

Raspberry Pi Pico Neopixel Hookup

You can use a strip with as many LEDs as you wish, just be sure to provide a power supply capable of driving all of them. 

The LEDs have one control line that is “daisy-chained” between them, so be certain to use the input and not the output line. The input is connected to GPIO-0 on the first pin of the Pico.

Also, be sure to connect the LED strip ground to both the power supply ground and the Pico ground, so that the signals are all at the correct potential.

Adafruit Neopixel Demo Code

Adafruit has provided a couple of programs we can use to test the operation of our addressable RGB LEDs, or Neopixels.

The first example from Adafruit shows just how easy it is to work with addressable RGB LEDs, thanks to the Adafruit Neopixel Library. 

You will need to modify the program to have the correct number of Neopixels (addressable RGB LED Modules) on your strip.

The pixels.fill operation fills the RGB color values specified. In the sample code, it makes red. Try changing the values and see the results.

In this example, also from Adafruit, we import a color wheel library as well as the neopixel one. We use it to display a rainbow of colors on our addressable RGB LED strip.

Raspberry Pi Pico Neopixel Display with CircuitPython

Again you will need to modify this code sample for the number of LEDs in yo9ur strip.

Run the sample by copying it over code.py and observe the color display. If you can arrange your strip in a complete circle you should see the pattern repeat itself.

Conclusion

CircuitPython is another way we can program our Raspberry Pi Pico. The availability of over 300 libraries and their associated code samples means that we can build cool projects today, without waiting for new MicroPython features or ports to popular IDEs.

Even after the C++ codebase of the Pico has matured, and it is part of the Arduino and Platform IO IDEs there will still be applications that are perfect for CircuitPython on the Raspberry Pi Pico. So it pays to learn how to use it.

It’s pretty amazing what you can do with a 4-dollar microcontroller these days!

Resources

Code Used Here – All of the CircuitPython code used in this article, in one ZIP file.

CircuitPython – The CircuitPython home page.

CircuitPython Download for Pi Pico – The download page for the latest version of CircuitPython for the Raspberry Pi Pico

CircuitPython Libraries – The latest library bundles for download.

CircuitPython Essentials – Adafruit guide to the features of CircuitPython.

 

 

Raspberry Pi Pico with CircuitPython
Summary
Raspberry Pi Pico with CircuitPython
Article Name
Raspberry Pi Pico with CircuitPython
Description
Build a keyboard emulator, a mouse emulator, work with microSD cards and flash some addressable RGB LEDs - all with a Raspberry Pi Pico and CircuitPython.
Author
Publisher Name
DroneBot Workshop
Publisher Logo

If you have a question...

Comments about this article are encouraged and appreciated. However, due to the large volume of comments that I receive, it may not be possible for me to answer you directly here on the website.

You are much more likely to get answers to technical questions by making a post on the DroneBot Workshop Forum. Your post will be seen not only by myself, but by a large group of tech enthusiasts who can quickly answer your question. You may also add code samples, images and videos to your forum posts.

Having said that, please feel free to leave constructive comments here. Your input is always welcome. Please note that all comments may be held for moderation.

7 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
vvv
6 months ago

Looking forward to see more python and Audacity implementation.

Thanks for the video Bill.

Mike
5 months ago

I found that installing Circuitpython on Pico that prevously had Micropython was not completely successful. Although the Circuitpython UF2 installation seemed to go smoothly and the board seemed to be recognized as compatible, mu would not allow typing in command line >>>. I am using Mu on Windows 10 rather than on the raspberry pi. It could be that the problem is with the Windows version of Mu rather than with the Circuitpython installation.

Noel
5 months ago
Reply to  Mike

I have the same issue, but I’m using a Mac to work with the Pico.
I tried flash_nuke.uf2, but it didn’t help.
“CIRCUITPY” does not show up. I can, however, type commands in the REPL, and the Pico will react (led on/off, for instance).

Any ideas ?

Rodolfo
4 months ago
Reply to  Mike

This happened to me but in the opposite direction. When I got my picos I installed first CircuitPython and then, when trying to install MicroPython they wouldn’t work. It behaves exactly as you mentioned. No ‘reboot’, REPL works. I tried both with Mac and Linux. Same thing happened on two picos.
There is not much info on the web. I found these comments by chance.

Ken
5 months ago

I ran the mouse emulator it worked but the pointer kept drifting to the left of the screen. why is this so.

Rodolfo
4 months ago

microSD’s line 22 states:
cs = board.GP15

Isn’t that incorrect? SPI CS ports are GP[1, 5, 9, 13, 17]

Shouldn’t that be (choosing closest CS pin)
cs = board.GP13

Thank you for your examples. It’s a great tutorial!

kstarbe
3 months ago

Small typo in this sentence.

Again you will need to modify this code sample for the number of LEDs in *yo9ur* strip.

7
0
Would love your thoughts, please comment.x
()
x