There are a lot of embedded platforms with different performance today. Many devices have the same functionality and similar features. Thus, a developer accustomed to a variety of hardware platforms is very difficult to surprise with something really new.

What can the new board Raspberry Pi Pico, based on their own chip RP2040, surprise us with?

Raspberry Pi Pico is not such a high performance platform as other Raspberry Pi boards are,  but much cheaper than others. Its performance can be compared with Arduino Due or ESP32.

This is a really very interesting device, based on two Cortex M0+ cores with a unique PIO module, that works like FPGA pins and can be programmed in Assembler language(I would say simplified Assembler).

Support for Raspberry Pi Pico is impressive. There are different programming languages such as Assembler, C, C++ and Python, used for programming the Raspberry Pi Pico.

Raspberry Pi Pico can be programmed in Arduino IDE as well.

RP2040 chip and Raspberry Pi Pico board are well documented, the documentation contains datasheets for both, hardware design with RP2040 and getting started with the board.

Raspberry Pi Foundation provides two SDKs to develop applications in Python and C/C++.

Let’s begin with the main features of the board :

  • RP2040 microcontroller chip designed by Raspberry Pi in the United Kingdom
  • Dual-core Arm Cortex M0+ processor, flexible clock running up to 133 MHz
  • 264KB of SRAM, and 2MB of on-board Flash memory
  • Castellated module allows soldering direct to carrier boards
  • USB 1.1 with device and host support
  • Low-power sleep and dormant modes
  • Drag-and-drop programming using mass storage over USB
  • 26 × multi-function GPIO pins
  • 2 × SPI, 2 × I2C, 2 × UART, 3 × 12-bit ADC, 16 × controllable PWM channels
  • Accurate clock and timer on-chip
  • Temperature sensor
  • Accelerated floating-point libraries on-chip
  • 8 × Programmable I/O (PIO) state machines for custom peripheral support

Raspberry Pi Pico datasheet is available here

This contains an electrical schematic of Raspberry Pi Pico as well. 

Look at the pinout diagram. As you can see, the board has a SWD connector for debugging, a user’s LED, micro USB connector, BOOTSEL button and 2×20 expansion contacts.

First of all, we need to read ‘Getting started with Raspberry Pi Pico’ and follow the instructions there.

If you are going to use the RPi 4B or RPi 400 board to develop applications for RPi Pico, it is very simple to deploy a developing environment there . The following actions should be performed on Raspberry Pi 4B/400 (make sure that you have an internet connection) :

  1. Download an installation script

$ wget

  1. Add permissions to execute the script

$ chmod +x

  1. Run the installation script

$ ./

  1. Reboot your operating system

$ sudo reboot

If not, it depends on your host operating system. I use Ubuntu 20.04 LTS, so I had to read ‘Chapter 2. The SDK’.

Windows and OSX users should read ‘Chapter 9. Building on other platforms’ of ‘Getting started with RPi Pico’.

Author of the documentation prefers us to use Visual Studio Code. If you are not used to developing in Visual Studio Code, you can choose anything else, for example Eclipse or Clion.

After installing the necessary tools, it is time to blink the LED of the Raspberry Pi Pico. Run the following commands in the terminal:

$ cd ~/pico/pico-examples

$ mkdir build && cd build

$ export PICO_SDK_PATH=../../pico-sdk

$ cmake ..

$ cd blink

$ make -j $(nproc)

That’s all. Now we can upload the firmware to the Raspberry Pi Pico board.

Updating and debugging firmware

If you are running the Ubuntu 20.04 LTS Desktop like me, the Raspberry Pi Pico should automatically mount as a USB Mass Storage Device. From here, you can Drag-and-drop blink.uf2 onto the Mass Storage Device. RP2040 will reboot, unmounting itself as a Mass Storage Device, and start to run the flashed code. Next time, when you want to upgrade the firmware, you have to push the BOOT button before you power on the Raspberry Pi Pico to enter the upgrade mode.

If your application does not work or you want to understand how it works, you can use in-circuit debugging via SWD connector. But you have to have some hardware JTAG/SWD adapter such as J-Link, DAP-Link or another Raspberry Pi board with a pin expansion connector.

Using Picoprobe

From the documentation ‘Getting started with RPi Pico’ I knew that it is possible to use another Raspberry Pi Pico board as a SWD adapter (see ‘Appendix A. Using Picoprobe’).

This is a very interesting possibility, considering the low cost of the board. Let’s try it.

If I am not mistaken, picoprobe is a DAP-Link firmware, based on open standard CMSIS-DAP for Cortex-M microcontrollers, that provides USB-UART and USB-SWD bridge.

All we have to do is load the special firmware(picoprobe) onto the second Pico board. After that, we will get a full-fledged SWD adapter at the price of the Pico board.

By the way, you can use it for debugging other Cortex-M microcontrollers as well.

You have to read ‘Appendix A. Using Picoprobe’ to know what you need to do.

Here is the same description for Linux, because I am using Ubuntu 20.04 LTS.

For picoprobe to work, you need to build openocd with the picoprobe driver enabled:

$ sudo apt update

$ sudo apt install automake autoconf build-essential texinfo libtool libftdi-dev libusb-1.0-0-dev

$ cd ~/pico && git clone --branch picoprobe --depth=1 --no-single-branch

$ cd openocd && ./bootstrap

$ ./configure --enable-picoprobe

$ make -j$(nproc) && sudo make install

It is time to build and flash picoprobe :

$ cd ~/pico && git clone

$ cd picoprobe

$ mkdir build && cd build

$ cmake .. && make -j$(nproc)

Boot the Raspberry Pi Pico you would like to act as a debugger with the BOOTSEL button pressed and drag on picoprobe.uf2.

What we got in the end, it is a debugger with two interfaces, one of them is SWD, the other is UART to work as a USB-UART adapter independently of the first one.

The wiring between the two Pico boards is shown in the following table:

Pico A (picoprobe)Pico B (dev board)

On a bright orange background, it looks like this:

To use picoprobe’s UART you can engage any terminal utility, for example minicom.

First, add yourself to dialout users’ group and reboot:

$ sudo usermod -a -G dialout $USER

$ sudo reboot

After that, check if you are in dialout group doing following:

$ groups

If so, let’s run minicom :

$ minicom -D /dev/ttyACM0 -b 115200

Using OpenOCD and GDB

To use debugging via SWD you need to launch openocd as a server and gdb as a client :

$ openocd -f interface/picoprobe.cfg -f target/rp2040.cfg -s tcl

Open On-Chip Debugger 0.10.0+dev-g18b4c35-dirty (2021-08-12-18:55)

Licensed under GNU GPL v2

For bug reports, read

Info : only one transport option; autoselect 'swd'

Warn : Transport "swd" was already selected adapter speed: 5000 kHz

Info : Hardware thread awareness created

Info : Hardware thread awareness created

Info : RP2040 Flash Bank Command

Info : Listening on port 6666 for tcl connections

Info : Listening on port 4444 for telnet connections

Info : clock speed 5000 kHz

Info : SWD DPIDR 0x0bc12477

Info : SWD DLPIDR 0x00000001

Info : SWD DPIDR 0x0bc12477

Info : SWD DLPIDR 0x10000001

Info : rp2040.core0: hardware has 4 breakpoints, 2 watchpoints

Info : rp2040.core1: hardware has 4 breakpoints, 2 watchpoints

Info : starting gdb server for rp2040.core0 on 3333

Info : Listening on port 3333 for gdb connections

Install gdb:

$ sudo apt install gdb-multiarch -y

Launch gdb:

$ cd ~/pico/pico-examples/build/blink

$ gdb-multiarch blink.elf

(gdb) target remote loacalhost:3333

(gdb) load

(gdb) b main

(gdb) c

Of Course , you can debug your application in your favorite IDE, in this case the IDE works as a client.

Automatic Project Generation

To create a new project automatically you can use a Python script that can run in GUI mode and command line mode.

Want to make use of this you’ll need to go ahead and clone the project creation script from its Git repository:

$ cd ~/pico && git clone

Do not forget to install TKInter library for using GUI:

$ sudo apt-get install python3-tk

Then it can be run in graphical mode:

$ cd pico-project-generator

$ ./ --gui

Adding Pico to Arduino IDE

It is also possible to program Raspberry Pi Pico in Arduino IDE. Even a new version of Arduino Nano based on the RP 2040 chip was released.

If you decide to work with Raspberry Pi Pico in Arduino IDE, you will have to add support of the board first. For this, select File->Preferences menu item of Arduino IDE, then fill in ‘Additional Board Manager URLs’ with the link

After that select ‘Board: “Arduino Uno”->Board Manager…’ menu item, type ‘raspberry pi pico’ and install ‘Raspberry Pi Pico/RP2040’ package, which is installed in my picture.

When the package is installed, we need to select the board in ‘Tools->Boards: “Arduino Uno”->Raspberry Pi RP2040 Boards(1.9.4)->Raspberry Pi Pico’ menu item. The board information appears in the Tools menu.

C/C++ SDK Workflow

In this article I will show you that programming Raspberry Pi Pico using C/C++ SDK is no more difficult than in Arduino IDE. Even so, you use the Linux command shell.

Add the pico-project-generator path to your .bashrc config file:

$ gedit ~/.bashrc

export PATH=$PATH:~/pico/pico-project-generator

Then reboot the system :

$ sudo reboot

After that you can launch from any directory.

Let’s create a new directory for our experiments :

$ cd ~/pico && mkdir pico-workspace && cd pico-workspace

$ --gui

Select Project Name and Location, then click OK button

Blinking the LED

Now we can open automatically generated C file, edit it :

$ cd blink

$ gedit blink.c

I am using White LED Module from Keyestudio Sensor Kit KS0068 :

If you have the same module, connect it with the Raspberry Pi Pico as shown in the next table:

Raspberry Pi PicoWhite LED Module

Let’s modify our automatically generated project with following changes:

Hold down the BOOTSEL button, then connect your Raspberry Pi Pico to your PC using micro USB cable, release the button. A new Mass Storage Device should appear.

Build the project and upload the firmware by copying the blink.uf2 file onto the device:

$ cd build

$ cmake .. && make -j$(nproc)

$ cp blink.uf2 /media/$USER/RPI-RP2

If you did everything right, the white LED should flash at 0.5 Hz (every two seconds).

As you can see, I’ve just changed the GPIO pin number and delay in the blink project from pico-examples. It works without debugging! It is easy!

This example is located here

You can download all examples from my GitHub repository by the link

Automation using

In order not to enter all these commands manually, I created a shell script called

Run this script without any parameters to see help message:

$ ./

[./] : use "./ create" to launch in GUI mode

[./] : use "./ build" to compile the project

[./] : use "./ clean" to remove temporary files

[./] : use "./ upgrade" to copy the firmware to the device

[./] : use "./ debug" to launch openocd

[./] : use "./ monitor" to launch minicom

[./] : use "./ show" to show a tree of current directory

Reading from the ADXL345 sensor

You can say “blinking a LED is simple on any board”. Since I undertook to prove that programming Raspberry Pi Pico in the C/C++ SDK is as easy as in Arduino, let’s try to connect the Pico board to a more complex module from the KS0068 Sensor Kit.

In my opinion, the ADXL345 module is complex enough for demonstration. This is a 3-axis MEMS accelerometer with high resolution (13-bit) measurement at up to +-16 g. Digital output data is formatted as 16-bit twos complement and is accessible through either a SPI (3- or 4-wire) or I2C digital interface.

I’ll just try to remake the example for Arduino using the API of the SDK.

Let’s take a look, what we can use from the SDK API to communicate through I2C.

For this let’s open pico-examples/i2c. There are three functions to work with I2C there:

I just rewrote the Arduino sketch and it worked almost immediately. Here is the original sketch for Arduino .

But there was one problem. The integer type (int) in Arduino sketch means a signed 16-bit variable, and Pico is a 32-bit microcontroller which has a 32-bit integer type. I used the int16_t type instead.

This example is located here

If you have the ADXL345 module from the KS0068 Sensor Kit, connect it with the Raspberry Pi Pico as shown in the next table:

Raspberry Pi PicoADXL345 Module

Let’s build and upload the example:

$ cd && git clone

$ cp -r ~/cxemotexnika/Examples/Raspberry-Pi-Pico/ADXL345/ ~/pico/pico-workspace/

$ cd ~/pico/pico-workspace/ADXL345

$ ./ build

$ ./ upgrade

Now we can connect USB-UART of picoprobe and run minicom:

$ ./ monitor

[ 3934.052504] cdc_acm 1-2:1.0: ttyACM0: USB ACM device

Welcome to minicom 2.7.1


Compiled on Dec 23 2019, 02:06:26.

Port /dev/ttyACM0, 22:26:58

Press CTRL-A Z for help on special keys

RAW: -29 11 -243

ACCEL: -0.113100 0.042900 -0.947700

RAW: -23 14 -238

ACCEL: -0.089700 0.054600 -0.928200

RAW: -23 12 -242

ACCEL: -0.089700 0.046800 -0.943800

RAW: -25 19 -238

ACCEL: -0.097500 0.074100 -0.928200

RAW: -20 19 -230

ACCEL: -0.078000 0.074100 -0.897000

RAW: -28 10 -240

ACCEL: -0.109200 0.039000 -0.936000

RAW: -27 10 -232

ACCEL: -0.105300 0.039000 -0.904800

The ADXL345 accelerometer works!

Conclusion: We can use other Arduino examples to change them a bit and use along with Raspberry Pi Pico C/C++ SDK.

That is all for now. Wish you a good Raspberry Pi Pico experience!

Viewed 38761 times by 10801 viewers

Last modified: 19 August 2021



Write a Reply or Comment