Raspberry Pi Pico

The Raspberry Pi Pico is a microcontroller board featuring the RP2040, a dual-core Arm Cortex-M0+ chip with 264 KB SRAM and 2 MB flash. With 26 GPIO pins, USB, and support for MicroPython/C++, it’s ideal for embedded projects, IoT, and robotics. Unlike SoCs, it’s a lightweight MCU for real-time tasks, enhanced by programmable I/O. The Pico W variant adds Wi-Fi/Bluetooth.

Raspberry Pi Pico Board
Fig.: Raspberry Pi Pico Board

Features/Specifications

Microcontroller: RP2040 (32-bit) with two ARM Cortex-M0+ cores
Clock Speed: up to 133 MHz (variable/overclockable)
Memory: 256kB on-chip SRAM; 2MB on-board QSPI Flash
USB: On-board USB v1.1 (as device or host)
Power Supply: USB (5V) or ~1.8V to 5.5V (e.g., lithium-ion cell with 3.7V or 2-3 AA batteries in series)
Connectors: 26 GPIO pins (including 3 analog inputs) at 3.3V
ADC: 12-bit 500ksps
Interfaces: 2× UART
2× I2C
2× SPI
16× PWM channels
1× Timer with 4 alarms
1× Real time counter
Operating Temperature: -20°C to 85°C (maximum recommended: 70°C)
Miscellaneous:
  • Built-in temperature sensor for the MCU
  • Integrated floating-point libraries
  • Various low-power/deep-sleep modes
  • Drag-and-drop programming via USB
  • 8 programmable I/O (PIO) state machines

📄 Raspberry Pi Pico schematic (261 kB)
📄 Raspberry Pi Pico datasheet (17359 kB)
📄 Raspberry Pi RP2040 datasheet (5301 kB)

Connections

Pinout-Chart of the Raspberry Pi Pico
Fig.: Pinout-Chart of the Raspberry Pi Pico
GPIO (General Purpose IO) GP0 - GP22: purely digital input/output pins
GP26 - GP28: digital or analog (ADC) input/output pins
GND Ground connections
#40 (VBUS) VBUS corresponds to the input voltage from the Micro-USB port. This is either 5V or 0V if the USB port is not connected.
#39 (VSYS) VSYS is the input voltage for the board and can range between 1.8V and 5.5V.
#37 (3V3_EN) 3V3_EN is connected to the board's SMPS and has an internal 100kΩ pull-up resistor to VSYS. To disable the 3.3V rail, this pin must be set to LOW (which will also turn off the RP2040).
#36 (3V3) 3V3 provides a 3.3V supply used internally and can also be used for external circuits. However, make sure that no more than 300mA is drawn.
#35 (ADC_VREF) ADC_VREF is the operating or reference voltage for the ADC. An external voltage source connected to this pin can improve the accuracy of the ADC.
#33 (AGND) AGND is the ground reference for GPIO 26–29. If the ADC is not used or its performance is not critical, this pin can be connected to the digital GND.
#30 (RUN) RUN is the enable pin for the RP2040 and is connected to 3.3V via a 50kΩ pull-up resistor. To reset the RP2040, this pin must be set to LOW (GND).

Safety precautions for using the Raspberry Pi Pico

Used Components

Connecting the Raspberry Pi Pico to the PC

To connect the Raspberry Pi Pico to the PC (in this case: Microsoft Windows) in programming mode, you need a Micro-USB cable, which should first be plugged into the board. Then, press and hold the BOOTSEL button on the board and connect the USB cable to the PC. After a short moment, a new USB drive named RPI-RP2 should appear in the file explorer. If it does not appear, check whether the USB cable you are using supports data transfer and is not just a simple charging cable.

Programming in MicroPython

MicroPython is an implementation of the Python 3 programming language for embedded hardware, such as the Raspberry Pi Pico. It provides an interactive console (the so-called REPL) to execute commands via USB, as well as an integrated file system. The MicroPython port for the Raspberry Pi Pico also provides modules that give access to the lower levels of the Pico's hardware.
(Detailed information: micropython/wiki or micropython.org)

Preparations

The Raspberry Pi Foundation recommends the development environment "Thonny" for programming. It can be downloaded for free for common operating systems from thonny.org. For Microsoft Windows, I used the portable version, which does not require installation. Simply launch the thonny.exe and you can get started right away.

In the menu item "Run" → "Select interpreter...", select MicroPython (Raspberry Pi Pico) and follow the instructions to install the firmware correctly:

Install MicroPython firmware in Thonny
Fig.: Install MicroPython firmware in Thonny

After a few seconds, the firmware will be installed, and you can start programming the Pico right away.
(Current firmware is also available at Firmware for Raspberry Pi Pico)

Shell (REPL)

You can now enter Python commands directly into the shell, which will be immediately interpreted by the Pico, for example, a simple output:

Python shell in Thonny
Fig.: Python shell in Thonny

Ex. I: Blink the internal LED

The following program makes the internal LED (an SMD component directly mounted on the board) of the Raspberry Pi Pico blink at a frequency of 1 Hz. Unlike the Arduino, the LED does not have a physical pin, but it can be accessed internally in the same way.

Once the code is written, it can be saved (either on the PC or directly on the Pico) and then executed by pressing F5 or the small Play button in the menu bar.

import machine
import utime

led = machine.Pin(25, machine.Pin.OUT)

while True:
    led.toggle()
    utime.sleep(0.5)

Ex. II: Reading the temperature

The datasheet states that the RP2040 has a built-in temperature sensor, which can be easily read. In section 4.9.4. Temperature Sensor, the formula is described for converting the read data into a temperature. The following sketch outputs this temperature once per second:

from machine import Pin
from utime import sleep

sensor = machine.ADC(4)

while True:
    val = sensor.read_u16() * 3.3 / (65535)
    temp = 27 - (val - 0.706)/0.001721
    print (str(round(temp, 2)) + " °C")
    sleep(1)

More information about MicroPython can be found here:
Getting started with MicroPython

Ex. III: Blink an external LED

For this experiment, an LED (e.g., 5mm) with a current-limiting resistor (R1 = 330Ω) is connected to pin GP15 of the Pico, as shown in the following circuit diagram:

Circuit diagram for setting up an LED and a button. (The same setup is also used in Ex. IV)
Fig.: Circuit diagram for setting up an LED and a button. (The same setup is also used in Ex. IV)

As a sketch, we could use the same one as shown in Sketch I, but the pin for the LED would need to be adjusted to 15. However, this time, we use a different method of timing for the blink cycle: a so-called timer.

from machine import Pin, Timer
led = Pin(15, Pin.OUT)
timer = Timer()

def blinkLed(timer):
    led.toggle()

timer.init(freq=5, mode=Timer.PERIODIC, callback=blinkLed)

Here, a periodic timer is started with a frequency of 5 Hz, which calls the callback function blinkLed on each cycle. This function toggles the LED, i.e., it turns the LED on or off in each cycle.

Ex. IV: Read button input

The following sketch checks the state of a connected button and responds by turning the LED on or off at pin GP15. It is important to ensure that the button is connected with the internal pull-down resistor in the declaration, as it is connected to 3V3. However, it is also possible to connect the button to GND, but in that case, a pull-up resistor must be used in the declaration.

from machine import Pin
import time

led = Pin(15, Pin.OUT)
button = Pin(14, Pin.IN, Pin.PULL_DOWN)

while True:
    if button.value():
        led.toggle()
        time.sleep(0.5)

Ex. V: Potentiometer dims LED

In this experiment, two functions are tested: reading analog data from a potentiometer and dimming an LED using PWM. We use the following setup for this:

Circuit diagram to connect a potentiometer and an LED to the Raspberry Pi Pico
Fig.: Circuit diagram to connect a potentiometer and an LED to the Raspberry Pi Pico

Since the Raspberry Pi Pico has a higher-resolution ADC compared to the Arduino, values between 0 and 65535 can be read. These can be read using read_u16() from the prepared pin.
With PWM(Pin(15)), the pin GP15 is defined as a PWM output, and with freq(1000), a frequency of 1000 Hz is set, indicating how often the signal should switch between HIGH and LOW on this output.
With duty_u16(), it is defined how much time the PWM signal should be pulsing, e.g., 100% (duty=65025) would keep the LED permanently on, and 0% (duty=0) would turn the LED off completely. All values in between result in the well-known dimming effect of the LED due to the high switching speed.

from machine import Pin, PWM, ADC

led = PWM(Pin(15))
led.freq(1000)

potentiometer = ADC(Pin(26))

while True:
    duty = potentiometer.read_u16()
    led.duty_u16(duty)

Standalone operation of the Raspberry Pi Pico

If you want to run the Pico without it being connected to the PC (e.g., via a power bank), there are a few things to consider:

Programming in CircuitPython

One variant for programming with Python is CircuitPython, developed by Adafruit. If you already have experience with this language/platform, I recommend continuing to read in this direction: Getting Started with Raspberry Pi Pico and CircuitPython

Programming in C++

With the official Raspberry Pi Pico C/C++ SDK, programs can be written in C++ and then executed on the Pico. I haven't tried this option yet. For more information: Getting started with C/C++

Programming in C++ with the Arduino IDE

It is also possible to program the Raspberry Pi Pico within the Arduino IDE. An unofficial port for the RP2040 has been made available in the Arduino ecosystem and can be downloaded from https://github.com/earlephilhower/arduino-pico . To get the Raspberry Pi Pico running in the Arduino IDE, the following steps are necessary:

Preparations

Compiling/Uploading Sketches

To upload a sketch for the first time, press BOOTSEL while connecting the board to the PC via USB cable. Then, you can upload the sketch to the board as usual in the Arduino IDE.
After this first upload, you can select the recognized port in the "Tools" → "Port" menu, and subsequent uploads should work without any issues. This didn't work for me, and I had to repeat the procedure of pressing BOOTSEL for every upload.

Ex. I: Blinking the internal LED

Similar to the first sketch that every Arduino beginner probably tries, this example blinks the internal LED at a frequency of 1 Hz. Unlike Arduino, this LED does not have a physical pin, but it can be accessed internally just like the following sketch shows:

#define INT_LED_PIN 25

void setup() {
    pinMode(INT_LED_PIN, OUTPUT);
}

void loop() {
    digitalWrite(INT_LED_PIN, HIGH);
    delay(500);
    digitalWrite(INT_LED_PIN, LOW);
    delay(500);
}

Note: Since the Raspberry Pi Pico is still relatively new on the market (as of March 2021), this port is still under development and subject to frequent changes. Additionally, 100% compatibility has not yet been achieved, meaning not all functions are available. It is important to regularly check for updates and bug fixes.

Last edited by Christian Grieger on 2025-05-12
X
  1. [top]
  2. Features/Specifications
  3. Connections
  4. Safety precautions for using the Raspberry Pi Pico
  5. Used Components
  6. Connecting the Raspberry Pi Pico to the PC
  7. Programming in MicroPython
  8. Programming in CircuitPython
  9. Programming in C++
  10. Programming in C++ with the Arduino IDE