SPCoast
Railroading on the Southern Pacific Coast

XyloTiger

From SPCoast

Revision as of 04:28, 15 October 2008 by Plocher (Talk | contribs)
(diff) ←Older revision | Current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search
// 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(); }}