Project

The BIG Arduino Piano! Use Pulse Width Modulation to Dance like Tom Hanks

March 29, 2017 by Ryan Jones

This BIG piano will help exercise the mind and body! All you need is a few buttons, a speaker, and some dancing shoes.

This BIG piano will help exercise the mind and body! All you need is a few buttons, a speaker, and some dancing shoes.

BOM:

Why?

I was watching the movie Big the other day and I realized I wanted to dance just like Tom Hanks. With no fortune teller or genies nearby to help make this keyboard big, I knew I needed to get to thinking. With some quality foamcore board lying around and other miscellaneous art supplies, I got to prototyping and came up with an easy-to-follow recipe for a giant, pushbutton-activated piano!

I wanted to keep this project simple so I figured most viewers have more pushbuttons lying around than force-sensitive-resistors, so I glued my extra buttons to the bottom of the keys. In an ideal world, adding FSRs to the keys instead would make for a softer touch, but I'll leave that modification to you guys.

 

A closer look at our components

How?

The foamcore board isn't necessary as this project can be simply assembled on a breadboard. The video covers the basics of measuring, cutting, and attaching the pushbuttons, so I'll just stick to the technical details here. If you don't have the proper number of components, you can follow along with just one pushbutton, some resistors, and a speaker.

If you've used an Arduino before, you've most likely used a pushbutton and understand the importance of a pulldown resistor. A pulldown resistor "holds the logic signal near zero volts when no other active device is connected", (Arduino Playground). This helps ensure reliable and accurate readings from our pushbuttons.

Basically, we have eight pushbuttons connected to pins 2-9, respectively. Each button requires 5V power, a 10k pulldown resistor, and a signal line to the input pins. Within our program, we assign each of these buttons a specific square-wave frequency to play whenever the button is pressed (logic HIGH). These are specific frequencies that help create musical scale.

 

A basic look at our inputs and output

There are many different types of electrical waves, including sine waves, sawtooth waves, triangle waves, and (for our use with Arduino) square waves. To create sound from these buttons, our speaker needs to be driven by an Arduino pin that can handle pulse-width modulation (PWM). Arduino pins that can produce pulse-width modulation generate square waves of varying frequency.

We don’t actually need to vary the pulse width of our signals. All our speaker signals will be 50% duty cycle. But we will use an Arduino PWM pin because the PWM functionality provides an easy way to set the frequency.

Our eight buttons represent eight notes on a musical keyboard/piano, a full octave scale—specifically, the C major scale. These notes include C5, D5, E5, F5, G5, A5, B5, and C6.

You probably notice that there are two different C notes, C5 and C6. Note C6 is simply twice the frequency of C5, an interval known as an octave, and is still considered a C note. While C5's frequency is 523Hz, C6 is 1047Hz. Though not perfectly "in tune", this is as close to a proper signal that the Arduino can produce.

You see, while pianos and musical instruments may seem intimidating, they are in fact just the same notes repeating over and over again in different "octaves". For example, note G7 would be triple the frequency of G5.

 

A waveform comparison of an octave

Enough with the music lesson! The positive lead of the speaker should have a 220 ohm resistor in series with pin 10, which is capable of producing PWM. The other lead should be tied to ground. Because we are using square waves, the signal has harmonic frequencies in addition to the fundamental frequency. Ideally, we would use a sine wave for better sound quality but the square wave is good enough for our purposes.

Looking at our code, we use simple statements to produce specific frequencies within the "pitches.h" library each time a certain button reads logic HIGH. You will notice that, for example, note F5 is 698Hz while F6 is about double in frequency, 1397Hz.

Just repeat these steps with all of the buttons you own and you'll have the world's biggest keyboard!

if (buttonCState == HIGH) {
    tone(10, NOTE_C5);
  }


  if (buttonDState == HIGH) {
    tone(10, NOTE_D5);
  }

  if (buttonEState == HIGH) {
    tone(10, NOTE_E5);
  }

  if (buttonFState == HIGH) {
    tone(10, NOTE_F5);
  }

#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397

Now let's get to dancing!

 

Give this project a try for yourself! Get the BOM.

 

Other MIT-i Innovations:

BIG_Button_Keyboard.zip

3 Comments
  • pius4109 August 23, 2017

    Can I set the pins high and then activate the Arduino input pull up resistor and change the if statement to example if(buttonCstate==LOW) :

    Like. Reply
  • pius4109 August 23, 2017

    Make all the pins that are HIGH, LOW

    Like. Reply
    • RK37 September 04, 2017
      Yes, you could use an internal pull-up resistor (instead of an external pull-down resistor). The other side of the switch would be connected to ground instead of 5 V, and you would check for a logic low on the button pins.
      Like. Reply