*This post is part of a series of projects(I currently have 4 designs in mind) where I incorporate Adafruit’s MPR121 12-Key Capacitive Touch Sensor with different plants and Raspberry Pis to create several carbon-neutral electronic musical instruments.*
**The DWG and code are my own. Both were built /designed by me with no input or support from outside sources.**
The following video is a brief demonstration of the Bamboo Box in action.
BOM(Bill of Materials):
- 3D Printer
- Raspberry Pi
- Capacitor(I needed a 100μf, your’s will be probably be different)
- External battery power supply(optional, you could use the Pi)
- Power supply for Raspberry Pi
- Couple screws
- Hot glue gun
- Magnet wire
- Sandpaper
- Electrical wires
- Sewing needles
- perf board(optional I used it for the capacitor)
- LM386(it’s an audio amplifier – you’ll need to find some way to power this)
- Junk pair of headsets or aux cord(it’s for the 3.5mm plug)
- Drill(you can avoid needing this if you modify the DWG’s provided below)
- Dirt
- Pebbles(I found white ones at Wal-Mart in the aquarium dept)
- A plant(I’ve tried a few. So far bamboo has worked the best)
- Adafruit’s Capacitive Touch Hat
- Tubing(again, I got it from the aquarium dept)
Construction:
- Print the parts provided in the DWG above.
- Solder wires to the back of your speaker.
- Mount the Raspberry Pi and speaker.
- You may need to modify the DWG to fit your particular speaker.
- With the sandpaper, sand a length of your magnet wire.
- Using a sewing needle, stitch your magnet wire through the plant. Keep in mind, it’ll be helpful if you keep at least part of the wire exposed(just incase) and that you want the sanded length to be what it stitched through the plant.
- After you have the wire stitched through each part, make sure to leave a LONG length hanging out and connected. That way you have plenty to reach the board.
- Solder the capacitor and the unsoldered ends of the speaker wires into the perf board.
- Solder a pair of wires to the perf board and connect the other end to the LM386.
- Strip the headset wires, identify ground and signal wires and connect them to the LM386.
- Drill holes, large enough for the tubing, into the inner pot reservoir.
- Run the aquarium tubing through the holes you just drilled up to the interior of the inner pot reservoir.
- The idea here is to have enough tubing that when you fill the inner reservoir with soil you won’t cover the tubes.
- Run the magnet wires through the tubes.
- Connect the copper wires to your MPR121 12-Key Capacitive Touch Sensor.
- Connect the sensor and LM386 to your Raspberry Pi.
- Connect you pwer supply to the Pi and LM386
- Put the pot together and add soil.
The Code:
The following code is a first draft.
# Author:
# Mathew Tucker
# Date:
# 16OCT21
# Description:
# The following code allows
# the user to trigger musical
# notes via signals captured
# Adafruit's Touch Capacitive
# Hat.
#Definition for building and setting scales
def scale():
# Notes of intstrument
C = 62
D = 76
E = 78
F = 79
G = 81
A = 83
B = 85
# Scales
MajorPenatonic_1 = [C,D,E,G,A]
MajorPenatonic_2 = [F,G,A,C,D]
MajorPenatonic_3 = [G,A,B,D,E]
EgyptianSuspen_1 = [D,E,G,A,C]
EgyptianSuspen_2 = [G,A,C,D,F]
EgyptianSuspen_3 = [A,B,D,E,G]
val = 4#int(input("Please enter a value 1-6 to select a scale: "))
if val == 1:
return MajorPenatonic_1
if val == 2:
return MajorPenatonic_2
if val == 3:
return MajorPenatonic_3
if val == 4:
return EgyptianSuspen_1
if val == 5:
return EgyptianSuspen_2
if val == 6:
return EgyptianSuspen_3
else:
print("Please try again")
scale()
def play(midi_out, inst):
import board
import busio
import adafruit_mpr121
import pygame
import pygame.midi
import sys
import time
# Create I2C bus.
i2c = busio.I2C(board.SCL, board.SDA)
# Create MPR121 object.
mpr121 = adafruit_mpr121.MPR121(i2c)
note=scale()
midi_out.set_instrument(inst)
# Volume
MAX = 127
# Touch Threshhold
touch = [0,1,2,3,4]
# Each the leads each shoot of the bamboo plant
# is conntected to
shoots = [1, 4, 7, 9, 11]
j=0
for i in shoots:
touch[j]= 90#0.75*mpr121[i].raw_value
j=j+1
# The Try-Except block allows the user to break the while-loop with CTRL+C and
# change the instrument from the default- Grand Piano(0)
try:
# Loop until CTRL+C is pressed
while True:
# Loop through each lead (1,4,7,9,11).
for i in shoots:
if mpr121[i].raw_value:
print('pin ' + str(i) + ': ' + str(mpr121[i].raw_value))
if mpr121[1].raw_value<touch[0]:
#Play note
midi_out.note_on(note[4],MAX)
print("playing note 4")
else:
#Stop note
midi_out.note_off(note[4],MAX)
if mpr121[4].raw_value<touch[1]:
#Play note
midi_out.note_on(note[2],MAX)
print("playing note 2")
else:
#Stop note
midi_out.note_off(note[2],MAX)
if mpr121[7].raw_value<touch[2]:
#Play note
midi_out.note_on(note[1],MAX)
print("playing note 1")
else:
#Stop note
midi_out.note_off(note[1],MAX)
if mpr121[9].raw_value<touch[3]:
#Play note
midi_out.note_on(note[3],MAX)
print("playing note 3")
else:
#Stop note
midi_out.note_off(note[3],MAX)
if mpr121[11].raw_value<touch[4]:
#Play note
midi_out.note_on(note[0],MAX)
print("playing note 0")
else:
#Stop note
midi_out.note_off(note[0],MAX)
time.sleep(1)
except KeyboardInterrupt:
inst = int(input("Please enter a value from 0-127: "))
play(midi_out, inst)
import pygame
import pygame.midi
pygame.mixer.pre_init(44100, -16, 2, 2048)
pygame.init()
pygame.midi.init()
port = pygame.midi.get_default_output_id()
#print(port)
midi_out = pygame.midi.Output(3, 0)
#print(pygame.midi.get_device_info(port))
inst = 1
play(midi_out, inst)
To run the code and get the Bamboo Box to play, run the following commands in two separate terminal sessions-
timidity -A800 -iA
cd <the path to the folder holding your file>
python3 Your_File.py
A few quick notes:
- You’ll need to have Timidity to run the above Timidity command. If you do not already have I would suggest going to the following pages-
- The command -A### sets the audio level. ### must be between 0 and 800.
The Code(Fin?):
The following code is a more finished version. I may still clean it up some more, but for now… I’ve got it working; and, am moving on to designing and building a “wind instrument” version of this project.
# Author:
# Mathew Tucker
# Date:
# 21JAN22
# Description:
# The following code allows
# the user to trigger musical
# notes via signals captured
# Adafruit's Touch Capacitive
# Hat.
inst = 1
# Notes of intstrument
C = 62
D = 76
E = 78
F = 79
G = 81
A = 83
B = 85
# Scales
MajorPenatonic_1 = [C,D,E,G,A]
MajorPenatonic_2 = [F,G,A,C,D]
MajorPenatonic_3 = [G,A,B,D,E]
EgyptianSuspen_1 = [D,E,G,A,C]
EgyptianSuspen_2 = [G,A,C,D,F]
EgyptianSuspen_3 = [A,B,D,E,G]
def scale():
val = 4#int(input("Please enter a value 1-6 to select a scale: "))
if val == 1:
return MajorPenatonic_1
if val == 2:
return MajorPenatonic_2
if val == 3:
return MajorPenatonic_3
if val == 4:
return EgyptianSuspen_1
if val == 5:
return EgyptianSuspen_2
if val == 6:
return EgyptianSuspen_3
else:
print("Please try again")
scale()
def plant_instrument(midi_out, inst):
import board
import busio
import adafruit_mpr121
import pygame
import pygame.midi
import sys
import time
# Create I2C bus.
i2c = busio.I2C(board.SCL, board.SDA)
# Create MPR121 object.
mpr121 = adafruit_mpr121.MPR121(i2c)
note=scale()
midi_out.set_instrument(inst)
# Each the leads each shoot of the bamboo plant
# is conntected to
shoots = [1, 4, 7, 9, 11]
# Initial state of all shoots if "off"
state = [0, 0, 0, 0, 0]
# Volume
MAX = 127
# Touch Threshhold
touch = [90, 90, 90, 90, 90]
def play(j):
if state[j] == 1:
if mpr121[shoots[j]].raw_value > touch[j]:
midi_out.note_off(note[j], MAX)
state[j] = 0
if state[j] == 0:
if mpr121[shoots[j]].raw_value < touch[j]:
midi_out.note_on(note[j], MAX)
state[j] = 1
# print(state)
time.sleep(0.1)
try:
# Loop until CTRL+C is pressed
while True:
# Loop through each lead (1,4,7,9,11).
for i in range(5):
if mpr121[shoots[i]].raw_value:
print('pin ' + str(shoots[i]) + ': ' + str(mpr121[shoots[i]].raw_value))
play(i)
except KeyboardInterrupt:
inst = int(input("Please enter a value from 0-127: "))
plant_instrument(midi_out, inst)
import pygame
import pygame.midi
pygame.mixer.pre_init(44100, -16, 2, 2048)
pygame.init()
pygame.midi.init()
port = pygame.midi.get_default_output_id()
print(port)
midi_out = pygame.midi.Output(3, 0)
print(pygame.midi.get_device_info(port))
plant_instrument(midi_out, inst)
As a quick note, I will be addressing the lack of “velocity” control in the next iteration of this project.