Raspberry Pi Pico: A $4 beast!

Vinay Lanka
8 min readJan 26, 2021

--

The Raspberry Pi Foundation’s foray into the microcontroller market. (First Impressions/Tutorial)

a whole lotta microcontroller

First of all, what’s a microcontroller?

A Microcontroller is a small computer system on a single chip. They contain just enough memory, power, and I/O required to perform small tasks. There are different microcontroller architectures and vendors, a few notable ones include — ARM’s Cortex-M, Microchip’s AVR and PIC, NXP’s LPC, STM’s STMx, and Intel’s 8051.

You can also check out my guide on selecting a microcontroller board or exploring the AVR microcontrollers.

Raspberry Pi’s RP2040

RP2040 is a microcontroller chip developed by the Raspberry Pi foundation. It actually runs not one but two 32 bit ARM Cortex-M0+ cores clocked at 133MHz. It adds a generous amount of SRAM and 8 × Programmable I/O (PIO) state machines for custom peripheral support that will likely mean that you never have to bit-bang again. (Covered later in this article).

Raspberry Pi Pico

A microcontroller is just an IC chip and is only useful to us in the form of a development board and the Pi foundation delivers with the Pico that houses the RP2040 microcontroller.

The Pico board also adds a whopping 2MB of flash memory, a temperature sensor, USB connectivity that allows both device and host support, and great power management.

Specifications:

Credits — Raspberry Pi Foundation

If you’d like to buy one or know more, check it out here.

An excellent article by hackaday mentioned great hardware conveniences such as the existence of 30 GPIOs being in one register so we don't need to have Ports and Pins. All the registers are 32 bit with a memory map that lets you set, clear, or XOR any bit. It stores memory on an external flash but runs code directly from the flash as if it were on internal memory.

When you plug the Pico in holding down the BOOTSEL button, it shows up as a USB mass storage device due to the UF2 bootloader, and you can just copy your code across, with no programmer. If you copy the Pico’s MicroPython binary across, however, you’ll never need the bootloader again. The mask ROM also contains some fast routines that support integer and floating-point math, and all of the contents are open source as mentioned above.

The PIO

The Programmable I/O is the real star of the show. Generally on most microcontrollers, working with peripherals requires “bit-banging” which requires one of the processing cores to turn the pins on and off directly. This approach works for the most part but can fall apart during high-speed IO or while using interrupts as if can take a lot of processing resources.

The Pico has Programmable I/O along with the two main Cortex cores. There are two PIO blocks that each have 4 state machines. Each state machine has 2 FIFO(First In First Out) structures, for data coming in and out respectively.

When you need to send data via a PIO state machine, you push it to the FIFO, and when your state machine is ready for the next chunk of data, it pulls it. This way, your PIO state machine and program running on the main core don’t have to be perfectly in-sync.

TLDR;

PIO is a really fancy hardware block that lets you make your own digital communication peripheral on the fly due to its very fast IO capability.

If you want to program another UART, for instance, it’s trivial. But so is Manchester-encoded UART, or a grey code encoder/decoder, or even fancier tricks. One of the example applications is a DPI video example, with one state machine handling the scanline timing and pixel clock, while another pushes out the pixel data and run-length encodes it.

These are the sort of simple-but-fast duties that can bog down a CPU, leading to timing glitches, so dedicated hardware is the right solution.

Getting Started (The Tutorial):

My soldering isn’t the neatest :P

I got my Raspberry Pi Pico extremely quickly as I pre-ordered one on the day of release. Your mileage may vary according to the supply/demand. My particular Pico came without the Berg pins so I had to buy and solder them myself. I also had a Micro-USB cable lying around which I used to program the Pico.

Development Env

I’m using the Pico off a Ubuntu machine atm. You can pretty much use any device with the best option being a Raspberry Pi. You can easily setup/program/debug on the Pi and all of it is set up by a convenience script pico_setup.sh which can be accessed by following the guide given on the Pico website. Similarly, you can set up environments on Windows and macOS as well.

Blink

First, make a directory for the pico workspace and clone both the pico_examples and the pico_sdk in this folder. The Pico SDK provides the headers, libraries, and build system necessary to write programs for RP2040-based devices such as Raspberry Pi Pico in C, C++, or Arm assembly language.

$ cd ~
$ mkdir pico
$ cd pico
$ git clone -b master https://github.com/raspberrypi/pico-sdk.git
$ cd pico-sdk
$ git submodule update --init
$ cd ..
$ git clone -b master https://github.com/raspberrypi/pico-examples.git
$ sudo apt install cmake gcc-arm-none-eabi build-essentia

Note: If you’re using ROS or generally using an older version of Ubuntu (18.04 in my case), you’ve to install cmake from source and use that version. (If any of you face that issue, please comment so that I could help out)

$ cd ~/pico/pico-examples
$ mkdir build
$ cd build
$ export PICO_SDK_PATH=../../pico-sdk
$ cmake ..

We’re setting the CMake generator path as PICO_SDK_PATH for setting the necessary build files for pico. To build and run the blink example:

$ cd ~/pico/pico-examples/build/blink
$ make -j4
As easy as drag and drop.

This exports a blink.hex, blink.elf and blink.uf2. We’re interested in the blink.uf2 file, which we then just drag and drop into the Pico acting as a mass storage device. The Pico acts as a mass storage device when plugged in while pressing the BOOTSEL button.

Success!

Creating your own project and using VSCode

Ideally, for a project, you’re going to need a decent code editor, and what better editor to use than the universally supported Microsoft VSCode. Eclipse and a few other IDEs are supported too, check out their docs on how to set it up!

First of all, you’re gonna download VSCode. Then run these three commands in a terminal window or install the extensions manually on the market.

$ code --install-extension marus25.cortex-debug 
$ code --install-extension ms-vscode.cmake-tools
$ code --install-extension ms-vscode.cpptools

Then in the pico workspace, create a new directory, for example, test.

$ cd pico
$ mkdir test && cd test
$ code

Now, this opens up a VSCode Workspace. Make a new file test.c

#include<stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "pico/binary_info.h"
const uint LED_PIN = 25;
int main() {
bi_decl(bi_program_description("This is a test binary."));
bi_decl(bi_1pin_with_name(LED_PIN, "On-board LED"));
stdio_init_all();
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
while (1) {
gpio_put(LED_PIN, 0);
sleep_ms(250);
gpio_put(LED_PIN, 1);
puts("Hello World\n");
sleep_ms(1000);
}
}

Make another file called CMakeLists.txt

cmake_minimum_required(VERSION 3.12)
include(pico_sdk_import.cmake)
project(test_project)
pico_sdk_init()
add_executable(test
test.c
)
pico_enable_stdio_usb(test 1)
pico_add_extra_outputs(test)
target_link_libraries(test pico_stdlib)

Finally, we need to copy a file

$ cp ../pico-sdk/external/pico_sdk_import.cmake .

When we enable the CMakeTools extension, it asks us if we want to configure the project. If it hasn’t then restart the editor.

You’ll then be prompted to select a compiler. Select arm-none-eabi.

That’s it! If you wanna build then click the cogwheel that says build at the bottom of the screen and you’ll find the test.uf2 file that you drag and drop into the microcontroller.

The test.uf2 file generated (To be dragged and dropped)

A Simpler Process

You needn’t set up the whole folder manually. The folks over at the Pi foundation have made a code generator written in python that autogenerates the folder + boilerplate code for you.

You can add specific features to your project by selecting them from the checkboxes on the GUI. This will ensure the build system adds the appropriate code to the build, and also adds simple example code to the project showing how to use the feature.

$ git clone https://github.com/raspberrypi/pico-project-generator.git
$ cd pico-project-generator
$ ./pico_project.py --gui
Check the Create VSCode project to configure IntelliSense and other features

Conclusion

The Raspberry Pi Pico is an excellent microcontroller that undercuts most on the market while delivering unique features. There’s also a lot of thought that’s gone into designing this board and its build system. Not to mention the exhaustive documentation that goes along with it.

I myself am planning to use the Pico in projects immediately, using the PIO with encoders from differential drive motors would be an interesting project as I’m already using the Raspberry Pi as a ROS node. The motor encoders usually use hardware interrupts due to their high tick rate so the PIO might be a good alternative.

I’ll probably make more blogs with the stuff I make with the Pico! Follow if y’all are interested!

What do you guys think about the Pi Pico? Lemme know via the replies or on Twitter!

--

--