Getting Started with Physical Programming on Raspberry Pi Pico

Getting Started with Physical Programming on Raspberry Pi Pico

The RP2040 microcontroller on the Raspberry Pi Pico was designed with physical computing in mind. Its numerous General Purpose Input/Output (GPIO) pins allow it to interact with a variety of components, enabling you to build projects ranging from lighting LEDs to recording data about your surroundings.

Physical computing is not any harder to learn than traditional computing, and if you follow the content of this article, you will understand how to build your own circuits and program them to execute your commands.

First Physical Computing Program: Hello, LED!

Just as printing “Hello, World” on the screen is the first step in learning a programming language, lighting up an LED is a classic entry point for learning physical computing.

You can also start without any additional components, as there is a small LED on the Pico board itself.

Getting Started with Physical Programming on Raspberry Pi Pico

This LED lights up when powered; when it loses power, it goes out.

The onboard LED is connected to pin GP25 of the RP2040. You might remember that this is one of the “missing” GPIO pins on the RP2040.

Open Thonny and connect your Pico. Click into the script editing area and start your programming with the following line:

import machine

This small line of code is crucial for using MicroPython on the Pico. It imports the MicroPython code library, known as the “machine” library. This library contains all the instructions needed for MicroPython to communicate with the Pico and other MicroPython-compatible devices. Without this line, you will not be able to control any GPIO pins on the Pico.

Selective imports in MicroPython and Python allow you to import part of a library rather than the entire library. This helps your program use less memory and allows you to mix and match functions from different libraries. The program in this tutorial imports the entire library, but elsewhere, you might see programs that use something like from machine import Pin, which tells MicroPython to import only the “Pin” function from the “machine” library, rather than the entire library.

The machine library exposes an Application Programming Interface (API). This name may sound complex, but it accurately describes its function: it provides a way for your program to communicate with the Pico through an interface.

The next line of the program provides an example of the machine library’s API:

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

This line defines an object named led_onboard, while the second part of the code calls the Pin function from the machine library. As the name suggests, this function is designed to handle your Pico’s GPIO pins. The first parameter is 25, which is the pin number you set. machine.Pin.OUT tells the Pico that this pin should be used as an output rather than an input.

This line of code only sets up the pin; it does not light up the LED. To do that, you need to tell the Pico to turn on this pin. Enter the following code on the next line:

led_onboard.value(1)

This line sets the value of led_onboard to 1 (meaning “on”), and you can also set the value to 0 (meaning “off”).

Click Run and save the program on the Pico, naming it Blink.py. You will see the LED light up. Congratulations—you have written your first physical computing program!

However, you will notice that the LED remains lit. This is because your program tells the Pico to turn it on but never tells it to turn off the LED. You can add another line at the bottom of the program:

led_onboard.value(0)

However, this time when you run the program, the LED seems to never light up. This is because the Pico works very, very fast, much faster than you can see with the naked eye. The LED is turned on, but for such a short time that it appears to stay off. To solve this problem, you need to slow down the program by introducing a delay.

Go to the top of the program, click at the end of the first line, and press Enter to insert a new line:

import utime

Similar to import machine, this line imports a new utime library into MicroPython. This library handles everything related to time, from measuring time to inserting delays into your program.

Go to the bottom of the program, click at the end of the led_onboard.value(1) line, and press Enter to insert a new line:

utime.sleep(5)

This will call the sleep function from the utime library, which will pause your program for the number of seconds you input, in this case, 5 seconds.

Click Run again. This time you will see the LED on your Pico light up, stay lit for 5 seconds, and then turn off.

Finally, it’s time to make the LED blink in a loop. To do this, you need to create a loop. Rewrite your program:

import machine
import utime

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

while True:
	led_onboard.value(1)
	utime.sleep(5)
	led_onboard.value(0)
	utime.sleep(5)

Remember, the lines in the loop need to be indented four spaces so that MicroPython knows they make up the loop. Click Run again, and you will see the LED light up for 5 seconds, turn off for 5 seconds, and then light up again in a continuous cycle. The LED will continue to blink until you click the stop icon to cancel your program and reset your Pico.

There is also another way to handle the same task, which is to use toggle instead of explicitly setting the LED output to 0 or 1. Delete the last four lines of the program and replace them with the following:

import machine
import utime

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

while True:
	led_onboard.toggle()
	utime.sleep(5)

Run the program again. You will see the same effect as before. The onboard LED will light up for 5 seconds, turn off for 5 seconds, and then light up again in an infinite loop. However, this time, your program is two lines shorter, and you have optimized it. toggle() can be used for all digital output pins; it simply switches between on and off: if the pin is currently on, toggle() will turn it off; if it is off, toggle() will turn it on.

Using a Breadboard

If you use a breadboard to hold components and make electrical connections, the next projects in this chapter will be easier to accomplish.

Getting Started with Physical Programming on Raspberry Pi Pico

A breadboard has many holes spaced 2.54 mm apart. Under these holes are metal strips that connect them like jumper wires.

The two rows marked with positive and negative signs are typically used to connect the Pico’s 5V/3.3V and GND pins. They can also be used to connect the positive and negative terminals of an external power supply to power the required components.

Adding electronic components to the breadboard is easy; just align their pins with the holes and gently push them in. You can use jumper wires to connect the pins to the Pico.

Insert your Pico into the breadboard so that it spans the gap in the middle, with the microUSB port at the top. Before inserting, make sure all the pins are aligned with the holes; otherwise, it may be difficult to insert or break the Pico’s pins.

Getting Started with Physical Programming on Raspberry Pi Pico

External LED

For this project, you will need a breadboard, male-to-male jumper wires, an LED, and a 330Ω resistor (or close to 330Ω). If you do not have a breadboard, you can use female-to-female jumper wires.

The resistor is used here as a current-limiting resistor. It protects your Pico and LED by limiting the amount of current the LED can draw. Without it, the LED may draw too much current and burn out. 330Ω is suitable for most common LEDs. The higher the value, the dimmer the LED; the lower the value, the brighter the LED.

Do not connect the LED to the Pico without a current-limiting resistor unless you know that the LED has a suitable built-in resistor.

Holding the LED, you will notice that one of the leads is longer than the other. The longer lead is the positive, while the shorter lead is the negative. The positive needs to be connected to your Pico’s GPIO pin through the resistor; the negative needs to be connected to a GND pin.

Take one end of the resistor (which end does not matter) and insert it into the same row on the breadboard as the Pico’s GP15 pin in the bottom left corner. Insert the other end into an empty row below on the breadboard.

Pick up the LED and push the longer leg (positive) into the same row as the end of the resistor. Place the shorter leg (negative) into the same row but across the gap in the middle of the breadboard so that it lines up. Finally, insert a male-to-male jumper wire into the same row as the LED’s shorter leg and connect it directly to your Pico’s GND pin. See the diagram below.

Getting Started with Physical Programming on Raspberry Pi Pico

Controlling an external LED in MicroPython is no different from controlling the onboard LED on the Pico; you just need to change the pin number in the program code. If you close Thonny, reopen it, and load the previous Blink.py program. Find:

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

Edit the pin number by changing it from 25 to 15. Change led_onboard to led_external. The final code looks like this:

import machine
import utime

led_external = machine.Pin(15, machine.Pin.OUT)

while True:
	led_external.toggle()
	utime.sleep(5)

Input: Reading a Button

For this project, you will need a breadboard, male-to-male jumper wires, and a push button switch. Install them according to the positions indicated in the diagram. The button pins should be inserted on either side of the breadboard, spanning the middle (physically breaking the connection between the two sides of the pins).

One side of the button connects to the Pico’s 3V3 pin, and the other side connects to the Pico’s GND pin.

Getting Started with Physical Programming on Raspberry Pi Pico

Hidden Built-in Resistor Unlike the LED, the button switch does not require a current-limiting resistor. However, it still needs a so-called pull-up or pull-down resistor, depending on how your circuit works. Without a pull-up or pull-down resistor, the input signal can have “noise,” triggering even when you don’t press the button.

So where is the resistor in the circuit? It is hidden inside the Pico chip. Just as it has a built-in LED, the Pico has a built-in programmable resistor connected to each GPIO pin. You can set it to be a pull-down or pull-up resistor in MicroPython as needed.

What’s the difference? A pull-down resistor connects the pin to GND, which means that when the button is pressed, the input value read is 0. A pull-up resistor connects the pin to 3V3, meaning that when the button is not pressed, the input value read is 1.

All the circuits in this book use a programmable resistor in pull-down mode.

Open Thonny and start a new program on a new line:

import machine

Next, you need to set a pin as an input using the machine API rather than an output:

button = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)

This works the same way as in your LED project: creating an object named “button” that includes pin number GP14 and sets it as an input with a pull-down resistor. However, creating the object does not mean it will do anything by itself, just like creating the LED object does not make the LED light up.

To actually read the button, you need to use the machine API again, this time using the value function to read rather than set the pin value. Enter the following line:

print(button.value())

Click Run and save the program as Button.py, ensuring it is saved on your Pico MicroPython device. Your program will print the value read from GP14. Since the input uses a pull-down resistor, this value will be 0, letting you know that the button has not been pressed.

Press the button with your finger and click Run again. This time, you will see the value 1 printed to the Shell. Pressing the button completes the circuit and changes the value read from the pin. To continuously read the button, you need to add a loop to the program. Edit the program as follows:

import machine
import utime

button = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)

while True:
	if button.value() == 1:
		print("You pressed the button!")
		utime.sleep(2)

Click Run again. Your Pico runs much faster than you can observe, and without delays, even a simple press of the button can print hundreds of messages to the Shell! If you hold the button for more than two seconds, it will print a message every two seconds until you release the button.

Input and Output: Using Together

Most circuits have more than one component, which is why the Pico has so many GPIO pins. It’s time to combine everything you have learned and create a more complex circuit: a device that uses a button switch to control an LED.

Getting Started with Physical Programming on Raspberry Pi Pico

In fact, this circuit combines the previous two circuits into one. You might remember that you used GP15 to drive the external LED and GP14 to read the button. Now rebuild your circuit so that the LED and button are both on the breadboard, still connected to GP15 and GP14. Don’t forget the current-limiting resistor for the LED.

Start a new program in Thonny and begin importing the two libraries your program needs:

import machine
import utime

Next, set up the input and output pins:

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

Then create a loop to read the button value:

while True:
	if button.value() == 1:

However, this time you will toggle the LED state on the output pin based on the input pin value, rather than printing messages to the Shell. Use the following code:

led_external.value(1)
utime.sleep(2)

This is enough to turn on the LED, but when the button is not pressed, you also need to turn it off again. Add this new line, removing 4 spaces from the previous 8 spaces, meaning this line will be part of the infinite loop rather than the if statement:

led_external.value(0)

The final code looks like this:

import machine
import utime

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

while True:
	if button.value() == 1:
		led_external.value(1)
		utime.sleep(2)
	led_external.value(0)

Click Run and save the program as Switch.py on your Pico.

At first, nothing will happen. When you press the button, you will see the LED light up. It will turn off again two seconds after you release the button, until you press the button again.

Congratulations! You have built your first circuit that controls one output pin based on another input pin, and we have taken a big step towards building modular programs!

The links in the text can be clicked to read the original article at the end

Getting Started with Physical Programming on Raspberry Pi Pico

More exciting content

Making a Mini Retro TV with ESP32

Open Source Smart Watch Based on ESP32-S3

Neowave: RGB WiFi Colorful Mood Light

Photoresistor + micro:bit DIY Color Ball Sorter

Making a Decent NAS “Upgraded Version” with Raspberry Pi

PiCalc: DIY OLED Screen Calculator Based on Raspberry Pi Pico

Emo: DIY Desktop Robot Based on Raspberry Pi 4B That Can Smile and Move

Leave a Comment

×