This project implements an interactive Circle of Fifths MIDI controller designed to facilitate music composition and performance through direct interaction with fundamental music theory concepts. The Circle of Fifths is a foundational musical chart that organises the twelve chromatic pitches in a sequence of perfect fifth intervals, providing a visual representation of key relationships, scale construction, and harmonic progressions.
The device was conceived to address a significant challenge faced by beginning musicians: the cognitive burden of simultaneously learning instrument technique, music theory, chord construction, and composition. Traditional music education often creates barriers between theoretical understanding and practical music-making, causing learners to lose motivation before achieving proficiency. This controller bridges that gap by embedding music theory directly into the physical interface, allowing users to compose and perform music while intuitively reinforcing theoretical concepts.
Unlike conventional MIDI keyboards that follow a chromatic layout, this controller organises inputs according to the Circle of Fifths, forcing users to internalise intervallic relationships, scale degrees, and chord progressions through physical interaction. The device constrains available notes and chords to those within the selected key, providing a structured learning environment that prevents harmonically incorrect choices while maintaining creative freedom.
The primary application of this device is music composition and performance within Digital Audio Workstations (DAWs) such as Ableton Live, Logic Pro, or FL Studio. As a class-compliant USB MIDI device, it requires no special drivers and can also interface with visual programming environments such as Max/MSP and Pure Data. The controller is particularly suited for:
- Educational contexts where music theory fundamentals are being taught
- Songwriting and composition workflows requiring rapid harmonic exploration
- Live performance scenarios where key-constrained improvisation is desired
- Music production environments where chord progressions and melodic ideas need to be quickly captured
The device enables users to record musical ideas without requiring the technical proficiency to perform them on traditional instruments, making it especially valuable for composers, producers, and students who think conceptually about music but lack advanced instrumental skills.
- Arduino Micro (ATmega32U4-based)
- Native USB support for MIDI-over-USB communication
- Sufficient I/O pins for multiplexed input/output
- I2C capability for OLED display communication
- 5V operating voltage
- 12 Push Buttons - Chord input buttons (arranged in Circle of Fifths layout)
- 12 Push Buttons - Melody/chromatic note input buttons
- 4 Tactile Buttons:
- 1x Shift button (key selection and mode switching)
- 1x Mode button (major/minor toggle)
- 1x Octave Up button
- 1x Octave Down button
- 1x 2-Axis Analog Joystick - Key selection, pitch bend, and modulation control
- 3x CD4067 16-Channel Analog Multiplexer/Demultiplexer
- One for chord button matrix
- One for melody button matrix
- One for LED control output
- 24x LEDs (any color, 3-5mm recommended)
- 12 LEDs for chord button indication
- 12 LEDs for melody button indication
- 24x Current-Limiting Resistors (220-470 ohm, depending on LED specifications)
- 1x SSD1306 OLED Display (128x64 pixels, I2C interface)
- USB Micro cable - Power supply and MIDI data transmission
- Breadboard or perfboard - For circuit construction
- Jumper wires - For connections
- Soldering equipment - For permanent connections
- Project enclosure (wood or 3D-printed case recommended over cardboard)
- Pull-up resistors (10k ohm) if not using internal pull-ups for buttons
The following pin assignments are used in the Arduino Micro implementation:
Multiplexer Control:
- Chord multiplexer: Signal pin D4, Select pins D5, D6, D7, D8
- Melody multiplexer: Signal pin D9, Select pins D10, D18, D19, D20
- LED multiplexer: Signal pin D17, Select pins D12, D16, D0, D1
Control Buttons:
- Shift button: D11
- Mode button: D15
- Octave Up: D13
- Octave Down: D14
Analog Inputs:
- Joystick X-axis: A4
- Joystick Y-axis: A5
I2C Communication (OLED):
- SDA: D2 (Arduino Micro I2C)
- SCL: D3 (Arduino Micro I2C)
#include <MIDIUSB.h> // Native USB MIDI support
#include <Wire.h> // I2C communication for OLED
#include <Adafruit_SSD1306.h> // OLED display driver
#include <Bounce2.h> // Button debouncing (optional but recommended)Install via Arduino Library Manager or manually:
- MIDIUSB: Built-in library for Arduino boards with native USB support
- Adafruit SSD1306:
Sketch > Include Library > Manage Libraries > Search "SSD1306" - Adafruit GFX: Required dependency for SSD1306
- Bounce2: For improved button debouncing (optional)
- Connect the Arduino Micro to the breadboard with USB connection for power and programming
- Wire the three CD4067 multiplexers with common ground and VCC (5V) connections
- Connect multiplexer select pins to the Arduino according to pin configuration
- Wire chord buttons through the first multiplexer (12 buttons total, channels 0-11)
- Wire melody buttons through the second multiplexer (12 buttons total, channels 0-11)
- Connect LEDs through the third multiplexer with appropriate current-limiting resistors
- Wire control buttons directly to Arduino pins with INPUT_PULLUP configuration
- Connect joystick analog outputs to A4 and A5 pins
- Wire OLED display to I2C pins (SDA/SCL) with 3.3V or 5V power depending on module
The physical arrangement follows the Circle of Fifths structure:
- Chord buttons arranged in a circular pattern representing the Circle of Fifths (C at top, proceeding clockwise: G, D, A, E, B, F#/Gb, C#/Db, G#/Ab, D#/Eb, A#/Bb, F)
- Melody buttons arranged in a linear chromatic layout (similar to piano keyboard)
- Control elements positioned ergonomically for simultaneous operation
- OLED display positioned for clear visibility during performance
- LEDs placed adjacent to their corresponding buttons for immediate visual feedback
While the original prototype used a cardboard enclosure with a wooden support plank, a more robust construction is recommended:
- Laser-cut wooden panels or 3D-printed enclosure
- Button mounting holes precisely measured for secure fit
- Access panel for USB connection
- Transparent or open top section for OLED display viewing
- Adequate internal space for wiring management
- Open the Arduino IDE
- Select
Tools > Board > Arduino Micro - Select the appropriate port under
Tools > Port - Open the source file:
Submission/src/src.ino - Verify/compile the code using the checkmark button
- Upload to the Arduino Micro using the arrow button
The joystick requires initial calibration due to manufacturing variations. The device automatically calibrates on startup by averaging 10 readings over 500ms. If manual adjustment is needed:
- Uncomment debug lines 174-177 in the source code
- Upload and open Serial Monitor at 115200 baud
- Note the resting X and Y values
- Update
joyRestXandjoyRestYconstants (lines 31-32) - Re-upload the firmware
Key Selection:
- Press and hold the Shift button
- Move the joystick in the direction of the desired key (the circle is divided into 12 sectors of 30 degrees each)
- The OLED will display the selected key
- The corresponding LED will illuminate
- Release the Shift button
Mode Toggle:
- Press the Mode button to toggle between Major (Ionian) and Minor (Aeolian) modes
- The OLED displays the current mode
- Scale degree chord qualities update automatically
Free Chord Mode:
- Hold the Shift button
- Press the Mode button to toggle between Free Major and Free Minor modes
- In Free Chord Mode, all 12 chord buttons are active and play the selected chord quality
- All 12 chord LEDs illuminate
Playing Chords:
- Press any chord button in the illuminated positions
- The device plays a triad (root, third, fifth) appropriate to the scale degree
- The OLED displays the chord name and constituent notes
Playing Melody:
- Press any of the 12 melody buttons to play individual chromatic notes
- These can be combined with chord buttons for extended harmonies
- The OLED displays the note name
Octave Control:
- Press Octave Up to shift all notes up one octave (range: +3 octaves)
- Press Octave Down to shift all notes down one octave (range: -2 octaves)
Expression Control:
- Move joystick left/right for pitch bend (when Shift is not held)
- Move joystick up/down for modulation (CC#1, mappable in DAW)
- Connect the device via USB
- The device appears as a class-compliant MIDI input (no drivers required)
- In your DAW, enable the Arduino Micro as a MIDI input device
- Route MIDI to a software instrument or external hardware via MIDI routing
- Map joystick modulation (CC#1) to desired parameters (filter cutoff, vibrato depth, etc.)
The Circle of Fifths is a geometric representation of the twelve pitch classes arranged in a circle, where each position is a perfect fifth interval (seven semitones) higher than the previous one. Starting from C and moving clockwise: C - G - D - A - E - B - F#/Gb - C#/Db - G#/Ab - D#/Eb - A#/Bb - F - (returns to C).
This arrangement reveals several important musical relationships:
- Key Signatures: Adjacent keys differ by only one sharp or flat
- Relative Majors and Minors: Keys directly opposite share key signatures
- Common Chord Progressions: Movement between adjacent positions creates strong harmonic motion
- Modulation Paths: Keys close on the circle are easier to modulate between
Further reading: Circle of Fifths - Wikipedia
A diatonic scale consists of seven notes selected from the twelve chromatic pitches according to a specific pattern of whole and half steps.
Major Scale (Ionian Mode): The major scale follows the interval pattern: W-W-H-W-W-W-H (where W = whole step/2 semitones, H = half step/1 semitone). In semitones from the root: 0, 2, 4, 5, 7, 9, 11.
Natural Minor Scale (Aeolian Mode): The natural minor scale pattern: W-H-W-W-H-W-W. In semitones from the root: 0, 2, 3, 5, 7, 8, 10.
This controller implements both modes and constrains chord generation to scale degrees within the selected mode.
Further reading: Diatonic Scale - Wikipedia
A triad is a three-note chord constructed by stacking thirds. The device generates triads using the root, third, and fifth degrees of the scale:
- Major Triad: Root + Major 3rd (4 semitones) + Perfect 5th (7 semitones)
- Minor Triad: Root + Minor 3rd (3 semitones) + Perfect 5th (7 semitones)
- Diminished Triad: Root + Minor 3rd (3 semitones) + Diminished 5th (6 semitones)
Chord Qualities by Scale Degree:
Major Mode: I (maj), ii (min), iii (min), IV (maj), V (maj), vi (min), vii° (dim)
Minor Mode: i (min), ii° (dim), III (maj), iv (min), v (min), VI (maj), VII (maj)
The device automatically generates the appropriate chord quality based on the selected key, mode, and button pressed.
Further reading: Triad - Wikipedia
An interval describes the distance between two pitches. The perfect fifth (7 semitones) is one of the most consonant intervals and forms the basis of the Circle of Fifths organisation. Other important intervals used in triad construction include:
- Major Third: 4 semitones
- Minor Third: 3 semitones
- Perfect Fifth: 7 semitones
The controller's layout reinforces these interval relationships through physical button positioning and constrained note selection.
Further reading: Interval - Wikipedia
MIDI (Musical Instrument Digital Interface) is a technical standard for communication between electronic musical instruments and computers. This device sends MIDI Note On/Off messages (with fixed velocity of 100), Pitch Bend messages, and Control Change messages (CC#1 for modulation).
Further reading: MIDI - Wikipedia
The firmware implements music theory concepts through data structures and algorithms:
Scale Definition:
const uint8_t majorOff[7] = {0, 2, 4, 5, 7, 9, 11}; // Major scale intervals
const uint8_t minorOff[7] = {0, 2, 3, 5, 7, 8, 10}; // Natural minor intervalsMode Profiles: Each mode stores scale intervals and chord qualities for seven scale degrees:
struct ModeProfile {
const uint8_t *offsets; // Pointer to scale intervals
uint8_t qualities[7]; // 0=major, 1=minor, 2=diminished
};Circle of Fifths Mapping:
The array circleSemi[12] maps button positions to semitone offsets in Circle of Fifths order.
Chord Generation Algorithm:
- Detect button press via multiplexer
- Calculate semitone offset from current key root
- Map semitone to scale degree in active mode
- Determine chord quality from mode profile
- Generate triad notes (root, third, fifth)
- Send MIDI Note On messages for all three notes
Key Selection via Joystick: The joystick angle (0-360 degrees) is divided into 12 sectors of 30 degrees each, mapping directly to Circle of Fifths positions.
- MIDI Implementation: USB MIDI Class Compliant (no drivers required)
- Polyphony: 3-note triads plus up to 12 melody notes (limited by connected sound source)
- Latency: <10ms (hardware + USB transmission)
- Octave Range: -2 to +3 octaves from middle C
- Key Range: All 12 chromatic keys
- Modes: 2 (Major/Ionian, Minor/Aeolian)
- Display Refresh: Real-time chord and key information
- Power Consumption: USB-powered (approximately 150-200mA at 5V)
- Velocity Sensitivity: Implementation of velocity-sensitive buttons or capacitive touch sensors for dynamic expression
- Additional Modes: Support for Dorian, Phrygian, Lydian, Mixolydian, and Locrian modes
- Extended Chords: Options for seventh, ninth, suspended, and augmented chords
- Arpeggiator: Built-in arpeggiator with variable patterns and rates
- Standalone Operation: MIDI output jack for use without computer
- Rechargeable Battery: Wireless operation capability
- Robust Enclosure: Professionally manufactured case for durability
- Settings Memory: EEPROM storage for preferred key and mode settings
Device not recognised by computer:
- Ensure USB cable supports data transfer (not charge-only)
- Try a different USB port
- Check that Arduino Micro is properly powered (LED should illuminate)
No MIDI output:
- Verify device appears in DAW's MIDI preferences
- Check MIDI routing in DAW
- Ensure MIDIUSB library is properly installed
Incorrect key selection with joystick:
- Re-run joystick calibration procedure
- Check joystick wiring to A4 and A5 pins
- Verify joystick has stable power supply
LEDs not illuminating:
- Check LED polarity (longer leg = anode/positive)
- Verify current-limiting resistors are installed
- Test LED multiplexer select pin connections
Buttons not responding:
- Test button continuity with multimeter
- Verify multiplexer connections
- Check that INPUT_PULLUP is configured for button pins
This project was developed as part of the CS5041 Interactive Hardware and Software module at the University of St Andrews (Academic Year 2024-2025).
- MIDIUSB Library: Arduino LLC
- Adafruit SSD1306 Library: Adafruit Industries
- Adafruit GFX Library: Adafruit Industries
- Bounce2 Library: Thomas O Fredericks
- Circle of Fifths concept: Public domain music theory
- MIDI specification: MIDI Manufacturers Association
- Circle of Fifths - Wikipedia
- Diatonic Scale - Wikipedia
- Triad (music) - Wikipedia
- Interval (music) - Wikipedia
- Mode (music) - Wikipedia
- Scale degree - Wikipedia
- Semitone - Wikipedia
- MIDI - Wikipedia
- USB MIDI - Wikipedia
- I2C Communication Protocol - Wikipedia
- CD4067 Multiplexer Datasheet
- ATmega32U4 Microcontroller - Wikipedia
- SSD1306 OLED Controller - Wikipedia
Project Author: Student ID 240030041 Course: CS5041 - Interactive Hardware and Software Institution: University of St Andrews Submission Date: April 21, 2025