Piano for Campus School Project With Arduino Nano RP2040 + MPR121

Hi! My name’s Jack and I’m a senior at Boston College studying Computer Science and Finance. This semester, I’m taking Physical Computing with Professor Gallaugher. We’ve been following a flipped classroom model and I made this project utilizing Professor Gallaugher’s Circuit Python YouTube tutorials.Piano for Campus School Project With Arduino Nano RP2040 + MPR121

For my Campus School Assistive Tech Project, I made a realistic-looking touch-enabled piano that plays appropriately-determined tones when you press on each key.

This project utilizes an Arduino Nano RP2040 running CircuitPython as well as an MPR121 Capacitive Touch Sensor. The sensor uses a STEMMA QT connector to connect to the Arduino, which is mounted on top of a breadboard in order to easily connect cables. There is a small speaker connected to play sounds. Lots of the wiring is connected with alligator clips (for example, these connect the touchpads on the MPR121 to the tinfoil on the keyboard keys). Finally, the Arduino is connected to an external power bank I have so that the setup can run on its own power (standalone, doesn’t need to be connected to a laptop).

I wanted to build this project in particular because I am a piano player myself and remember how fun it was to mess around with electronic keyboards when I was really young (and I still enjoy doing so). I thought it was so cool we learned how to make something like this and wanted to build it for kids at the Campus School to share that joy I had when it came to keyboards and music. I also wanted to make sure it looked realistic and fun (so that’s why I spent a fair amount of time designing the wood and acrylic lasercut stencils by hand).

If you have any questions, don’t hesitate to reach out and I’ll try my best to answer – I’m [email protected].

Supplies

Supplies

All materials:

  • Circuits and wiring materials (middle of image):
  • Arduino Nano RP2040 (can also substitute with Adafruit Circuit Playground Bluefruit or similar)
  • Breadboard (for easily connecting the Arduino to the speaker and MPR121 sensor)
  • MPR121 Capacitive Touch Sensor
  • Speaker with aux out cord (you’ll clip alligator clips to the tip and sleeve)
  • 14 alligator clips (12 to connect MPR121 touchpads to keys, 2 to connect speaker to Arduino)
  • External battery pack or power bank
  • USB 2.0 to Micro USB cable to connect external battery pack to Arduino
  • Any other alligator clips or wires you need to connect all the above
  • Frame and building materials (top and bottom of image):
  • Wood frame to house the piano
  • Acrylic keys (used 1/8″ “vanity” [mirrored] and 1/8″ dark blue acrylic in this project)
  • Take to secure elements like the box sides and keys to create the frame
  • Tinfoil (for the capacitive touch part, will be attached to the bottom of the keys)
  • Scissors to cut the tinfoil (ripping works too but is much less clean)

Step 1: Lasercut and Assemble the Frame and Keys

Lasercut and Assemble the Frame and Keys

First, design and lasercut the materials for the frame and keys. I designed this in Adobe Illustrator and went to my university’s Maker Space to cut this out (they were super nice and helpful).

The frame I made out of wood (1/8″ birch wood I believe), and I made sure to include a hole for the speaker. Optionally, you can add volume control or pitch control potentiometers and I cut out two squares at the top for that. Make sure you include a hole for the keys so they can sit flush (make this bigger than you think as you’ll need to space the keys out so they don’t touch each other), and I also added some text at the top and cut that out too so it looks nice. I made sure the sides of the box could easily slot into slits I made in the top.

For the keys, I tried to make it look realistic, and so used a combination of alternating light and dark keys. I saw the vanity / mirrored acrylic and had to go with that for the white keys! The dark keys are the darkest acrylic I could find which was dark blue.

Assemble the wooden part of the box, which should be as easy as slotting in the sides into the notches on the top and then using tape to make sure everything stays together.

Then cut out some tinfoil to place at the bottom of each key. Wrap the tinfoil around each key, then place the keys next to each other in the proper pattern so you can attached them to the box. I found this was easiest done when the box was upside down. I also used two long thin pieces of wood to support the keys in place, which is critical. Use tape to secure everything down.

Once you have the box all good to go, it’s time to write the code that will run on the circuitry!

Contact me (email at the top and bottom of this Instructable) if you’d like for me to send you the Adobe Illustrator file I used to cut this design!

Step 2: Write the Code!

Write the Code

Now it’s time to write the CircuitPython code that will run on the Arduino Nano RP2040.

Let’s briefly walk through it line-by-line:

First, add your import statements for the libraries you’ll need for the project.

import time, board, pwmio, adafruit_mpr121

Then, add these lines to set up your touchpad (MPR121 Capacitive Touch Sensor).

i2c = board.I2C()
touch_pad = adafruit_mpr121.MPR121(i2c)

Next, add these lines to set up your Arduino with your external speaker.

tone = pwmio.PWMOut(board.D3, variable_frequency = True)
volume = 500
tone.duty_cycle = volume

Now, set up the frequency and duration for your tones that will play each time you touch a key.

notes = [262, 277, 294, 311, 330, 349, 370, 392, 410, 440, 466, 494]
tone_duration = 0.2
rest_duration = 0.01

Create a function that will be responsible for playing tones when it is called.

def play_a_tone(freq):
    tone.duty_cycle = volume
    tone.frequency = freq

Now that everything’s set up, let’s get to the main part of the code, explained below:

while True:
    touched = False
    for i in range(12):
        if touch_pad[i].value:
            print("Pad {} touched".format(i))
            play_a_tone(notes[i])
            touched = True
    if touched == False:
        tone.duty_cycle = 0

while True runs everything in this loop during the program’s execution in perpetuity.

  1. First, initialize the variable touched = false, so we know nothing’s playing at the moment.
  2. Next, we have 12 keys that play 12 notes (see the notes[] list), so let’s loop through them here.
  3. If a pad is touched…
  4. Then print that to the console (for debugging and visibility purposes)
  5. Also, run the function play_a_tone() we defined earlier, and pass in the pad / key that was touched
  6. Now set the variable touched = True because a key was just touched, a note is being played
  7. If touched = False, then we want to make sure nothing’s playing
  8. And that’s what happens with this line

Let me know if you have any questions about the code! Here it is in full:

import time, board, pwmio, adafruit_mpr121


i2c = board.I2C()
touch_pad = adafruit_mpr121.MPR121(i2c)


tone = pwmio.PWMOut(board.D3, variable_frequency = True)
volume = 500
tone.duty_cycle = volume


notes = [262, 277, 294, 311, 330, 349, 370, 392, 410, 440, 466, 494]
tone_duration = 0.2
rest_duration = 0.01


def play_a_tone(freq):
    tone.duty_cycle = volume
    tone.frequency = freq


def play_a_rest(duration):
    tone.duty_cycle = 0
    time.sleep(duration)


while True:
    touched = False
    for i in range(12):
        if touch_pad[i].value:
            print("Pad {} touched".format(i))
            play_a_tone(notes[i])
            touched = True
    if touched == False:
        tone.duty_cycle = 0

Attachments

Source: Piano for Campus School Project With Arduino Nano RP2040 + MPR121


About The Author

Muhammad Bilal

I am a highly skilled and motivated individual with a Master's degree in Computer Science. I have extensive experience in technical writing and a deep understanding of SEO practices.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top