{"id":16131923,"url":"https://github.com/uberi/anana","last_synced_at":"2026-02-05T23:01:28.908Z","repository":{"id":140669659,"uuid":"42372329","full_name":"Uberi/Anana","owner":"Uberi","description":"The least ergonomic MIDI keyboard ever invented.","archived":false,"fork":false,"pushed_at":"2015-09-13T01:03:34.000Z","size":29676,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-12T03:20:16.578Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Uberi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-12T20:41:47.000Z","updated_at":"2016-12-05T12:32:14.000Z","dependencies_parsed_at":"2023-03-13T10:41:16.244Z","dependency_job_id":null,"html_url":"https://github.com/Uberi/Anana","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Uberi/Anana","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Uberi%2FAnana","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Uberi%2FAnana/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Uberi%2FAnana/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Uberi%2FAnana/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Uberi","download_url":"https://codeload.github.com/Uberi/Anana/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Uberi%2FAnana/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29137751,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T22:49:08.052Z","status":"ssl_error","status_checked_at":"2026-02-05T22:45:32.059Z","response_time":65,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-09T22:28:20.406Z","updated_at":"2026-02-05T23:01:28.883Z","avatar_url":"https://github.com/Uberi.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"Ananaphone\n==========\nThe least ergonomic MIDI keyboard ever invented.\n\nTouch the metal bits to play sounds! The LEDs pulse and react to your actions.\n\n![Animated demo](img/demo.gif)\n\n# [VIDEO DEMO](https://www.youtube.com/watch?v=Nx6oU0oYaCI)\n\n![Back view](img/back.jpg)\n\n![Front view](img/front.jpg)\n\nPhysical Setup\n--------------\n\nThe base is a piece of Delrin about 10cm by 20cm - I used about half of an old cutting board. The metal sticking-up bits are lengths of 12 guage galvanized steel gardening wire, available from most hardware stores:\n\n![Bottom view](img/bottom.jpg)\n\nI started off by drilling 3/32\" holes (that's 2.38mm in real units) where the wire should stick up, then for each hole, drilling another one 1.5cm away from it. The gardening wire was threaded through each hole, then bent back through the corresponding hole spaced 1.5cm away, using locking pliers. Bending it back in on itself, the gardening wire is securely attached to the base. Afterward, the gardening wire was bent and twisted until it was no longer ergonomic. I glued a transparent plastic sheet to the bottom of the whole thing to prevent the gardening wires from shorting together if placed on a conductive surface.\n\nThe gardening wire is electrically connected using alligator clips crimped to 22AWG copper wire:\n\n![Alligator clips on the gardening wire](img/clips.jpg)\n\nIn hindsight, the copper wires were way too long and resulted in a rat's nest of wires above the Arduino. However, this does make it pretty easy to rearrange the connection layout afterward.\n\nThe other ends of each wire are soldered to the touch terminals of the [Adafruit MPR121 12-channel capacitive touch shield](https://www.adafruit.com/products/2024) on top of the [Arduino Uno](https://www.arduino.cc/en/Main/arduinoBoardUno):\n\n![Arduino plus touch shield](img/arduino.jpg)\n\nThat's all that's needed for the touch sensing! The touch shield conveniently includes through-hole soldering connection points for attaching the wires, and it is mechanically very robust.\n\nFor the lights, I made a 4-channel low-side switch with 2N2222 NPN transistors and a few resistors:\n\n![Amplifier board](img/amplifier.jpg)\n\nThis board was needed because the I/O pins on the Arduino can't handle the ~50mA each LED draws. Instead, each pin simply switches the transistor.\n\nThe amplifier board has 6 inputs (power, ground, and 4 signal lines that are connected to Arduino PWM outputs) and is connected directly to 4 LEDs.\n\n![Lights setup](img/light.jpg)\n\nKneading the hot glue as it's cooling reulted in a nice \"organic\" effect that also made it diffuse light better. I love hot glue. The lights are wound around various parts of the gardening wire structure.\n\nSoftware\n--------\n\nThe Arduino is running a pretty short sketch that simply sends touch data (retrieved using the excellent [Adafruit MPR121 library](https://github.com/adafruit/Adafruit_MPR121_Library)) to the computer over serial, and controls the LED brightnesses. The sketch source code can be found under the `arduino/Touch` directory.\n\nThe touch data is sent as strings of base-10 numbers, one per line, such that, when converted into a 12-bit binary number, each binary digit represents the touch state of one of the 12 channels (the least significant bit represents channel 0, and the most significant bit represents channel 11). For example, a line containing `7` means that channel 0, 1, and 2 have detected touches, and no others. Touch data is sent when one or more untouched channels are touched, or one or more touched channels are no longer touched.\n\nOn the computer side, there's a few Python scripts that interface with the Arduino using [PySerial](http://pyserial.sourceforge.net/):\n\n* `anana-samples.py` uses [PyGame](http://www.pygame.org/hifi.html) to play WAV samples in `sounds/` when any of the channels are touched.\n* `anana-midi.py` uses [PyGame](http://www.pygame.org/hifi.html) to send MIDI messages, which can then be interpreted by software such as [LMMS](https://lmms.io/) or [Ableton Live](https://www.ableton.com/).\n\nTo use these scripts:\n\n1. Make sure you have the dependencies (Python 3.4+, PySerial 2.7+ and PyGame 1.9+) - on Debian/Ubuntu, these can be installed simply by running `setup.sh`.\n2. It may be necessary to configure the scripts. For example, the `SERIAL_PORT` and the `MIDI_OUTPUT` variables will often depend on your system configuration. The `SERIAL_PORT` variable should be a string like `COM5` (for Windows) or `/dev/ttyACM0` (for POSIX), and the MIDI_OUTPUT variable should be a non-negative integer representing the MIDI output device index to use.\n3. Plug in the Arduino.\n4. Wait for the LED bulbs to come on, then start one of the `anana-*.py` scripts.\n5. Touch the metal bits!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuberi%2Fanana","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuberi%2Fanana","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuberi%2Fanana/lists"}