Skip to content

Commit 4c0f244

Browse files
authored
Add piano (tone playback) demo.
1 parent 54d2903 commit 4c0f244

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

examples/piano.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# MPR121 piano demo.
2+
# Listens to the first 7 inputs of the MPR121 and plays a middle scale note
3+
# when an input is touched. Note only one note is played at a time!
4+
# Author: Tony DiCola
5+
import time
6+
7+
import board
8+
import nativeio
9+
10+
# Uncomment _one_ of the following lines depending on how your board supports I2C.
11+
# For hardare I2C (SAMD21/M0 boards):
12+
import nativeio as io
13+
# For software I2C (ESP8266):
14+
#import bitbangio as io
15+
16+
# Import MPR121 module.
17+
import adafruit_mpr121
18+
19+
20+
# Configure PWM buzzer and other state:
21+
BUZZER_PIN = board.D9
22+
TONE_ON_DUTY = 2**15 # Duty cycle of tone when turned on, a square wave.
23+
TONE_OFF_DUTY = 0 # Duty cycle of tone when turned off, 0 or no signal.
24+
NOTE_FREQS = [ 261, # Input 0 = 261 hz = middle C
25+
294, # Input 1 = middle D
26+
329, # Input 2 = middle E
27+
349, # Input 3 = middle F
28+
392, # Input 4 = middle G
29+
440, # Input 5 = middle A
30+
493, # Input 6 = middle B
31+
0, # Input 7 = nothing (set to a frequency in hertz!)
32+
0, # Input 8
33+
0, # Input 9
34+
0, # Input 10
35+
0 ] # Input 11
36+
37+
38+
# Create I2C bus.
39+
i2c = io.I2C(board.SCL, board.SDA)
40+
41+
# Create MPR121 class.
42+
mpr121 = adafruit_mpr121.MPR121(i2c)
43+
# Note you can optionally change the address of the device:
44+
#mpr121 = adafruit_mpr121.MPR121(i2c, address=0x91)
45+
46+
# Setup buzzer PWM output.
47+
buzzer = nativeio.PWMOut(BUZZER_PIN, duty_cycle=TONE_OFF_DUTY, frequency=440,
48+
variable_frequency=True)
49+
50+
# Main loop.
51+
# First grab an initial touch state for all of the inputs. The touched()
52+
# function can quickly get the state of all input pins and returns them as a
53+
# 12-bit value with a bit set to 1 for each appropriate input (i.e. bit 0 is
54+
# input 0, bit 1 is input 1, etc.)
55+
last = mpr121.touched()
56+
while True:
57+
# Every loop iteration get an updated touch state and look to see if it
58+
# changed since the last iteration.
59+
current = mpr121.touched()
60+
if last != current:
61+
# Some pin changed, turn off playback and look for any touched pins.
62+
buzzer.duty_cycle = TONE_OFF_DUTY
63+
# Loop through all 12 inputs (0-11) and look at their bits in the
64+
# current touch state. A bit that's set is touched!
65+
for i in range(12):
66+
if (1 << i) & current > 0:
67+
print('Input {} touched!'.format(i))
68+
# Grab the frequency for the associated pin and check that it's
69+
# not zero (unused).
70+
freq = NOTE_FREQS[i]
71+
if freq != 0:
72+
# Pin with a specified frequency was touched, play the tone!
73+
buzzer.frequency = NOTE_FREQS[i]
74+
buzzer.duty_cycle = TONE_ON_DUTY
75+
# Update touch state and delay a bit before next loop iteration.
76+
last = current
77+
time.sleep(0.01)

0 commit comments

Comments
 (0)