# Faderwave Synthesizer

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/126/762/medium800/circuitpython_faderwave-6300_sine.jpg?1703017531)

This project uses 16 analog fader potentiometers to create custom waveforms that are then used as the basis for synthesizer audio. Sine, square, triangle, saw, banana...any shape you can 'draw' will be re-created on the fly.

The Faderwave is based on the [Hardware Reverse Oscilloscope 2 project by Mitxela](https://mitxela.com/projects/rscope2) a synth designed to hand build single-cycle waveforms. In CircuitPython synthio [we can generate arbitrary single-cycle waveforms](https://learn.adafruit.com/audio-synthesis-with-circuitpython-synthio/advanced-synthio-examples#step-3154334), so this seems like a great mashup!

The Faderwave was designed to ingest USB MIDI notes and turn them into polyphonic wavetable synth audio, however you could turn this platform into a MIDI fader box, sequencer, sample player, CV box, or who knows what else!

https://youtu.be/EW4jw09yoeI

## Parts
### Adafruit ItsyBitsy M4 Express featuring ATSAMD51

[Adafruit ItsyBitsy M4 Express featuring ATSAMD51](https://www.adafruit.com/product/3800)
What's smaller than a Feather but larger than a Trinket? It's an **Adafruit ItsyBitsy M4 Express** featuring the **Microchip ATSAMD51**! Small, powerful, with a ultra fast ATSAMD51 Cortex M4 processor running at 120 MHz - this microcontroller board is perfect...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3800)
[Related Guides to the Product](https://learn.adafruit.com/products/3800/guides)
![Adafruit ItsyBitsy M4 Express featuring ATSAMD51 connected to a small breadboard. ](https://cdn-shop.adafruit.com/product-videos/640x480/3800-04.jpg)

or

### Adafruit ItsyBitsy RP2040

[Adafruit ItsyBitsy RP2040](https://www.adafruit.com/product/4888)
A new chip means a new ItsyBitsy, 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 ItsyBitsy teensy-weensy Treatment" and so we did! This Itsy' features the RP2040, <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4888)
[Related Guides to the Product](https://learn.adafruit.com/products/4888/guides)
![Video of hand holding an ItsyBitsy PCB. An on-board LED glows rainbow colors.](https://cdn-shop.adafruit.com/product-videos/640x480/4888-05.jpg)

### ADS7830 8-Channel ADC x2
![circuitpython_5836-00.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/593/medium640/circuitpython_5836-00.jpg?1702086014)

### Part: Adafruit ADS7830 8-Channel 8-Bit ADC
quantity: 2
with I2C
[Adafruit ADS7830 8-Channel 8-Bit ADC](https://www.adafruit.com/product/5836)

### Slide Potentiometer x16
![circuitpython_4219-00.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/594/medium640/circuitpython_4219-00.jpg?1702076897)

### Part: Slide Potentiometer with Knob - 75mm Long
quantity: 16
10KΩ
[Slide Potentiometer with Knob - 75mm Long](https://www.adafruit.com/product/4219)

### Monochrome 1.3" 128x64 OLED graphic display - STEMMA QT / Qwiic

[Monochrome 1.3" 128x64 OLED graphic display - STEMMA QT / Qwiic](https://www.adafruit.com/product/938)
These displays are small, only about 1.3" diagonal, but very readable due to the high contrast of an OLED display. This display is made of 128x64 individual white OLED pixels, each one is turned on or off by the controller chip. Because the display makes its own light, no backlight is...

In Stock
[Buy Now](https://www.adafruit.com/product/938)
[Related Guides to the Product](https://learn.adafruit.com/products/938/guides)
![Monochrome 1.3" OLED module with Adafruit logos falling like snow](https://cdn-shop.adafruit.com/product-videos/640x480/938-05.jpg)

### Adafruit AD5693R Breakout Board - 16-Bit DAC with I2C Interface

[Adafruit AD5693R Breakout Board - 16-Bit DAC with I2C Interface](https://www.adafruit.com/product/5811)
Which is better, less bits or more? MORE of course! So why settle for a 12-bit DAC like the [MCP4725](https://www.adafruit.com/product/935) when you can go for the 16-bits of the AD5693? OK well there may be some reason to go with 12-bits, say if you don't need high resolution...

In Stock
[Buy Now](https://www.adafruit.com/product/5811)
[Related Guides to the Product](https://learn.adafruit.com/products/5811/guides)
![Angled shot of DAC breakout board.](https://cdn-shop.adafruit.com/640x480/5811-00.jpg)

### Adafruit TRRS Jack Breakout Board

[Adafruit TRRS Jack Breakout Board](https://www.adafruit.com/product/5764)
Tip-Ring-Ring-Sleeve style audio cables are often used for situations where you want stereo audio and then an extra contact for a microphone input. [For example, headsets for cell phones](https://www.adafruit.com/product/3959). Also called TRRS jacks for short, they're also...

In Stock
[Buy Now](https://www.adafruit.com/product/5764)
[Related Guides to the Product](https://learn.adafruit.com/products/5764/guides)
![angled shot of TRRS jack breakout board.](https://cdn-shop.adafruit.com/640x480/5764-00.jpg)

### Part: Tactile Button switch (6mm)
quantity: 1
20 pack
[Tactile Button switch (6mm)](https://www.adafruit.com/product/367)

### Part: 0.1uF ceramic capacitors
quantity: 1
10 pack
[0.1uF ceramic capacitors](https://www.adafruit.com/product/753)

### Part: Through-Hole Resistors - 1.0K ohm 5% 1/4W
quantity: 1
Pack of 25
[Through-Hole Resistors - 1.0K ohm 5% 1/4W](https://www.adafruit.com/product/4294)

### Part: Short Male Header Kit
quantity: 2
for ItsyBitsy
[Short Male Header Kit](https://www.adafruit.com/product/4173)

### Part: Short Female Header Kit
quantity: 2
for ItsyBitsy
[Short Female Header Kit](https://www.adafruit.com/product/4174)

### Part: Black Nylon Machine Screw and Stand-off Set
quantity: 1
M2.5 Thread
[Black Nylon Machine Screw and Stand-off Set](https://www.adafruit.com/product/3299)

### Part: Black Nylon Machine Screw and Stand-off Set
quantity: 1
M3 Thread
[Black Nylon Machine Screw and Stand-off Set](https://www.adafruit.com/product/4685)

### Part: USB A/Micro Cable
quantity: 1
2m
[USB A/Micro Cable](https://www.adafruit.com/product/2185)

# Faderwave Synthesizer

## Faderwave Circuit

![](https://cdn-learn.adafruit.com/assets/assets/000/126/597/medium800/circuitpython_faderwave_fritz2.jpg?1702084429)

The Faderwave circuit has these components and features:

- **ItsyBitsy M4** or **RP2040** microcontroller dev board is the brains of the circuit and provides the audio output. Power and USB MIDI come into the system via the ItsyBitsy USB port
- **3.5mm TRRS breakout** (with optional RC filter circuit) allows you to connect the audio output to an external amp/powered speaker
- Two **ADS7830** 8-channel 8-bit **ADC** boards read the sixteen **10k slide potentiometers** and send their values over I2C to the ItsyBitsy
- **1.3" OLED** display running over SPI provides a settings menu
- **Rotary encoder** with push button is used for menu settings selection and entry
- Optional **AD5693R 16-bit DAC** board can be used to send control voltage to vintage/modular (e.g., Eurorack) synthesizers for alternate projects

## PCB Design

While it would be possible to wire up the Faderwave using protoboards or breadboards, it would be a pretty wild mess of wires, so it made sense to design a PCB for it instead.

I used KiCad to lay out the circuit schematic, using the Adafruit Eaglecad part symbols imported and edited to serve the purpose. I also imported the Adafruit Eaglecad part footprints for the PCB layout.

![](https://cdn-learn.adafruit.com/assets/assets/000/126/595/medium800/circuitpython_faderwave_sch.jpg?1702086278)

![](https://cdn-learn.adafruit.com/assets/assets/000/126/710/medium800/circuitpython_faderwave_top_brd.jpg?1702690857)

![](https://cdn-learn.adafruit.com/assets/assets/000/126/711/medium800/circuitpython_faderwave_bot_brd.jpg?1702690872)

## Order PCBs

I ordered my PCBs from JLCPCB, but you can order from a number of different places online including OSHPark, DigiKey, PCBWay and others.

The boards I got were $14.84 for five boards, plus shipping. Download the .zip file linked below to get the Gerber and drill files needed to have your own set made.

![circuitpython_faderwave-6203.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/691/medium640/circuitpython_faderwave-6203.jpg?1702677727)

[wavefader_v02.zip](https://cdn-learn.adafruit.com/assets/assets/000/126/695/original/wavefader_v02.zip?1702679876)
# Faderwave Synthesizer

## Assemble the Synth

![](https://cdn-learn.adafruit.com/assets/assets/000/126/641/medium800/circuitpython_faderwave--2.jpg?1702671187)

## Parts Prep

Get all of your parts together, as well as the headers.

The DAC is optional, so we'll add that last.

![circuitpython_faderwave-6204.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/642/medium640/circuitpython_faderwave-6204.jpg?1702671270)

![](https://cdn-learn.adafruit.com/assets/assets/000/126/644/medium800/circuitpython_faderwave-6206.jpg?1702671448)

## ItsyBitsy Headers

Solder in place the two inner rows of ItsyBitsy short female headers.

![circuitpython_faderwave-6207.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/645/medium640/circuitpython_faderwave-6207.jpg?1702671478)

## ADC Prep

The ADS7830 analog-to-digital (ADC) boards each have eight channels to read the faders and convert their analog values into 8-bit digital messages sent over the I2C bus.

The first ADC board will use the default I2C address and will be soldered closer to the ItsyBitsy. The second one will need to be set to a different I2C address. Heat the **AD0** pads and jumper them with solder.

&nbsp;

![circuitpython_faderwave-6209.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/647/medium640/circuitpython_faderwave-6209.jpg?1702672277)

Danger: 

Solder the first board into place with header pins as shown, being careful to match the orientation of the silkscreen shown on the Faderwave PCB.

Clip the extra pin lengths with diagonal cutters.

![circuitpython_faderwave-6210.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/648/medium640/circuitpython_faderwave-6210.jpg?1702672340)

![circuitpython_faderwave-6212.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/649/medium640/circuitpython_faderwave-6212.jpg?1702672350)

## Second ADC

Repeat for the second ADC board, being careful to match the silkscreen orientation, as this board is rotated 180º from the first board.

![circuitpython_faderwave-6214.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/650/medium640/circuitpython_faderwave-6214.jpg?1702672457)

![circuitpython_faderwave-6215.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/651/medium640/circuitpython_faderwave-6215.jpg?1702672468)

## Reset Button

Insert the tactile button and then solder it in place.

![circuitpython_faderwave-6229.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/646/medium640/circuitpython_faderwave-6229.jpg?1702671544)

## OLED Prep

Solder in short header pins as shown. Then to modify the board to use SPI mode, flip the OLED over and cut the traces for J1 and J2.

![circuitpython_faderwave-6236.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/652/medium640/circuitpython_faderwave-6236.jpg?1702672598)

![circuitpython_faderwave-6237.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/653/medium640/circuitpython_faderwave-6237.jpg?1702672608)

## OLED Mount

First, solder in place the short header for the OLED display.

Then, fasten four M2.5 x 8mm standoffs to the board as shown, screwing four short screws in from under the PCB.

Insert the OLED into the headers, and then screw in four screws from the top to secure.

![circuitpython_faderwave-6216.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/654/medium640/circuitpython_faderwave-6216.jpg?1702672766)

![circuitpython_faderwave-6220.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/656/medium640/circuitpython_faderwave-6220.jpg?1702672830)

![circuitpython_faderwave-6221.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/657/medium640/circuitpython_faderwave-6221.jpg?1702672842)

![circuitpython_faderwave-6217b.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/661/medium640/circuitpython_faderwave-6217b.jpg?1702674655)

## Audio Out

Use two M2.5 x 6mm screws with nuts to create a stabilizing mount for the TRRS 3.5mm breakout.

Then, solder it in place with a header pin row as shown.

![circuitpython_faderwave-6222.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/663/medium640/circuitpython_faderwave-6222.jpg?1702674991)

![circuitpython_faderwave-6224.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/664/medium640/circuitpython_faderwave-6224.jpg?1702675006)

![circuitpython_faderwave-6225.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/665/medium640/circuitpython_faderwave-6225.jpg?1702675107)

![circuitpython_faderwave-6226.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/666/medium640/circuitpython_faderwave-6226.jpg?1702675125)

## Rotary Encoder

Solder the rotary encoder in place.

![circuitpython_faderwave-6227.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/668/medium640/circuitpython_faderwave-6227.jpg?1702675243)

![circuitpython_faderwave-6228.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/669/medium640/circuitpython_faderwave-6228.jpg?1702675260)

## ItsyBitsy

Solder the short header pins to the Itsy Bitsy as shown, then insert it into the board with the USB jack facing left.

![circuitpython_faderwave-6234.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/670/medium640/circuitpython_faderwave-6234.jpg?1702675320)

![circuitpython_faderwave-6233.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/671/medium640/circuitpython_faderwave-6233.jpg?1702675382)

## In Go the Faders

Check for any bent pins and straighten them. Then, insert the slide potentiometers into the PCB (they can only go in one way).

You can use tape or a rubber band to hold them flush to the board as you flip it over and start soldering!

Note, the four hardware tabs can require increased soldering iron heat to get the large copper ground planes hot enough so solder easily.

![circuitpython_faderwave-6245.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/672/medium640/circuitpython_faderwave-6245.jpg?1702675483)

![circuitpython_faderwave-6249.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/673/medium640/circuitpython_faderwave-6249.jpg?1702675759)

![circuitpython_faderwave-6250.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/674/medium640/circuitpython_faderwave-6250.jpg?1702675991)

![circuitpython_faderwave-6251.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/675/medium640/circuitpython_faderwave-6251.jpg?1702676006)

![](https://cdn-learn.adafruit.com/assets/assets/000/126/676/medium800/circuitpython_faderwave-6252.jpg?1702676017)

Warning: 

## Option A: Solder the RC Filter

If you want to filter the audio a bit from the high end, solder in the 1k resistors and 0.1uF capacitors as shown. There is one RC pair per channel of the stereo output that will massage the audio on its way to the left and right channels of the 3.5mm TRS output.

![circuitpython_faderwave-6258.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/681/medium640/circuitpython_faderwave-6258.jpg?1702677350)

## Option B: RC Circuit Bypass

To bypass the resistor/capacitor filter on the audio outputs (they can be used with either ItsyBitsy RP2040 or M4, but are more helpful with the PWM out of the RP2040), cut the trace between the left and middle pad of JP1 and JP2. Then, solder a jumper blob between the middle and right pad of both.

![circuitpython_faderwave-6254.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/679/medium640/circuitpython_faderwave-6254.jpg?1702676294)

![circuitpython_faderwave-6255.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/680/medium640/circuitpython_faderwave-6255.jpg?1702676331)

![](https://cdn-learn.adafruit.com/assets/assets/000/126/683/medium800/circuitpython_faderwave-6259.jpg?1702677476)

## Optional DAC Output

The Faderwave is a platform for audio experimentation, so I decided to include a 16-bit DAC output for possible control voltage (CV) use on vintage and modular synthesizers, such as Eurorack modules. This is optional, but if you think you may want to try it out at some point, go ahead and solder it in place now!

![circuitpython_faderwave-6260.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/687/medium640/circuitpython_faderwave-6260.jpg?1702677511)

![circuitpython_faderwave-6261.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/688/medium640/circuitpython_faderwave-6261.jpg?1702677521)

![circuitpython_faderwave-6262.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/689/medium640/circuitpython_faderwave-6262.jpg?1702677552)

![circuitpython_faderwave-6263.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/690/medium640/circuitpython_faderwave-6263.jpg?1702677563)

## Panels

You can optionally have a front and back panel laser cut for the Faderwave. I made mine on my trusty [Epilog](https://www.epiloglaser.com/) Zing 16.

Use the SVG file linked below. The vector curves are meant to be cut from 1/8" thick acrylic, with the hatch pattern for the type, level indicators, and waveform graphic being raster etched at 400dpi.

![](https://cdn-learn.adafruit.com/assets/assets/000/126/709/medium800/circuitpython_casefaderwave.jpg?1702690607)

![](https://cdn-learn.adafruit.com/assets/assets/000/126/697/medium800/circuitpython_faderwave-6282.jpg?1702681478)

[faderwave_case_05.svg](https://cdn-learn.adafruit.com/assets/assets/000/126/699/original/faderwave_case_05.svg?1702681587)
![](https://cdn-learn.adafruit.com/assets/assets/000/126/698/medium800/circuitpython_faderwave-6270.jpg?1702681493)

Fasten the panels with four M3 x 12mm standoffs, four M3 hex nuts, and eight short M3 screws.

![circuitpython_faderwave-6271.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/700/medium640/circuitpython_faderwave-6271.jpg?1702681697)

![circuitpython_faderwave-6272.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/701/medium640/circuitpython_faderwave-6272.jpg?1702681720)

![circuitpython_faderwave-6273.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/702/medium640/circuitpython_faderwave-6273.jpg?1702681732)

![circuitpython_faderwave-6283.jpg](https://cdn-learn.adafruit.com/assets/assets/000/126/703/medium640/circuitpython_faderwave-6283.jpg?1702681750)

Add your fader caps and rotary encoder knob and you're ready to play.

![](https://cdn-learn.adafruit.com/assets/assets/000/126/704/medium800/circuitpython_faderwave-6288.jpg?1702683028)

# Faderwave Synthesizer

## CircuitPython on ItsyBitsy

[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.

## Set up CircuitPython Quick Start!
Follow this quick step-by-step for super-fast Python power :)

[Download the latest version of CircuitPython for this board via CircuitPython.org](https://circuitpython.org/board/itsybitsy_m4_express/)
## Further Information
For more detailed info on installing CircuitPython, check out [Installing CircuitPython](../../../../welcome-to-circuitpython/installing-circuitpython).

 **Click the link above and download the latest UF2 file.**

Download and save it to your desktop (or wherever is handy).

![adafruit_products_uf2.png](https://cdn-learn.adafruit.com/assets/assets/000/055/475/medium640/adafruit_products_uf2.png?1529260343)

Plug your Itsy M4 into your computer using a known-good USB cable.

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

Double-click the **Reset** button on your board, and you will see the DotStar RGB LED turn green. If it turns red, check the USB cable, try another USB port, etc.

If double-clicking doesn't work the first time, try again. Sometimes it can take a few tries to get the rhythm right!

![adafruit_products_3800.gif](https://cdn-learn.adafruit.com/assets/assets/000/055/476/medium640thumb/adafruit_products_3800.jpg?1529260376)

You will see a new disk drive appear called **ITSYBOOT**.

Drag the **adafruit\_circuitpython\_etc.uf2** file to **ITSYBOOT.**

![adafruit_products_itsyboot.png](https://cdn-learn.adafruit.com/assets/assets/000/055/477/medium640/adafruit_products_itsyboot.png?1529260440)

![adafruit_products_drag.png](https://cdn-learn.adafruit.com/assets/assets/000/055/478/medium640/adafruit_products_drag.png?1529260485)

The LED will flash. Then, the **ITSYBOOT** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

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

![adafruit_products_circuitpy.png](https://cdn-learn.adafruit.com/assets/assets/000/055/479/medium640/adafruit_products_circuitpy.png?1529260731)

# Faderwave Synthesizer

## Code the Faderwave Synth

## Text Editor

Adafruit recommends using the&nbsp; **Mu** &nbsp;editor for editing your CircuitPython code. You can get more info in&nbsp;[this guide](https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor).

Alternatively, you can use any text editor that saves simple text files.

## Download the Project Bundle

Your project will use a specific set of CircuitPython libraries, and the&nbsp; **code.py** &nbsp;file. To get everything you need, click on the&nbsp; **Download Project Bundle** &nbsp;button below, and uncompress the .zip file.

Connect your computer to the board via a known good USB power+data cable. A new flash drive should show up as&nbsp; **CIRCUITPY**.

Drag the contents of the uncompressed bundle directory onto your board&nbsp; **CIRCUITPY** &nbsp;drive, replacing any existing files or directories with the same names, and adding any new ones that are necessary.

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

## How it Works

### Imports

First the code imports the necessary library modules:

```auto
import board
import busio
import ulab.numpy as np
import rotaryio
from digitalio import DigitalInOut, Pull
import displayio
from adafruit_display_text import label
from adafruit_display_shapes.rect import Rect
import terminalio
import synthio
import audiomixer
from adafruit_debouncer import Debouncer
import adafruit_ads7830.ads7830 as ADC
from adafruit_ads7830.analog_in import AnalogIn
import adafruit_displayio_ssd1306
import adafruit_ad569x
import usb_midi
import adafruit_midi
from adafruit_midi.note_on import NoteOn
from adafruit_midi.note_off import NoteOff
```

### Setup and Constants

First some setup, including user constants for `DEBUG` and `ITSY_TYPE`. Also to release the display before setting it up for use.

```auto
displayio.release_displays()

DEBUG = False  # turn on print debugging messages
ITSY_TYPE = 0  # Pick your ItsyBitsy: 0=M4, 1=RP2040

# neopixel setup for RP2040 only
if ITSY_TYPE == 1:
    import neopixel
    pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.3)
    pixel.fill(0x004444)
```

### I2C, MIDI, Synthio, and Driver Setup

- `busio.I2C`&nbsp;initializes one I2C bus on the STEMMA QT port pins
- `adafruit_midi` is set up for USB MIDI input
- Initial `synthio` settings are established to define parameters for the synthesizer, such as the number of faders, initial number of oscillators, detune amount, volume, and low-pass filter settings.

```auto
i2c = busio.I2C(board.SCL, board.SDA, frequency=1_000_000)

midi = adafruit_midi.MIDI(midi_in=usb_midi.ports[0], in_channel=0)

NUM_FADERS = 16
num_oscs = 1       # how many oscillators for each note to start
detune = 0.000  # how much to detune the oscillators
volume = 0.6  # mixer volume
lpf_freq = 12000  # user Low Pass Filter frequency setting
lpf_basef = 500     # filter lowest frequency
lpf_resonance = 0.1  # filter q

faders_pos = [0] * NUM_FADERS
last_faders_pos = [0] * NUM_FADERS
```

### Fader Initialization

Initializes the ADC for reading values from faders. Creates a list of `AnalogIn` objects representing the faders.

```auto
adc_a = ADC.ADS7830(i2c, address=0x48)  # default address 0x48
adc_b = ADC.ADS7830(i2c, address=0x49)  # A0 jumper 0x49, A1 0x4A

faders = []  # list for fader objects on first ADC
for fdr in range(8):  # add first group to list
    faders.append(AnalogIn(adc_a, fdr))
for fdr in range(8):  # add second group
    faders.append(AnalogIn(adc_b, fdr))
```

### DAC Setup

The DAC is initialized with its value being tied to the first fader's value.

```auto
# Initialize AD5693R for CV out
dac = adafruit_ad569x.Adafruit_AD569x(i2c)
dac.gain = True
dac.value = faders[0].value  # set dac out to the slider level
```

### Rotary Encoder

Next, to initialize the rotary encoder.

```auto
ENC_A = board.D9
ENC_B = board.D10
ENC_SW = board.D7

button_in = DigitalInOut(ENC_SW)  # defaults to input
button_in.pull = Pull.UP  # turn on internal pull-up resistor
button = Debouncer(button_in)

encoder = rotaryio.IncrementalEncoder(ENC_A, ENC_B)
encoder_pos = encoder.position
last_encoder_pos = encoder.position
```

### OLED Display Setup

Now to set up the OLED display using the SSD1306 driver and initialize the `displayio` group.

```auto
OLED_RST = board.D13
OLED_DC = board.D12
OLED_CS = board.D11

spi = board.SPI()
display_bus = fourwire.FourWire(spi, command=OLED_DC, chip_select=OLED_CS,
                                 reset=OLED_RST, baudrate=30_000_000)
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=64)
```

### Screen Elements

Here all of the various screen elements are created, including text labels, selector cursor, and value fields.

```auto
group = displayio.Group()

# Set the font for the text label
font = terminalio.FONT

# Create text label
title = label.Label(font, x=2, y=4, text=("FADERWAVE SYNTHESIZER"), color=0xffffff)
group.append(title)

column_x = (8, 60, 100)
row_y = (22, 34, 46, 58)

midi_lbl_rect = Rect(column_x[2]-3, row_y[0]-5, 28, 10, fill=0xffffff)
group.append(midi_lbl_rect)
midi_lbl = label.Label(font, x=column_x[2], y=row_y[0], text="MIDI", color=0x000000)
group.append(midi_lbl)
midi_rect = Rect(column_x[2]-3, row_y[1]-5, 28, 10, fill=0xffffff)
group.append(midi_rect)
midi_counter_lbl = label.Label(font, x=column_x[2]+8, y=row_y[1], text='-', color=0x000000)
group.append(midi_counter_lbl)

# Create menu selector
menu_sel = 0
menu_sel_txt = label.Label(font, text=("&gt;"), color=0xffffff)
menu_sel_txt.x = column_x[0]-10
menu_sel_txt.y = row_y[menu_sel]
group.append(menu_sel_txt)

# Create detune text
det_txt_a = label.Label(font, text=("Detune "), color=0xffffff)
det_txt_a.x = column_x[0]
det_txt_a.y = row_y[0]
group.append(det_txt_a)

det_txt_b = label.Label(font, text=(str(detune)), color=0xffffff)
det_txt_b.x = column_x[1]
det_txt_b.y = row_y[0]
group.append(det_txt_b)

# Create number of oscs text
num_oscs_txt_a = label.Label(font, text=("Num Oscs "), color=0xffffff)
num_oscs_txt_a.x = column_x[0]
num_oscs_txt_a.y = row_y[1]
group.append(num_oscs_txt_a)

num_oscs_txt_b = label.Label(font, text=(str(num_oscs)), color=0xffffff)
num_oscs_txt_b.x = column_x[1]
num_oscs_txt_b.y = row_y[1]
group.append(num_oscs_txt_b)

# Create volume text
vol_txt_a = label.Label(font, text=("Volume "), color=0xffffff)
vol_txt_a.x = column_x[0]
vol_txt_a.y = row_y[2]
group.append(vol_txt_a)

vol_txt_b = label.Label(font, text=(str(volume)), color=0xffffff)
vol_txt_b.x = column_x[1]
vol_txt_b.y = row_y[2]
group.append(vol_txt_b)

# Create lpf frequency text
lpf_txt_a = label.Label(font, text=("LPF "), color=0xffffff)
lpf_txt_a.x = column_x[0]
lpf_txt_a.y = row_y[3]
group.append(lpf_txt_a)

lpf_txt_b = label.Label(font, text=(str(lpf_freq)), color=0xffffff)
lpf_txt_b.x = column_x[1]
lpf_txt_b.y = row_y[3]
group.append(lpf_txt_b)

# Show the display group
display.root_group = group
```

### synthio Setup

Next: set up `synthio`. This can work with different audio output types depending on the ItsyBitsy board you use. I also set up a mixer object and the `wave_user` object that is the single-cycle waveform you'll be editing on the fly with the faders.

```auto
# Synthio setup
if ITSY_TYPE == 0:
    import audioio
    audio = audioio.AudioOut(left_channel=board.A0, right_channel=board.A1)  # M4 built-in DAC
if ITSY_TYPE == 1:
    import audiopwmio
    audio = audiopwmio.PWMAudioOut(board.A1)
# if using I2S amp:
# audio = audiobusio.I2SOut(bit_clock=board.MOSI, word_select=board.MISO, data=board.SCK)

mixer = audiomixer.Mixer(channel_count=2, sample_rate=44100, buffer_size=4096)
synth = synthio.Synthesizer(channel_count=2, sample_rate=44100)
audio.play(mixer)
mixer.voice[0].play(synth)
mixer.voice[0].level = 0.75

wave_user = np.array([0]*NUM_FADERS, dtype=np.int16)
amp_env = synthio.Envelope(attack_time=0.3, attack_level=1, sustain_level=0.65, release_time=0.3)
```

### Functions

We'll create a number of functions to call during play.

`faders_to_wave()` remaps the fader positions to the wavetable array points. This is the key to the whole thing!

`note_on()`&nbsp;and&nbsp;`note_off()` are called when MIDI messages for note on/off are received.

```auto
def faders_to_wave():
    for j in range(NUM_FADERS):
        wave_user[j] = int(map_range(faders_pos[j], 0, 127, -32768, 32767))

notes_pressed = {}  # which notes being pressed. key=midi note, val=note object

def note_on(n):
    voices = []   # holds our currently sounding voices ('Notes' in synthio speak)
    fo = synthio.midi_to_hz(n)
    lpf = synth.low_pass_filter(lpf_freq, lpf_resonance)

    for k in range(num_oscs):
        f = fo * (1 + k*detune)
        voices.append(synthio.Note(frequency=f, filter=lpf, envelope=amp_env, waveform=wave_user))
    synth.press(voices)
    note_off(n)  # help to prevent double note_on for same note which can get stuck
    notes_pressed[n] = voices

def note_off(n):
    note = notes_pressed.get(n, None)
    if note:
        synth.release(note)

# simple range mapper, like Arduino map()
def map_range(s, a1, a2, b1, b2):
    return b1 + ((s - a1) * (b2 - b1) / (a2 - a1))
```

### Main Loop

The main loop continuously checks for MIDI messages, updates the synthesizer state based on input, and adjusts parameters using faders and the rotary encoder.

**MIDI Input Handling (`note_on` and `note_off`):**

- Processes MIDI messages, triggers note on/off events, and updates a counter label on the display.

**Fader Handling (`faders_to_wave`):**

- Reads values from faders and updates a waveform array. Also, sends out a DAC value based on the first fader.

**Encoder Handling:**

- Monitors the rotary encoder and adjusts parameters based on the selected menu.

**Display Updates:**

- Updates the OLED display with the current values of parameters like detune, number of oscillators, volume, and LPF frequency.

**Synthio Operation:**

- Creates a waveform based on the fader values and triggers note events based on MIDI input.

**Hardware Interaction:**

- Manages hardware components such as DAC, NeoPixel, and the display.

**Debugging Output:**

- If `DEBUG` is set to `True`, it prints debugging messages, including MIDI notes on/off and polyphony information.

**Display Output:**

- If you are not seeing output on the TFT try adding a small delay and lowering the SPI baudrate to 6MHz.

```auto
spi = board.SPI()

time.sleep(0.5)  # Brief delay for the SPI bus to stabilize

display_bus = fourwire.FourWire(
    spi,
    command=OLED_DC,
    chip_select=OLED_CS,
    reset=OLED_RST,
    baudrate=6_000_000  # Lowered from 30_000_000
)
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=64)
```

```auto
msg = midi.receive()
    if isinstance(msg, NoteOn) and msg.velocity != 0:
        note_on(msg.note)
        notes_on = notes_on + 1
        if DEBUG:
            print("MIDI notes on:     ", msg.note, "      Polyphony:", " "*notes_on, notes_on)
        midi_counter_lbl.text=str(msg.note)
    elif isinstance(msg, NoteOff) or (isinstance(msg, NoteOn) and msg.velocity == 0):
        note_off(msg.note)
        notes_on = notes_on - 1
        if DEBUG:
            print("MIDI notes off:", msg.note, "          Polyphony:", " "*notes_on, notes_on)
        midi_counter_lbl.text="-"

    # check faders
    for i in range(len(faders)):
        faders_pos[i] = faders[i].value//512
        if faders_pos[i] is not last_faders_pos[i]:
            faders_to_wave()
            last_faders_pos[i] = faders_pos[i]
            if DEBUG:
                print("fader", [i], faders_pos[i])

            # send out a DAC value based on fader 0
            # if i == 1:
            #     dac.value = faders[1].value

    # check encoder button
    button.update()
    if button.fell:
        menu_sel = (menu_sel+1) % 4
        menu_sel_txt.y = row_y[menu_sel]

    # check encoder
    encoder_pos = encoder.position
    if encoder_pos &gt; last_encoder_pos:
        delta = encoder_pos - last_encoder_pos
        if menu_sel == 0:
            detune = detune + (delta * 0.001)
            detune = min(max(detune, -0.030), 0.030)
            formatted_detune = str("{:.3f}".format(detune))
            det_txt_b.text = formatted_detune

        elif menu_sel == 1:
            num_oscs = num_oscs + delta
            num_oscs = min(max(num_oscs, 1), 5)
            formatted_num_oscs = str(num_oscs)
            num_oscs_txt_b.text = formatted_num_oscs

        elif menu_sel == 2:
            volume = volume + (delta * 0.01)
            volume = min(max(volume, 0.00), 1.00)
            mixer.voice[0].level = volume
            formatted_volume = str("{:.2f}".format(volume))
            vol_txt_b.text = formatted_volume

        elif menu_sel == 3:
            lpf_freq = lpf_freq + (delta * 1000)
            lpf_freq = min(max(lpf_freq, 1000), 20_000)
            formatted_lpf = str(lpf_freq)
            lpf_txt_b.text = formatted_lpf

        last_encoder_pos = encoder.position

    if encoder_pos &lt; last_encoder_pos:
        delta = last_encoder_pos - encoder_pos
        if menu_sel == 0:
            detune = detune - (delta * 0.001)
            detune = min(max(detune, -0.030), 0.030)
            formatted_detune = str("{:.3f}".format(detune))
            det_txt_b.text = formatted_detune

        elif menu_sel == 1:
            num_oscs = num_oscs - delta
            num_oscs = min(max(num_oscs, 1), 8)
            formatted_num_oscs = str(num_oscs)
            num_oscs_txt_b.text = formatted_num_oscs

        elif menu_sel == 2:
            volume = volume - (delta * 0.01)
            volume = min(max(volume, 0.00), 1.00)
            mixer.voice[0].level = volume
            formatted_volume = str("{:.2f}".format(volume))
            vol_txt_b.text = formatted_volume

        elif menu_sel == 3:
            lpf_freq = lpf_freq - (delta * 1000)
            lpf_freq = min(max(lpf_freq, 1000), 20_000)
            formatted_lpf = str(lpf_freq)
            lpf_txt_b.text = formatted_lpf

        last_encoder_pos = encoder.position
```

# Faderwave Synthesizer

## Play the Faderwave Synth

![](https://cdn-learn.adafruit.com/assets/assets/000/126/763/medium800/circuitpython_faderwave-6300_triangle.jpg?1703017608)

![](https://cdn-learn.adafruit.com/assets/assets/000/126/764/medium800/circuitpython_faderwave-6300_sine.jpg?1703017624)

https://youtu.be/EW4jw09yoeI

To play the Faderwave, plug it into a powered speaker or amp with a stereo TRS 3.5mm audio cable. Then, plug it into your computer or other USB MIDI Host controller and send MIDI note on/note off messages. You'll hear the synth play!

Adjust the faders to make different waveforms, which will change the timbre of the sound by emphasizing or deemphasizing different harmonic content of the audio waveform.

Click the encoder to move between menu items on the OLED. You can turn the rotary encoder to:

- increase or decrease the detune amount between multiple voices
- adjust the number of voices for a thicker sound
- adjust the volume
- change the low pass filter cutoff frequency

You can also write new menu items into the code if you like to further customize your Faderwave synth.

![](https://cdn-learn.adafruit.com/assets/assets/000/126/765/medium800/circuitpython_faderwave-6300b_square.jpg?1703017637)

https://www.youtube.com/live/BszG22RdVUo?feature=shared&t=2244


## Featured Products

### Adafruit ItsyBitsy M4 Express featuring ATSAMD51

[Adafruit ItsyBitsy M4 Express featuring ATSAMD51](https://www.adafruit.com/product/3800)
What's smaller than a Feather but larger than a Trinket? It's an **Adafruit ItsyBitsy M4 Express** featuring the **Microchip ATSAMD51**! Small, powerful, with a ultra fast ATSAMD51 Cortex M4 processor running at 120 MHz - this microcontroller board is perfect...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3800)
[Related Guides to the Product](https://learn.adafruit.com/products/3800/guides)
### Adafruit ADS7830 8-Channel 8-Bit ADC with I2C

[Adafruit ADS7830 8-Channel 8-Bit ADC with I2C](https://www.adafruit.com/product/5836)
Many microcontrollers have ADCs these days, for reading analog/resistive sensors like potentiometers, thermistors, LDR light sensors, etc. but sometimes you need MOAR! Or maybe you're using a single board computer like a Raspberry Pi that has no ADCs at all!

The&nbsp; **Adafruit...**

In Stock
[Buy Now](https://www.adafruit.com/product/5836)
[Related Guides to the Product](https://learn.adafruit.com/products/5836/guides)
### Slide Potentiometer with Knob - 75mm Long - 10KΩ

[Slide Potentiometer with Knob - 75mm Long - 10KΩ](https://www.adafruit.com/product/4219)
_Slip slidin' away&nbsp;  
Slip slidin' away&nbsp;  
You know the nearer your resistance&nbsp;  
The more you're slip slidin' away_

If you're tired of the regular-old-twisty potentiometers we carry, why not _slide_ over and try this slide pot?...

In Stock
[Buy Now](https://www.adafruit.com/product/4219)
[Related Guides to the Product](https://learn.adafruit.com/products/4219/guides)
### Monochrome 1.3" 128x64 OLED graphic display - STEMMA QT / Qwiic

[Monochrome 1.3" 128x64 OLED graphic display - STEMMA QT / Qwiic](https://www.adafruit.com/product/938)
These displays are small, only about 1.3" diagonal, but very readable due to the high contrast of an OLED display. This display is made of 128x64 individual white OLED pixels, each one is turned on or off by the controller chip. Because the display makes its own light, no backlight is...

In Stock
[Buy Now](https://www.adafruit.com/product/938)
[Related Guides to the Product](https://learn.adafruit.com/products/938/guides)
### Adafruit AD5693R Breakout Board - 16-Bit DAC with I2C Interface

[Adafruit AD5693R Breakout Board - 16-Bit DAC with I2C Interface](https://www.adafruit.com/product/5811)
Which is better, less bits or more? MORE of course! So why settle for a 12-bit DAC like the [MCP4725](https://www.adafruit.com/product/935) when you can go for the 16-bits of the AD5693? OK well there may be some reason to go with 12-bits, say if you don't need high resolution...

In Stock
[Buy Now](https://www.adafruit.com/product/5811)
[Related Guides to the Product](https://learn.adafruit.com/products/5811/guides)
### Adafruit TRRS Jack Breakout Board

[Adafruit TRRS Jack Breakout Board](https://www.adafruit.com/product/5764)
Tip-Ring-Ring-Sleeve style audio cables are often used for situations where you want stereo audio and then an extra contact for a microphone input. [For example, headsets for cell phones](https://www.adafruit.com/product/3959). Also called TRRS jacks for short, they're also...

In Stock
[Buy Now](https://www.adafruit.com/product/5764)
[Related Guides to the Product](https://learn.adafruit.com/products/5764/guides)
### Rotary Encoder + Extras

[Rotary Encoder + Extras](https://www.adafruit.com/product/377)
This rotary encoder is the best of the best, it's a high-quality 24-pulse encoder, with detents and a nice feel. It is panel mountable for placement in a box, or you can plug it into a breadboard (just cut/bend the two mechanical side tabs.) We also include a nice soft-touch knob with an...

Out of Stock
[Buy Now](https://www.adafruit.com/product/377)
[Related Guides to the Product](https://learn.adafruit.com/products/377/guides)
### Tactile Button switch (6mm) x 20 pack

[Tactile Button switch (6mm) x 20 pack](https://www.adafruit.com/product/367)
Little clicky switches are standard input "buttons" on electronic projects. These work best in a PCB but [can be used on a solderless breadboard as shown in this tutorial](https://learn.adafruit.com/adafruit-arduino-lesson-6-digital-inputs?view=all). The pins are normally...

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

## Related Guides

- [Adafruit ItsyBitsy RP2040](https://learn.adafruit.com/adafruit-itsybitsy-rp2040.md)
- [Adafruit TRRS Jack Breakout Board](https://learn.adafruit.com/trrs-jack-breakout.md)
- [Adafruit AD5693R 16-Bit DAC Breakout Board](https://learn.adafruit.com/adafruit-ad5693r-16-bit-dac-breakout-board.md)
- [Adafruit ADS7830 8-Channel 8-Bit ADC](https://learn.adafruit.com/adafruit-ads7830-8-channel-8-bit-adc.md)
- [PyPortal Titano Weather Station](https://learn.adafruit.com/pyportal-titano-weather-station.md)
- [Compost Friend!](https://learn.adafruit.com/compost-optimization-machine.md)
- [Square NeoPixel Display with Black LED Acrylic](https://learn.adafruit.com/sqaure-neopixel-display-with-black-led-acrylic.md)
- [Adafruit Swirly Aluminum Mounting Grid for 0.1" Spaced PCBs](https://learn.adafruit.com/swirly-grid.md)
- [Portable Macrodata Refinement Terminal](https://learn.adafruit.com/portable-macrodata-refinement-terminal.md)
- [Stepper Motor Turntable](https://learn.adafruit.com/stepper-motor-turntable.md)
- [RGB LED Matrix Cube with 25,000 LEDs](https://learn.adafruit.com/rgb-led-matrix-cube-for-pi.md)
- [CircuitPython MIDI to CV Skull](https://learn.adafruit.com/circuitpython-midi-to-cv-skull.md)
- [Raspberry Pi Pico and LED Arcade Button MIDI Controller](https://learn.adafruit.com/raspberry-pi-pico-led-arcade-button-midi-controller-fighter.md)
- [CircuitPython OLED Watch Clock](https://learn.adafruit.com/circuitpython-oled-watch.md)
- [Introducing Adafruit ItsyBitsy M4](https://learn.adafruit.com/introducing-adafruit-itsybitsy-m4.md)
- [Mini VOTE Keyboard](https://learn.adafruit.com/vote-keyboard.md)
- [How to train new TensorFlow Lite micro speech models](https://learn.adafruit.com/how-to-train-new-tensorflow-lite-micro-speech-models.md)
- [Feather Fingerboard](https://learn.adafruit.com/feather-fingerboard.md)
- [Program CircuitPython USB Devices with iPhone & iPad](https://learn.adafruit.com/use-circuitpython-devices-with-iphone-ipad.md)
