Featured image of post Pi Pico Random Looping Sequencer

Pi Pico Random Looping Sequencer

In development

This module is licensed under the MIT License

Module GitHub link

A random control voltage and trigger/gate sequencer Eurorack module

This module is a random CV and trigger/gate sequencer with a built in quantizer with predefined scales. An upgrade from my first random sequencer module.

Built with the Pi Pico. Coded in Python.

Demo

Prototype plugged In

Prototype Front

Back Side Back Back

Inspiration

I’ve taken some inspiration from the popular random module called the Turing Machine. Also, I’ve taken some code from the EuroPi, specifically the analog reader for the CV inputs and knobs.

TODO

  • Prototype
  • Schematic
  • CV input code
  • Random triggers
  • A better menu system
  • Better logic, moving the rotary encoder while its running will make the sequencer glitch

Features

Basic features

  • 128x64 oled screen
  • Rotary Encoder
  • A random cv sequencer
  • A random trigger/gate sequencer
  • Trigger length based on clock input
  • Output cv quantized based on scale chosen
  • 4 Analog parameter knobs with inputs

IO

  • 4 Analog inputs with attenuation and offset knobs (serving as control knobs if no input is connected)
  • Clock/trigger input
  • Digital input (unused)
  • Trigger output
  • vOct output
  • Scale/Mode
  • CV Probability
  • Trigger Probability
  • Trigger length (0 to 100% of clock)
  • Number of steps (2 to 16 (You can modify the max steps in the code))
  • Octaves (the number of octaves it should range from (1 to 5))
  • Starting note (note 1 to 12)
  • CV sequence erase toggle
  • Trigger sequence erase toggle
  • Test CV scale/sequence toggle (it will run through the current scale chosen ascending)
  • Tuning CV scale/sequence toggle (to help you tune your vco)

How it randomizes

Every high clock pulse, the current step will be changed randomly depending on the probability.

The algorithm simply does the following:

It selects a random note from the current scale chosen. Then it decides if the current step will be overwritten by the random note based on the probability.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def randomly_change_current_step_cv() -> None:
    # get random index of scale chosen
    random_scale_index = random.randint(0, len(current_12bit_scale) - 1)
    # set cv from scale list
    if generate_boolean_with_probability(cv_probability_of_change):
        # print("change cv")
        cv_sequence[current_step] = current_12bit_scale[random_scale_index]


def randomly_change_step_trigger() -> None:
    global trigger_sequence
    trig_on_or_off = random.randint(0, 1)
    if generate_boolean_with_probability(trigger_probability_of_change):
        trigger_sequence[current_step] = trig_on_or_off


def generate_boolean_with_probability(probability: float) -> bool:
    """
    Returns True or False based on the given probability.

    :param probability: The probability of returning True, in the range [0, 100].
    :type probability: float
    :return: True with probability `probability`, False otherwise.
    :rtype: bool
    """
    if not 0 <= probability <= 100:
        raise ValueError("Probability must be between 0 and 100")

    return random.random() * 100 <= probability

Schematic

I used a clone of the Pi Pico (Pi Pico Lite Black 16MB).

If you don’t have it available, you can use an original Pi Pico. You just have to change some pin assignments. The clone I found has an additional ADC pin (GP29). You can ommit the fourth cv input, you just have to adjust the code.

Schematic

Programming instructions

Starting fresh (Preparing the pico for the firmware)

  1. Download flash_nuke.uf2 from Adafruit.
  2. While holding down the BOOTSEL button on the Pi Pico, connect the usb cable to your computer.
  3. It should be visible as a USB drive as RPI-RP2. Copy the downloaded flash_nuke.uf2 into it. This will wipe any firmware in the Pico. Be sure to backup any files in your Pico.

Uploading main.py and lib

You can use Thonny IDE or VSCode with the Micropico plugin.

Development instructions

If you need to program the pico while it is connected to eurorack power, you can.

  • Turn on the module (eurorack power)
  • Plug in the usb to the pico (yes it won’t damage the pico)

Developing with VSCode

Use VSCode with the plugin MicroPico

Use the commands while developing:

  • Delete all files from pico
  • Upload project files to pico
  • Run

I cobbled up some code to help me make a menu system for this project. Its still in the early stages of development. I still need to clean it up. You can take a look at my menu.py code in the GitHub repo for this project.

How the menu system works

SETTING SUBMENUS:

First, you would have to create instances of submenus in your main program. Then you can put those instances in a list called submenu_list. Lastly, call the set_submenus().

MAKING THE DISPLAY AND ENCODER DO ITS JOB:

Call loop_main_menu(update_main_program_values_callback=[callback_function]) in a while True loop. The callback function is for updating the variables used in your main program. It is discussed more in detail below.

GETTING DATA FROM THE MENU SYSTEM INTO YOUR MAIN PROGRAM:

This library only handles the “front end” of your main python program, handling user interaction with the display and the rotary encoder. It is designed to hold data but you should have variables in your main program so you can access the data easily. For example, you need to get data from a submenu: you would need to call get_submenu_list() in order to update the main program’s variables. To help you update your main program’s variables from the submenus, you will need to provide a callback function in your main program (example: update_values()). This callback function will only be called when a submenu’s selected value has been changed (user pressed the encoder button).

MCP 4725 lookup table

The optimal lowest voltage should not be 0. The MCP4725 cannot output exactly 0v for some reason. Your tuning will not be exact when the value is 0.

note no12 bit valuevoltage outputkeyboard note (example only)
000C
1680.0830078125C#
21360.166015625D
32040.2490234375D#
42720.33203125E
53400.4150390625F
64080.498046875F#
74760.5810546875G
85440.6640625G#
96120.7470703125A
106800.830078125A#
117480.9130859375B
128160.99609375C
138841.079101563C#
149521.162109375D
1510201.245117188D#
1610881.328125E
1711561.411132813F
1812241.494140625F#
1912921.577148438G
2013601.66015625G#
2114281.743164063A
2214961.826171875A#
2315641.909179688B
2416321.9921875C
2517002.075195313C#
2617682.158203125D
2718362.241210938D#
2819042.32421875E
2919722.407226563F
3020402.490234375F#
3121082.573242188G
3221762.65625G#
3322442.739257813A
3423122.822265625A#
3523802.905273438B
3624482.98828125C
3725163.071289063C#
3825843.154296875D
3926523.237304688D#
4027203.3203125E
4127883.403320313F
4228563.486328125F#
4329243.569335938G
4429923.65234375G#
4530603.735351563A
4631283.818359375A#
4731963.901367188B
4832643.984375C
4933324.067382813C#
5034004.150390625D
5134684.233398438D#
5235364.31640625E
5336044.399414063F
5436724.482421875F#
5537404.565429688G
5638084.6484375G#
5738764.731445313A
5839444.814453125A#
5940124.897460938B
6040804.98046875C
All rights reserved.