PiicoDev Button | Getting Started Guide

Updated 13 November 2022

Buttons are a ubiquitous user interface - of course, you've seen them everywhere! The humble button is often the fastest way to create a control interface for your project too. This guide will help you get started with a PiicoDev® Button - an intuitive input device that allows you to easily interact with your project. We'll walk through some examples to read from the Button and remix the example code to do something cool with our development board.

To get started - select your dev. board below.


Hardware Connections

To follow along you'll need:

Plug your Pico into the Expansion Board. Make sure it is installed in the correct orientation - Pin 0 on the expansion board should be adjacent to the Pico's USB connector.

Connect your PiicoDev Button to the expansion board with a PiicoDev Cable.

To follow along you'll need:

Mount the Adapter onto your Pi's GPIO. Make sure it is plugged in the correct orientation - An arrow on the Adapter will point to the Pi's Ethernet connector (on a Pi 3 the Ethernet connector and USB ports are swapped.)

Connect your PiicoDev Button to the Adapter with a PiicoDev Cable.

To follow along you'll need:

Plug your micro:bit into the Adapter, making sure the buttons on the micro:bit are facing up.

Connect your PiicoDev Button to the Adapter with a PiicoDev Cable.

The PiicoDev Button features four ID switches - ensure all the switches are OFF before proceeding. This will use the default device address.


Setup Thonny

Select your dev board from the tabs above to get ready for programming with Thonny for the first time. 

If you have already programmed with PiicoDev modules before, there's probably no need to follow these steps again.

Let's get set up with scripting in Thonny for the Raspberry Pi Pico.

We'll install Thonny, configure for Pico and write our first script. To follow along you'll need:

Contents

 

Install Thonny

If you're working on a Raspberry Pi 4, you're in luck - Thonny comes pre-installed. For those on another operating system, download Thonny here and run the installer.

Once the installer finishes, run Thonny.

Set up Thonny

Hold the BOOTSEL button on your Pico, and connect your Pico to your computer via USB.

Go to Run > Select interpreter and choose MicroPython (Raspberry Pi Pico).

It's also a good idea to install or update firmware. This will update your Pico with the latest version of MicroPython, or install MicroPython if it wasn't already.

Select Interpreter

REPL interface (Shell)

We can immediately start executing code in the REPL - Enter this code in the shell tab: print("Hello, World!")

The command will be sent to your Pico, which will execute the command and display back the message.

We can also take control of the on-board LED by executing the following code:

from machine import Pin
led = Pin(25, Pin.OUT)
led.toggle()

This code will toggle the LED. If you keep executing led.toggle() the LED will keep changing state.

REPL Interface

LED On

Writing a Script

Create a new script with File > New and paste in the following code:

from machine import Pin
from time import sleep
led = Pin(25, Pin.OUT)
n = 0;
while True:
    led.toggle()
    print("13 x {} = {}".format(n, 13*n)) # print the thirteen-times table
    n = n + 1
    sleep(0.5)

Save the script - you will be prompted to save to your computer OR the pico. Select save to Pico and name the file main.py

Return to the REPL and press Ctrl+D (or use the Stop/Restart button) to restart your Pico. The LED should flash at a steady rate and the shell should begin printing multiples of thirteen.

Script Output

Installing a Package

Packages are reusable pieces of code that another programmer has written for a common task, such as interfacing with a specific piece of hardware. Thonny has support for installing micropython packages from the Python Package Index - aka 'PyPI' directly onto the Raspberry Pi Pico.

To install a package, ensure the Pico is plugged in and go to Tools > Manage Packages, which will show the Manage Packages dialog.

Enter the name of the package you would like to install into the search bar and click 'Search on PyPI'.

In the search results list, click the title of the package you would like to install. A title that's in bold simply indicates a direct search match on the text you entered in the search bar.

The Manage Packages dialog will show an overview of the package you have clicked. Click Install to install the package on your Pico.

You can confirm the package has been installed by checking the 'Raspberry Pi Pico' section of the File View in Thonny. The view should show a new folder named 'lib', and inside this folder will be one or more folders containing the metadata and source code of the library you just installed.

 

An example of installing the micropython-servo libraryAn example of installing the micropython-servo library
An example of installing the micropython-servo library

Conclusion

We've installed Thonny and uploaded scripts to our Raspberry Pi Pico - if you have any questions feel free to start the conversation below, or open a topic in our forums - we're full time makers and happy to help!

Good news! Thonny comes pre-installed with Raspberry Pi OS. However, to work with PiicoDev we need to enable I2C communications as follows:

  • Power on your Raspberry Pi.
  • Open the Preferences > Raspberry Pi Configuration, select the Interfaces tab
  • Ensure I2C is Enabled

You only need to do this step for your first PiicoDev project - from here on you probably won't have to repeat this step when using PiicoDev hardware.

Let's get set up with scripting in Thonny for the Micro:bit. We'll install Thonny, configure for Micro:bit, and write our first script.

All you'll need to follow along is a Micro:bit v2 GO kit

Contents

Install Thonny

Download Thonny here and run the installer.

Once the installer finishes, run Thonny.

Set up Thonny

Connect your Micro:bit V2 to your computer with the USB cable.

connect-microbit-to-computer-with-usb-cable

Open Thonny, and in the menu bar find Run > Select interpreter and choose MicroPython (BBC micro:bit)

It's also a good idea to install or update firmware. This will update your micro:bit with the latest version of MicroPython, or install MicroPython if it wasn't already.

select-microbit-interpreter-in-thonny

Make sure the Files pane and Plotter are visible by selecting them in View > Files, and View > Plotter.

REPL interface (Shell)

Click the red STOP button to restart the MicroPython on your micro:bit if necessary. The Shell tab should display a block of text that indicates MicroPython is running:

thonny-shell-restarted

We can immediately start executing code in the REPL - Enter this code in the shell tab: print("Hello, World!")

The command will be sent to your micro:bit, which will execute the command and display back the message - nice!

Next, we can also take control of the on-board speaker by executing the following code:

from microbit import *
import audio
audio.play(Sound.HAPPY)

This code will play a happy tone from the micro:bit's speaker! If you the LED. If you keep executing audio.play(Sound.HAPPY), the tone will repeat.

microbit-thonny-repl-play-audio

Writing a Script

The REPL is great for test-driving some new commands and performing short experiments - the real power is in scripting though.

Create a new script with File > New and paste in the following code:

from microbit import *
import audio

print("Hello!")

multiple = 1 # initialise the counter

while True:
    if button_a.was_pressed(): # get the next multiple of the thirteen
        result = multiple * 13 # Calculate the result
        print("13 times " + str(multiple) + " is " + str(result)) # print the multiplication
        multiple = multiple + 1 # increment the multiple
    
    if button_b.was_pressed(): # Say Hello
        display.show(Image.HAPPY)
        audio.play(Sound.HAPPY)
        display.clear()
        
    sleep(10) # a 10 millisecond delay

Save the script - you will be prompted to save to your computer OR the micro:bit. Select save to micro:bit and name the file main.py

Return to the REPL and press Ctrl+D to restart your micro:bit. If something went wrong, use the Stop/Restart button, then Ctrl+D. 

Now, when we press the A button, the Shell will print the next multiple of 13, or if we press the B-button, our micro:bit gives us a smile and a hello sound.

thonny-example-script-for-microbit

Notice the plot is also showing some lines, and they're colour-coded to numbers in the print statement! In my case:

  • The Blue line is the constant 13,
  • The Orange Line is the multiple variable that increases slowly, and
  • The Red line is the result variable, which increases really quickly.

Useful Tips

  • You can stop a running script by selecting the Shell window and pressing Ctrl+C. This is useful if we want to make changes to the file(s) stored on the micro:bit.
  • Reboot your micro:bit (or other MicroPython device) by selecting the Shell window and pressing Ctrl+D
  • If something goes wrong, you can always click the red STOP button in the menu bar

Uploading and Downloading Files

We've been working with a file stored directly on the micro:bit - if you'd like to keep a copy on your computer, right-click the main.py file and select the 'download' option. Similarly, you can always upload code to your micro:bit by right-clicking files on your computer and selecting the upload button.

download-script-from-microbit-to-computer

Conclusion

We've installed Thonny and uploaded our first script to our micro:bit. The script includes branches depending on which button is pressed and can generate audio tones and perform basic arithmetic. Now we can write scripts, move them between micro:bit and computer, or test code interactively using the REPL.

If you have any questions feel free to start the conversation below or open a topic in our forums - we're full-time makers and happy to help!


Download / Install PiicoDev Modules

To work with PiicoDev hardware, we need to download some drivers. The drivers provide all the functions to easily connect and communicate with PiicoDev hardware. Select your dev board from the options above.

We will need these files to easily drive the PiicoDev Button:

  • Save the following files to your preferred coding directory - In this tutorial, we save to My Documents > PiicoDev.
    • Download the PiicoDev Unified LibraryPiicoDev_Unified.py (right-click, "save link as").
    • Download the device modulePiicoDev_Switch.py (right-click, "save link as"). This module is named "Switch" instead of "Button" because it could be used for other switching components too - not just buttons.
  • Upload the files to your Pico. This process was covered in the Setup Thonny section.

The PiicoDev Unified Library is responsible for communicating with PiicoDev hardware, and the device module contains functions for driving specific PiicoDev devices.

We will now install/upgrade the PiicoDev python module for Thonny. This module contains all the drivers to work with all current PiicoDev hardware. Even if you have already installed the PiicoDev modules before, it's still worth upgrading to the latest version if one is available.

First, run Thonny by clicking the:

  1. Pi Start Menu
  2. Programming
  3. Thonny IDE

We need to set up a virtual environment to install the PiicoDev module into. This only needs to be done once as Thonny will remember an environment you have already made. If you are unsure if you have already set one up, you can always create a new one by following these steps.

To set up a virtual environment, click on run  > configure interpreter, to open up the interpreter tab.

In this window, we can create a new virtual environment in the bottom right. A notification window will first pop up, just click OK.

In this window, we are going to create a new empty folder in our Home Directory which will be the location of our virtual environment. To do so follow these steps:

  1. Select the Home tab on the left-hand side of the window.
  2. Click the Create Folder button in the top right.
  3. Enter the name of the new folder. You can call it what you want, but we will call ours "myenv". Once you have written the name, click Create next to it.
  4. Click OK in the bottom left.

Thonny will then set up your virtual environment and when it has finished, it will return to the Interpreter tab. Click OK, and you will have successfully set up the environment.

Note: the Python Executable path now points to the environment we just created.

Remember, you only need to do this once as the next time you open Thonny it will use this environment.

Next, open the package manager. From within Thonny click Tools > Manage Packages

Enter "piicodev" and click "Search on PyPI"

Finally, Install PiicoDev. If you already have PiicoDev installed, there may be an Upgrade button instead, to upgrade to a newer version.

 

With the PiicoDev module installed we are now ready to begin programming with PiicoDev hardware.

We will need these files to easily drive the PiicoDev Button:

  • Save the following files to your preferred coding directory - In this tutorial, we save to My Documents > PiicoDev.
    • Download the PiicoDev Unified LibraryPiicoDev_Unified.py (right-click, "save link as").
    • Download the device modulePiicoDev_Switch.py (right-click, "save link as"). This module is named "Switch" instead of "Button" because it could be used for other switching components too - not just buttons.
  • Upload the files to your Pico. This process was covered in the Setup Thonny section.

The PiicoDev Unified Library is responsible for communicating with PiicoDev hardware, and the device module contains functions for driving specific PiicoDev devices.

Check if the Button was / is pressed

We are ready to begin reading the state of the PiicoDev Button using two simple properties: .was_pressed and .is_pressed. Run the following example code to read the button using the .was_pressed property and observe the output. The program prints a zero to the shell unless a press is detected, then it prints a 1. Notice that holding the button down has no effect on the shell output? 

 

 

# Check if a PiicoDev Button was pressed

from PiicoDev_Switch import PiicoDev_Switch # Switch may be used for other types of PiicoDev Switch devices
from PiicoDev_Unified import sleep_ms
 
button = PiicoDev_Switch()   # Initialise the module

while True:
    if button.was_pressed: # was the button pressed since the last time we checked?
        print(1) # print a result that can be plotted
    else:
        print(0)
        
    sleep_ms(100)

.was_pressed only returns True if the button was pressed since the last time we checked. The program will print a 1 only on the first time we press the button - holding the button down has no effect.

Remix Idea: now change .was_pressed to .is_pressed which returns True if the button is being pressed right now. You ought to observe a different result when the Button is held down. The following figure summarises the behaviour of .was_pressed and .is_pressed.

Different read-types for the PiicoDev Button. was_pressed will reject a button-held event.


Code Remix

Remix: Flash Rate Selector

Let's control something real now! This remix flashes the Pico's onboard LED. Pressing the button selects a new flash rate (from a list of delays). As we click the button the flashing becomes slower, until we hit the end of the list and wrap back to the start. This is a practical use for the .was_pressed property - even when a delay is quite long, the button press is still captured.

# Use a PiicoDev Button to control the flash-rate of RPi Pico's onboard LED
from machine import Pin
from PiicoDev_Switch import PiicoDev_Switch # Switch may be used for other types of PiicoDev Switch devices
from PiicoDev_Unified import sleep_ms
 
button = PiicoDev_Switch()   # Initialise the module
led = Pin('LED', Pin.OUT)    # Initialise the onboard LED

index = 0
delays = [100, 200, 500, 1000] # a pool of delay values

while True:
    if button.was_pressed:          # change the flash rate by
        index += 1                  # incrementing the index
        index = index % len(delays) # wrap the index back to zero when it goes out of bounds
        print("index: ",index)
        
    led.toggle()
    delay = delays[index] # select the current delay duration
    sleep_ms(delay)

Remix: Run a program at the touch of a button!

Let's use the PiicoDev Button to trigger a system event. We can use the subprocess module to execute commands like we would in a terminal. This example will launch a new instance of the File Manager every time the button is pressed. The run() command accepts commands as a list, with the first item being the command (pcmanfm), and following items being the arguments (the directory to launch to manager at, /home/pi).

Read more about subprocess in the subprocess docs.

# Use a PiicoDev Button to launch a program on the Raspberry Pi
# This can be used to launch any program or run a script.

from PiicoDev_Switch import PiicoDev_Switch
from PiicoDev_Unified import sleep_ms
import subprocess # subprocess is used for executing shell commands
 
button = PiicoDev_Switch()   # Initialise the module

while True:
    if button.was_pressed: # execute a command (open the File Manager at the user's home directory)
        p = subprocess.run(["pcmanfm", "/home/pi"])
    sleep_ms(100)

It should be noted this example assumes the current user is called pi. If you're using a different username, you'll have to change this directory as appropriate.

Remix: Scroll through some images.

Let's control something real now! This remix flashes the Pico's onboard LED. Pressing the button selects a new flash rate (from a list of delays). As we click the button the flashing becomes slower, until we hit the end of the list and wrap back to the start. This is a practical use for the .was_pressed property - even when a delay is quite long, the button press is still captured.

# Use a PiicoDev Button to scroll images on the micro:bit display
from microbit import display, Image
from PiicoDev_Switch import PiicoDev_Switch
from PiicoDev_Unified import sleep_ms
 
button = PiicoDev_Switch()   # Initialise the module

index = 0
images = [Image.HEART, Image.HAPPY, Image.SAD] # a pool of images to display

while True:
    if button.was_pressed:          # change the image by
        index += 1                  # incrementing the index
        if index >= len(images):    # wrap the index back to zero when it goes out of bounds
            index=0
        print("index: ",index)
        
    display.show( images[index] )   # Show the selected image
    
    sleep_ms(100)


Other Examples

The .press_count property is a counter that returns the number of button presses since the switch was last read. This is useful when polling the switch slowly, where multiple press events may occur between polls.

The following example will keep a running total of button-presses, even though the update rate is very slow (3 seconds). Try clicking the button rapidly and you ought to see the count remains accurate, even with a slow polling rate.

# Get an accurate press-count, even when the sample-rate is very slow (3 seconds)
# Try clicking the button multiple times between updates. You ought to see that
# every click is accounted for!

from PiicoDev_Switch import PiicoDev_Switch # Switch may be used for other types of PiicoDev Switch devices
from PiicoDev_Unified import sleep_ms
 
button = PiicoDev_Switch()   # Initialise the module

total_presses = 0

while True:
    total_presses += button.press_count # press_count resets to zero after being read
    print('Total Presses:', total_presses)
    sleep_ms(3000)

The power-LED on the PiicoDev Button turns on every time power is applied. However, you can still take control of this LED using the .led property. The following example toggles the LED every time the button is clicked. The .led property is both read/write capable: you can use it to read the current state of the LED, and set the desired state.

# Toggle the Button's "Power" LED on every click
from PiicoDev_Switch import PiicoDev_Switch
from PiicoDev_Unified import sleep_ms
 
button = PiicoDev_Switch()

while True:
    if button.was_pressed:
        button.led = not button.led
    sleep_ms(100)

It is possible to connect to more than one PiicoDev Button at the same time. The following example uses two PiicoDev Buttons to create a simple controller. One Button increments a counter while the other decrements. The incrementing-Button is left in the default state (ID switches OFF), and the decrementing-Button will have its ID #1 switch set to ON. Referring to the example code, we can see each Button is initialised with an id argument which encodes the positions of the ID switches (1=ON, 0=OFF). This example also makes use of .press_count to ensure that no clicks are ever missed.

# Use multiple PiicoDev Buttons to increment / decrement a counter

from PiicoDev_Switch import PiicoDev_Switch
from PiicoDev_Unified import sleep_ms
 
button_up   = PiicoDev_Switch(id=[0,0,0,0])   # Initialise the 1st module
button_down = PiicoDev_Switch(id=[1,0,0,0])   # Initialise the 2nd module

count = 0

while True:
    count +=   button_up.press_count
    count -= button_down.press_count
    
    print("Count",count)
    
    sleep_ms(1000)

The following table describes the actual I2C addresses that are selected:

The PiicoDev Button can detect double presses too, though a single-press will still be detected for the first press. Detecting double presses is very similar to detecting single presses - use the .was_double_pressed attribute.

The window for a double press (milliseconds) is tunable with the double_press_duration property.

from PiicoDev_Switch import PiicoDev_Switch
from PiicoDev_Unified import sleep_ms
button = PiicoDev_Switch(double_press_duration=400)
while True:
    print('Double Press:', button.was_double_pressed)
    sleep_ms(1000)

The PiicoDev Button can detect double presses too, though a single-press will still be detected for the first press. Detecting double presses is very similar to detecting single presses - use the .was_double_pressed attribute.

Up to 16 PiicoDev Buttons may share an I2C bus by selecting unique addresses with the ID switch (see the Multiple Buttons example). For advanced users, the device I2C address may be set explicitly using the .setI2Caddr() method which accepts the new desired address. This allows setting any address in the valid I2C address space (0x08-0x77). The address update is immediate and the device will only respond to the new address for subsequent commands. To use a user-defined software address, the Button must have all ID switches OFF.

# Set a new (software) address
from PiicoDev_Switch import PiicoDev_Switch
from PiicoDev_Unified import sleep_ms
 
button = PiicoDev_Switch()   # Initialise the module

new_address = 0x70

print("Setting new address to {}".format(new_address))
button.setI2Caddr(new_address)

To reset the device to defaults, either use the .setI2Caddr() method to set the address back to 0x42 or perform the factory reset procedure:

  • Remove power
  • Select a hardware address by setting any of the ID switches ON
  • Apply power
  • Remove power

Now, the device will respond to address 0x42 again when all ID switches are OFF.

The PiicoDev Button features internal debouncing using an EMA filter which is pretuned by default to provide good results. The state of the button is polled rapidly, which updates the value of the moving average - the average increases when the button is closed, and decays when the button is open. A press is valid when the average is greater than some threshold.

The EMA tuning parameter can be read/write with the .ema_parameter property which accepts 0-255 and maps to 0->1.0. The polling period (milliseconds) can be read/write with the .ema_period property.

from PiicoDev_Switch import PiicoDev_Switch
from PiicoDev_Unified import sleep_ms
 
button = PiicoDev_Switch(ema_parameter=73, ema_period=30)   # Initialise the module with 30ms poll period and EMA parameter = 73.0/255.0 => 0.286

Conclusion

There's more than meets the eye to the PiicoDev Button - a simple input device, yes - but capable and feature-rich. We can read the button status in a couple of ways, measure counts and connect many buttons together for more complex projects. The button really is the perfect, intuitive input device.

If you make something cool using the PiicoDev Button we'd love to see it! Leave a comment below to show us your projects or if you have any questions about this material.

- Happy Making!

Have a question? Ask the Author of this guide today!

Please enter minimum 20 characters

Your comment will be posted (automatically) on our Support Forum which is publicly accessible. Don't enter private information, such as your phone number.

Expect a quick reply during business hours, many of us check-in over the weekend as well.

Comments


Loading...
Feedback

Please continue if you would like to leave feedback for any of these topics:

  • Website features/issues
  • Content errors/improvements
  • Missing products/categories
  • Product assignments to categories
  • Search results relevance

For all other inquiries (orders status, stock levels, etc), please contact our support team for quick assistance.

Note: click continue and a draft email will be opened to edit. If you don't have an email client on your device, then send a message via the chat icon on the bottom left of our website.

Makers love reviews as much as you do, please follow this link to review the products you have purchased.