User:Tolga Ozuygur/Xylomatron

From XPUB & Lens-Based wiki

Xylomatron (:D) is a xylophone playing robot. The starting point was trying to find a way to play the clapping music. Actually I could talk about;

How clapping music is being played by clapping and instead of using a piezo by using a real physical way to produce sound would fit amazingly to the context.

But I will not. In fact, I built this just because I thought it would be fun.

My first idea was just to play the beat of the clapping music on the same notes. Here is the result video with a fancy thumbnail (Michael did it!): File:TolgaClappingMusic.ogv

But then, I mean the robot was not robot enough. It was just using 2 servos in order to make a repetitive movement. To make it feel more like a robot, I knew I should have use some double axis setup. That way it would look much more like a couple of terminator arms and hypnotize the spectator with all the complex-looking (yet simple) double axis rotations and twirls. It is definitely a great way to make your robot look complex with just a little bit of extra cost. And as a surprise I would be able to play any note I'd like to play on the xylophone. Excellent. Here is a video from the new version trying its speed level with a test algorithm:


{{#ev:vimeo|16340757|640}}


After talking to Michael about adding some human interaction to the project, I have decided to turn this into a game. You will be able to play a Simon Says style game by using the xylophone.

Here is the current source (a little bit messy at the moment):

#include <Servo.h>
int servos[] = {
  4,5,6,7};
Servo servo_0;
Servo servo_1;
Servo servo_2;
Servo servo_3;
Servo servo_instance[] = {
  servo_0, servo_1,servo_2, servo_3};
int servo_timer[] = {
  0,0,0,0};
int servo_start_angle[] = {
  130, 100, 70, 100};
int servo_hit_angle[]= {
  154, -1, 46, -1};
int servo_trim[] = {
  0,-5,3,-6};
int servo_amount = 4;
int servo_max_timer = 12;
int notes_servo_array[] = {
  1,1,1,1,3,3,3,3};
int notes_angle_array[] = {
  125,110,95,80,125,110,95,80};
//note value: 0-7

void setup()
{
  servo_0.attach(servos[0]);
  servo_1.attach(servos[1]);
  servo_2.attach(servos[2]);
  servo_3.attach(servos[3]);
  for(int i=0; i<servo_amount; i++){
    reset_servo(i); 
  }
  Serial.begin(19200);
}

int a = 0;
int count_note = 0;
int temp_play_note_array[]= {0,4,1,5,2,6,3,7,0,4,1,5,2,6,3,7,0,4,1,5,2,6,3,7,0,7,1,6,2,5,3,4,0,7,1,6,2,5,3,4,0,7,1,6,2,5,3,4};
void loop()
{
  if(a > 17){
    play_note(temp_play_note_array[count_note]);
    count_note = count_note + 1;
    if(count_note > 42){
      count_note = 0; 
    }
    a = 0;
  }
  else{
    a = a +1; 
  }
  handle_servo_timers();
  delay(10);
}

void play_note(int temp_which_note){
  int temp_which_servo = notes_servo_array[temp_which_note];
  if(servo_timer[temp_which_servo] == 0){
    servo_set_angle(temp_which_servo, notes_angle_array[temp_which_note]);
    servo_timer[temp_which_servo] = servo_max_timer;
  }
}
void servo_hit(int temp_which_servo){
  servo_set_angle(temp_which_servo,servo_hit_angle[temp_which_servo]);
  servo_timer[temp_which_servo] = servo_max_timer;
}

void reset_servo(int temp_which_servo){
  servo_set_angle(temp_which_servo,servo_start_angle[temp_which_servo]);
}

void servo_set_angle(int temp_which_servo, int temp_angle){
  servo_instance[temp_which_servo].write(temp_angle+servo_trim[temp_which_servo]);
}

void handle_servo_timers(){
  for(int i=0; i<servo_amount; i++){
    if(servo_timer[i] > 0){
      servo_timer[i] = servo_timer[i] - 1;
      if(servo_timer[i] == 4){
        if((i == 0) || (i==2)){
          reset_servo(i); 
        }
      }
      if(servo_timer[i] == 0){        
        if(i == 0){
          reset_servo(1);  
        }
        if(i == 1){
          servo_hit(0); 
        }
        if(i == 2){
          reset_servo(3);  
        }
        if(i == 3){
          servo_hit(2); 
        }
      }
    }
  }
}