STM32 Digital Piano

ENGR 478 Term Project

Four-button digital piano using the STM32 NUCLEO-L476RG

This project uses GPIO, EXTI interrupts, SysTick, and ADC to make a small embedded piano. Four push buttons select chords, three speaker outputs play the sound, and two potentiometers control volume and octave.

NUCLEO-L476RG
PC0
PA0
PA1
PA5
PA6
PA7
4 push buttons
3 speaker outputs
2 ADC knobs
20 kHz SysTick timing

Hardware Setup

Inputs and outputs used by the piano

Push Buttons

PC0, PC1, PC2, and PC3 are configured as inputs with pull-up resistors. Pressing a button creates an EXTI interrupt.

Speaker Outputs

PA5, PA6, and PA7 are GPIO outputs. The SysTick handler changes these pins to create the sound waveform.

Volume Knob

PA0 is an ADC input connected to a 10 kOhm potentiometer. It controls the duty time of the sound output.

Octave Knob

PA1 is an ADC input connected to a 10 kOhm potentiometer. It moves the selected note lower or higher.

Pin Direction Project Use
PA5OutputSpeaker output 1
PA6OutputSpeaker output 2
PA7OutputSpeaker output 3
PC0-PC3InputPush buttons through EXTI
PA0Analog inputVolume potentiometer
PA1Analog inputOctave potentiometer

Software Flow

How the code runs

The program initializes GPIO, SysTick, EXTI, and ADC. After setup, the main loop sleeps with __WFI() and wakes when an interrupt happens. Button interrupts select the active note. The main loop reads the two ADC knobs every 20 ms. SysTick creates the sound timing at 20 kHz.

  • EXTI handles button press and release.
  • ADC reads volume and octave.
  • SysTick creates the speaker waveform.
  • The main loop connects the modules together.
Software flowchart for the STM32 digital piano

Chord Table

Each button selects a three-note chord

SW1 / PC0

C Major

C - E - G

SW2 / PC1

G Major

G - B - D

SW3 / PC2

A Minor

A - C - E

SW4 / PC3

F Major

F - A - C

Project outcomes and AD2 test results

Testing

Measured with Analog Discovery 2

The project was tested by checking the speaker output pins, button press and release behavior, ADC volume control, and ADC octave control. The measured values showed that the expected notes were close to the target musical frequencies.

FrequencyChord outputs verified on PA5, PA6, and PA7.
VolumeDuty timing changes when the PA0 knob moves.
OctavePA1 changes the selected note lower or higher.

Code Structure

Multi-file C project

main.c

Initializes the project, reads ADC updates, checks the active button, and calls the sound functions.

button.c

Configures PC0-PC3 as EXTI inputs and handles software debounce for button changes.

Systick_timer.c

Runs the sound engine, applies the chord table, controls volume, and updates milliseconds.

ADC.c

Reads PA0 and PA1, averages ADC samples, and converts knob values into volume and octave settings.