STM32 Digital Piano

ENGR 478 Embedded Systems Term Project

Digital piano on the STM32 NUCLEO-L476RG

A register-level embedded piano built with four push buttons, three speaker outputs, SysTick sound timing, EXTI button interrupts, and two ADC potentiometer controls.

GPIO EXTI SysTick ADC No HAL

Real-time signal path

NUCLEO-L476RG
PC0-PC3
PA0
PA1
PA5
PA6
PA7

Buttons select chords. Potentiometers control volume and octave.

4 button inputs
3 speaker pins
2 ADC controls
20 kHz SysTick timing

Hardware Setup

Simple hardware, clear pin responsibilities

The hardware is intentionally small so the software behavior can be measured and explained clearly.

Push Buttons

PC0, PC1, PC2, and PC3 are inputs with pull-up resistors. Each press or release creates an EXTI interrupt.

Speaker Outputs

PA5, PA6, and PA7 are GPIO outputs. SysTick updates 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

Main logic and interrupts are separated

The program initializes GPIO, SysTick, EXTI, and ADC. After setup, the main loop waits with __WFI(). Button changes are handled by EXTI interrupts, while sound timing runs from the SysTick interrupt at 20 kHz.

  • Main loop reads ADC values every 20 ms.
  • EXTI interrupt updates the active button state.
  • SysTick interrupt drives PA5, PA6, and PA7.
  • Shared variables connect the modules without using HAL.
View detailed flowchart
Software flowchart for the STM32 digital piano

Chord Table

Each button selects a three-note chord

The software maps each button to a chord table, then the SysTick sound engine outputs the selected tones.

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

Demo Plan

What the project demonstrates

The live demo is organized around the main embedded concepts used in the project.

01

Button Response

Press each button and show that a different chord is selected.

02

Release Behavior

Release the button and show that the sound stops cleanly.

03

Volume Control

Turn the PA0 potentiometer and show the sound level changing.

04

Octave Control

Turn the PA1 potentiometer and show the pitch moving lower and higher.

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 show that the generated tones closely match the expected 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.

AD2 Volume Readings

Volume changes while pitch stays stable

These measurements were taken while playing the SW1 C major chord. The frequencies stay nearly constant while the positive duty cycle decreases, which shows that PA0 changes loudness without changing the note pitch.

Volume Setting PA5 Frequency / Duty PA6 Frequency / Duty PA7 Frequency / Duty
High 263.85 Hz / 48.582% 334.45 Hz / 48.188% 385.85 Hz / 48.006%
Medium 263.85 Hz / 26.253% 334.36 Hz / 26.525% 385.73 Hz / 26.840%
Low 264.03 Hz / 1.254% 334.45 Hz / 1.589% 385.73 Hz / 1.736%
C Major Verified PA5, PA6, and PA7 measured C, E, and G chord tones.
Pitch Stable The frequency values stayed almost unchanged as the volume knob moved.
Volume Verified Duty cycle changed from about 48% to about 1%, showing visible loudness control.

AD2 Octave Readings

Octave knob shifts the chord frequency

These measurements show the PA1 octave potentiometer moving the same SW1 C major chord down, back to normal, and up. Each octave step approximately doubles or halves the frequency.

Octave Setting PA5 PA6 PA7
Lower Octave 132.06 Hz 167.29 Hz 193.05 Hz
Middle Octave 264.29 Hz 334.54 Hz 386.10 Hz
Higher Octave 528.54 Hz 669.27 Hz 772.63 Hz

Firmware

How the code is organized

The project is split into small C files so each peripheral has a clear job and the full program is easy to explain.

main.c

Starts the board setup, reads the two ADC knobs, checks the active button, and calls the sound functions.

button.c

Sets PC0-PC3 as button inputs, uses EXTI interrupts, and debounces button press and release changes.

Systick_timer.c

Runs the 20 kHz sound timing, loads chord frequencies, changes volume duty time, and counts milliseconds.

ADC.c

Reads PA0 and PA1, smooths the knob values, and converts them into volume and octave settings.