HomeRaspberry Pi TutorialsC/C++ and MicroPython SDK for Raspberry Pi Pico on Windows

C/C++ and MicroPython SDK for Raspberry Pi Pico on Windows

Raspberry Pi Pico SDK is a bit of a mess right now

Everyone got excited about Raspberry Pi Pico – the latest product from the Raspberry Pi Foundation. I promptly bought 3 of them (max per person at the time of purchase) just in case I will make some grave mistakes resulting in boards giving up their lives. Unfortunately, SDK for Raspberry Pi Pico is a bit of a mess right now. I’m here to give you a quick guide on how to get started with Raspberry Pi Pico, so you don’t have to read 270 & 70 pages PDFs.

A “raspberry”, but different

Raspberry Pi Pico is a completely new animal to Raspberry Pi lineup. It’s a microcontroller, so there is no Raspbian OS to play with. Instead, the boards come with 2 most popular programming languages in the maker’s space: C/C++ and MicroPython. As I found out in my 1.5h livestream, getting started can be messy if this is your 1st time holding the board in your hands.

Encouraged by others and my mistakes, I’m here to make it work for you in a couple of minutes so all the frustration is removed from the process. This guide is for Windows devices, as this is how I do most of my tinkering with microcontrollers.

If you want a fast start – pick MicroPhyton, C/C++ is a mess right now to set up.

Getting started with MicroPhyton and Raspberry Pi Pico

To play with Raspberry Pi Pico on Windows, you will need 1 download. The Foundation recommends Thonny (Windows) as your IDE as it comes with everything you need (including Python 3.7), but you can also install the latest version of Python 3.x as the system-wide language installer in case you need some extras for your projects.

Open Thonny and go to Tools>Options>Interpreter and select MicroPython (Raspberry Pi Pico). You can leave the port configuration to automatic. Then hit “Install or update firmware” before clicking OK.

As per instructions, you have to plug the USB cable while holding the button on the Raspberry Pi Pico. When done, OK all windows and click Run (green play button) to verify that you can connect to your microcontroller. If everything went well, you should see something like this:

You are ready to program with MicroPython. Any application written in this window will be processed by Raspberry Pi Pico and results returned in the shell window below. Don’t forget to save your files as name.py. You can store it locally on your PC as well, but to run them, you should save it on Raspberry Pi Pico.

While you can have as many files saved as you want, to run them without a computer, Raspberry Pi Pico has to know where to start. The file that will run on boot should be saved as main.py. If you don’t do this, your script won’t run when connected to a power supply.

If your project includes external libraries, you have to open the files and save it to Raspberry Pi Pico as well. Here is a sample off LED library from benevpi/pico_python_ws2812b:

And you are ready to take on the world with MicroPhyton and Raspberry Pi Pico!

Getting started with C/C++ and Raspberry Pi Pico

I spent a couple of hours trying to figure out what is the correct process of setting up SDK for C/C++ on my Windows machine. I carefully followed official instructions but I run into errors. To make the process more complicated, it’s not a case of installing one thing and just rolling with it. In the world filled with alternative microcontrollers that simply work with PlatformIO or Arduino IDE, Raspberry Pi Pico SDK falls really short.

The only light in the tunnel is the cooperation with Arduino. As they will also get RP2040-based microcontroller, I’m pretty sure that programming in C/C++ will be as easy as selecting the correct board from the board manager in Arduino IDE.

If you want to give it a shot here is what you have to do. Download all programs listed below (yes, this is why I’m not too impressed with the toolchain):

During the installation, please pay attention to the installer options and make sure the following items are selected:
Python: Add Path, Install for all users
AGM GCC compiler: Add Path (all options selected, the installer may hang at the end so give it time)
CMAKE: Add Path
Build Tools for Visual Studio: Install C++ only with default options
pico-sdk: download the zip and unpack the folder to the directory of your choice

Once the installation is complete, let’s make sure the Environmental Variables on Windows are set correctly. (Win key + type “edit the system environmental variables”). In User Variables add:

VariableValue
PICO_SDK_PATHC:\path to downloaded folder\pico-sdk
PathC:\Users\mzoln\AppData\Local\Programs\Microsoft VS Code\bin

In System, Variables make sure you have the following

VariableValue
PathC:\Program Files\Python39\
PathC:\Program Files\Python39\Scripts\
PathC:\Program Files\CMake\bin
PathC:\Program Files (x86)\GNU Arm Embedded Toolchain\10 2020-q4-major\bin
PathC:\Users\mzoln\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Visual Studio Code


Next, search installed programs for Visual Studio 2019 – and use Developer Command Prompt (open as an administrator via right-click) to open VSC (if you open VSC normally, it won’t work and after 2h of playing with variables I gave up). Type code to open the VSC with correct build tools.

VSC configuration

In Extension panel to the left, search for C/C++ & CMake Tools from Microsoft. Once installed go to Extension settings for CMake Tools and change the following:

Create a new folder on your computer for the test project. Use VSC to open this folder, it’s going to be your workspace for the project. At the bottom of the VSC window select the compiler (you may need to use a scan option) to GCC for arm-none-eabi.

Congratulations, you are set!

Test program (blink)

Instead of confusing you with the list of everything available for Raspberry Pi Pico, I slimmed down the files needed for compilations. I will shortly explain the files and functions for you. Each project will need a 3 file (at least) to compile. Your program file (program.c) the SDK import instructions for CMake (pico_sdk_import.cmake) and CMake build instructions (CMakeLists.txt).

blink.c

This is your program file. Pay attention to the name, as you will need to use this name in other files to compile it correctly. All your programming should go into the name.c file, any referred files should be also placed in the same project folder.

blink.c

#include "pico/stdlib.h"

int main() {
const uint LED_PIN = 25;
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
while (true) {
gpio_put(LED_PIN, 1);
sleep_ms(250);
gpio_put(LED_PIN, 0);
sleep_ms(250);
}
}

pico_sdk_import.cmake

This is an instruction set for CMake that contains information about where the sdk is and how to compile the code for you. You won’t need to modify this, but the file has to be present for each workspace. You can have multiple examples of your program in the workspace, but you will only need one pico_sdk_import.cmake file

pico_sdk_import.cmake

# This is a copy of /external/pico_sdk_import.cmake

# This can be dropped into an external project to help locate this SDK
# It should be include()ed prior to project()

# todo document

if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
endif ()

if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
endif ()

if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
endif ()

set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the PICO SDK")
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of PICO SDK from git if not otherwise locatable")
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")

if (NOT PICO_SDK_PATH)
if (PICO_SDK_FETCH_FROM_GIT)
include(FetchContent)
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
if (PICO_SDK_FETCH_FROM_GIT_PATH)
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
endif ()
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
)
if (NOT pico_sdk)
message("Downloading PICO SDK")
FetchContent_Populate(pico_sdk)
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
endif ()
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
else ()
message(FATAL_ERROR
"PICO SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
)
endif ()
endif ()

get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
if (NOT EXISTS ${PICO_SDK_PATH})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
endif ()

set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the PICO SDK")
endif ()

set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the PICO SDK" FORCE)

include(${PICO_SDK_INIT_CMAKE_FILE})

CMakeLists.txt

You will have to modify this file according to your project. CMake needs to know what files to compile and this lists tell it so. For each project you should append to file the following:

project(blink)
add_executable(blink blink.c)

# Pull in our pico_stdlib which pulls in commonly used features
target_link_libraries(blink pico_stdlib)

# create map/bin/hex file etc.
pico_add_extra_outputs(blink)

Highlighted sections have to be changed to the name of your program.c file. If your project has multiple files and directories, your CMake file will has to reflect his as well. Assuming that your project structure looks like this:

main.c
-FolderA
    --fileA.h
    --fileB.c

Your CMake section to append would have to look like this:

project(test)
include_directories(FolderA)
file(GLOB SOURCES "FolderA/*.c")
add_executable(test main.c ${SOURCES})


# Pull in our pico_stdlib which pulls in commonly used features
target_link_libraries(test pico_stdlib)

# create map/bin/hex file etc.
pico_add_extra_outputs(test)

Compiler would generate the file build/test.uf2 to transfer to Raspberry Pi Pico.

CMakeLists.txt

cmake_minimum_required(VERSION 3.12)

include(pico_sdk_import.cmake)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

pico_sdk_init()
project(blink)
add_executable(blink blink.c)

# Pull in our pico_stdlib which pulls in commonly used features
target_link_libraries(blink pico_stdlib)

# create map/bin/hex file etc.
pico_add_extra_outputs(blink)

Build

Thankfully, flashing programs to Raspberry Pi Pico is easy. Build and compile the program using VSB button at the bottom of the screen (blue section) and the compiled file .uf2 will be available in the build folder.

Hold the button of Raspberry Pi Pico when powering up and it will open as portable drive. Drag the .uf2 file over and you are set!

Final thoughts

C/C++ is a bit of a mess. I’m surprised there is no PlatformIO integration or anything more streamlined. After all Windows machines are the most popular machines, so it makes perfect sense to spend some time streamlining this process. I spent way too much time trying to figure out the perfect combinations of settings with a friend of mine (Hi Dmytro!) and I can only imagine the frustrations an average Pi enthusiast have to go through to do a bit o C/C++ on Windows. I hope the experience improves and I cannot wait for Arduino IDE integration. Issues or comments? Let me know in this Reddit thread.

PayPal

Nothing says "Thank you" better than keeping my coffee jar topped up!

Patreon

Support me on Patreon and get an early access to tutorial files and videos.

image/svg+xml

Bitcoin (BTC)

Use this QR to keep me caffeinated with BTC: 1FwFqqh71mUTENcRe9q4s9AWFgoc8BA9ZU

M5Paper

Programable, ESP32 based awesome dev platform with 4.7 e-ink display by M5Stack

More HATs

client-image
client-image

Argon One M.2

Enclose Raspberry Pi 4 inside this great case with custom I/O, cooling and GPIO and M.2 SSD support

More cases on

client-image
client-image

Best Raspberry Pi Projects

How to use Raspberry PI as WOL (wake on lan) server

0
While you could wake up your PC from a mobile directly, having a dedicated server capable of doing so is the best solution. The reason is simple. You can hook up as many devices as you wish with a single endpoint. This is why Raspberry Pi is perfect for this.

Slow Internet Warning

0
From time to time my Internet grinds to a stop. Since Raspberry Pi 4 comes with a 1Gbps Ethernet, I decided to take advantage of it and create a reporting system in NodeRED that will monitor and report when the ISP is not keeping the contractual agreements. Works with Alexa, Google Home, Android and Windows 10.

How fast Raspberry Pi NAS is?

0
Let's see how fast Raspberry Pi NAS really is?

Argon18: Argon ONE SSD modification

0
Argon One case just got better - now you can boot it from USB without ruining the design thanks to Argon 18: Argon One SSD modification

HOW TO...

How to boot Raspberry Pi 5 from NVMe M.2 SSD

0
This is how you can boot your Raspberry PI 5 from NVMe in 10 min! Check out these easy instructions

It took me 2 months to boot CM4 from NVMe

0
Complete beginners guide to Compute Module 4 boot from NVMe.

Raspberry Pi Zero 2 W vs other Zero boards

0
It's time to test the Raspberry Pi Zero 2 W against other Raspberry Pi boards from Zero series: power, WiFi, temperature and core performance

A comprehensive guide to Grafana & InfluxDB

0
How to use Grafana and InfluxDB on Raspberry Pi for IoT sensors in home automation

How to boot Raspberry Pi 4 from USB

0
How to set up and boot Raspberry Pi 4 from USB drive - headless guide.