# Circle of Fifths Euclidean Synth with synthio and CircuitPython

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/121/443/medium800/led_matrices_edited_P1400786.jpg?1685588037)

This synth celebrates all things circular: the circle of fifths, Euclidean rhythms, and rotary encoders. Four synth voices play random notes in a triad to the beat of a determined Euclidean rhythm animated on the 8x8 matrix. You can scroll through the [circle of fifths](https://en.wikipedia.org/wiki/Circle_of_fifths) on each synth voice to change the triad for easy modulation between keys.

https://youtube.com/shorts/Exk-TGRGq00

The code is written in CircuitPython with the [synthio module](https://docs.circuitpython.org/en/latest/shared-bindings/synthio/index.html) and runs on a Feather RP2040. An I2S amp outputs audio to a speaker and the rotary encoders, alphanumeric displays, and 8x8 matrix all connect to the Feather over I2C with STEMMA QT cables.

The synth has multiple functions that can be selected using the top encoder:

- **Play** - the synth plays and you can adjust the chords for each of the four synth voices
- **Euclidean** - adjust the Euclidean rhythm for each voice
- **BPM** - raise or lower the Beats Per Minute of the sequence (speed)
- **Beat** - change the beat division of the sequence from a range of 1/16th notes to whole notes
- **Wave** - change the waveform for each synth voice to a square wave, sine wave, sawtooth wave, or noise
- **ADSR** - adjust the attack, decay, sustain, and release for each synth voice
- **Ring** - adjust the percentage of ring modulation applied to each synth voice
- **LFO** - adjust the rate of the LFO being used for ring modulation
- **Volume** - control the overall volume of the synth

![led_matrices_menus.gif](https://cdn-learn.adafruit.com/assets/assets/000/121/318/medium640thumb/led_matrices_menus.jpg?1685479034)

## What are Euclidean Rhythms?

[Euclidean rhythms](https://en.wikipedia.org/wiki/Euclidean_rhythm) are derived from an algorithm that determines how to spread the number of steps over a number of beats as equally as possible. The interplay between different time signatures can create complex and interesting polyrhythms, even something as simple as one person clapping in 4/4 time while another person claps in 6/8 can sound interesting!

Euclidean algorithms have become popular as an option in Eurorack modules that generate rhythms. C code for this algorithm was [originally referenced in Godfried Toussaint's paper](http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf)&nbsp;and Brian House ported the algorithm to [Python in this repository](https://github.com/brianhouse/bjorklund). You'll see this function in the CircuitPython code.&nbsp;

The Euclidean rhythm for each synth voice is controlled with the four lower encoders in Euclidean mode. The 8x8 matrix displays the total number of steps in each rhythm. As the rhythms advance, a pixel on the matrix turns red when a note plays to denote the place in the sequence.

![led_matrices_euc_edits.gif](https://cdn-learn.adafruit.com/assets/assets/000/121/322/medium640thumb/led_matrices_euc_edits.jpg?1685479316)

## Parts
Featured
### Adafruit Feather RP2040

[Adafruit Feather RP2040](https://www.adafruit.com/product/4884)
A new chip means a new Feather, and the Raspberry Pi RP2040 is no exception. When we saw this chip we thought "this chip is going to be awesome when we give it the Feather Treatment" and so we did! This Feather features the&nbsp; **RP2040** , and all niceties you know and...

In Stock
[Buy Now](https://www.adafruit.com/product/4884)
[Related Guides to the Product](https://learn.adafruit.com/products/4884/guides)
![Angled shot of black rectangular microcontroller "Feather RP2040"](https://cdn-shop.adafruit.com/640x480/4884-04.jpg)

Featured
### Adafruit I2S 3W Class D Amplifier Breakout - MAX98357A

[Adafruit I2S 3W Class D Amplifier Breakout - MAX98357A](https://www.adafruit.com/product/3006)
Listen to this good news - we now have an all in one digital audio amp breakout board that works incredibly well with the&nbsp;[Raspberry Pi](https://www.adafruit.com/category/105)! If you're looking for an easy and low cost way to get your digital sound files...

In Stock
[Buy Now](https://www.adafruit.com/product/3006)
[Related Guides to the Product](https://learn.adafruit.com/products/3006/guides)
![Angled shot of blue, square-shaped, amplifier breakout with a pre-soldered terminal block.](https://cdn-shop.adafruit.com/640x480/3006-04.jpg)

Featured
### Mono Enclosed Speaker - 3W 4 Ohm

[Mono Enclosed Speaker - 3W 4 Ohm](https://www.adafruit.com/product/3351)
Listen up! This 2.8" x 1.2" speaker&nbsp;is&nbsp;a&nbsp;great addition to any audio project where you need 4 ohm impedance and 3W or less of power. We particularly like this&nbsp;speaker&nbsp;as it is&nbsp;small and enclosed for good audio volume and quality. It has a handy JST 2PH...

In Stock
[Buy Now](https://www.adafruit.com/product/3351)
[Related Guides to the Product](https://learn.adafruit.com/products/3351/guides)
![Enclosed Speaker with JST cable](https://cdn-shop.adafruit.com/640x480/3351-01.jpg)

Featured
### Adafruit ANO Rotary Navigation Encoder to I2C Stemma QT Adapter

[Adafruit ANO Rotary Navigation Encoder to I2C Stemma QT Adapter](https://www.adafruit.com/product/5740)
The ANO rotary encoder wheel is a funky user interface element, reminiscent of the [original clicking scroll wheel interface on the first iPods](https://gizmodo.com/a-visual-history-of-the-ipod-click-wheel-r-i-p-1632640054). It's a nifty kit, but the pin-out is a little odd...

In Stock
[Buy Now](https://www.adafruit.com/product/5740)
[Related Guides to the Product](https://learn.adafruit.com/products/5740/guides)
![Overhead video of a blue-manicured finger manipulating a rotary encoder connected to a 4-digit LED segment display. ](https://cdn-shop.adafruit.com/product-videos/640x480/5740-04.jpg)

Featured
### ANO Directional Navigation and Scroll Wheel Rotary Encoder

[ANO Directional Navigation and Scroll Wheel Rotary Encoder](https://www.adafruit.com/product/5001)
This funky user interface element is reminiscent of the [original clicking scroll wheel interface on the first iPods](https://gizmodo.com/a-visual-history-of-the-ipod-click-wheel-r-i-p-1632640054). It's a fancy mechanical kit but has an intuitiveness that is hard to argue with -...

Out of Stock
[Buy Now](https://www.adafruit.com/product/5001)
[Related Guides to the Product](https://learn.adafruit.com/products/5001/guides)
![Angled shot of ANM rotary encoder.](https://cdn-shop.adafruit.com/640x480/5001-00.jpg)

Featured
### Quad Alphanumeric Display - Red 0.54" Digits w/ I2C Backpack

[Quad Alphanumeric Display - Red 0.54" Digits w/ I2C Backpack](https://www.adafruit.com/product/1911)
Display, elegantly, 012345678 or 9! Gaze, hypnotized, at ABCDEFGHIJKLM - well it can display the whole alphabet. You get the point. This is a nice, bright alphanumeric display that shows letters and numbers in a beautiful red hue. It's super bright and designed for viewing from distances...

In Stock
[Buy Now](https://www.adafruit.com/product/1911)
[Related Guides to the Product](https://learn.adafruit.com/products/1911/guides)
![Overhead video of an assembled 14-segment LED backpack, emitting the follow text in red LEDS: "AdaFruit 14-Segment Backpack"](https://cdn-shop.adafruit.com/product-videos/640x480/1911-04.jpg)

### Quad Alphanumeric Display - Yellow 0.54" Digits w/ I2C Backpack

[Quad Alphanumeric Display - Yellow 0.54" Digits w/ I2C Backpack](https://www.adafruit.com/product/2158)
Display, elegantly, 012345678 or 9! Gaze, hypnotized, at ABCDEFGHIJKLM - well it can display the whole alphabet. You get the point. This is a nice, bright alphanumeric display that shows letters and numbers in a beautiful yellow hue. It's super bright and designed for viewing from...

In Stock
[Buy Now](https://www.adafruit.com/product/2158)
[Related Guides to the Product](https://learn.adafruit.com/products/2158/guides)
![Overhead shot of an assembled 14-segment LED backpack, emitting the follow text in yellow LEDS: "AdaFruit 14-Segment Backpack"](https://cdn-shop.adafruit.com/product-videos/640x480/2158-09.jpg)

### Quad Alphanumeric Display - Pure Green 0.54" Digits w/ Backpack

[Quad Alphanumeric Display - Pure Green 0.54" Digits w/ Backpack](https://www.adafruit.com/product/2160)
Display, elegantly, 012345678 or 9! Gaze, hypnotized, at ABCDEFGHIJKLM - well it can display the whole alphabet. You get the point. This is a nice, bright alphanumeric display that shows letters and numbers in a beautiful pure green hue. It's super bright and designed for viewing from...

In Stock
[Buy Now](https://www.adafruit.com/product/2160)
[Related Guides to the Product](https://learn.adafruit.com/products/2160/guides)
![Overhead shot of an assembled 14-segment LED backpack, emitting the follow text in green LEDS: "AdaFruit 14-Segment Backpack"](https://cdn-shop.adafruit.com/product-videos/640x480/2160-07.jpg)

### Quad Alphanumeric Display - Blue 0.54" Digits w/ I2C Backpack

[Quad Alphanumeric Display - Blue 0.54" Digits w/ I2C Backpack](https://www.adafruit.com/product/1912)
Display, elegantly, 012345678 or 9! Gaze, hypnotized, at ABCDEFGHIJKLM - well it can display the whole alphabet. You get the point. This is a nice, bright alphanumeric display that shows letters and numbers in a beautiful blue hue. It's super bright and designed for viewing from distances...

In Stock
[Buy Now](https://www.adafruit.com/product/1912)
[Related Guides to the Product](https://learn.adafruit.com/products/1912/guides)
![Overhead video of an assembled 14-segment LED backpack, emitting the follow text in blue LEDS: "AdaFruit 14-Segment Backpack"](https://cdn-shop.adafruit.com/product-videos/640x480/1912-06.jpg)

### Quad Alphanumeric Display - White 0.54" Digits w/ I2C Backpack

[Quad Alphanumeric Display - White 0.54" Digits w/ I2C Backpack](https://www.adafruit.com/product/2157)
Display, elegantly, 012345678 or 9! Gaze, hypnotized, at ABCDEFGHIJKLM - well it can display the whole alphabet. You get the point. This is a nice, bright alphanumeric display that shows letters and numbers in a beautiful white hue. It's super bright and designed for viewing from distances...

In Stock
[Buy Now](https://www.adafruit.com/product/2157)
[Related Guides to the Product](https://learn.adafruit.com/products/2157/guides)
![Overhead shot of an assembled 14-segment LED backpack, emitting the follow text in white LEDS: "AdaFruit 14-Segment Backpack"](https://cdn-shop.adafruit.com/product-videos/640x480/2157-05.jpg)

### Adafruit Bicolor LED Square Pixel Matrix with I2C Backpack

[Adafruit Bicolor LED Square Pixel Matrix with I2C Backpack](https://www.adafruit.com/product/902)
What's better than a single LED? Lots of LEDs! A fun way to make a small colorful display is to use a [1.2" Bi-color 8x8 LED Matrix](http://www.adafruit.com/products/458). Matrices like these are 'multiplexed' - so to control all the 128 LEDs you need 24 pins....

Out of Stock
[Buy Now](https://www.adafruit.com/product/902)
[Related Guides to the Product](https://learn.adafruit.com/products/902/guides)
![Top-down video of an 8x8 LED matrix wired up to a small, square-shaped microcontroller. The LED matrix displays scrolling text and emoticon faces.](https://cdn-shop.adafruit.com/product-videos/640x480/902-06.jpg)

### STEMMA QT / Qwiic JST SH 4-pin Cable - 100mm Long

quantity: 4
[STEMMA QT / Qwiic JST SH 4-pin Cable - 100mm Long](https://www.adafruit.com/product/4210)
This 4-wire cable is a little over 100mm / 4" long and fitted with JST-SH female 4-pin connectors on both ends. Compared with the chunkier JST-PH these are 1mm pitch instead of 2mm, but still have a nice latching feel, while being easy to insert and remove.

<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4210)
[Related Guides to the Product](https://learn.adafruit.com/products/4210/guides)
![Angled shot of STEMMA QT / Qwiic JST SH 4-pin Cable.](https://cdn-shop.adafruit.com/640x480/4210-00.jpg)

### STEMMA QT / Qwiic JST SH 4-Pin Cable - 50mm Long

quantity: 8
[STEMMA QT / Qwiic JST SH 4-Pin Cable - 50mm Long](https://www.adafruit.com/product/4399)
This 4-wire cable is&nbsp;50mm / 1.9" long and fitted with JST SH female 4-pin connectors on both ends. Compared with the chunkier JST PH these are 1mm pitch instead of 2mm, but still have a nice latching feel, while being easy to insert and remove.

<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4399)
[Related Guides to the Product](https://learn.adafruit.com/products/4399/guides)
![Angled of of JST SH 4-Pin Cable.](https://cdn-shop.adafruit.com/640x480/4399-00.jpg)

### USB C Round Panel Mount Extension Cable

[USB C Round Panel Mount Extension Cable](https://www.adafruit.com/product/4218)
If you need to add a panel-mount connection&nbsp;but don't have the time or ability to cut a custom oval or square hole, this **USB C&nbsp;Round Panel Mount Extension Cable&nbsp;** is the easiest and fastest way to panel-ify your project. The adapter can fit holes...

In Stock
[Buy Now](https://www.adafruit.com/product/4218)
[Related Guides to the Product](https://learn.adafruit.com/products/4218/guides)
![USB C Round Panel Mount Extension Cable - 30 cm](https://cdn-shop.adafruit.com/640x480/4218-03.jpg)

### Pink and Purple Woven USB A to USB C Cable - 1 meter long

[Pink and Purple Woven USB A to USB C Cable - 1 meter long](https://www.adafruit.com/product/5153)
This cable is not only super-fashionable, with a woven pink and purple Blinka-like pattern, it's also made for USB C for our modernized breakout boards, Feathers, and more.&nbsp;&nbsp;[If you want something just like it but for Micro B, we...](https://www.adafruit.com/product/4111)

Out of Stock
[Buy Now](https://www.adafruit.com/product/5153)
[Related Guides to the Product](https://learn.adafruit.com/products/5153/guides)
![Angled shot of coiled pink and purple USB cable with USB A and USB C connectors.](https://cdn-shop.adafruit.com/640x480/5153-02.jpg)

### Black Nylon Machine Screw and Stand-off Set – M2.5 Thread

[Black Nylon Machine Screw and Stand-off Set – M2.5 Thread](https://www.adafruit.com/product/3299)
Totaling 380 pieces, this **M2.5 Screw Set** &nbsp;is a must-have for your workstation.&nbsp;You'll have enough screws, nuts, and hex standoffs to fuel your maker tendencies&nbsp;for days on end! M2.5 size screws fit almost all of the Adafruit breakout/dev board mounting holes...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3299)
[Related Guides to the Product](https://learn.adafruit.com/products/3299/guides)
![Black Nylon Screw and Stand-off Set with M2.5 Threads, kit box](https://cdn-shop.adafruit.com/640x480/3299-00.jpg)

### Black Nylon Machine Screw and Stand-off Set – M3 Thread

[Black Nylon Machine Screw and Stand-off Set – M3 Thread](https://www.adafruit.com/product/4685)
Totaling **420 pieces** , this **M3 Screw Set** &nbsp;is a must-have for your workstation.&nbsp;You'll have enough screws, nuts, and hex standoffs to fuel your maker tendencies&nbsp;for days on end! M3 size screws fit a number of&nbsp;Adafruit breakout/dev board...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4685)
[Related Guides to the Product](https://learn.adafruit.com/products/4685/guides)
![Opened box showing many nylon screws](https://cdn-shop.adafruit.com/640x480/4685-01.jpg)

### Silicone Cover Stranded-Core Wire - 30AWG in Various Colors

[Silicone Cover Stranded-Core Wire - 30AWG in Various Colors](https://www.adafruit.com/product/2051)
Silicone-sheathing wire is super-flexible and soft, and its also strong! Able to handle up to 200°C and up to 600V, it will do when PVC covered wire wimps out. We like this wire for being extremely supple and flexible, so it is great for wearables or projects where the wire-harness has to...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2051)
[Related Guides to the Product](https://learn.adafruit.com/products/2051/guides)
![Silicone Cover Stranded-Core Wire - 30AWG in Various Colors laid out beside each other. ](https://cdn-shop.adafruit.com/640x480/2051-01.jpg)

# Circle of Fifths Euclidean Synth with synthio and CircuitPython

## Circuit Diagram

![](https://cdn-learn.adafruit.com/assets/assets/000/121/279/medium800/led_matrices_ano_encoder_synth_fritz_bb_cropped.jpg?1685374675)

Most of the wiring for this project is accomplished with STEMMA QT cables. The ANO rotary encoder breakouts, alphanumeric display breakouts and bicolor LED matrix all communicate over I2C and daisy chain together to attach to the Feather RP2040.

The Fritzing diagram has the I2C addresses for each breakout listed and the [Setting I2C Addresses](https://learn.adafruit.com/circle-of-fifths-euclidean-synth-with-synthio-and-circuitpython/setting-i2c-addresses) page in this guide walks through which jumpers need to be adjusted for each breakout.

The I2S amp does require some wiring and soldering though:

- **I2S amp LRC** to **Feather pin 11 (white wire)**
- **I2S amp BCLK** to **Feather pin 10 (yellow wire)**
- **I2S amp DIN** to **Feather pin 9 (blue wire)**
- **I2S amp GND** to **Feather GND (black wire)**
- **I2S amp VIN** to **Feather USB (red wire)**
- **I2S amp GAIN** to **I2S amp GND (green wire)**

The speaker is connected to the I2S amp speaker output terminal block.

- **Speaker negative** to **I2S amp - output (black wire)**
- **Speaker positive** to **I2S amp + output (red wire)**

# Circle of Fifths Euclidean Synth with synthio and CircuitPython

## 3D Printing

![](https://cdn-learn.adafruit.com/assets/assets/000/121/281/medium800thumb/led_matrices_crossCutCAD.jpg?1685375505)

The synth may be housed in a 3D printed enclosure described below. It consists of two parts: the case and the lid. The lid attaches to the case with M3 screws.

[STL Files on Printables](https://www.printables.com/model/495308-circle-of-fifths-euclidean-synth)
[circle_of_fifths_synth_stl_files.zip](https://cdn-learn.adafruit.com/assets/assets/000/121/455/original/circle_of_fifths_synth_stl_files.zip?1685555804)
The case benefits some supports for the speaker and USB-C mount cutouts. In your slicer, you can generate supports and adjust the **Support Overhang Angle** to **75.0** to limit the amount of supports generated.

![led_matrices_supportsCura.png](https://cdn-learn.adafruit.com/assets/assets/000/121/301/medium640/led_matrices_supportsCura.png?1685383612)

The lid has cutouts and mounting holes for the rotary encoders, alphanumeric displays and the bicolor LED matrix.

![led_matrices_edited_P1400700.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/415/medium640/led_matrices_edited_P1400700.jpg?1685543288)

The case has columns that act as supports for the lid that is otherwise only secured in the corners. There are also stand-offs to attach the Feather and I2S amp.

![led_matrices_edited_P1400699.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/416/medium640/led_matrices_edited_P1400699.jpg?1685543297)

# Circle of Fifths Euclidean Synth with synthio and CircuitPython

## Install CircuitPython

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** drive to iterate.

## CircuitPython Quickstart

Follow this step-by-step to quickly get CircuitPython running on your board.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_feather_rp2040/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/655/medium640/install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg?1618943202)

![](https://cdn-learn.adafruit.com/assets/assets/000/102/705/medium800/adafruit_products_FeatherRP_buttons_highlighted.jpg?1623167565)

To enter the bootloader, hold down the **BOOT/**** BOOTSEL button**(highlighted in red above), and while continuing to hold it (don't let go!), press and release the**reset button**(highlighted in red or blue above).&nbsp;**Continue to hold the BOOT/BOOTSEL button until the RPI-RP2 drive appears!**

If the drive does not appear, release all the buttons, and then repeat the process above.

You can also start with your board unplugged from USB, press and hold the BOOTSEL button (highlighted in red above), continue to hold it while plugging it into USB, and wait for the drive to appear before releasing the button.

A lot of people end up using charge-only USB cables and it is very frustrating! **Make sure you have a USB cable you know is good for data sync.**

You will see a new disk drive appear called **RPI-RP2**.

&nbsp;

Drag the **adafruit\_circuitpython\_etc.uf2** file to **RPI-RP2.**

![install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/656/medium640/install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg?1618943666)

![install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/657/medium640/install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg?1618943674)

The **RPI-RP2** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/658/medium640/install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg?1618943864)

## Safe Mode

You want to edit your **code.py** or modify the files on your **CIRCUITPY** drive, but find that you can't. Perhaps your board has gotten into a state where **CIRCUITPY** is read-only. You may have turned off the **CIRCUITPY** drive altogether. Whatever the reason, safe mode can help.

Safe mode in CircuitPython does not run any user code on startup, and disables auto-reload. This means a few things. First, safe mode _bypasses any code in_ **boot.py** (where you can set **CIRCUITPY** read-only or turn it off completely). Second, _it does not run the code in_ **code.py**. And finally, _it does not automatically soft-reload when data is written to the_ **CIRCUITPY** _drive_.

Therefore, whatever you may have done to put your board in a non-interactive state, safe mode gives you the opportunity to correct it without losing all of the data on the **CIRCUITPY** drive.

### Entering Safe Mode
To enter safe mode when using CircuitPython, plug in your board or hit reset (highlighted in red above). Immediately after the board starts up or resets, it waits 1000ms. On some boards, the onboard status LED (highlighted in green above) will blink yellow during that time. If you press reset during that 1000ms, the board will start up in safe mode. It can be difficult to react to the yellow LED, so you may want to think of it simply as a slow double click of the reset button. (Remember, a fast double click of reset enters the bootloader.)

### In Safe Mode

If you successfully enter safe mode on CircuitPython, the LED will intermittently blink yellow three times.

If you connect to the serial console, you'll find the following message.

```terminal
Auto-reload is off.
Running in safe mode! Not running saved code.

CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.

Press any key to enter the REPL. Use CTRL-D to reload.
```

You can now edit the contents of the **CIRCUITPY** drive. Remember, _your code will not run until you press the reset button, or unplug and plug in your board, to get out of safe mode._

## Flash Resetting UF2

If your board ever gets into a really _weird_ state and CIRCUITPY doesn't show up as a disk drive after installing CircuitPython, try loading this 'nuke' UF2 to RPI-RP2. which will do a 'deep clean' on your Flash Memory. **You will lose all the files on the board** , but at least you'll be able to revive it! After loading this UF2, follow the steps above to re-install CircuitPython.

[Download flash erasing "nuke" UF2](https://cdn-learn.adafruit.com/assets/assets/000/145/511/original/nuke_universal.uf2?1786537992)
# Circle of Fifths Euclidean Synth with synthio and CircuitPython

## Code the Synth

Once you've finished setting up your Feather RP2040 with CircuitPython, you can access the code and necessary libraries by downloading the Project Bundle.

To do this, click on the **Download Project Bundle** button in the window below. It will download as a zipped folder.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/ANO_Rotary_Encoder_Synth/code.py

## Upload the Code and Libraries to the Feather RP2040

After downloading the Project Bundle, plug your Feather RP2040 into the computer's USB port with a known good USB data+power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called **CIRCUITPY**. Unzip the folder and copy the following items to the Feather RP2040's **CIRCUITPY** drive.

- **lib** folder
- **code.py**

Your Feather RP2040 **CIRCUITPY** drive should look like this after copying the **lib** folder and the **code.py** file:

![CIRCUITPY](https://adafruit.github.io/Adafruit_Learning_System_Guides/ANO_Rotary_Encoder_Synth.png )

## How the CircuitPython Code Works

The code begins by creating some waveform and ADSR envelope objects. These objects are passed to `synthio.Note` objects. There are four `Note` objects and they will create four different voices.

The `Note`s are played by the `Synthesizer` object, which outputs through the `Mixer` object.

```python
SAMPLE_RATE = 44100
SAMPLE_SIZE = 256
VOLUME = 5000

# waveforms, envelopes and synth setup

square = np.concatenate((np.ones(SAMPLE_SIZE//2, dtype=np.int16)*VOLUME,np.ones(SAMPLE_SIZE//2,
                         dtype=np.int16)*-VOLUME))
sine = np.array(np.sin(np.linspace(0, 4*np.pi, SAMPLE_SIZE, endpoint=False)) * VOLUME,
                       dtype=np.int16)
saw = np.linspace(VOLUME, -VOLUME, num=SAMPLE_SIZE, dtype=np.int16)
noise = np.array([randint(-VOLUME, VOLUME) for i in range(SAMPLE_SIZE)], dtype=np.int16)

lfo = synthio.LFO(rate = .5, waveform = sine)

amp_env0 = synthio.Envelope(attack_time=0.1, decay_time = 0.1, release_time=0.1,
                           attack_level=1, sustain_level=0.05)
amp_env1 = synthio.Envelope(attack_time=0.05, decay_time = 0.1, release_time=0.1,
                           attack_level=1, sustain_level=0.05)

# synth plays the notes
synth = synthio.Synthesizer(sample_rate=SAMPLE_RATE)

# these are the notes
synth0 =  synthio.Note(frequency = 0.0, envelope=amp_env0, waveform=square, ring_frequency = 0,
                       ring_bend = lfo, ring_waveform = sine)
synth1 =  synthio.Note(frequency = 0.0, envelope=amp_env1, waveform=sine, ring_frequency = 0,
                       ring_bend = lfo, ring_waveform = sine)
synth2 =  synthio.Note(frequency = 0.0, envelope=amp_env0, waveform=square, ring_frequency = 0,
                       ring_bend = lfo, ring_waveform = sine)
synth3 =  synthio.Note(frequency = 0.0, envelope=amp_env1, waveform=sine, ring_frequency = 0,
                       ring_bend = lfo, ring_waveform = sine)

synths = [synth0, synth1, synth2, synth3]
wave_names = ["SQUR", "SINE", "SAW ", "NOIZ"]
waveforms = [square, sine, saw, noise]
synth0_wave = 0
synth1_wave = 1
synth2_wave = 0
synth3_wave = 1

# i2s amp setup
audio = audiobusio.I2SOut(bit_clock=board.D10, word_select=board.D11, data=board.D9)
mixer = audiomixer.Mixer(voice_count=4, sample_rate=SAMPLE_RATE, channel_count=1,
                         bits_per_sample=16, samples_signed=True, buffer_size=2048 )
audio.play(mixer)
vol_val = 2
mixer.voice[0].play(synth)
mixer.voice[0].level = 0.3
```

## Tones

Arrays of tones are created for triads. They are all I (tonic) chords in the circle of fifths.

```python
# these are the triads, all major
c_tones = [130.81, 164.81, 196.00]
g_tones = [196.00, 246.94, 293.66]
d_tones = [146.83, 185.00, 220.00]
a_tones = [220.00, 277.18, 329.63]
e_tones = [164.81, 207.65, 246.94]
b_tones = [246.94, 311.13, 369.99]
fsharp_tones = [185.00, 233.08, 277.18]
csharp_tones = [138.59, 174.61, 207.65]
aflat_tones = [207.65, 261.63, 311.13]
eflat_tones = [155.56, 196.00, 233.08]
bflat_tones = [233.08, 293.66, 349.23]
f_tones = [174.61, 220.00, 261.63]

# names for the alphanumeric displays
chord_names = ["Cmaj", "Gmaj", "Dmaj", "Amaj", "Emaj", "Bmaj",
               "F#ma", "C#ma", "Abma", "Ebma", "Bbma", "Fmaj"]
chords = [c_tones, g_tones, d_tones, a_tones, e_tones, b_tones, fsharp_tones, csharp_tones,
          aflat_tones, eflat_tones, bflat_tones, f_tones]
```

## I2C

Next are the I2C peripherals. There are five ANO rotary encoders, five alphanumeric displays and one 8x8 matrix.

```python
# i2c setup
i2c = board.I2C()
# the encoders
seesaw0 = seesaw.Seesaw(i2c, addr=0x49)
seesaw1 = seesaw.Seesaw(i2c, addr=0x4A)
seesaw2 = seesaw.Seesaw(i2c, addr=0x4B)
seesaw3 = seesaw.Seesaw(i2c, addr=0x4C)
menu_seesaw = seesaw.Seesaw(i2c, addr=0x4D)
# the alphanumeric displays
display0 = segments.Seg14x4(i2c, address=0x70)
display1 = segments.Seg14x4(i2c, address=0x71)
display2 = segments.Seg14x4(i2c, address=0x72)
display3 = segments.Seg14x4(i2c, address=0x73)
menu_display = segments.Seg14x4(i2c, address=0x74)
# the matrix
matrix0 = Matrix8x8x2(i2c, address=0x75)

seesaws = [seesaw0, seesaw1, seesaw2, seesaw3, menu_seesaw]
buttons0 = []
buttons1 = []
buttons2 = []
buttons3 = []
menu_buttons = []
button0_states = []
button1_states = []
button2_states = []
button3_states = []
menu_states = []
button0_names = ["Select", "Up", "Left", "Down", "Right"]

# setup the buttons on all of the encoders
for i in range(1, 6):
    seesaw0.pin_mode(i, seesaw0.INPUT_PULLUP)
    seesaw1.pin_mode(i, seesaw1.INPUT_PULLUP)
    seesaw2.pin_mode(i, seesaw2.INPUT_PULLUP)
    seesaw3.pin_mode(i, seesaw3.INPUT_PULLUP)
    menu_seesaw.pin_mode(i, menu_seesaw.INPUT_PULLUP)
    buttons0.append(digitalio.DigitalIO(seesaw0, i))
    buttons1.append(digitalio.DigitalIO(seesaw1, i))
    buttons2.append(digitalio.DigitalIO(seesaw2, i))
    buttons3.append(digitalio.DigitalIO(seesaw3, i))
    menu_buttons.append(digitalio.DigitalIO(menu_seesaw, i))
    button0_states.append(False)
    button1_states.append(False)
    button2_states.append(False)
    button3_states.append(False)
    menu_states.append(False)

# make all of the encoders
encoder0 = rotaryio.IncrementalEncoder(seesaw0)
last_position0 = 0
encoder1 = rotaryio.IncrementalEncoder(seesaw1)
last_position1 = 0
encoder2 = rotaryio.IncrementalEncoder(seesaw2)
last_position2 = 0
encoder3 = rotaryio.IncrementalEncoder(seesaw3)
last_position3 = 0
menu_enc = rotaryio.IncrementalEncoder(menu_seesaw)
last_menuPosition = 0
```

## Conjunction Function

There are two functions that are used in the loop. The first reads all of the selector encoder buttons to adjust the Euclidean rhythm parameters.

```python
def read_buttons(button_array, button_states, euc, e_step, e_pulse, the_step):
    for b in range(5):
        if not button_array[b].value and button_states[b] is False:
            button_states[b] = True
            if button0_names[b] == "Select":
                e_step = 8
                e_pulse = 4
                if the_step >= e_step:
                    the_step = 0
            elif button0_names[b] == "Up":
                if e_step > 16:
                    e_step = 16
                else:
                    e_step += 1
            elif button0_names[b] == "Down":
                if e_step < 1:
                    e_step = 1
                else:
                    e_step -= 1
                if the_step >= e_step:
                    the_step = 0
            elif button0_names[b] == "Left":
                e_pulse -= 1
                e_pulse = max(e_pulse, 1)
            else:
                e_pulse += 1
            e_pulse = min(e_pulse, e_step)
            euc = bjorklund(e_step, e_pulse)
        if button_array[b].value and button_states[b] is True:
            button_states[b] = False
            if button0_names[b] in ("Select", "Up", "Down"):
                matrix0.fill(matrix0.LED_OFF)
                draw_steps(euclid0_steps, 0)
                draw_steps(euclid1_steps, 2)
                draw_steps(euclid2_steps, 4)
                draw_steps(euclid3_steps, 6)
    return euc, e_step, e_pulse, the_step
```

The second actually plays the Euclidean rhythms with the passed in chord to the designated synth voice.

```python
def play_euclidean(this_synth, n, the_rhythm, rhythm_count, last_count, c, matrix_slot):
    if last_count <= 7:
        matrix0[matrix_slot, last_count] = matrix0.LED_GREEN
    else:
        c -= 1
        matrix0[matrix_slot + 1, (last_count - last_count) + c] = matrix0.LED_GREEN
        c += 1

    if the_rhythm[rhythm_count] == 1:
        this_synth.frequency = n[randint(0, 2)]
        synth.press(this_synth)
        if rhythm_count <= 7:
            matrix0[matrix_slot, rhythm_count] = matrix0.LED_RED
        else:
            matrix0[matrix_slot + 1, (rhythm_count - rhythm_count) + c] = matrix0.LED_RED
            c += 1
    else:
        synth.release(this_synth)
        if rhythm_count > 7:
            c += 1
    last_count = rhythm_count

    rhythm_count += 1
    if rhythm_count >= len(the_rhythm):
        rhythm_count = 0
    if rhythm_count == 1:
        c = 0
    return rhythm_count, last_count, c
```

## ADSR Prep

A few arrays and variables are prepared in order to affect the ADSR envelope for each synth voice. When a change is made to an envelope, a new envelope must be instantiated. These arrays allow you to store the previous ADSR values to pass to this new envelope. As a result, if you change the attack value, the previous decay, sustain and release values are retained and passed to the new envelope.

```python
# adsr mode
adsr_names = ["A", "D", "S", "R"]

synth_adsr_indexes = [0, 0, 0, 0]

adsr_properties = [0, 1, 4, 2]

adsr0_values = [amp_env0.attack_time, amp_env0.decay_time,
                amp_env0.sustain_level, amp_env0.release_time]
adsr1_values = [amp_env1.attack_time, amp_env1.decay_time,
                amp_env1.sustain_level, amp_env1.release_time]
adsr2_values = [amp_env0.attack_time, amp_env0.decay_time,
                amp_env0.sustain_level, amp_env0.release_time]
adsr3_values = [amp_env1.attack_time, amp_env1.decay_time,
                amp_env1.sustain_level, amp_env1.release_time]

all_adsr_values = [adsr0_values, adsr1_values, adsr2_values, adsr3_values]

adsr0_val = int(simpleio.map_range(amp_env0.attack_time, 0.0, 1.0, 0, 19))

adsr1_val = int(simpleio.map_range(amp_env0.decay_time, 0.0, 1.0, 0, 19))

adsr2_val = int(simpleio.map_range(amp_env0.sustain_level, 0.0, 1.0, 0, 19))

adsr3_val = int(simpleio.map_range(amp_env0.release_time, 0.0, 1.0, 0, 19))
```

## The Loop

The loop has four tasks happening: reading the rotary encoders, playing the Euclidean rhythms, updating the alphanumeric displays, and reading the encoder buttons.

The rotary encoders are read with a small delay. The menu encoder controls which mode is active. Each of the four other encoders' functionality changes depending on the mode.&nbsp;

```python
if ticks_diff(ticks_ms(), enc_clock) >= 100:
        position0 = encoder0.position
        position1 = encoder1.position
        position2 = encoder2.position
        position3 = encoder3.position
        menuPosition = menu_enc.position
        # menu changes mode
        if menuPosition != last_menuPosition:
            if menuPosition > last_menuPosition:
                mode_index = (mode_index + 1) % len(modes)
            else:
                mode_index = (mode_index - 1) % len(modes)
            if mode in ("EUC ", "ADSR"):
                clock_stretch = True
            if mode in ("PLAY", "BPM ", "BEAT", "WAVE") and clock_stretch:
                clock = ticks_ms()
                clock_stretch = False
            mode = modes[mode_index]
            menu_display.print(f"   {mode}")
            last_menuPosition = menuPosition
            
            ...
            
      if position1 != last_position1:
            if position1 > last_position1:
                if mode == "PLAY":
                    chord1_sel = (chord1_sel + 1) % len(chords)
                    display1.print(chord_names[chord1_sel])
                elif mode == "ADSR":
                    adsr1_val = (adsr1_val + 1) % 20
                    mapped_val = simpleio.map_range(adsr1_val, 0, 19, 0.0, 1.0)
                    all_adsr_values[1][synth_adsr_indexes[1]] = mapped_val
                    the_env = synthio.Envelope(attack_time=all_adsr_values[1][0],
                                               decay_time = all_adsr_values[1][1],
                                               release_time=all_adsr_values[1][3],
                                               attack_level=1, 
                                               sustain_level=all_adsr_values[1][2])
                    synth1.envelope = the_env
                elif mode == "WAVE":
                    synth1_wave = (synth1_wave + 1) % len(wave_names)
                    synth1.waveform = waveforms[synth1_wave]
                ...
```

No matter which mode, the synth plays on; using ticks to keep time. `play_states[]` keeps track of whether or not a synth voice is paused.

```python
# synth plays based on ticks timing
    if ticks_diff(ticks_ms(), clock) >= delay:
        if play_states[0] is True:
            r0, last_r0, c0 = play_euclidean(synth0, chords[chord0_sel],
                                             rhythm0, r0, last_r0, c0, 0)
        if play_states[1] is True:
            r1, last_r1, c1 = play_euclidean(synth1, chords[chord1_sel],
                                             rhythm1, r1, last_r1, c1, 2)
        if play_states[2] is True:
            r2, last_r2, c2 = play_euclidean(synth2, chords[chord2_sel],
                                             rhythm2, r2, last_r2, c2, 4)
        if play_states[3] is True:
            r3, last_r3, c3 = play_euclidean(synth3, chords[chord3_sel],
                                             rhythm3, r3, last_r3, c3, 6)
        clock = ticks_add(clock, delay)
```

Just like the rotary encoders, the buttons and alphanumeric displays have different functionality depending on the mode. The alphanumeric displays will update to show different values. For example, in Wave mode, the waveform for each voice is displayed. As the waveform is changed with the rotary encoder, the display updates.

```python
# in PLAY select button controls play/pause
    if mode == "PLAY":
        for i in range(4):
            if not select_buttons[i].value and select_states[i] is False:
                select_states[i] = True
                if play_states[i] is True:
                    synth.release(synths[i])
                    play_states[i] = False
                else:
                    play_states[i] = True
            if select_buttons[i].value and select_states[i] is True:
                select_states[i] = False
        display0.print(chord_names[chord0_sel])
        display1.print(chord_names[chord1_sel])
        display2.print(chord_names[chord2_sel])
        display3.print(chord_names[chord3_sel])
        
        ...
        
        # change waveform
    elif mode == "WAVE":
        display0.print(f"    {wave_names[synth0_wave]}")
        display1.print(f"    {wave_names[synth1_wave]}")
        display2.print(f"    {wave_names[synth2_wave]}")
        display3.print(f"    {wave_names[synth3_wave]}")
```

# Circle of Fifths Euclidean Synth with synthio and CircuitPython

## Setting I2C Addresses

This project uses multiple I2C breakouts. As a result, their addresses need to be adjusted by either soldering or cutting the address jumpers.

There are **five** ANO rotary encoder breakouts. These will be on addresses **0x49** - **0x4D**.

- **0x49** - default address, leave jumpers as-is
- **0x4A** - cut jumper **A0**
- **0x4B** - cut jumper **A1**
- **0x4C** - cut jumpers **A0** and **A1**
- **0x4D** - cut jumper **A2**

![led_matrices_edited_P1400598.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/284/medium640/led_matrices_edited_P1400598.jpg?1685380531)

There are **five** alphanumeric display breakouts. These will be on addresses **0x70** - **0x74**.

- **0x70** - default address, leave jumpers as-is
- **0x71** - solder jumper **A0**
- **0x72** - solder jumper **A1**
- **0x73** - solder jumpers **A0** and **A1**
- **0x74** - solder jumper **A2**

![led_matrices_edited_P1400590.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/282/medium640/led_matrices_edited_P1400590.jpg?1685380314)

The bicolor LED matrix is has the same default I2C address ( **0x70** ) as the alphanumeric displays. It will be set to **0x75** by soldering jumpers **A0** and **A2**.

![led_matrices_edited_P1400630.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/283/medium640/led_matrices_edited_P1400630.jpg?1685380513)

# Circle of Fifths Euclidean Synth with synthio and CircuitPython

## Wiring

![](https://cdn-learn.adafruit.com/assets/assets/000/121/300/medium800/led_matrices_edited_P1400680.jpg?1685382791)

Cut, splice, and tin five pieces of different colored wire (yellow, white, blue, red and black) that are approximately 3 inches in length. Cut, splice, and tin one piece of wire that is approximately 1 inch in length.

![led_matrices_edited_P1400642.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/294/medium640/led_matrices_edited_P1400642.jpg?1685382438)

Insert the 1 inch piece of wire into the **GND** pad on the I2S amp from the front. Then, insert the black piece of wire into the same **GND** pad from the back. Solder both pieces in place.&nbsp;

![led_matrices_edited_P1400644.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/295/medium640/led_matrices_edited_P1400644.jpg?1685382479)

Solder the other end of the 1 inch piece of wire into the **GAIN** pad on the I2S amp. This sets the gain to **12dB** since it is tied to **GND**.

![led_matrices_edited_P1400650.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/296/medium640/led_matrices_edited_P1400650.jpg?1685382520)

Solder the remaining four pieces of wire into the **LRC** , **BCLK** , **DIN** and **VIN** pads on the I2S amp.

![led_matrices_edited_P1400655.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/297/medium640/led_matrices_edited_P1400655.jpg?1685382617)

Solder the pieces of wire from the I2S amp to the Feather RP2040.

- **LRC** to **pin 11**
- **BCLK** to **pin 10**
- **DIN** to **pin 9**
- **GND** to **GND**
- **VIN** to **USB**

![led_matrices_edited_P1400658.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/298/medium640/led_matrices_edited_P1400658.jpg?1685382660)

Solder the terminal block to the speaker output on the I2S amp.

![led_matrices_edited_P1400672.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/299/medium640/led_matrices_edited_P1400672.jpg?1685382732)

# Circle of Fifths Euclidean Synth with synthio and CircuitPython

## STEMMA Wiring

![](https://cdn-learn.adafruit.com/assets/assets/000/121/285/medium800/led_matrices_edited_P1400606.jpg?1685380697)

Connect the ANO rotary encoders on addresses **0x49** - **0x4C** left to right with STEMMA QT cables.

![led_matrices_edited_P1400610.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/286/medium640/led_matrices_edited_P1400610.jpg?1685380705)

Plug the alphanumeric display on address **0x70** into the rotary encoder on **0x49** (farthest to the left).

![led_matrices_edited_P1400613.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/287/medium640/led_matrices_edited_P1400613.jpg?1685380747)

Plug in the alphanumeric displays on addresses **0x71** - **0x73** left to right into the alphanumeric display on address **0x70**.

![led_matrices_edited_P1400615.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/288/medium640/led_matrices_edited_P1400615.jpg?1685380797)

Plug in the alphanumeric display on address **0x74** into the alphanumeric display on address **0x73**.

![led_matrices_edited_P1400619.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/289/medium640/led_matrices_edited_P1400619.jpg?1685380858)

Plug in the rotary encoder on address **0x4D** into the alphanumeric display on address **0x74**. Then, plug in the bicolor LED matrix into the remaining port on the **0x4D** rotary encoder.

![led_matrices_edited_P1400621.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/290/medium640/led_matrices_edited_P1400621.jpg?1685380897)

That completes the STEMMA wiring.

![led_matrices_edited_P1400623.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/291/medium640/led_matrices_edited_P1400623.jpg?1685380999)

# Circle of Fifths Euclidean Synth with synthio and CircuitPython

## Assembly

![](https://cdn-learn.adafruit.com/assets/assets/000/121/417/medium800/led_matrices_edited_P1400707.jpg?1685543557)

## STEMMA Component Mounting
Attach the four rotary encoders with M2.5 screws and nuts to the cutouts at the bottom of the lid.

![led_matrices_edited_P1400711.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/418/medium640/led_matrices_edited_P1400711.jpg?1685544005)

Attach the four alphanumeric displays with M2 screws and nuts to the center cutouts in the lid.

![led_matrices_edited_P1400715.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/419/medium640/led_matrices_edited_P1400715.jpg?1685544044)

Attach the menu rotary encoder to the top encoder cutout on the lid with M2.5 screws and nuts. Attach the 8x8 matrix and menu alphanumeric display to the top cutouts on the lids with M2 screws and nuts.

![led_matrices_edited_P1400720.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/420/medium640/led_matrices_edited_P1400720.jpg?1685544071)

## Mount the Feather and Amp
Secure the Feather and I2S amp to the standoffs in the case with M2.5 screws.

![led_matrices_edited_P1400724.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/421/medium640/led_matrices_edited_P1400724.jpg?1685544429)

## Mount and Connect the Speaker
Cut and splice the speaker wires to prepare them for the I2S amp terminal block.

![led_matrices_edited_P1400731.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/423/medium640/led_matrices_edited_P1400731.jpg?1685544541)

Mount the speaker with M2.5 screws and nuts into the mounting hole in the back of the case.

![led_matrices_edited_P1400736.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/424/medium640/led_matrices_edited_P1400736.jpg?1685544656)

Secure the black speaker wire into the negative ( **-** ) terminal in the terminal block on the I2S amp. Secure the red speaker wire into the positive ( **+** ) terminal block on the I2S amp.

![led_matrices_edited_P1400741.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/425/medium640/led_matrices_edited_P1400741.jpg?1685544775)

## USB-C Extension
Insert and mount the USB-C extension into the mounting hole on the side of the case. Plug the cable into the USB-C port on the Feather.

![led_matrices_edited_P1400742.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/426/medium640/led_matrices_edited_P1400742.jpg?1685544981)

## Connect to the Feather
Plug a STEMMA QT cable into the STEMMA port on the Feather.

![led_matrices_edited_P1400745.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/428/medium640/led_matrices_edited_P1400745.jpg?1685545164)

Plug the other end of the Feather STEMMA QT cable into the open port on the lower right rotary encoder.

![led_matrices_edited_P1400749.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/430/medium640/led_matrices_edited_P1400749.jpg?1685545280)

## In Closing
Attach the lid to the case with M3 screws in the corner mounting holes.

![led_matrices_edited_P1400752.jpg](https://cdn-learn.adafruit.com/assets/assets/000/121/431/medium640/led_matrices_edited_P1400752.jpg?1685545419)

# Circle of Fifths Euclidean Synth with synthio and CircuitPython

## Making Beautiful Music

![](https://cdn-learn.adafruit.com/assets/assets/000/121/441/medium800/led_matrices_edited_P1400783.jpg?1685588105)

You can turn the encoder for each of the synth voices to change the chord being played. The chords are programmed in the order of the [circle of fifths](https://en.wikipedia.org/wiki/Circle_of_fifths). If you advance one by one, it will sound very natural since you will be modulating between the keys.

![led_matrices_chords.gif](https://cdn-learn.adafruit.com/assets/assets/000/121/319/medium640thumb/led_matrices_chords.jpg?1685479091)

https://youtu.be/k26zLJ7q8QE

You can change the BPM (the speed) and beat division in the menus. The beat can be divided into sixteenth notes, eighth notes, quarter notes, half notes or whole notes.

![led_matrices_bpm.gif](https://cdn-learn.adafruit.com/assets/assets/000/121/320/medium640thumb/led_matrices_bpm.jpg?1685479176)

There are four waveforms to choose from: square, sine, sawtooth or noise. Each synth voice can have its waveform changed.

![led_matrices_waves.gif](https://cdn-learn.adafruit.com/assets/assets/000/121/321/medium640thumb/led_matrices_waves.jpg?1685479241)


## Guide Products

### Adafruit Feather RP2040

[Adafruit Feather RP2040](https://www.adafruit.com/product/4884)
A new chip means a new Feather, and the Raspberry Pi RP2040 is no exception. When we saw this chip we thought "this chip is going to be awesome when we give it the Feather Treatment" and so we did! This Feather features the&nbsp; **RP2040** , and all niceties you know and...

In Stock
[Buy Now](https://www.adafruit.com/product/4884)
[Related Guides to the Product](https://learn.adafruit.com/products/4884/guides)
### Adafruit I2S 3W Class D Amplifier Breakout - MAX98357A

[Adafruit I2S 3W Class D Amplifier Breakout - MAX98357A](https://www.adafruit.com/product/3006)
Listen to this good news - we now have an all in one digital audio amp breakout board that works incredibly well with the&nbsp;[Raspberry Pi](https://www.adafruit.com/category/105)! If you're looking for an easy and low cost way to get your digital sound files...

In Stock
[Buy Now](https://www.adafruit.com/product/3006)
[Related Guides to the Product](https://learn.adafruit.com/products/3006/guides)
### Mono Enclosed Speaker - 3W 4 Ohm

[Mono Enclosed Speaker - 3W 4 Ohm](https://www.adafruit.com/product/3351)
Listen up! This 2.8" x 1.2" speaker&nbsp;is&nbsp;a&nbsp;great addition to any audio project where you need 4 ohm impedance and 3W or less of power. We particularly like this&nbsp;speaker&nbsp;as it is&nbsp;small and enclosed for good audio volume and quality. It has a handy JST 2PH...

In Stock
[Buy Now](https://www.adafruit.com/product/3351)
[Related Guides to the Product](https://learn.adafruit.com/products/3351/guides)
### Adafruit ANO Rotary Navigation Encoder to I2C Stemma QT Adapter

[Adafruit ANO Rotary Navigation Encoder to I2C Stemma QT Adapter](https://www.adafruit.com/product/5740)
The ANO rotary encoder wheel is a funky user interface element, reminiscent of the [original clicking scroll wheel interface on the first iPods](https://gizmodo.com/a-visual-history-of-the-ipod-click-wheel-r-i-p-1632640054). It's a nifty kit, but the pin-out is a little odd...

In Stock
[Buy Now](https://www.adafruit.com/product/5740)
[Related Guides to the Product](https://learn.adafruit.com/products/5740/guides)
### ANO Directional Navigation and Scroll Wheel Rotary Encoder

[ANO Directional Navigation and Scroll Wheel Rotary Encoder](https://www.adafruit.com/product/5001)
This funky user interface element is reminiscent of the [original clicking scroll wheel interface on the first iPods](https://gizmodo.com/a-visual-history-of-the-ipod-click-wheel-r-i-p-1632640054). It's a fancy mechanical kit but has an intuitiveness that is hard to argue with -...

Out of Stock
[Buy Now](https://www.adafruit.com/product/5001)
[Related Guides to the Product](https://learn.adafruit.com/products/5001/guides)
### Quad Alphanumeric Display - Red 0.54" Digits w/ I2C Backpack

[Quad Alphanumeric Display - Red 0.54" Digits w/ I2C Backpack](https://www.adafruit.com/product/1911)
Display, elegantly, 012345678 or 9! Gaze, hypnotized, at ABCDEFGHIJKLM - well it can display the whole alphabet. You get the point. This is a nice, bright alphanumeric display that shows letters and numbers in a beautiful red hue. It's super bright and designed for viewing from distances...

In Stock
[Buy Now](https://www.adafruit.com/product/1911)
[Related Guides to the Product](https://learn.adafruit.com/products/1911/guides)
### Quad Alphanumeric Display - Yellow 0.54" Digits w/ I2C Backpack

[Quad Alphanumeric Display - Yellow 0.54" Digits w/ I2C Backpack](https://www.adafruit.com/product/2158)
Display, elegantly, 012345678 or 9! Gaze, hypnotized, at ABCDEFGHIJKLM - well it can display the whole alphabet. You get the point. This is a nice, bright alphanumeric display that shows letters and numbers in a beautiful yellow hue. It's super bright and designed for viewing from...

In Stock
[Buy Now](https://www.adafruit.com/product/2158)
[Related Guides to the Product](https://learn.adafruit.com/products/2158/guides)
### Quad Alphanumeric Display - Pure Green 0.54" Digits w/ Backpack

[Quad Alphanumeric Display - Pure Green 0.54" Digits w/ Backpack](https://www.adafruit.com/product/2160)
Display, elegantly, 012345678 or 9! Gaze, hypnotized, at ABCDEFGHIJKLM - well it can display the whole alphabet. You get the point. This is a nice, bright alphanumeric display that shows letters and numbers in a beautiful pure green hue. It's super bright and designed for viewing from...

In Stock
[Buy Now](https://www.adafruit.com/product/2160)
[Related Guides to the Product](https://learn.adafruit.com/products/2160/guides)

## Related Guides

- [Adafruit LED Backpacks](https://learn.adafruit.com/adafruit-led-backpack.md)
- [Adafruit MAX98357 I2S Class-D Amps - Stereo and Mono](https://learn.adafruit.com/adafruit-max98357-i2s-class-d-mono-amp.md)
- [Introducing Adafruit Feather RP2040](https://learn.adafruit.com/adafruit-feather-rp2040-pico.md)
- [ANO Directional Navigation and Scroll Wheel Rotary Encoder and Breakout](https://learn.adafruit.com/ano-rotary-encoder.md)
- [Adafruit ANO Rotary Encoder to I2C Adapter](https://learn.adafruit.com/adafruit-ano-rotary-navigation-encoder-to-i2c-stemma-qt-adapter.md)
- [Raspberry Pi Video Synth with Blinka and Processing](https://learn.adafruit.com/raspberry-pi-video-synth-with-blinka-and-processing.md)
- [No-Code IoT CO2 "Canary In a Coalmine"](https://learn.adafruit.com/iot-canary.md)
- [Motorized POV LED Display](https://learn.adafruit.com/motorized-pov-led-display.md)
- [Guardian Robot with LEDs](https://learn.adafruit.com/guardian-robot-with-leds.md)
- [LED Emerald with Circuit Playground Bluefruit](https://learn.adafruit.com/led-emerald-with-circuit-playground.md)
- [Walkmellotron: Cassette Player Mods](https://learn.adafruit.com/walkmellotron.md)
- [Raspberry Pi Pico and LED Arcade Button MIDI Controller](https://learn.adafruit.com/raspberry-pi-pico-led-arcade-button-midi-controller-fighter.md)
- [Arcade Machine Ports for Fruit Jam](https://learn.adafruit.com/space-invaders-for-fruit-jam.md)
- [Servo Boss](https://learn.adafruit.com/servo-boss.md)
- [Adafruit IO IOT Hub with the Adafruit FunHouse](https://learn.adafruit.com/adafruit-io-hub-with-the-adafruit-funhouse.md)
- [No-Code Offline Data Logger with WipperSnapper](https://learn.adafruit.com/no-code-offline-data-logging-with-wippersnapper.md)
- [Adafruit ESP32-S2 Reverse TFT Feather](https://learn.adafruit.com/esp32-s2-reverse-tft-feather.md)
- [Feather RP2350 Audio Reactive Video Synth](https://learn.adafruit.com/feather-rp2350-audio-reactive-video-synth.md)
- [Toddler Timer](https://learn.adafruit.com/toddler-timer.md)
- [Blinka LED Sign](https://learn.adafruit.com/blinka-led-sign.md)
