the protopedal
An STM32 based guitar effects pedal written fully in rust.
Author: Andrei-Tudor Tănase
GitHub Project Link: https://github.com/UPB-PMRust-Students/fils-project-2026-protodoatt
Description
This project aims to build a (good sounding) guitar effects pedal in Rust using an STM32F767ZI Nucleo board at its core. The idea is to make use of the STM32's really strong SAI peripheral to get guitar audio from a TI PCM1802 module, process it using the STM then push it back to a TI PCM5102 DAC module. Of course, there are a lot of analog components involve to amplify the guitar signal, and other surronding components to interface with the user.
Motivation
I've recently been into embedded audio, I've had a few projects in the summer where I made prototypes for ESP32 internet radios and such, and upon seeing how much better the STM32 boards are equipped for this sort of workload(because of the SAI peripheral and also the really good clock tree), I thought it's worth a shot. I also saw it has a CAN peripheral, and I figured out a sneaky way to tie it into one of my previous projects.
Architecture
This is the project block diagram. What's red is sort of optional stuff that I will try squeezing in if I have time.
Log
Week 2-3
I started looking into this early. I looked into how filters are written and how I could design the hardware of the pedal.(Huge credits to Phil's Lab on youtube for both of these) I settled on the OPA2134 as the OpAmp for the preamp job(biased at half supply), decided on my DAC and ADC modules and I also decided on the MCP6022 as a little "temporary" OpAmp that I could use while testing the project powered fully by USB(OPA isn't rail to rail and needs higher voltage to work properly in this case).
Week 4-6
Messed around with writing a simple overdrive filter and setup a really basic version of the circuit on the breadboard. At this time I didn't have a guitar available so I used my portable oscilloscope and function generator to test behavior of the first filter structure. I see that my processing loop(with CMSIS-DSP wherever possible) is down to 1200us. I have approximately 21333us available before my audio stutters so this means the MCU is strong enough to do quite a few filters plus an OLED screen and UI, etc.
Week 7-9
I borrow a guitar, see that the circuit does in fact work with a real guitar, but, as expected, noise performance is not optimal. Couple this with time constraints and Mouser orders being thrown around groupchats left and right, I start designing a PCB to mitigate both issues. It takes a while but I manage to finish my schematics in time for my colleague's Mouser order. After doing that, I start laying out the PCB. I finished it in time for it to hopefully arrive and have time to assemble before the hardware deadline. I will continue developing code on the breadboard prototype in the meantime. The daughterboard isn't ready yet but will be in a day or two
Weeks 9-14
A lot happened in these weeks, sorry to squeeze them all in but here is what happened in the meantime. I finished the daughterboard and went ahead and ordered all the PCBs, while waiting for them to arrive I played a bit more with the breadboard prototype(adding potentiometers to adjust effect parameters and such) but I hit a big brick wall when adding the screen. Because all the jumpers are in mid-air, turning on the screen would add a horrible really loud noise to my analog side. At this point I knew breadboard wasn't feasible, so I patiently waited for the PCBs. After they arrived, I spent two days(and nights) assembling them myself using the tools(Hot-Air, Soldering Station and Consumables) provided by the NGO where I'm a volunteer, Alacrity Education. Big shoutout to them for helping me with the tools and soldering advice needed. Anyway, after assembling them, I realized some little PCB mistakes I made(as you do, but they were very minor), so after fixing them I plugged it in and it worked! Noise performance was great so I kept on working with the code. Although noise is amazing at normal gain, when you add an effect like overdrive(which is basically what I have running right now), it amplifies the noise too(by up to 10x)! So I coded a noise-gate algorithm(inspired by Phil's Lab DSP youtube series) which cleverly mutes the volume when its below a certain threshold(a tad more complex than that actually), but it all works great! As I'm writing this I'm working on the little bonus mentioned above, lets see how it pans out!
Hardware
The core of the hardware is the Nucleo board. It slots into the main PCB, that houses the analogue front-end and slots for the ADC, DAC, bluetooth and all other modules. This PCB then connects using a ribbon cable to a daughter board that houses the main SH1106 display, 5 potentiometers and a rotary encoder to navigate the menus(this can be replaced with three footswitches for ease of use). The main PCB uses a sig/gnd/gnd/sig 4 layer stackup to improve noise performance. The power is filtered quite a bit and the OpAmp at the core of the analogue frontend has its own separate 9V line provided by a low noise LDO ic. I routed it as carefully as possible to try and avoid unwanted noise caused by coupling and such. I saw the STM has a MicroSD peripheral so I added a slot cause why not.

Schematics

Bill of Materials
| Device | Usage | Price |
|---|---|---|
| NUCLEO-F767ZI | The "brains" | 104 RON |
| OPA2134PA | The main IC in the analogue frontend | 32 RON |
| PCM1802 Module | The "digitizer" of the sound | 38 RON |
| PCM5102A Module | The "de-digitizer" of the sound | 22 RON |
| SH1106 | The display | 20 RON |
There are of course a lot more components on the PCB and daughterboard, but those are in the BOM files of the PCB.
Software
| Library | Description | Usage |
|---|---|---|
| sh1106 | Display driver for SH1106 | Used for the display for the pedal |
| embedded-graphics | 2D graphics library | Used for drawing to the display |
| cmsis-dsp-pregenerated | Bindings to CMSIS DSP | Used to speed up filters and other DSP math |
| embassy-stm32 | Async Hardware Abstraction Layer (HAL) for STM32 | Used for hardware initialization and async peripheral control |