Instantly share code, notes, and snippets.

Embed
What would you like to do?
/* Pop-up Piano
* -----------
*
* Program to output musical tones in response to switches being closed.
*
* I referenced Tom Igoe's ToneTest and am importing the Tone library.
*
* Created by Corinna Sherman
* October 25, 2010
*
*/
#include <Tone.h>
#include "pitches.h"
// Variables for the piano keys and speaker
int switchPins[] = {
7, 6, 5, 4, 3, 2}; // digital switches to piano keys C, D, E, F, G, A
int notes[] = {NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4}; // musical notes corresponding to the piano keys
String noteNames[] = {"C","D","E","F","G","A"};
//int ledPin = 13; // LED to blink with each note played
int speakerPin = 9; // speaker output pin
Tone notePlayer; // tone to send to speaker
// notes in the melody:
int melody[] = {
NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
4, 8, 8, 4,4,4,4,4 };
// Variables for the paper variable resistor and LED
int sensorPin = 0; // analog input pin for the variable resistor
int ledPin = 10; // analog output (PWM) pin for the LED
int sensorValue = 0; // variable to hold the current sensor value
int maxSensorValue = 0; // variable to hold the max sensor value
int minSensorValue = 0; // variable to hold the min sensor value
String sensorLabel; // label for sensor reading printout
String intensityLabel; // label for intensity printout
int ledIntensity = 0; // variable to hold the intensity of light output to the LED
void setup() {
// Initialize serial communication.
Serial.begin(9600);
// Set switch pins as input
for (int i = 0; i < 6; i++) {
pinMode(switchPins[i], INPUT);
}
// Set LED and speaker pins as output
pinMode(ledPin, OUTPUT);
pinMode(speakerPin, OUTPUT);
//digitalWrite(ledPin, HIGH);
sensorLabel = String("sensor value = ");
intensityLabel = String("ledIntensity = ");
// Read the value from the sensor.
sensorValue = maxSensorValue = analogRead(sensorPin);
// Prepare to use speakerPin for outputting notes.
notePlayer.begin(speakerPin);
// iterate over the notes of the test melody:
for (int thisNote = 0; thisNote < 8; thisNote++) {
// to calculate the note duration, take one second
// divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000/noteDurations[thisNote];
notePlayer.play(melody[thisNote],noteDuration);
Serial.print(melody[thisNote]);
Serial.print(", ");
Serial.println(noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
}
}
void loop() {
updateLedIntensity(); // Update the LED brightness based on the variable resistor
// Play a note if the corresponding key is pressed, closing the switch.
for (int i = 0; i < 6; i++) {
if (digitalRead(switchPins[i]) == HIGH) {
Serial.print(noteNames[i]);
Serial.print(" = ");
Serial.println(notes[i]);
notePlayer.play(notes[i], 1000); // duration was determined empirically
delay(250); // delay was determined empirically
} else {
notePlayer.stop();
}
}
}
// Update the LED intensity based on the value read from analog input pin
// attached to the paper variable resistor.
void updateLedIntensity() {
// Read the value from the sensor.
sensorValue = analogRead(sensorPin);
// Update the max and min sensor values if applicable.
if (sensorValue > maxSensorValue) {
maxSensorValue = sensorValue;
}
else if (sensorValue < minSensorValue) {
minSensorValue = sensorValue;
}
Serial.println(sensorLabel + sensorValue);
// Light the LED with intensity proportional to the resistance sensed,
// ranging from 0 to 255.
int ledIntensity = map(sensorValue, minSensorValue, maxSensorValue, 0, 255);
analogWrite(ledPin, ledIntensity);
Serial.println(intensityLabel + ledIntensity);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment