Robot Project

In 2015, I decided to build a drum playing robot for my band. I was a beginning programmer and had no experience at all with robotics or electronics. I had seen several projects online where others had made similar types of robots, so I knew it was possible, but I didn't know how difficult it would be, or how long it would take.
I was pleasantly surprised on getting started that it wasn't as hard as I expected. Much of this is due to the excellent instructions in the Arduino starter kit that I got to start playing around and learning with. I'd like to share how easy it is to start making robots and how many of the examples in the kit translated into my drum robot.

This page has descriptions of how the robot was built, focusing on circuitry and code. For a more general overview of the project, see External Combustion Orchestra's page.

The Arduino starter kit includes a project book that guides you through exactly how to use the included components to do some very simple projects. These projects are designed to teach you how to use the Arduino as you build them. The hands on, "learn by doing" approach is very effective.
November 2015 -I started by reading the introductory sections and following the installation instructions for the Arduino IDE (aka the coding software). Then the projects start. The first project explains the basics of how a circuit works. The second introduces writing code in the IDE and how to use a switch. The third shows how to use the Serial monitor, which displays output from the Arduino so you can see what it's doing, and gets input from a sensor. I skipped the fourth (about LEDs) and did the fifth which introduces using servos and a potentiometer, both of which are part of my final robot!

Project 5, "Mood Cue" uses a potentiometer to change the position of a servo arm. After this project, I had most of what I needed and left the book for a while.Doing four of the first five projects in the book got me building on my own!

The Arduino IDE comes with a host of basic sample programs (or sketches) to help you get started and one of them, called "Sweep", tests a servo by moving the servo arm all the way back and forth. This gave me the code for type of motion I needed my servo to make without using a potentiometer. I added a second servo, tied some sticks to the servo arms and played with the code until I got it to move each stick separately.


            /* AsyncMove by Kelsey Reid  
            This code moves two servos independently of each other
            Based on the public domain example "Sweep"
            */
        
            #include < Servo.h >
                Servo servo1;  // create servo object to control a servo
                Servo servo2;
                int pos1 = 90;    // variable to store the servo position
                int pos2 = 0;
                unsigned int pos[] = {10,90,170,90};
                //int switchState = 0;
                void setup()
                {
                //pinMode(2,INPUT);
                servo1.attach(9);  // attaches the servo on pin 9 to the servo object
                servo2.attach(10);
                }
                void loop()
                {
                //moveUp();
                //moveDown();
                moveServo1();
                moveServo2();
                } //end loop
                void moveUp()
                {
                for(int i=0;i<=170; i++){
                servo1.write(i);
                delay(5);
                }
                for(int k=0;k< 80; k++){
                                  servo2.write(80-k);
                                  delay(5);
                                  }
                                  }//end moveup
                void moveDown()
                {
                for(int i=170;i>=0;i--){
                servo1.write(i);
                delay(5);
                }
                for (int k=80;k>=0;k--){
                servo2.write(80-k);
                delay(5);
                }
                }//end movedown
                void moveServo1 ()
                {
                for(int i=80;i>=0;i--){
                servo1.write(i);
                delay(5);
                }
                for(int i=0;i<=80; i++){
                servo1.write(i);
                delay(5);
                }
                }//end moveServo1
                void moveServo2()
                {
                for(int k=0;k< 80; k++){
                                  servo2.write(80-k);
                                  delay(5);
                                  }
                                  for (int k=80;k>
                    =0;k--){
                    servo2.write(80-k);
                    delay(5);
                    }
                    }//end moveServo2
        

Next I added a variable in the code to represent the tempo. Setting the delay on the servos movement to this variable meant that I could control the speed of the movement with it. Then I added the potentiometer back into the mix and set the tempo variable to be determined by the potentiometer, creating a tempo dial.

I also added a switch, just like the second project in the book, for "Run" and "Stop". The switches that come in the kit are the kind you have to hold down for the "on" position, so I picked up a toggle switch instead. You can see in the code sample I have separated the servos' movements into independent methods (moveServo1 and moveServo2) so that in the loop I can just call the method instead of writing all the code to move the stick up and down. This is very helpful in later programs where I need to tell the servos to move multiple times.


   /*TickTock TempoDial
        by Kelsey Reid
        This code moves two servos independently, will run or stop based on a switch,
        and changes the speed of the movement based on the input from a potentiometer
     */
//Servos
#include < Servo.h>
Servo servo1;
Servo servo2; 
//inputs
int switchState = 0;
int potpin = 0;
int dialvalue;
//variables

int bpm;
int hitDelay;
void setup() {
  // put your setup code here, to run once:
pinMode(2,INPUT);
servo1.attach(9);
servo2.attach(10);
}
void loop() {
  // put your main code here, to run repeatedly:
  dialvalue = analogRead(potpin);
  dialvalue = map(dialvalue, 0, 1023, 60, 135);
  bpm = dialvalue;
  hitDelay = (60000/bpm)-200;
  
 switchState = digitalRead(2);
  if(switchState == LOW){
    servo1.write(10);
    servo2.write(50);
  }
  else{
    moveServo1();
    moveServo2();
  }
}
void moveServo1()
{
  //down
 for(int i=10;i<=40; i++){
 servo1.write(i);
 delay(3);
}
//up
 for(int i=40;i>=10;i--){
 servo1.write(i);
delay(3);
}   
delay(hitDelay);
}//end moveServo1
void moveServo2()
{
  //down
 for(int i=50;i>=20;i--){
 servo2.write(i);
delay(3);
}   
//up
 for(int i=20;i<=50; i++){
 servo2.write(i);
 delay(3);
}
delay(hitDelay);
}//end moveServo2

My electronics were all connected to the Arduino through the breadboard that came with the starter kit and looked like this:

Gears

February 2016 -That was all the electronics and code for the first version, but the servos couldn't move the sticks fast enough for solid hits, so I decided to use gears to increase the speed. I wanted to 3D print them, which meant I had to learn yet another new skill! Sketchup is Google's free 3D modeling software and it was pretty easy to learn. There are lots of online tutorials. I also got a few tips from a coworker. Thanks Ron! To make the gears, I used an extention called DH involute gear.

Download My Sketchup Gear files (zip)

March, 2016 -This was basically it for the first version. I wrote several sketches for different rhythms and Junkbot was born.

Upgrades - back to the book!

May 2016 -Junkbot could now play, but still had some limitations. He had to be connected to a laptop for power and a new sketch had to be downloaded anytime you wanted to change rhythms. I set about fixing that by going back to the Arduino starter book.
Project 11 (Crystal Ball) shows how to hook up and use an LCD screen and the code changes the text being displayed when a switch is pressed. After doing this project with a new Arduino and a larger breadboard, I then transferred the old wiring all onto the larger breadboard. The LCD screen required a lot of wires, so there wasn't room on the starter kit breadboard for both it and all of the stuff the robot already had. Then I started modifying the code and combined it with my single-rhythm sketches to make one big sketch that changed both the LCD text and the rhythm being played. Getting this code to work did take some trial and error, but that's just part of coding.

This is the code as of May 2016


        /* Junkbot's program May 2016 by Kelsey Reid
Plays rhythms with 2 servos.  Rhythm pattern can be changed
with switch and rhythm names are displayed on LCD screen.
Includes Stop/Start switch and Tempo dial.
*/
//libraries
#include < Servo.h>
#include < LiquidCrystal.h>
//inputs
Servo servo1; //right hand
Servo servo2; //left hand
int potpin = 0; //potentiometer for tempo
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);//lcd display
const int switchPin = 6;//input to change rhythm
//variables
int runStop = 0; //"run" switch
int dialValue; //tempo dial 
int bpm;
int hitDelay;
int pattern;//the rhythms
int switchState = 00;// change rhythm switch
int prevSwitchState = 00;//compare state of rhythm switch
void setup() {
  Serial.begin(9600);
 pinMode(7, INPUT); //run switch
 servo1.attach(10);
 servo2.attach(9);
  lcd.begin(16,2);
  pinMode(switchPin, INPUT); //change rhythm
  lcd.print("Junkbot 1");
 // lcd.setCursor(0,1);
//  lcd.print("Junkbot 1");
    pinMode(13, OUTPUT);
}
void loop() {
  Serial.print("switchstate:");
  Serial.print(switchState);
  Serial.println(prevSwitchState);
  dialValue = analogRead(potpin);
  dialValue = map(dialValue, 0, 1023, 60, 140);
  bpm = dialValue;
  hitDelay = (60000/bpm)-200;
  runStop = digitalRead(7);
     switchState = digitalRead(switchPin);
     
       
    if(runStop == LOW){
    //raise sticks and hold position
   servo1.write(10);
  servo2.write(40); 
  if(switchState != prevSwitchState){
if(switchState == 00){
  //pattern++;
  
 lcd.clear();
  lcd.setCursor(0,1);
  
  switch(pattern){
    case 0:
    lcd.print("Frankie&Johnnie");  
    pattern = 1;
    prevSwitchState = switchState;
    break;
    case 1:
    lcd.print("Waltz");  
    pattern = 2;
    prevSwitchState = switchState; 
    break;
    case 2:
    lcd.print("Trailerpark");
    pattern = 3;
    prevSwitchState = switchState;
    break;
    case 3:
    lcd.print("Tick Tock");
    pattern = 0;
     prevSwitchState = switchState;
    break;
  }//end switch
  
  }//end low
    }//end switchstate
     prevSwitchState = switchState;
  }//end if
else{
    //run rhythm
    if(pattern == 0){
     boilerplate(); //aka Tick Tock
     //boilerplate, time machine, robot fugue
    }
    else if(pattern ==1){
      rock();
      //Frankie and Johnnie
    }
    else if(pattern ==2){
      waltz();
    }
    else{
      swing(); 
      //trailerpark vampire
    }
}//end else run rhythm
}//end loop------------------------------
//rhythm patterns-----------------------------
void rock(){
  moveServo1(); 
moveBoth();
}//end rock
void waltz(){ 
  moveServo1(); 
 moveServo2(); 
 moveServo2(); 
}//end waltz
void boilerplate(){
    moveServo1(); 
 moveServo2(); 
  
}//end boilerplate
void swing(){
fastServo1(); 
delay(hitDelay/2);
delay(hitDelay/2);
fastServo1(); 
delay(hitDelay/2);
fastServo2();
}//end swing
//stick movements------------------------------------
void moveServo1 ()
{
  //down
 for(int i=10;i<=40; i++){
 servo1.write(i);
 delay(3);
}
//up
 for(int i=40;i>=10;i--){
 servo1.write(i);
delay(3);
}   
delay(hitDelay);
}//end moveServo1
void moveServo2()
{
  //down
 for(int i=40;i>=10;i--){
 servo2.write(i);
delay(3);
}   
//up
 for(int i=10;i<=40; i++){
 servo2.write(i);
 delay(3);
}
delay(hitDelay);
}//end moveServo2
void moveBoth()
{
  //up
   for(int i=10;i<=40;i++){
 servo1.write(i);
 servo2.write(i*(-1) +60);
delay(3);
}   
//down
 for(int i=40;i>=10; i--){
 servo1.write(i);
 servo2.write(i*(-1) + 60);
 delay(3);
}
delay(hitDelay); 
}//end move both
void fastServo1 ()
{
  //down
 for(int i=10;i<=40; i++){
 servo1.write(i);
 delay(3);
}
//up
 for(int i=40;i>=10;i--){
 servo1.write(i);
delay(3);
}   
}//end swingServo1
void fastServo2()
{
  //down
 for(int i=40;i>=10;i--){
 servo2.write(i);
delay(3);
}   
//up
 for(int i=10;i<=40; i++){
 servo2.write(i);
 delay(3);
}
}//end swingServo2
        

And this is the circuitry. I also connected a 4 AA battery pack to the Arduino to power it all.

I hope this gives you an idea of how easy it is to get started making robotic devices! Now, go get yourself a starter kit and start building!

Back to External Combustion Orchestra