|
| 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