Create your own fruit piano with this python script. Place 12 apples on a table and create your own midi piano with light effects. YouTube Video
- Simultaneous Key Presses Play 12 notes at the same time
- High Quality Audio using .sf2 sound fonts and fluidsynth midi synthesizer
- HDMI or Analog Audio use an HDMI cable or the headphone jack for audio
- Sustain Hold down a piano key to sustain instruments like pipe organs
- Mode Switch Connect an optional switch to at GPIO pin and switch between different instruments or even drum kits YouTube demo of various modes
- Light Effects Add neopixel lights and each piano key will light up when pressed
- For best touch sensitivity, minimize distance between fruit and capacitive touch sensor. For small fruit like apples, no more than two or three feet. For large objects like pumpkins, 8 inches or less. Instead of placing the capacitive touch sensor on the breadboard, run long wires (I used cat5 cable) from the breadboard to the table with your fruit, then wire up the capacitive touch sensor as close as possible to the fruit.
- The capacitive touch sensor calibrates when initialized, so do not touch the fruit while starting piano.py until the lights flash orange. If one of the fruit is stuck on, or unresponsive, stop the script (Ctrl+C) and restart it
sudo python piano.py
to recalibrate the sensitivity. - Protect your neopixels with a capacitor and read the *Adafruit NeoPixel Überguide - Powering Neopixels section
This is my first Python project so I'm sure the code could be more elegant.
- Raspberry Pi 3
- MPR121 12-key capacitive touch sensor
- 12 conductive objects like fruit or aluminium foil
- Dupont wire jumper cables
- Breadboard
- Speaker (must be amplified, HDMI cable to TV/receiver sounds great, headphone jack has a little background noise but is tolerable)
- Neopixel string or strip (addressable LEDs such as WS2812 lights)
- Neopixel power supply see Adafruit Powering NeoPixels guide
- Logic level shifter to convert 3.3v to 5v. Required for driving neopixels from a 3.3v source like a Raspberry Pi.
- Capacitor (1000 µF, 6.3V or higher) to protect the neopixels from being damaged by initial onrush of current
- Momentary button (if switching between multiple instruments)
- 10k resistor
- Adafruit_MPR121 12-key capacitive touch sensor
- fluidsynth
- python-mingus midi synthesizer
- rpi_ws281x neopixel lights
- Enable i2c support in Raspian
- Install the above software libraries
sudo apt-get install fluidsynth
to install fluidsynthsudo pip install mingus
to install Mingus
- Edit piano.py
- fluidsynth.init('path/to/your/soundfont.sf2')
- LED_COUNT = (number of neopixels)
- LED_STRIP = (type of neopixel strip)
- lightSegments = (array of which neopixels should illuminate for each key)
- Might have to edit /etc/asound.conf with default audio card
- run
sudo python piano.py
from terminal (Sudo is required for python to access the GPIO pins)
- Install pm2
sudo pm2 start piano.py
sudo pm2 save
sudo reboot
- piano.py will run at startup, neopixels will blink orange when piano is ready
A sound font (.sf2 file) is required for generating audio. .sf3 files won't work with fluidsynth. Installing ``fluidsynth using apt-getshould also download the default sound font to
/usr/share/sounds/sf2/FluidR3_GM.sf2``` but you can download other sound fonts from this link. I used the Arachno sound font. Larger .sf2 files like Timbres of Heaven caused an out of memory error when attempting to run piano.py.
A .sf2 file contains dozens or hundreds of instruments, from pianos to drum kits, sometimes organized into seperate "banks". To find an instrument I liked, I use a free program called Polyphone to open the .sf2 file and browse each instrument. Clicking the keyboard at the top right of Polyphone lets you preview what each note will sound like. Once you find an instrument you like, note the preset and bank number, and enter these numbers into the piano.py. For example, the Arachno sound font has an orchestra drum kit as preset 48 in bank 128. So to load this instrument into your piano as channel 1, use the following line of code:
fluidsynth.set_instrument(1, 48, 128)