The Programmable Hurdy-Gurdy

Bringing "Digital" Sound to the Middle Ages


The Programmable Hurdy-Gurdy seeks to combine embedded systems with a traditional instrument to produce innovative sounds and experiences. It exists alongside a growing number of projects which fuse art and electronics 🎔


In this project, the team connected the worlds of classical acoustic instruments and mechatronics to create something new and unique. The instrument in question is a Hurdy-Gurdy, which were common in the medieval to renessaince eras in Europe. It is similar to a violin in some respects, however the bow is replaced by a wheel which is traditionally turned with a crank. To bring this instrument into the digital age, we used a Raspberry Pi, along with several motors to emulate the cranking of the wheel and the pressing of keys against the strings to change notes. In the software side, MIDI files as well as live input were translated into the mechanical actions necessary to produce the appropriate notes and pace. For example, if we received the note A we would trigger the appropriate linear actuator to sound A on the string. Finally, a UI application was made to configure and run the project.


Evan Welsh (ew469)

The Primary Programmer

Elliot Hare (eph58)

The Best™ Builder



The Programmable Hurdy-Gurdy is comprised of a Raspberry Pi connected to multiple motor drivers. These motor drivers control "fretters" which manipulate the instrument's strings in place of a human player's fingers. An additional motor replaces the traditional crank to turn the wheel which sounds the instrument.

Behind-the-scenes, The Programmable Hurdy-Gurdy is orchestrated by a multi-threaded Python application. The Python application has a web server thread which serves an API for the user interface to control the Hurdy-Gurdy, send MIDI files, and connect MIDI instruments for live playing. The other thread is our "motor controller" which handles queueing motor actions and timing.


The circuit diagram above shows the wiring for the motors that drive the Hurdy-Gurdy. The four fretting motors share one PWM signal to control their speed, and the wheel has one for itself. 100 Ohm current-limiting resistors are in series with each GPIO pin to prevent any damage to the Pi from a backrush of current. Lastly, the motors are powered from a battery pack of four AA batteries, driving them at 6V.

Instrument Box

Design of Hurdy-Gurdies became more ornate and complex as history moved into the renaissance. Our design is more similar to the earlier medieval examples, which are more box-like and simple. We also referenced a set of DIY Hurdy-Gurdy instructions, but did not follow any specific guidelines it lays out.

Beginning with a box, the moving components were arranged inside to keep the design compact. This was sensible for the wheel, where the crank arm in a manual instrument was replaced with a motor. However for the fingers, to control them from within the box needed a slightly differnt playing mechanism than keys on a traditional intstrument. Instead of pressing on the strings from the side, these act as frets which can be engaged or disengaged through lifting by a rotating cam. Parts were laser cut from plywood, then assembled with both glue and mechanical fasteners.

Construction Challenges

There was some difficulty in the construction and assembly of the prototype. These were partly from poor design choices, but mostly caused by acoustic instruments needing quite exact tolerances and dimensions. Mainly, there were two issues. First, the wheel had a large enough radius that when combined with the friction of the strings pushing down on it was able to stall the motor. To address this issue, the original four strings were reduced to one. The second construction issue came in the tolerances of the fingers. The contact between them and the string needs to be firm, to produce a clean tone, but applying to much force could lift the string off of the wheel, such that it was no longer 'bowed' and created no sound. To attempt to fix this, each cam follower was filed by hand to be the hieght that needed to produce the best tone.


For our project, we purchased many of the components necessary for a musical instrument independently. Our motors, motor controllers, and wood were sourced from Prof. Skovira and the lab. We have provided our "best guess" of pricing for the provided components. The total build was approx. $89.65, though wood costs could likely be significantly reduced.

Purchased Parts
C String Link1$7.19
G String Link1$12.50
String Tuning Pegs Link1$14.99
Rosin Link1$3.15
Cotton Link1 Bundle$5.97
Provided Parts
Estimated Price
Motors 5$10
Lauan Plywood 1 Sheet$30
Motor Driver 3$4.95
Est. Total$45.85

Software Stack

The software is split into two parts: a frontend interface and a backend which serves an API and orchestrates our motors. The frontend is built using Ionic React, a framework of responsive web components. We use axios to connect to our API, to facilitate live connections, and WebMIDI.js to connect MIDI keyboards (and other inputs) to our live sessions.

The backend is split into two threads: the motor controller and the web server. The web server utilizes Flask and Flask-RESTful to create a basic REST API with the ability to upload MIDI files for playback, playing and stopping the Hurdy-Gurdy, and viewing some current state. In live sessions, we utilize to connect to the web server and issue MIDI key presses over a web socket (web sockets are network sockets between a web browser and server). Web sockets provide much lower latency than simple REST API calls and allow for near-realtime event handling over a network.

The motor controller is comprised of an event loop and thread-safe Python queue. The web server thread uses the queue to initiate future key presses and the event loop contiuously pulls key presses from the queue in a FIFO fashion. In addition to the queue, the motor controller remains a dispatch queue which dispatches future motor events which much occur at precise times. The most common of these is a "stop" event. After a note is supposed to stop playing we must reverse the "finger" motor. After approx. 0.25 seconds we must stop this reverse action. The dispatch loop handles this behavior.

We use Mido to translate MIDI input into notes and timing metadata. Due to a limited number of motors, The Programmable Hurdy-Gurdy can only play a subset of notes so we utilize musicalbeeps to virtualize missing notes.

User Interface

The Home Screen

The Home Screen

Recorded Audio Playback View

Recorded Audio Playback View

Live Playback View

Live Playback View

Connecting A MIDI Keyboard

Connecting A MIDI Keyboard

MIDI Keyboard Connected

MIDI Keyboard Connected


Working virtually, with each group member in different halves of the country made some parts of testing a challenge. Because Evan was working with the software while Elliot worked on hardware, Evan controlled the prototype from his home machine using SSH after accessing Elliot's home network. The testing procedure then involved Evan running simple test songs from midi files or from his keyboard to see the response from Elliot's end. Even though this was a difficult and slow process, testing went smoothly. Issues were located and fixed as best as possible where they appeared.


Our final prototype was less capable than we had intended; There were two places where our objectives were not met. First, playing back existing midi files turned out to be much more of a challenge than first anticipated, as our instrument can only play one note at a time, and has its own restrictions in terms of the practical tempo at which the motors could change notes. Secondly, we initially wanted to have four strings playing at different notes to round out the sound, but compromised functionality, so we went to using one string instead. We did succeed insofar as we made an instrument which we could play with a live midi input -- from halfway accross the country no less.

Future Work

  • Improving Sound Quality
  • As mentioned in the Construction Challenges section, Some changes to the instrument design are needed to improve the quality of the sound. To address this, a more robust fretting mechanism is needed, along with a higher torque motor driving the wheel. For the fretting mechanism, we believe going back to original Hurdy-Gurdies and using a system that pushes laterally would avoid the problems of weak contact, as well as adding felt pads to the fingers for some compression to further improve contact.

  • Fine-grained software controls
  • In addition to basic start and stop functionality when playing back MIDI files, the player would ideally also include the ability to skip ahead and manage tracks.

  • Local USB "live" control
  • While we support live control over local and remote networks, we do not currently support directly plugging MIDI devices into a Pi. This would require adding handlers for USB-based MIDI events in Python and Mido.

Source Code

Cornell GitHub