Pi Pico PIO Poly Tone Step Sequencer – Part 2

In this project I’ve added some basic IO to the Pi Pico PIO Poly Tone Step Sequencer.

Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

These are the key tutorials for the main concepts used in this project:

If you are new to microcontrollers, see the Getting Started pages.

Parts list

The Circuit


Once again I’m using my RGB Keypad and my Tone Pack.  here you can see a potentiometer connected to 3V, GND and ADC2, and a button switch across GP6 and GND. If you are not using my “pack” but hooking up to your Pi Pico itself, you can connect these direct.

2021-03-14 17.52.47

The Code

This is an addition to the code in the Pi Pico PIO Poly Tone Step Sequencer project. I’ve added a new routine “updateIO” to scan the additional GPIO and update various aspects of the sequencer as required.  In this case I’m using the potentiometer to set the tempo and the button to reset the grid back to playing no notes.

Before anything else can happen the IO pins must be initialised.  The following sets up two buttons and three potentiometers on the pins as used by my “tone pack”.

button1 = machine.Pin(6, machine.Pin.IN, machine.Pin.PULL_UP)
button2 = machine.Pin(7, machine.Pin.IN, machine.Pin.PULL_UP)
pot1 = machine.ADC (machine.Pin(26))
pot2 = machine.ADC (machine.Pin(27))
pot3 = machine.ADC (machine.Pin(28))
btn1val = True
btn2val = True

btn1val and btn2val can be used to detect a HIGH to LOW transition on the buttons – note that they are in PULL_UP mode, so normally will be reading True until pressed, when they will switch to False.

The updateIO routing reads the two IO values of interest and then actions them.

def ioUpdate():
    global TEMPO, btn1val
    TEMPO = (pot3.read_u16()>>6)+30;
    if TEMPO > 800:
        TEMPO = 800
    if TEMPO < 60:
        TEMPO = 60

    btn1 = button1.value()
    if (btn1val == True) and (btn1 == False):
        for key in range (NUM_PADS):
            noteGrid[key] = 0
    btn1val = btn1

The potentiometer reading is scaled from a 0 to 65535 (u16) value into a range between 30 and a few hundred and stored in the TEMPO global variable which is used in the main scanning routine later on to set the timings of the sequencer.

On a button press the note grid is initialised back to 0s, after having send “off” messages for an already sounding notes.

All that is left is to make sure the updateIO() function is called as part of the main “loop” routing in the code.

Find it on GitHub here.

Closing Thoughts

Handling IO in MicroPython is relatively straight forward so now that the basics are in place, we can start to experiment with other controllable parameters to change other aspects of the sound generation.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s