https://github.com/jonnor/hangdrum
Electronic percussive instrument using capacitive touch (firmware)
https://github.com/jonnor/hangdrum
arduino cplusplus-11 embedded-systems firmware functional-programming midi
Last synced: 3 months ago
JSON representation
Electronic percussive instrument using capacitive touch (firmware)
- Host: GitHub
- URL: https://github.com/jonnor/hangdrum
- Owner: jonnor
- Created: 2017-02-25T22:14:38.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2018-04-10T09:43:51.000Z (about 7 years ago)
- Last Synced: 2025-02-08T15:48:04.153Z (4 months ago)
- Topics: arduino, cplusplus-11, embedded-systems, firmware, functional-programming, midi
- Language: C++
- Homepage: https://www.dhang.eu/
- Size: 16.3 MB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Hangdrum
Firmware for a MIDI hang-drum using capacitive touch pads.

Blogposts
* [Host-based simulation for embedded systems](http://www.jonnor.com/2017/03/host-based-simulation-for-embedded-systems/)
* [Optimizing latency of an Arduino MIDI controller](http://www.jonnor.com/2017/04/optimizing-arduino-midi-controller-latency/)## Status
**In production*** Used as the firmware for [dhang](https://www.dhang.eu/) since March 2017
* Tested on Arduino Lenonardo (Atmega 32u4)
* Latency until triggered sound heard below 20ms with 8 pads, using Windows with ASIO4LL 96samples
* Detection latency around 1ms per pads## Installing firmware
1. Download repository from Github, or use git to clone.
2. Install the `CapacitiveSensor` Arduino library
3. Open `hangdrum.ino` in Arduino IDE
4. Make sure that the hardware pin configuration is correct
5. Flash the Arduino sketch to device## Hardware setup
See [CapSense documentation](https://playground.arduino.cc/Main/CapacitiveSensor?from=Main.CapSense)
## Architecture
The [core](./hangdrum.hpp) of the firmware is platform and I/O independent, written in C++11.
It can run on a Arduino-compatible microcontroller (tested on Arduino Leonardo), or on a host computer (tested on Arch Linux).A single `State` datastructure holds all state. The program logic is expressed as a pure function of new Input and current State:
`State next = calculateState(const Input inputs, const State current)`.
Both Input and State are plain-old-data which can be safely serialized and de-serialized.
The Hardware Abstraction Layer, which has real-life side-effects, consists of:
A function to read current Input, and a function to "realize" a State.This formulation allows us to:
* *trace* the execution of the program, by capturing and storing the `Input, State` pairs.
* *replay* a trace, by taking the `Input` and applying it to a modified program
* *visualize* a whole-program execution from its trace, both end-results and intermediates
* *test* a whole-program execution, by applying checks against the generated trace
* *simulate* new scenarios by synthesizing or mutating InputWanderers of non-traditional programming methods may recognize inspirations from (Extended) Finite State Machines,
Functional Reactive Programming and Dataflow/Flow-based-programming.
And basically a rejection of Object Oriented Programming (as typically practiced in C++/Java/Python/..),
particularly the idea of combining data and methods that operate on the data into a single class.## Tools
There is an decent set of analysis, simulation and testing tools available.* [tools/logserial.py](./tools/logserial.py): Record capacitive sensor input from device.
* [tools/plot.py](./tools/plot.py): Plot a stream of sensor data
* [bin/simulator](./tools/simulator.cpp): Run the firmware on host. Takes a sensor stream as input.
Can run in real-time, producing ALSA MIDI output. Or in faster-than-realtime, producing a Flowtrace of the entire run.
* [tools/plotflowtrace.py](./tools/plotflowtrace.py): Plot a flowtrace produced by simulator, showing decisions made
* [tools/sendserial.py](./tools/sendserial.py`): Send an input sensor stream to device