From SPCoast
// Make music with servos and a Tiger Xylopiano
// by John Plocher
// Application: several servos with wooden hammers
#include <Servo.h>
int servo1Pin = 14; // pwm outputs for servos
int servo2Pin = 15;
int home=90; // "hover" position...
Servo servo1, servo2;
void setup() {
servo1.attach(servo1Pin); servo1.write(home);
servo2.attach(servo2Pin); servo2.write(home);
Servo::refresh();
}
void loop() {
quiesce();
play("a b c d e f g A Agfedcba "); // scale
play("edcdeee8ddd8eee8edcdeee4eddedc "); // Mary had a little lamb
play("a6a6a2bc6c2bc2de66AAAeeecccaaae2dc2ba6 "); // Row Row your boat
play("eefggfedccdeedd8eefggfedccdedcc8 "); // Ode to Joy
play("ededcddcbcaeaeaeabcbcddcdede "); // Arduino on Bells tune
play("fdfdcdAdcgbcafafafgAeabcbcddcdfAdfgeca "); // Random...
quiesce();
while (1) { } // Play thru the set ONLY ONCE each reset...
}
void play(char *s) {
int l = strlen(s);
for (int x = 0; x < l; x++) {
switch (s[x]) {
// Produce each note - positions determined empiricly
case 'a': note(160); strike(); break;
case 'b': note(140); strike(); break;
case 'c': note(120); strike(); break;
case 'd': note(105); strike(); break;
case 'e': note(81); strike(); break;
case 'f': note(70); strike(); break;
case 'g': note(58); strike(); break;
case 'A': note(20); strike(); break;
case ' ': d1000();
case '8': d20();
case '6': d20();
case '4': d20();
case '2': d20(); break;
}
}
}
// Move hammer to the right note position
void note(int n) {
servo2.write(n); Servo::refresh(); d100(); d100(); d100();
}
// Strike the note
void strike() {
servo1.write(home + 6); Servo::refresh(); d20(); d20();
servo1.write(home); Servo::refresh(); d20();
}
void quiesce() {
note(160); // move hammer back to 'a'...
servo1.write(home - 45 ); Servo::refresh(); d1000();
servo1.write(home); Servo::refresh(); d1000();
}
// Various delays thak keep the servo library happy
void d20() { delay(20); Servo::refresh(); }
void d100() { for (int x = 0; x < 5; x++) { d20(); }}
void d1000() { for (int x = 0; x < 10; x++) { d100(); }}