CARDBOARD ROBOT --- DANCE, DANCE, DANCE!!

by marc.cryan in Circuits > Robots

17995 Views, 15 Favorites, 0 Comments

CARDBOARD ROBOT --- DANCE, DANCE, DANCE!!

IMG_1407.JPG
IMG_1432.JPG
IMG_0691.JPG
IMG_0737.JPG
IMG_0574.JPG
IMG_0745.JPG
IMG_1297.JPG
IMG_1122-1.JPG

Robots:
-Can hear or see, or both - kinda
-Are strong, but break easily
-Can robot dance

The goal here is to build a robot, that is like a robot. It should be able to do human scale stuff, and look like a robot.

Don't get too excited - it does not end well!

This is Emma's clean up robot -

-It is supposed to:
- Here what you say
- Pick stuff up and put it away
- Look like a robot

The big challanges are: getting good motors( harvest from drills at Harbor Freight  ) , controlling the motors, powering the motors, voice recognition, navigation, not catching on fire, not breaking things, not spending to much money..... -- link to drill --

Very few of these goals are completed in this instructable - but it is getting too long.

So, lets begin!

NOTE:  If you follow this instructable step-be-step from begining to end, it will probably drive you insane (have you every tried following a cat all day?)  I say, learn what you can, put a fresh battery in your smoke detector, and bash on.

Everybody likes videos up front - here are a few:


Video - shows basic functions - all motors running bi-directional




Video:  Wheels working well (ie before they broke)







Video: Crash:



Video: Emma explains:



Video - with head - serial commands


Plans

IMG_0578.JPG
IMG_0574.JPG
IMG_0576.JPG

Get Motors

IMG_0549.JPG
IMG_0545.JPG
IMG_0542.JPG
IMG_0543.JPG
This is the kind of robot that runs on motors.  Little robots can use servo motors, which makes motor control simple. But big servos are expensive.  Stepper motors are a good option, they can be precisely controlled and most are easy to mount.  I'll be hooking some up towards the end of this project.  

Right now I'm going for quick and dirty.

So, HarborFreight.com here I come!  -- here is a link to the drill I am using -- link--

I bought a bunch of cordless drills from Harbor Freight for about 15$ each.  They come with the motor (of course), 18V battery, and charger.  That is a pretty good price for all that.  Also I like the way you can just jam stuff in the drill chuck and tighten it down.  Nothing easier than that for attaching an axle, drive-screw, or whatever.

The problem with these motors, is that with coil resistance of only 0.5ohm and a 18V power supply, we are dealing with alot of power.  (some math:  V = IR... so I = V/R  or I = 18/.5  which is 36Amps)  ( more math: W = VI (right?)  or W = 36 * 18 which is 648 Watts (is that right?)  if that is correct, then running these at full power uses as much power a 6-and-a-half 100 watt light bulbs (really?)) 

If you are used to regular Arduino type stuff, then this kind of power will, as they say, burn up your sh*t.  (even if my math is wrong - 648 watts? yikes)

But let's deal with that latter and play with the boxes!

Take 'em Apart

IMG_0554.JPG
IMG_0553.JPG
IMG_0742.JPG
So this what I am good at - taking things apart.  (in high school, do they still tell kids that if they are good at math and like to take things apart then they should be engineers?  That might be true, but you would also probably like to work in a junk-yard or repair vending machines, just saying.)

Ummmm...

Right, the drills. 

Take them apart.  

You know how.  

See the pictures (unless you want to be surprised (also, there is a screw under the label))

So, What Is All This Stuff

IMG_0742.JPG
IMG_0555.JPG
IMG_0563.JPG
IMG_0562.JPG
IMG_0558.JPG
Well done.

Now, what do we have here?

Well, we have the parts that make a cordless drill do what a cordless drill does.
- Motor (with gear box and a chuck)
- A trigger to control the speed (in a fancy way it turns out)
- Forward/reverse switch (this is heavy duty - you will see why)
- The connection for the battery
- Some plastic
- And an LED (yay!)

This drill is not really made out of cheap parts, but you can tell it was cheaply assembled. Very few of the wires are soldered in place, they are mostly just sort of jammed in holes.

So:

(a)Now you know why stuff like this often stops working suddenly, then works fine, then stops working again, then it sounds like something is loose.

and

(b) This is easy to take apart, you just pull the wires out

but

(c)* It is easy to break stuff that would have been useful, expect now it is just a little pile of wire, plastic and springs never to be put back together again (like the head of a Barbie that is attached with a plastic ring on the end of a little rubber band, so to get it back together you have to pull the ring out of the head, and stretch the rubber band far enough (but no so far it breaks off) and jam the wring back in the neck whole. You know? I'll take a picture. (no I won't, even if I remember to take a picture I'll never come back and add it in))


Now!

- Take the motor out and set aside
-Take out and examine the trigger mechanism.

The trigger mechanism is actually a complete little PWM motor driver, complete with a microcontroller and everything. Unfortunately, even if you new what was going on here, it would be very hard to get back together once you'd opened it up. The more useful (and easy to use) part is the high power mosfet on a big heat sink. We will use this plus and Arduino in the next step to get the motor running.




*why are these lettered?



Control Motor Speed With Arduino

IMG_0561.JPG
IMG_0566.JPG
IMG_0573.JPG
IMG_0572.JPG

Control Direction... or Burn Things

IMG_0748.JPG
IMG_0558.JPG
So that worked well - nothing can stop us now!

err..

Remember that big mechanical switch that controlls the motor direction?

Not me.

I confidently wired up some relays on a neat little perf-board.

Plugged it all in.

AND

hmm... the relays are clicking but the motor isn't turning... it is making some high pitched noise though, so that's good (right?)

(puts ear up to board)

well, I can here the relays clicking. So I have clearly done everything correctly.

hmm... my ear is hot.

(pffffff sound)

hmmm... what's all this smoke?

ohhhhhh....... right the 648watts of power!!! Yikes, I've burnt all that stuff up. I grabbed these nice big relays with a big 2amp rating - but these are not hobby motors - they pull 36amps and up. So I haven't made a direction switcher --- I've made a fire starter!!

So that explains why among all the little pieces the drill had that big mechanical switch to reverse direction, which big metal, spring loaded contacts. We are dealing with some power!

And, in electronics, as in life, power = money, power components get expensive quick (maybe only 1-3$ per part, but then you need four of them for each motor, and we want to use like 8 motors... so pretty soon we'll be spending more to switch directions then we did on the motors, MOSFET, batteries, and charger...

Let's find a cheap (and roboty) way out of this mess!

Video: testing current draw with digital multimeter (fuse will blow above 2 amp)

Tiny Servos to the Rescue?

Use servos to create a cheap but heavy duty direction switcher (in this case, a DPDT relay --- sort off)

Have Some Cake

IMG_0703.JPG
IMG_0710.JPG
mmmm.... cake

Build the Mechanical Parts of the Mechanical Man

IMG_0737.JPG
Now that we've had a snack. Let's work on the mechanical robot parts.

What do we want to move?
      -  Arms, starting with the shoulders
      - Wheels, to get a round (legs would be nice, but we have to start somewhere)
      - Hips - to bend  at the waist  --- maybe this is a torso, I don't know....

What do we have?
    - All these drills we took apart
    - Screws
    - Plywood
    - Bits of plumbing supplies
    - General basement debris
     - Whatever is cheap at the Depot
    - Cat poo  

Here is a look at what we will end up with as the basic skeleton and joints.

Mount Drill Motors

IMG_0664.JPG
IMG_0665.JPG
IMG_0666.JPG
IMG_0667.JPG
IMG_0669.JPG
IMG_0689.JPG
Mounting a motor can be easy, hard, or somewhere in between.

Plumbers Strap:
I like to use metal plumbers strap to mount motors - cheap and easy.  
However this stuff will break if you bend it too many times.
Here are the basic steps: 
             - Position motor
             - Cut a peice of plumbers strap
             - Bend the plumbers strap over the motor
             - Drill the strap down with short screws (using 1 inch drywall screws)
             - Make sure it is tight (you can usually do this by adding third screw, but you might have to shim it a little)
  
             The gear box is  a little wider than the motor, so I am a wooden shim to make up the difference.
             
              - Add a second strap if needed

A Fancy Bracket

 

I went looking for a 'better' way, and found these brackets for hanging electrical conduit.
The one labeled ' #2 ' is the right side (in the electrical stuff section of Depot, near conduit - but in an aisle, not against the wall)

Steps:

  •  Bolt the bracket to the plywood
  • Put the motor in the bracket
  • Tighten the bolt on the bracket
This lets you loosen and adjust the motor position easily, unlike the plumbers strap which is a hassle to change.


Wheels

IMG_0669.JPG
IMG_0672.JPG
IMG_0674.JPG
IMG_0678.JPG
IMG_0682.JPG
Mount two drills for the wheels.  

Then find something to use for wheels.

I'm using circles cut out of some MDF using a 4" hole saw.  

Using 1/4"-20 machine screw for axles.

This looks like something that might need to get re-done latter.

Arms (or Shoulders at Least)

IMG_0689.JPG
IMG_0688.JPG
Now, lets mount some arm motors.

I am using #2 conduit clamps to hold the motors.

A bent steel rod serves as a temporary arm.


Basic Structure

IMG_0724.JPG
IMG_0683.JPG
IMG_0685.JPG
IMG_0686.JPG
IMG_0687.JPG
IMG_0718.JPG
IMG_0719.JPG
IMG_0721.JPG
As you can see in the pictures, there is a basic scrap-wood structure that we are building.  No real plan here, just need a place to put everything.  

There is one 'leg' made from a 4x4.

Some plywood makes the hips, back and chest.

The upper body is attached to the lower body with a strap hinge, so it can bend at the 'waist'

Latter we are going to fit the cardboard boxes over this frame, it doesn't have to be perfect - sloppy is good here, you can tighten things up as needed.




Something to Make It Bend at Waist

IMG_0731.JPG
IMG_0732.JPG
IMG_0726.JPG
IMG_0733.JPG
IMG_0736.JPG

The motor will need to take some weight. We will also want to be able to leave it in a fixed position (such as upright), without having to keep power to the motor.

After some tinkering, I decided to use a drive-screw attached to a crude linkage.

The key to this is a part from the plumbing department (down towards the end and sort of high up). It is a '3/8 Side Beam' - but who cares - it cost $1.30 and is heavy duty.

Here are the steps:
- Mount the thing to the ply-wood. ( getting lazy here)
- Get a 3/8" threaded rod (cheapest is back in the conduit section, but there are shorter pieces near the nails)
- Cut the threaded rod to a good length (guess)
-put 2 bolts and a lock washer one end of the rod
- screw the rod into the threaded part of the 'side beam'
- Add a spot to mount a motor
- Hope that it will work out okay.

Update: this mechanism has problems - here is one:

Video -


Go to Maker Fair NY

IMG_0613-1.JPG
IMG_0622.JPG
Meet up with your brother Tom and play some theromones

Slap Some Cardboard on and See How It Works

IMG_0692.JPG
IMG_0697.JPG
IMG_0698.JPG
IMG_0695.JPG
IMG_0693.JPG
IMG_0691.JPG
That was fun.

Now lets take a minute to put the cardboard pieces on to see if this is going to work out.

Man - this is a long instructable....   isn't this the same as step 1? 

What Next?

IMG_0714.JPG
This is as far as I had planned.  So I do not know what to do next.

It is clear that unless we can run these motors, we don't have a robot.

Speed control is not a problem because we have the power mosfets from the drill.  Switching directions is still a problem.  Position feedback will be needed, at least for the arms, but let's forget about that for now.

Let's get the motor controls running well.  As I said, and will repeat now, switching directions is still a problem.  Doing it for less than the cost of the drills is the goal.

Here is  my problem solving method:
  1. Give up
  2. Eat cake
  3. Find and use multi-meter
  4. Shop for big servos from McCmaster Carr
  5. Check bank account
  6. Have a cookie
  7. Shop for a motor controller kit
  8. Shop for components from digikey
  9. Check credit card balance
  10. Drink beer
  11. Scrounge around the house
  12. Repeat until out of beer, money, or cake



Foward and Reverse Motor Control

IMG_0766.JPG
IMG_0789.JPG
IMG_0767.JPG
IMG_0768.JPG
IMG_0765.JPG
IMG_0745.JPG
IMG_0747.JPG
IMG_0558.JPG
IMG_0791.JPG
IMG_0792.JPG
IMG_0796.JPG
IMG_0799.JPG
IMG_0800.JPG
IMG_0804.JPG
IMG_0806.JPG
IMG_0808.JPG
IMG_0809.JPG
IMG_0834.JPG
IMG_0826.JPG
IMG_0811.JPG
IMG_0824.JPG
IMG_0825.JPG
IMG_0830.JPG
After some small fires - we have a workable solution.

Cofrol the stock (original or 'as purchased') switch witha cheap little servo. These are havea small motor and a bunch of gears. You just need to give it some power and then tell it what position to go to. These go from 0 to 180 degress ( or 0 to pi radians). They are low power and mainly plastic and nylon.

Here's how -
  1. get a servo
  2. hold it up to switch
  3. scratch head
  4. find the little bag of plastic gears that it somes with
  5. snap a gear on the servo
  6. hold it up to the switch
  7. get a knife
  8. wittle down the gear so that it looks like it will work
  9. bandage wounds
  10. hold it up to the switch

Now - ge the servo some power

servo has 3 lines

  1. brown/black - is ground
  2. Red - is power - 5volt for these
  3. orange or yellow - is communication

Run some test code with arduino

  1. get arduino
  2. open the example scetch - Sketch -> examples -> servo -> sweep
  3. upload to arduino
    • right com port?
    • right board selected?
    • pluged in
    • most recent arduino software on PC?
    • Did you break the arduino board las time....
  4. Wire servo to arduino like this
    • Black - Ground
    • Red -> 5 Volt
    • Orange -> Digital 9 (PWM)
  5. Press reset button (you really should have unplugged the arduino while doing the wiring...)
  6. Watch it go!

Now - get it all to work

  1. edit the example program so it goes to 90deg and stops
  2. with srvo at 90deg, hold it up to switch so it looks right
  3. Take off the plastic gear, and put it back on, so the switch is in the middle position
  4. Tape it all togetehr with electrical tape (or do somehting better..)
  5. Now, edidt the the sweep example so it goes like this - 45deg -- 90deg -- 135 deg -- 90 -- 135 -- 90 --135...
  6. Load it up
  7. Now the servo should move the swtich back and forth ... pretty much
  8. Make adjustements
  9. The servos will try to go to whatever angle it is told, if it can't then things might break.
  10. Reducing the angles helps --- I wound up with - 40deg --- 90deg --- 140deg (that doesn't seem right... 50--90--140 makes more sense)
  11. This runs better, but the motor is still straining at eitheend
  12. Now - you could get everything perfect --- or you can just limit how long the motors try to reach the position
  13. This is done by setting the angle, waiting a moment, then turning off the servo n(there is a function called 'detach' that does this.
  14. The final test code is below.
  15. This tells the servo to move, gives it a moment (0.3seconds) to move, then tuns the motor off
  16. This works well enough to move on
  17. (why was this all a numbered list? eh...)


    Arduino code that works:

    //////////////////ARDUINO//////////////////

    // This example code is in the public domain.

    #include

    Servo myservo; // create servo object to control a servo
    int pos = 0; // variable to store the servo position

    void setup()
    {
    myservo.attach(9); // attaches the servo on pin 9 to the servo object
    }

    void loop()
    {
    myservo.attach(9);
    myservo.write(90); // go to middle
    delay(300); // try to get to position for 0.3 seconds
    myservo.detach(); // let servo give up
    delay(2000);

    myservo.attach(9);
    myservo.write(140); //got to side
    delay(300); //trying
    myservo.detach(); //give up
    delay(2000);

    myservo.attach(9);
    myservo.write(90); //go to middle
    delay(300); //trying
    myservo.detach(); //give up
    delay(2000);

    myservo.attach(9);
    myservo.write( 40); //go to other side
    delay(300); // trying
    myservo.detach(); //give up
    delay(2000);
    }

 

Build First Version of Motor Controller











//////////////ARDUINO CODE////////////////////////

////////////////TEST CODE ////////////////
////////////////MOTOR SPEED CHANGES/////////////////
////////////////MOTOR DIRECTION CHANGES///////////////


// This example code is in the public domain.

#include

Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position
int Ctrl = 6; // pin that will controll mosfet (to blue)
int spd = 0; // variable for speed
void setup()
{
// myservo.attach(9); // attaches the servo on pin 9 to the servo object
pinMode(Ctrl, OUTPUT); // set control pin as output
}

void loop()
{

// set direction with servo //
analogWrite(Ctrl, 0 ); // power off
delay(100);
myservo.attach(9);
myservo.write(140); // go to side
delay(600); // try to get to position for 0.6 seconds
myservo.detach(); // let servo give up
delay(1000);
//run the drill motor at different speeds

analogWrite(Ctrl, 20);
delay(1000);
analogWrite(Ctrl, 50);
delay(1000);
analogWrite(Ctrl, 100);
k
]]
1000);

analogWrite(Ctrl, 20);
delay(1000);
analogWrite(Ctrl, 50);
delay(1000);
analogWrite(Ctrl, 100);
delay(1000);
analogWrite(Ctrl,150);
delay(1000);
analogWrite(Ctrl, 200);
delay(500);
analogWrite(Ctrl,150);
delay(500);
analogWrite(Ctrl,100);
delay(500);
analogWrite(Ctrl,50);
delay(500);
analogWrite(Ctrl,20);
delay(500);
analogWrite(Ctrl,100);
delay(500);
analogWrite(Ctrl,200); // a little different
delay(500);
analogWrite(Ctrl,20);
delay(500);
analogWrite(Ctrl,0);
delay(500);

delay(3000); // 3 second delay befor repeat
}

Use a Relay Instead

IMG_0844.JPG
IMG_0841.JPG
IMG_0983.JPG

Here is a much better way to control the motor direction -- ahhhh -- I seem to have lost all the build photos -- I will have to come back and fill this in --- There are photos of the breadboard version..... crap.


Parts:
  • Relay - RTE24005F, tcyco - DPDT - contacts rated at 30VDC and 8 amps - Coil uses 5V and draws 400mW (will need a transistor to control this)
  • Transistor (to control relay) - 2N3906TF - PNP - controls a max of 40V, 200mA, 625mW. ('max' means that if you go past any of these it will break)
  • MOSFET - (to control motor speed) - use the MOSFET from the drill - - this one is good too: BUK7511 - N channel MOSFET, can control up to 55V, 75A, 157W
  • Diodes - to protect against kickback from motor and solenoid (white line goes towards positive voltage, other side to ground/negative voltage)
  • Screw terminals (because they are useful) - 1935161, Phoenix, - these have 2 positions (spots for wires) and a spacing of 5mm (0.2")
  • Perfboards - (very useful) - 21-113, Datak - 2.8"x1.8" -- Electronix Express, RSR Electronics, www.elexp.com
  • Wires

Video of test run with relay:

Build Motor Control Boards

IMG_0866.JPG
IMG_0867.JPG
IMG_0868.JPG
IMG_0869.JPG
IMG_0870.JPG
IMG_0871.JPG
IMG_0872.JPG
IMG_0873.JPG
IMG_0874.JPG
IMG_0875.JPG
IMG_0877.JPG
IMG_0878.JPG
IMG_0880-1.JPG
IMG_0881.JPG
IMG_0883.JPG
IMG_0983.JPG

Assembled Driver Boards - Clear Pictures

IMG_0985.JPG
IMG_0984.JPG
IMG_0987.JPG
IMG_0991.JPG
Here are additional photos of the assembled driver boards.

Wiring - Motor Power

IMG_1023.JPG
IMG_1013.JPG
IMG_1028.JPG
IMG_1020.JPG
Wire the 18V battery to the motor drives - and wire the motor drivers to the motors.

For this I used the cords from wall-warts.  I have a big box of these.  A thicker wire would be better, but this is what I have, the wires do not  get hot.

A power bus can be made by wiring together all the power inputs on the motor drivers, I've used orange for +18V.

I guessed at the pinouts from the relays to the motors.  Basically, if a motor is running the wrong way you just need to switch these wires.

Wire screws are used to make connections to motors; these are commonly used in household wiring, and are brightly colored.


Wiring - 5volt Supply

IMG_1030.JPG
IMG_1029.JPG
Next - get the 5Volt supply to all the drivers.  

For this I've used more zip cords from wall-warts.  All 5volt inputs are connected.  All grounds are connected.

5V and 18V grounds are connected to each other.  A common ground is needed for the mosfets to work.

Wiring - Control Lines From Arduino to Motor Drivers

IMG_1033.JPG
IMG_1040.JPG
IMG_1036.JPG
IMG_1037.JPG
IMG_1038.JPG
IMG_1039.JPG
IMG_1041.JPG
Wire the motor driver boards to the arduino.

So - we have already brought the 5V and Grounds from the arduino to the relay boards, all that is left are the control lines.

Each board has 2 inputs that control the speed and direction of the motor.  CatV cable is convenient because it is already bundled into pairs of 2.  

Get organized:

Solid = direction pin (digital)
Striped = speed pin (pwm)

Wiring:

Color                             Solid:                                                    Striped:
not yet                           2 - right arm direction                        3 - right arm speed
Orange                         4 - left arm direction                          5 - left arm speed
Green                           7 - waist bend direction                    6 - waist bend speed
Brown                           8 - right wheel direction                    9 - right weel speed
Blue                              12 - left wheel direction                     10 - Left wheel direction

not used                        13                                                         11
 yet                                  0
                                        1

not used                        Analog 
yet                                   0 to 5

Using Firmata to Test Stuff

IMG_1056.JPG
Firmata is a very useful tool for testing out hardware. It is software that lets you control the arduino from a PC pretty easily.

There are at least two parts to the program:
  1. Firmware that you load onto the Arduino (ie Arduino Code) this is included in the Arduino IDE: Examples -> Firmata -> Firmata 2_2 for Arduino UNO (if you are using an UNO)
  2. The other half runs on the computer - There is example code in Processing (get from Processing.org) ( http://www.arduino.cc/playground/Interfacing/Processing ) There is also an executable with a GUI here http://firmata.org/wiki/Main_Page
Here is a test video:

Test All Motors With Arduino - Autonomish

IMG_1014.JPG
IMG_1027.JPG
IMG_1050.JPG
With everything wired together and tested with Firmata control, we can now take a first stab and some autonomy. On the robot scale of autonomy (which I will make up as I go along) - this will get us somewhere between a blender (button push = one action) and a dish-washing machine (one button push = a series of actions).

So here is some simple (but long) Arduino code.

It runs each motor - forward and backward - fast and slow.


///////////////////////// ARDUINO ////////////////////////////

// Direction low = towards body or Foward
//Direction High = away from body or Backward
int RightArmDir = 2;
int RightArmSpeed = 3;
int LeftArmDir = 4;
int LeftArmSpeed = 5;
int WaistDir = 7;
int WaistSpeed = 6;
int RightWheelDir = 8;
int RightWheelSpeed = 9;
int LeftWheelDir = 12;
int LeftWheelSpeed = 10;

int Slow = 20;
int Fast = 40;
int t1 = 500;
int t2 = 100;

void setup() {
pinMode(RightArmDir, OUTPUT);
pinMode(RightArmSpeed, OUTPUT);
pinMode(LeftArmDir, OUTPUT);
pinMode(LeftArmSpeed, OUTPUT);
pinMode(WaistDir, OUTPUT);
pinMode(WaistSpeed, OUTPUT);
pinMode(RightWheelDir, OUTPUT);
pinMode(RightWheelSpeed, OUTPUT);
pinMode(LeftWheelDir, OUTPUT);
pinMode(LeftWheelSpeed, OUTPUT);

Serial.begin(9600);
}

void loop() {

//BASIC TESTS//
Serial.println("BASIC TESTS");
// Test Right Arm
Serial.println("Right Arm");
//Right Arm Up
Serial.println("Up");
digitalWrite(RightArmDir, HIGH);
digitalWrite(RightArmSpeed, Slow);
delay (t1);
digitalWrite(RightArmSpeed,Fast);
delay (t2);
digitalWrite(RightArmSpeed,Slow);
delay(t1);
digitalWrite(RightArmSpeed, 0);
delay(t1);
//Right Arm Down
Serial.println("Down");
digitalWrite(RightArmDir, LOW);
digitalWrite(RightArmSpeed, Slow);
delay (t1);
digitalWrite(RightArmSpeed, Fast);
delay (t2);
digitalWrite(RightArmSpeed, Slow);
delay(t1);
digitalWrite(RightArmSpeed, 0);
delay(t1);
// Test Left Arm
Serial.println("Left Arm");
//Left Arm Up
Serial.println("Up");
digitalWrite(LeftArmDir, HIGH);
digitalWrite(LeftArmSpeed, Slow);
delay (t1);
digitalWrite(LeftArmSpeed, Fast);
delay (t2);
digitalWrite(LeftArmSpeed, Slow);
delay (t1);
digitalWrite(LeftArmSpeed, 0);
delay(t1);
//Left Arm Down
Serial.println("Down");
digitalWrite(LeftArmDir, LOW);
digitalWrite(LeftArmSpeed, Slow);
delay (t1);
digitalWrite(LeftArmSpeed, Fast);
delay (t2);
digitalWrite(LeftArmSpeed,Slow);
delay(t1);
digitalWrite(LeftArmSpeed, 0);
delay(t1);
// Test Waist
Serial.println("Waist");
//Bend Down
Serial.println("Down");
digitalWrite(WaistDir, HIGH);
digitalWrite(WaistSpeed, Slow);
delay (t1);
digitalWrite(WaistSpeed, Fast);
delay (t2);
digitalWrite(WaistSpeed, Slow);
delay(t1);
digitalWrite(WaistSpeed, 0);
delay(t1);
//Bend Up
Serial.println("Up");
digitalWrite(WaistDir, LOW);
digitalWrite(WaistSpeed, Slow);
delay (t1);
digitalWrite(WaistSpeed, Fast);
delay (t2);
digitalWrite(WaistSpeed, Slow);
delay(t1);
digitalWrite(WaistSpeed, 0);
delay(t1);
//Test Right Wheel
Serial.println("Right Wheel");
//Right Wheel Foward'
Serial.println("Foward");
digitalWrite(RightWheelDir, HIGH);
digitalWrite(RightWheelSpeed, Slow);
delay (t1);
digitalWrite(RightWheelSpeed, Fast);
delay (t2);
digitalWrite(RightWheelSpeed, Slow);
delay(t1);
digitalWrite(RightWheelSpeed, 0);
delay(t1);
//Right Wheel Backward
Serial.println("Backward");
digitalWrite(RightWheelDir, LOW);
digitalWrite(RightWheelSpeed, Slow);
delay (t1);
digitalWrite(RightWheelSpeed, Slow);
delay (t2);
digitalWrite(RightWheelSpeed, Slow);
delay (t1);
digitalWrite(RightWheelSpeed, 0);
delay(t2);
//Test Left Wheel
Serial.println("Left Wheel");
//Left Wheel Foward
Serial.println("Foward");
digitalWrite(LeftWheelDir, HIGH);
digitalWrite(LeftWheelSpeed, Slow);
delay (t1);
digitalWrite(LeftWheelSpeed, Slow);
delay (t2);
digitalWrite(LeftWheelSpeed, Slow);
delay(t1);
digitalWrite(LeftWheelSpeed, 0);
delay(t1);
//Left Wheel Back
Serial.println("Backward");
digitalWrite(LeftWheelDir, LOW);
digitalWrite(LeftWheelSpeed, Slow);
delay (t1);
digitalWrite(LeftWheelSpeed, Slow);
delay (t2);
digitalWrite(LeftWheelSpeed,Slow);
delay(t1);
digitalWrite(LeftWheelSpeed, 0);
delay(t1);
//FANCY TESTS//
Serial.println("FANCY TESTS");
//Touch Floor
//Touch Sky
//Home Position
//Spin Left
//Spin Right
//Go Foward
//Go Backward
//Robot Dance
Serial.println("Repeat....");
}

Too Loud

IMG_1184-1.JPG
IMG_1151-1.JPG
IMG_1152-1.JPG
IMG_1153-1.JPG
Using pieces of rubber inner-tube to pad the motors helps to reduce noise and vibrations - a little.

Some motors fit inside the inner-tube, like this stepper.

For the drill motors you can jab rubber between the motors and the brackets/plywood.

Shoulder - With Two Hinges

IMG_1124-1.JPG
IMG_1125-1.JPG
IMG_1162-1.JPG
IMG_1160-1.JPG
IMG_1164-1.JPG
IMG_1122-1.JPG
The left shoulder was built with just go up and down.

We can do slightly better by building a super hinge, out of two hinges. Goal is to get up/down and side/side.

Here is a video of the 2 way hinge:


Mount Shoulder Motor - Cut Screw Rod to Length

IMG_1167-1.JPG
IMG_1180-1.JPG
IMG_1168-1.JPG
IMG_1176-1.JPG
IMG_1169-1.JPG
IMG_1173-1.JPG
IMG_1177-1.JPG
IMG_1179-1.JPG
IMG_1175.JPG
IMG_1209.JPG
Now - hook it all up to a motor via a threaded rod
  1. Attach everything with motor loose
  2. Raise and lower arm to find good motor position
  3. Mount motor - had to make L bracket
  4. Find max/min heights on threaded rod
  5. Cut rod (note: best cut ever)
  6. Re-attach rod

SpeakJet - Arduino Shield From SparkFun

IMG_1199.JPG
IMG_1196.JPG
IMG_1198.JPG
IMG_1200.JPG
IMG_1201.JPG
IMG_1203.JPG
Voice box out of the box.

Here is the assembly and testing of the Voice Box Shield from SparkFun.

This is pretty easy - however, it is not what I thought it would be. I'd expected to be able to spew out words straight from regular text. This can be done, but you need a second chip that does text-to-speech. As is, there is a table of phonetic sounds that can be strung together to make words. That should be fine, but I was hoping for really really easy.

Anyway - solder on some stackable headers and attach a speaker.

Load up some sample code and see how it sounds!



Here is molly running it -


/////////ARDUINO CODE//////////
/*
Voice Box Demo Sketch
Written by Ryan Owens
SparkFun Electronics

Uses the Voice Box Shield from SparkFun to send the message "All your base are belong to us" and a series
of robot sounds to the SpeakJet chip on the shield.

A speaker can be plugged directly into the SPK+ and - pins on the shield.

*/

//Soft serial library used to send serial commands on pin 2 instead of regular serial pin.
#include

//Define the Pin Numbers for the sketch.
#define E0 5
#define E1 6
#define E2 7
#define E3 8
#define E4 9
#define E5 10
#define E6 11
#define E7 12

#define RDY 13
#define RES 3
#define SPK 4

#define txPin 2

//Create a SoftSerial Objet
SoftwareSerial speakjet = SoftwareSerial(0, txPin);

//The message array contains the command for sounds to be sent in order to inunciate the words "All your base belong to us." Check the SpeakJet Manual for more information
//on producing words
//All Your Base Are Belong to us
char message[] = {20, 96, 21, 114, 22, 88, 23, 5, 8, 135, 8, 146, 5, 128, 153, 5, 170, 154, 8, 188, 5, 152, 5, 170, 8,128,146,8,135,8,144,5,8,191,162,5,8,134,187};

//The sounds array contains the commands to send robot sounds to the SpeakJet chip.
char sounds[] = {200, 201, 202, 203, 220, 221, 222};

void setup()
{
//Configure the pins for the SpeakJet module
pinMode(txPin, OUTPUT);
pinMode(SPK, INPUT);

//Set up a serial port to talk from Arduino to the SpeakJet module on pin 3.
speakjet.begin(9600);

//Configure the Ready pin as an input
pinMode(RDY, INPUT);

//Configure Reset line as an output
pinMode(RES, OUTPUT);

//Configure all of the Event pins as outputs from Arduino, and set them Low.
for(int i=E0; i<=E7; i++)
{
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}

//All I/O pins are configured. Reset the SpeakJet module
digitalWrite(RES, LOW);
delay(100);
digitalWrite(RES, HIGH);

}

void loop()
{
//Send "All Your Base are Belong to Us" to the SpeakJet module
speakjet.print(message);
//Wait before sending the next string.
delay(3000);
//Send the robotic sounds to the module.
speakjet.print(sounds);
while(1);
}

Get Ready for a Test Run of Motors

IMG_1227.JPG
IMG_1225.JPG
IMG_1226.JPG
IMG_1228.JPG
Lets test out the motors to see what breaks.

In preparation:
  1. Attach Arduino Vin to 18v battery - allows it to run without being plugged into USB port
  2. Fasten individual circuit boards to the wooden board, with screws and nails (do not smash stuff)
  3. Take some 'before' photos - so it will be easier to rebuild after the tests

Robot Motor Test - Gone Awry

So watch this video and see if you can tell what as gone wrong....

Video - First Try -


1 - Motors are running at very fast
2 - Burns out the mosfet controlling the waist motor


Video 2 - Try turning off and on again



1 - Motors are running at very fast
Do you see why?

I have run all the speeds as digital outputs, so we are just getting 0Volts or 18Volts going to the motor.

So wherever there is something like this:

digitalWrite(RightArmSpeed, Fast);

it should be;

analogWrite(RightArmSpeed, Fast);

the analogWrite command sends what is basically a variable voltage between 0 and 5V (with 0 = 0V; and 255 = 5V)- running this through the mosfet gives an output with 0 = 0V; and 255 = 18V.

So - below is the code fixed. The speed values are now in the range of 0-255, and can be changed at the top of the code.

2 - Burns out the mosfet controlling the waist motor

Two problems here - the first is that we are not properly controlling power to the motor - but that should now be fixed. The other issue is that it is really hard to lift up the back of the robot like this - so the motor is drawing a lot of current to get the robot to bend at the waist. We should be able to fix this mechanically by: building a better linkage; adding springs or weights to balance the upper body, or something else..... I feel like there will be a whole long step about fixing this part. I will ignore the problem for now.



///////// Arduino Code to Control Speed with analogWrite function ////////


// Direction low = towards body or Foward
//Direction High = away from body or Backward
int RightArmDir = 2;
int RightArmSpeed = 3;
int LeftArmDir = 4;
int LeftArmSpeed = 5;
int WaistDir = 7;
int WaistSpeed = 6;
int RightWheelDir = 8;
int RightWheelSpeed = 9;
int LeftWheelDir = 12;
int LeftWheelSpeed = 10;

int Slow = 100;
int Fast = 200;
int t1 = 500;
int t2 = 100;
int WheelSpeed =120;

void setup() {
pinMode(RightArmDir, OUTPUT);
pinMode(RightArmSpeed, OUTPUT);
pinMode(LeftArmDir, OUTPUT);
pinMode(LeftArmSpeed, OUTPUT);
pinMode(WaistDir, OUTPUT);
pinMode(WaistSpeed, OUTPUT);
pinMode(RightWheelDir, OUTPUT);
pinMode(RightWheelSpeed, OUTPUT);
pinMode(LeftWheelDir, OUTPUT);
pinMode(LeftWheelSpeed, OUTPUT);

Serial.begin(9600);
}

void loop() {

//BASIC TESTS//
Serial.println("BASIC TESTS");
// Test Right Arm
Serial.println("Right Arm");
//Right Arm Up
Serial.println("Up");
digitalWrite(RightArmDir, HIGH);
analogWrite(RightArmSpeed, Slow);
delay (t1);
analogWrite(RightArmSpeed,Fast);
delay (t2);
analogWrite(RightArmSpeed,Slow);
delay(t1);
analogWrite(RightArmSpeed, 0);
delay(t1);
//Right Arm Down
Serial.println("Down");
digitalWrite(RightArmDir, LOW);
analogWrite(RightArmSpeed, Slow);
delay (t1);
analogWrite(RightArmSpeed, Fast);
delay (t2);
analogWrite(RightArmSpeed, Slow);
delay(t1);
analogWrite(RightArmSpeed, 0);
delay(t1);
// Test Left Arm
Serial.println("Left Arm");
//Left Arm Up
Serial.println("Up");
digitalWrite(LeftArmDir, HIGH);
analogWrite(LeftArmSpeed, Slow);
delay (t1);
analogWrite(LeftArmSpeed, Fast);
delay (t2);
analogWrite(LeftArmSpeed, Slow);
delay (t1);
analogWrite(LeftArmSpeed, 0);
delay(t1);
//Left Arm Down
Serial.println("Down");
digitalWrite(LeftArmDir, LOW);
analogWrite(LeftArmSpeed, Slow);
delay (t1);
analogWrite(LeftArmSpeed, Fast);
delay (t2);
analogWrite(LeftArmSpeed,Slow);
delay(t1);
analogWrite(LeftArmSpeed, 0);
delay(t1);
// Test Waist
Serial.println("Waist");
//Bend Down
Serial.println("Down");
digitalWrite(WaistDir, HIGH);
analogWrite(WaistSpeed, Slow);
delay (2 * t1);
analogWrite(WaistSpeed, Fast);
delay (4 * t2);
analogWrite(WaistSpeed, Slow);
delay(2 * t1);
analogWrite(WaistSpeed, 0);
delay(t1);
//Bend Up
Serial.println("Up");
digitalWrite(WaistDir, LOW);
analogWrite(WaistSpeed, Slow);
delay (2 * t1);
analogWrite(WaistSpeed, Fast);
delay (4 * t2);
analogWrite(WaistSpeed, Slow);
delay(2 * t1);
analogWrite(WaistSpeed, 0);
delay(t1);
//Test Right Wheel
Serial.println("Right Wheel");
//Right Wheel Foward'
Serial.println("Foward");
digitalWrite(RightWheelDir, HIGH);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay (t1);
analogWrite(RightWheelSpeed, WheelSpeed);
delay (t2);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay(t1);
analogWrite(RightWheelSpeed, 0);
delay(t1);
//Right Wheel Backward
Serial.println("Backward");
digitalWrite(RightWheelDir, LOW);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay (t1);
analogWrite(RightWheelSpeed, WheelSpeed);
delay (t2);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay(t1);
analogWrite(RightWheelSpeed, 0);
delay(t2);
//Test Left Wheel
Serial.println("Left Wheel");
//Left Wheel Foward
Serial.println("Foward");
digitalWrite(LeftWheelDir, HIGH);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay (t1);
analogWrite(RightWheelSpeed, WheelSpeed);
delay (t2);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay(t1);
analogWrite(LeftWheelSpeed, 0);
delay(t1);
//Left Wheel Back
Serial.println("Backward");
digitalWrite(LeftWheelDir, LOW);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay (t1);
analogWrite(RightWheelSpeed, WheelSpeed);
delay (t2);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay(t1);
analogWrite(LeftWheelSpeed, 0);
delay(t1);
//FANCY TESTS//
Serial.println("FANCY TESTS");
//Touch Floor
//Touch Sky
//Home Position
//Spin Left
//Spin Right
//Go Foward
Serial.println("Go Foward");
digitalWrite(LeftWheelDir, HIGH);
digitalWrite(RightWheelDir,HIGH);
analogWrite(RightWheelSpeed, WheelSpeed/2);
analogWrite(LeftWheelSpeed, WheelSpeed/2);
delay (t1);
analogWrite(RightWheelSpeed, WheelSpeed);
analogWrite(LeftWheelSpeed, WheelSpeed/2);
delay (t2);
analogWrite(RightWheelSpeed, WheelSpeed/2);
analogWrite(LeftWheelSpeed, WheelSpeed/2);
delay(t1);
analogWrite(LeftWheelSpeed, 0);
analogWrite(RightWheelSpeed, 0);
delay(t1);
//Go Backward
//Robot Dance
Serial.println("Repeat....");
}// Direction low = towards body or Foward
//Direction High = away from body or Backward
int RightArmDir = 2;
int RightArmSpeed = 3;
int LeftArmDir = 4;
int LeftArmSpeed = 5;
int WaistDir = 7;
int WaistSpeed = 6;
int RightWheelDir = 8;
int RightWheelSpeed = 9;
int LeftWheelDir = 12;
int LeftWheelSpeed = 10;

int Slow = 100;
int Fast = 200;
int t1 = 500;
int t2 = 100;
int WheelSpeed =120;

void setup() {
pinMode(RightArmDir, OUTPUT);
pinMode(RightArmSpeed, OUTPUT);
pinMode(LeftArmDir, OUTPUT);
pinMode(LeftArmSpeed, OUTPUT);
pinMode(WaistDir, OUTPUT);
pinMode(WaistSpeed, OUTPUT);
pinMode(RightWheelDir, OUTPUT);
pinMode(RightWheelSpeed, OUTPUT);
pinMode(LeftWheelDir, OUTPUT);
pinMode(LeftWheelSpeed, OUTPUT);

Serial.begin(9600);
}

void loop() {

//BASIC TESTS//
Serial.println("BASIC TESTS");
// Test Right Arm
Serial.println("Right Arm");
//Right Arm Up
Serial.println("Up");
digitalWrite(RightArmDir, HIGH);
analogWrite(RightArmSpeed, Slow);
delay (t1);
analogWrite(RightArmSpeed,Fast);
delay (t2);
analogWrite(RightArmSpeed,Slow);
delay(t1);
analogWrite(RightArmSpeed, 0);
delay(t1);
//Right Arm Down
Serial.println("Down");
digitalWrite(RightArmDir, LOW);
analogWrite(RightArmSpeed, Slow);
delay (t1);
analogWrite(RightArmSpeed, Fast);
delay (t2);
analogWrite(RightArmSpeed, Slow);
delay(t1);
analogWrite(RightArmSpeed, 0);
delay(t1);
// Test Left Arm
Serial.println("Left Arm");
//Left Arm Up
Serial.println("Up");
digitalWrite(LeftArmDir, HIGH);
analogWrite(LeftArmSpeed, Slow);
delay (t1);
analogWrite(LeftArmSpeed, Fast);
delay (t2);
analogWrite(LeftArmSpeed, Slow);
delay (t1);
analogWrite(LeftArmSpeed, 0);
delay(t1);
//Left Arm Down
Serial.println("Down");
digitalWrite(LeftArmDir, LOW);
analogWrite(LeftArmSpeed, Slow);
delay (t1);
analogWrite(LeftArmSpeed, Fast);
delay (t2);
analogWrite(LeftArmSpeed,Slow);
delay(t1);
analogWrite(LeftArmSpeed, 0);
delay(t1);
// Test Waist
Serial.println("Waist");
//Bend Down
Serial.println("Down");
digitalWrite(WaistDir, HIGH);
analogWrite(WaistSpeed, Slow);
delay (2 * t1);
analogWrite(WaistSpeed, Fast);
delay (4 * t2);
analogWrite(WaistSpeed, Slow);
delay(2 * t1);
analogWrite(WaistSpeed, 0);
delay(t1);
//Bend Up
Serial.println("Up");
digitalWrite(WaistDir, LOW);
analogWrite(WaistSpeed, Slow);
delay (2 * t1);
analogWrite(WaistSpeed, Fast);
delay (4 * t2);
analogWrite(WaistSpeed, Slow);
delay(2 * t1);
analogWrite(WaistSpeed, 0);
delay(t1);
//Test Right Wheel
Serial.println("Right Wheel");
//Right Wheel Foward'
Serial.println("Foward");
digitalWrite(RightWheelDir, HIGH);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay (t1);
analogWrite(RightWheelSpeed, WheelSpeed);
delay (t2);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay(t1);
analogWrite(RightWheelSpeed, 0);
delay(t1);
//Right Wheel Backward
Serial.println("Backward");
digitalWrite(RightWheelDir, LOW);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay (t1);
analogWrite(RightWheelSpeed, WheelSpeed);
delay (t2);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay(t1);
analogWrite(RightWheelSpeed, 0);
delay(t2);
//Test Left Wheel
Serial.println("Left Wheel");
//Left Wheel Foward
Serial.println("Foward");
digitalWrite(LeftWheelDir, HIGH);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay (t1);
analogWrite(RightWheelSpeed, WheelSpeed);
delay (t2);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay(t1);
analogWrite(LeftWheelSpeed, 0);
delay(t1);
//Left Wheel Back
Serial.println("Backward");
digitalWrite(LeftWheelDir, LOW);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay (t1);
analogWrite(RightWheelSpeed, WheelSpeed);
delay (t2);
analogWrite(RightWheelSpeed, WheelSpeed/2);
delay(t1);
analogWrite(LeftWheelSpeed, 0);
delay(t1);
//FANCY TESTS//
Serial.println("FANCY TESTS");
//Touch Floor
//Touch Sky
//Home Position
//Spin Left
//Spin Right
//Go Foward
Serial.println("Go Foward");
digitalWrite(LeftWheelDir, HIGH);
digitalWrite(RightWheelDir,HIGH);
analogWrite(RightWheelSpeed, WheelSpeed/2);
analogWrite(LeftWheelSpeed, WheelSpeed/2);
delay (t1);
analogWrite(RightWheelSpeed, WheelSpeed);
analogWrite(LeftWheelSpeed, WheelSpeed/2);
delay (t2);
analogWrite(RightWheelSpeed, WheelSpeed/2);
analogWrite(LeftWheelSpeed, WheelSpeed/2);
delay(t1);
analogWrite(LeftWheelSpeed, 0);
analogWrite(RightWheelSpeed, 0);
delay(t1);
//Go Backward
//Robot Dance
Serial.println("Repeat....");
}

Still Messed Up

Here is a video showing my first run with the fixed code.



You will notice that instead of doing an orderly - right arm, left arm, waist, right wheel, left wheel, both wheels

It is doing something like - right arm, left arm, wheel, right arm, left arm, right wheel, left wheel, right arm, right arm, left arm, right arm....

What is happening?

Well, one problem is that the program is restarting before it is finished. The Arduino is probably being reset, either because power is dropping when a motor kicks on, or just due to noise (probably both)/. There is porbably noise on the digital lines also, enough to randomly toggle the relays and stuff. So we will have some fixing to do.

Do We Need Separate Power Supply for Arduino?

IMG_1278.JPG
IMG_1207.JPG
IMG_1272.JPG
IMG_1298.JPG
IMG_1299.JPG
If the reset problem is caused by dips in power, then running the arduino off of a second power supply (i.e. not the 12V drill battery) should stop it from happening.

Easiest thing to do is to disconnect the positve 18V line from the arduino Vin, and plug the Arduino USB into a computers USB port. This will give 5V power to the arduino. We have to leave the grounds attached to each other (0V from battery to ground on USB/Arduino). There is some risk of breaking the computers USB port.

This also lets us monitor the program by getting the serial ouput telling us which step the program is at.

Here is video.





Since this does seem to solve alot of problems, it will be very useful to add a separate power supply for the arduino. The Arduino Uno (and many others) have a built in 5Volt regulater (this is what allows the arduino to run of the 18V battery) - an input between 5 and 12Volts will be good. For example a 9V battery with a plug - or 4 AA batteries (6V).

********* IMPORTANT NOTE***********

Plug does not work right on this board - seems to be converting to 3.3V - or just not right.

So: CONNECT POWER TO Vin and GROUND

Check 5V on Arduino (from the regulator - "5V" pin) with meter

************************************

Take It Outside

IMG_1300.JPG
IMG_1301.JPG
I tried running some tests in the driveway -- this went very poorly.  

I had connected the 6V battery pack to the jack on the arduino - but the jack was knocking the power way down to 3V.

Re-wiring to Vin fixes the problem.

Also - it is obvious that the wheels will need to be redone

Waist Linkage Redo

IMG_1291.JPG
IMG_1293.JPG
IMG_1292.JPG
IMG_1282.JPG
IMG_1281.JPG
IMG_1279.JPG
IMG_1297.JPG
IMG_1296-1.JPG
IMG_1295.JPG
IMG_1294.JPG
Rebuilt mechanism to bend at waist - still not great

-moved motor a little
-added L bracket to try and get more leverage (had to make L bracket)
-added small link to give it some slack
-added a screw to keep the link from locking up when robot is bent all the way down

-also - replace mosfet driving waist motor (second time - should add fuse, or something better)

Test Code Redo - Using Function



The test code is getting long and confusing.

As it is now, every action needs its own block of code with all the details in it. So, repeating an action needs a whole 'nother copy of the code.

An easy way to deal with this is to make each action into a 'Function' then call the function from the main loop.

The new code is below. I have taken everything that was in the main loop and moved it down to the end. Then I made each action into its own function, with its own name.

Like this (the changes are in bold):
void RightArmDown(){
//Right Arm Down
Serial.println("Right Arm Down");
digitalWrite(RightArmDir, LOW);
analogWrite(RightArmSpeed, Slow);
delay (t1);
analogWrite(RightArmSpeed, Fast);
delay (2*t2);
analogWrite(RightArmSpeed, Slow);
delay(t1);
analogWrite(RightArmSpeed, 0);
delay(2*t1);
}

Now - in the main loop, you can replace the long section of code with the name of the function:

void RightArmDown();

So - that makes things a little easier.

Below is the newly organized code (copied as html...)

A video with it working well:
[1318]




////////////////////// ARDUINO CODE //////////////////////////

 ////// Robot test with little routines made into functions//////  /////VARIABLES///////// // Direction low = towards body or Foward //Direction High = away from body or Backward int RightArmDir     =  2; int RightArmSpeed   =  3; int LeftArmDir      =  4; int LeftArmSpeed    =  5; int WaistDir        =  7; int WaistSpeed      =  6; int RightWheelDir   =  8; int RightWheelSpeed =  9; int LeftWheelDir    = 12; int LeftWheelSpeed  = 10;  int Slow = 100; int Fast = 200; int t1 = 100; int t2 = 500; int WheelSpeed =120;  ///////// SETUP  /////////  void setup() { pinMode(RightArmDir, OUTPUT); pinMode(RightArmSpeed, OUTPUT); pinMode(LeftArmDir, OUTPUT); pinMode(LeftArmSpeed, OUTPUT); pinMode(WaistDir, OUTPUT); pinMode(WaistSpeed, OUTPUT); pinMode(RightWheelDir, OUTPUT); pinMode(RightWheelSpeed, OUTPUT); pinMode(LeftWheelDir, OUTPUT); pinMode(LeftWheelSpeed, OUTPUT);  Serial.begin(9600); }  //////// MAIN LOOP /////// void loop() {   Serial.println("Start...."); delay(2000);       RightArmUp();   RightArmDown();   LeftArmUp();   LeftArmDown();   WaistBendDown();   WaistBendUp();   Foward();   Backward();   Spin();    Serial.println("Repeat....");   }  /////////////////////////////////////////////// /////////   BASIC FUNCTIONS /////////////////// ///////////////////////////////////////////////   void RightArmUp(){ // Test Right Arm    Serial.println("Right Arm");   //Right Arm Up   Serial.println("Up");   digitalWrite(RightArmDir, HIGH);   analogWrite(RightArmSpeed, Slow);   delay (t1);   analogWrite(RightArmSpeed,Fast);   delay (2*t2);   analogWrite(RightArmSpeed,Slow);   delay(t1);   analogWrite(RightArmSpeed, 0);   delay(t1);  }    void RightArmDown(){   //Right Arm Down   Serial.println("Right Arm Down");   digitalWrite(RightArmDir, LOW);   analogWrite(RightArmSpeed, Slow);   delay (t1);   analogWrite(RightArmSpeed, Fast);   delay (2*t2);   analogWrite(RightArmSpeed, Slow);   delay(t1);   analogWrite(RightArmSpeed, 0);   delay(2*t1);  }    void LeftArmUp(){ // Test Left Arm   Serial.println("Left Arm Up");   //Left Arm Up   digitalWrite(LeftArmDir, HIGH);   analogWrite(LeftArmSpeed, Slow);   delay (t1);   analogWrite(LeftArmSpeed, Fast);   delay (2*t2);   analogWrite(LeftArmSpeed, Slow);   delay (t1);   analogWrite(LeftArmSpeed, 0);   delay(t1);  }    void LeftArmDown(){   //Left Arm Down   Serial.println("Left Arm Down");   digitalWrite(LeftArmDir, LOW);   analogWrite(LeftArmSpeed, Slow);   delay (t1);   analogWrite(LeftArmSpeed, Fast);   delay (2*t2);   analogWrite(LeftArmSpeed,Slow);   delay(t1);   analogWrite(LeftArmSpeed, 0);   delay(2*t1);  }    void WaistBendDown(){ // Test Waist   Serial.println("Waist Bend Down");   digitalWrite(WaistDir, HIGH);   analogWrite(WaistSpeed, Slow);   delay (t1);   analogWrite(WaistSpeed, Fast);   delay (2*t2);   analogWrite(WaistSpeed, Slow);   delay(t1);   analogWrite(WaistSpeed, 0);   delay(t1);  }    void WaistBendUp(){   //Bend Up   Serial.println("Up");   digitalWrite(WaistDir, LOW);   analogWrite(WaistSpeed, Slow);   delay (t1);   analogWrite(WaistSpeed, Fast);   delay (2*t2);   analogWrite(WaistSpeed, Slow);   delay(t1);   analogWrite(WaistSpeed, 0);   delay(2*t1);  }    void Spin(){   Serial.println("SPIN");   digitalWrite(LeftWheelDir, LOW);   digitalWrite(RightWheelDir,HIGH);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay (t1);   analogWrite(RightWheelSpeed, WheelSpeed);   analogWrite(LeftWheelSpeed, WheelSpeed);   delay (t2);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay(t1);   analogWrite(LeftWheelSpeed, 0);   analogWrite(RightWheelSpeed, 0);   delay(2*t1);   }          void Foward(){   Serial.println("Go Foward");   digitalWrite(LeftWheelDir, HIGH);   digitalWrite(RightWheelDir,HIGH);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay (t1);   analogWrite(RightWheelSpeed, WheelSpeed);   analogWrite(LeftWheelSpeed, WheelSpeed);   delay (t2);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay(t1);   analogWrite(LeftWheelSpeed, 0);   analogWrite(RightWheelSpeed, 0);   delay(2*t1);   }      void Backward(){   Serial.println("Go Backward");   digitalWrite(LeftWheelDir, LOW);   digitalWrite(RightWheelDir,LOW);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay (t1);   analogWrite(RightWheelSpeed, WheelSpeed);   analogWrite(LeftWheelSpeed, WheelSpeed);   delay (t2);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay(t1);   analogWrite(LeftWheelSpeed, 0);   analogWrite(RightWheelSpeed, 0);   delay(2*t1);   }  

 


 

Move to the Floor - Wheels Bad

It is time to test this thing on the floor.

The wheels do not work well.

Video:
[1319]




I tried changing the wheel speed - but it is still no good.

Video:
[1320]




Wheel Redo

IMG_1321.JPG
IMG_1322.JPG
IMG_1325.JPG
IMG_1327.JPG
IMG_1329.JPG
IMG_1326.JPG
IMG_1330.JPG
IMG_1331.JPG
The wheels are not working well and the drills will probably break from trying to support the weight of the machine.

A soluction that works okay - is to add casters to the base of the robot.  The casters will support most of the weight and the drills will just have to rotate the wheels.

I was lucky to have a heavy duty 5 wheel caster thing lying around.

To align the drill - I mounted them to a peice of plywood, then bolted the plywood to the caster thing.  I've attempted to spring load the wheels, so that they will always make contact with the floor, but this does not really seem to do anything.

Better Wheels and Base

Here is a video -  
[1333]



The wheels are still not great, but at least we have some ability to move the robot around.

Problems:
  • the casters resist changes in direction, because they have to spin
  • rolls after stopping - try adding a short motor reverse to halt the wheels ( ie.  wheels forward ->reduce speed to zero -> wheels backward for a moment, maybe at a low speed, just enough to stop momentum)

Test Code - Control From PC Via USB

We are quickly using up the pins on the first arduino. We will have to use multiple boards and then communicate between them. To get this started I have added serial inputs to the test code. A switch case control structure calls the function based on serial input.

The code is below:
Now the following commands control the motions. They are sent using the serial monitor.  Using all lower case (it is actually the ascii codes for the letters that are sent, so case matters)

f = forward
b = backward
r = right arm up
t = right arm down
w = left arm up
e = left arm down
z = waist bend down
x = waist bend up

/////////////////////////////Arduino Code //////////////////////////////

 ////// Robot test with little routines made into functions////// ////// Added serial control  /////VARIABLES///////// // Direction low = towards body or Foward //Direction High = away from body or Backward int RightArmDir     =  2; int RightArmSpeed   =  3; int LeftArmDir      =  4; int LeftArmSpeed    =  5; int WaistDir        =  7; int WaistSpeed      =  6; int RightWheelDir   =  8; int RightWheelSpeed =  9; int LeftWheelDir    = 12; int LeftWheelSpeed  = 10;  int Slow = 100; int Fast = 200; int t1 = 200; int t2 = 1000; int WheelSpeed =75;  int incomingByte; ///////// SETUP  /////////  void setup() { pinMode(RightArmDir, OUTPUT); pinMode(RightArmSpeed, OUTPUT); pinMode(LeftArmDir, OUTPUT); pinMode(LeftArmSpeed, OUTPUT); pinMode(WaistDir, OUTPUT); pinMode(WaistSpeed, OUTPUT); pinMode(RightWheelDir, OUTPUT); pinMode(RightWheelSpeed, OUTPUT); pinMode(LeftWheelDir, OUTPUT); pinMode(LeftWheelSpeed, OUTPUT);  Serial.begin(9600); }  //////// MAIN LOOP /////// void loop() {   Serial.println("...."); delay(2000);    if(Serial.available()>0){     incomingByte = Serial.read();    switch(incomingByte){      case 'f':        Foward();        break;       case 'b':         Backward();         break;        case 'r':          RightArmUp();          break;         case 't':           RightArmDown();           break;          case 'w':            LeftArmUp();            break;           case 'e':             LeftArmDown();             break;            case 'z':              WaistBendDown();              break;             case 'x':               WaistBendUp();               break;    }   } }  /////////////////////////////////////////////// /////////   BASIC FUNCTIONS /////////////////// ///////////////////////////////////////////////   void RightArmUp(){ // Test Right Arm    Serial.println("Right Arm");   //Right Arm Up   Serial.println("Up");   digitalWrite(RightArmDir, HIGH);   analogWrite(RightArmSpeed, Slow);   delay (t1);   analogWrite(RightArmSpeed,Fast);   delay (2*t2);   analogWrite(RightArmSpeed,Slow);   delay(t1);   analogWrite(RightArmSpeed, 0);   delay(t1);  }    void RightArmDown(){   //Right Arm Down   Serial.println("Right Arm Down");   digitalWrite(RightArmDir, LOW);   analogWrite(RightArmSpeed, Slow);   delay (t1);   analogWrite(RightArmSpeed, Fast);   delay (2*t2);   analogWrite(RightArmSpeed, Slow);   delay(t1);   analogWrite(RightArmSpeed, 0);   delay(2*t1);  }    void LeftArmUp(){ // Test Left Arm   Serial.println("Left Arm Up");   //Left Arm Up   digitalWrite(LeftArmDir, HIGH);   analogWrite(LeftArmSpeed, Slow);   delay (t1);   analogWrite(LeftArmSpeed, Fast);   delay (2*t2);   analogWrite(LeftArmSpeed, Slow);   delay (t1);   analogWrite(LeftArmSpeed, 0);   delay(t1);  }    void LeftArmDown(){   //Left Arm Down   Serial.println("Left Arm Down");   digitalWrite(LeftArmDir, LOW);   analogWrite(LeftArmSpeed, Slow);   delay (t1);   analogWrite(LeftArmSpeed, Fast);   delay (2*t2);   analogWrite(LeftArmSpeed,Slow);   delay(t1);   analogWrite(LeftArmSpeed, 0);   delay(2*t1);  }    void WaistBendDown(){ // Test Waist   Serial.println("Waist Bend Down");   digitalWrite(WaistDir, HIGH);   analogWrite(WaistSpeed, Slow);   delay (t1);   analogWrite(WaistSpeed, Fast);   delay (2*t2);   analogWrite(WaistSpeed, Slow);   delay(t1);   analogWrite(WaistSpeed, 0);   delay(t1);  }    void WaistBendUp(){   //Bend Up   Serial.println("Up");   digitalWrite(WaistDir, LOW);   analogWrite(WaistSpeed, Slow);   delay (t1);   analogWrite(WaistSpeed, Fast);   delay (2*t2);   analogWrite(WaistSpeed, Slow);   delay(t1);   analogWrite(WaistSpeed, 0);   delay(2*t1);  }    void Spin(){   Serial.println("SPIN");   digitalWrite(LeftWheelDir, LOW);   digitalWrite(RightWheelDir,HIGH);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay (t1);   analogWrite(RightWheelSpeed, WheelSpeed);   analogWrite(LeftWheelSpeed, WheelSpeed);   delay (t2);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay(t1);   analogWrite(LeftWheelSpeed, 0);   analogWrite(RightWheelSpeed, 0);   }         void Spin2(){   Serial.println("SPIN2");   digitalWrite(LeftWheelDir, HIGH);   digitalWrite(RightWheelDir,LOW);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay (t1);   analogWrite(RightWheelSpeed, WheelSpeed);   analogWrite(LeftWheelSpeed, WheelSpeed);   delay (t2);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay(t1);   analogWrite(LeftWheelSpeed, 0);   analogWrite(RightWheelSpeed, 0);   }          void Foward(){   Serial.println("Go Foward");   digitalWrite(LeftWheelDir, HIGH);   digitalWrite(RightWheelDir,HIGH);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay (t1);   analogWrite(RightWheelSpeed, WheelSpeed);   analogWrite(LeftWheelSpeed, WheelSpeed);   delay (t2);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay(t1);   analogWrite(LeftWheelSpeed, 0);   analogWrite(RightWheelSpeed, 0);   }      void Backward(){   Serial.println("Go Backward");   digitalWrite(LeftWheelDir, LOW);   digitalWrite(RightWheelDir,LOW);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay (t1);   analogWrite(RightWheelSpeed, WheelSpeed);   analogWrite(LeftWheelSpeed, WheelSpeed);   delay (t2);   analogWrite(RightWheelSpeed, WheelSpeed/2);   analogWrite(LeftWheelSpeed, WheelSpeed/2);   delay(t1);   analogWrite(LeftWheelSpeed, 0);   analogWrite(RightWheelSpeed, 0);   }  

Make One Arm Good - Right Handed Robot

IMG_1223.JPG

Using stepper motors and servos we can get better motion control than by using DC motors (hopefully)

Servos are pretty easy - you just tell them where to go, and they go.

Steppers are a little harder - they have alot of wires.

I will try using a motor shield from Adafruit 

It controls 2 servos and 4 dc motors
                or
               2 servos and 2 stepper motors

   Will try:
         - 1 stepper: shoulder out (abduction)
         - 2 stepper: elbow flex
         - 1 servo: wrist
         - 2 servo: hand



lots of info:  http://www.ladyada.net/make/mshield/use.html


Shoulder - 1 Stepper

IMG_1215.JPG
IMG_1210.JPG
IMG_1214.JPG
IMG_1223.JPG
Add a second motor to give the left shoulder more movement.
  1. Using stepper motor to pull a string
  2. Shaft collar with set screw used to mount string to stepper
  3. Add spring to return arm to down position
Has 4 wires out: 
  Blue:
  Black:
  Green:
  Red:

Elbow Motor - Stepper 2

Using a little stepper for this:
http://www.adafruit.com/products/168

It has 6 leads:

  Green + Read : ground
  Brown:M1 
  Black: M1 (other terminal)
  Orange: M2
  Yellow: M2 (other terminal)

Will need a new library for this:  http://www.ladyada.net/make/mshield/download.html


load that up and run.

Video: 


Sample code:

////////////////////////////////
////// http://www.ladyada.net/make/mshield/use.html ///////////////
/////////////////////////
///////////// Cut/paste -- change motor port as needed
/////////////////////////////////////////////////////////////////////////////////////////////
#include <AFMotor.h>


AF_Stepper motor(48, 1);  //48 steps per roation - on motor port 1


void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Stepper test!");

  motor.setSpeed(10);  // 10 rpm  

  motor.step(100, FORWARD, SINGLE);
  motor.release();
  delay(1000);
}

void loop() {
  motor.step(100, FORWARD, SINGLE);
  motor.step(100, BACKWARD, SINGLE);

  motor.step(100, FORWARD, DOUBLE);
  motor.step(100, BACKWARD, DOUBLE);

  motor.step(100, FORWARD, INTERLEAVE);
  motor.step(100, BACKWARD, INTERLEAVE);

  motor.step(100, FORWARD, MICROSTEP);
  motor.step(100, BACKWARD, MICROSTEP);
}

Put the Skin (cardboard) Back On

IMG_1407.JPG
IMG_1398.JPG
IMG_1396.JPG
IMG_1395.JPG
IMG_1394.JPG
Re-attach cardboard shell.  

Cut and tape as needed.

Good for kids.

Used some deck screws.




Neck - Servo to Move Head

IMG_1420.JPG
IMG_1405.JPG
IMG_1403.JPG
IMG_1401.JPG
To move the head back and forth - mount a medium sized servo motor on the top peice of carboard (see pic).

The axle pokes through the cardboard, then a plastic gear is added.  I've taped a a piece of carboard to the plastic gear.  The head will be taped to this.

Servos are easy with arduino.

3 wires from servo - 
    Yellow - position - attaches to pin 11 (pwm) on arduino
    Red - 5V - to 5V arduino supply
    Black - ground - to arduino ground.


The only tricky part is to figure out the angles that are useful.
    Turned out to be: 
               5deg - faces left
               80deg - faces forward
               155 deg - faces left
   This will be different depending on how the servo is mounted.

 I've adapted this servo example code to output the position via USB.

Also the movements are all in a function called moveHead()
Should be able to mash this in with the other test code and run it from the serial port.
   

Video:
[neck]


Video:
[head]


//////////////////////  ARDUINO CODE  /////////////////////

// Sweep
// by BARRAGAN <http://barraganstudio.com>
// This example code is in the public domain.
/////pin 9 to pin11
//// changed angles

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
                // a maximum of eight servo objects can be created

int pos = 0;    // variable to store the servo position
int posFront = 81;
void setup()
{
  myservo.attach(11);  // attaches the servo on pin 11 to the servo object
  Serial.begin(9600);
}
 
void loop()
{
  moveHead();  // call the function move head
}

void moveHead(){       //create function move head// head go back anbd forth
  for(pos = 5; pos < 145; pos += 1)   //goes from 5 to 145degrees
  {                                  // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    Serial.println(pos);
    delay(15);                       // waits 15ms for the servo to reach the position
    if(pos == posFront){
      delay(600);
    }
     
}
  for(pos = 145; pos>=5; pos-=1)     // goes from 145 degrees to 5 degrees
  {                               
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);     // waits 15ms for the servo to reach the position
    if(pos == posFront){
      delay(600);
    }
  }
}

Added MoveHead() to the Rest of the Serial Test Code

I guess we have enough moves to start working on something else.  

serial commands added:
   'h' - to move the head - runs through full sweep
   's' - spin one way (function was already there, but did not have a case)
   'd' - spin the other way   (function was already there, but did not have a case)

This code should be made shorter but here it is:


video
[allMoves





////////////////////////////////  ARDUINO CODE//////////////////////////////////

////// Robot test with little routines made into functions//////
//// added head moving ////


/////motor VARIABLES/////////
// Direction low = towards body or Foward
//Direction High = away from body or Backward
int RightArmDir     =  2;
int RightArmSpeed   =  3;
int LeftArmDir      =  4;
int LeftArmSpeed    =  5;
int WaistDir        =  7;
int WaistSpeed      =  6;
int RightWheelDir   =  8;
int RightWheelSpeed =  9;
int LeftWheelDir    = 12;
int LeftWheelSpeed  = 10;

int Slow = 100;
int Fast = 200;
int t1 = 200;     //time at slow speed
int t2 = 1000;    //time at fast speed
int tBreak = 100; //time to stop motor by reversing dir
int WheelSpeed =75;
int breakSpeed = 10;
int bendSpeed = 255;
int incomingByte;

///////////// head variables
#include <Servo.h>
Servo myservo;  // create servo object to control a servo
int pos = 80;  
int posFront = 80;
///////// SETUP  /////////

void setup() {
pinMode(RightArmDir, OUTPUT);
pinMode(RightArmSpeed, OUTPUT);
pinMode(LeftArmDir, OUTPUT);
pinMode(LeftArmSpeed, OUTPUT);
pinMode(WaistDir, OUTPUT);
pinMode(WaistSpeed, OUTPUT);
pinMode(RightWheelDir, OUTPUT);
pinMode(RightWheelSpeed, OUTPUT);
pinMode(LeftWheelDir, OUTPUT);
pinMode(LeftWheelSpeed, OUTPUT);

myservo.attach(11);  // attaches the servo on pin 11 to the servo object

Serial.begin(9600);
}

//////// MAIN LOOP ///////
void loop() { 
Serial.println("....");
delay(400);
  if(Serial.available()>0){
    incomingByte = Serial.read();
   switch(incomingByte){
     case 'f':
       Foward();
       break;
      case 'b':
        Backward();
        break;
       case 'r':
         RightArmUp();
         break;
        case 't':
          RightArmDown();
          break;
         case 'w':
           LeftArmUp();
           break;
          case 'e':
            LeftArmDown();
            break;
           case 'z':
             WaistBendDown();
             break;
            case 'x':
              WaistBendUp();
              break;
           case 'h':
              MoveHead();
              break;
            case 's':
               Spin();
               break;
              case'd':
                Spin2();
                break;
   }
  }
}

///////////////////////////////////////////////
/////////   BASIC FUNCTIONS ///////////////////
///////////////////////////////////////////////

void RightArmUp(){
// Test Right Arm
   Serial.println("Right Arm");
  //Right Arm Up
  Serial.println("Up");
  digitalWrite(RightArmDir, HIGH);
  analogWrite(RightArmSpeed, Slow);
  delay (t1);
  analogWrite(RightArmSpeed,Fast);
  delay (1.8*t2);
  analogWrite(RightArmSpeed,Slow);
  delay(t1);
  analogWrite(RightArmSpeed, 0);
  delay(t1);
}

void RightArmDown(){
  //Right Arm Down
  Serial.println("Right Arm Down");
  digitalWrite(RightArmDir, LOW);
  analogWrite(RightArmSpeed, Slow);
  delay (t1);
  analogWrite(RightArmSpeed, Fast);
  delay (1.8*t2);
  analogWrite(RightArmSpeed, Slow);
  delay(t1);
  analogWrite(RightArmSpeed, 0);
  delay(2*t1);
}

void LeftArmUp(){
// Test Left Arm
  Serial.println("Left Arm Up");
  //Left Arm Up
  digitalWrite(LeftArmDir, HIGH);
  analogWrite(LeftArmSpeed, Slow);
  delay (t1);
  analogWrite(LeftArmSpeed, Fast);
  delay (2*t2);
  analogWrite(LeftArmSpeed, Slow);
  delay (t1);
  analogWrite(LeftArmSpeed, 0);
  delay(t1);
}

void LeftArmDown(){
  //Left Arm Down
  Serial.println("Left Arm Down");
  digitalWrite(LeftArmDir, LOW);
  analogWrite(LeftArmSpeed, Slow);
  delay (t1);
  analogWrite(LeftArmSpeed, Fast);
  delay (2*t2);
  analogWrite(LeftArmSpeed,Slow);
  delay(t1);
  analogWrite(LeftArmSpeed, 0);
  delay(2*t1);
}

void WaistBendDown(){
// Test Waist
  Serial.println("Waist Bend Down");
  digitalWrite(WaistDir, HIGH);
  analogWrite(WaistSpeed, Slow);
  delay (t1);
  analogWrite(WaistSpeed, bendSpeed);
  delay (2*t2);
  analogWrite(WaistSpeed, Slow);
  delay(t1);
  analogWrite(WaistSpeed, 0);
  delay(t1);
}

void WaistBendUp(){
  //Bend Up
  Serial.println("Up");
  digitalWrite(WaistDir, LOW);
  analogWrite(WaistSpeed, Slow);
  delay (t1);
  analogWrite(WaistSpeed, bendSpeed);
  delay (2*t2);
  analogWrite(WaistSpeed, Slow);
  delay(t1);
  analogWrite(WaistSpeed, 0);
  delay(2*t1);
}

  void Spin(){
  Serial.println("SPIN");
  digitalWrite(LeftWheelDir, LOW);
  digitalWrite(RightWheelDir,HIGH);
  analogWrite(RightWheelSpeed, WheelSpeed/2);
  analogWrite(LeftWheelSpeed, WheelSpeed/2);
  delay (t1);
  analogWrite(RightWheelSpeed, WheelSpeed);
  analogWrite(LeftWheelSpeed, WheelSpeed);
  delay (t2);
  analogWrite(RightWheelSpeed, WheelSpeed/2);
  analogWrite(LeftWheelSpeed, WheelSpeed/2);
  delay(t1);
  analogWrite(LeftWheelSpeed, 0);
  analogWrite(RightWheelSpeed, 0);
  delay(t1);
  digitalWrite(LeftWheelDir, HIGH);
  digitalWrite(RightWheelDir,LOW);
  analogWrite(LeftWheelSpeed, breakSpeed);
  analogWrite(RightWheelSpeed, breakSpeed);
  delay(tBreak);
  analogWrite(LeftWheelSpeed, 0);
  analogWrite(RightWheelSpeed,0);
}
 
    void Spin2(){
  Serial.println("SPIN2");
  digitalWrite(LeftWheelDir, HIGH);
  digitalWrite(RightWheelDir,LOW);
  analogWrite(RightWheelSpeed, WheelSpeed/2);
  analogWrite(LeftWheelSpeed, WheelSpeed/2);
  delay (t1);
  analogWrite(RightWheelSpeed, WheelSpeed);
  analogWrite(LeftWheelSpeed, WheelSpeed);
  delay (t2);
  analogWrite(RightWheelSpeed, WheelSpeed/2);
  analogWrite(LeftWheelSpeed, WheelSpeed/2);
  delay(t1);
  analogWrite(LeftWheelSpeed, 0);
  analogWrite(RightWheelSpeed, 0);
  delay(t1);
  digitalWrite(LeftWheelDir, LOW);
  digitalWrite(RightWheelDir,HIGH);
  analogWrite(LeftWheelSpeed, breakSpeed);
  analogWrite(RightWheelSpeed,breakSpeed);
  delay(tBreak);
  analogWrite(LeftWheelSpeed, 0);
  analogWrite(RightWheelSpeed,0);
  }
 
 
  void Foward(){
  Serial.println("Go Foward");
  digitalWrite(LeftWheelDir, HIGH);
  digitalWrite(RightWheelDir,HIGH);
  analogWrite(RightWheelSpeed, WheelSpeed/2);
  analogWrite(LeftWheelSpeed, WheelSpeed/2);
  delay (t1);
  analogWrite(RightWheelSpeed, WheelSpeed);
  analogWrite(LeftWheelSpeed, WheelSpeed);
  delay (t2);
  analogWrite(RightWheelSpeed, WheelSpeed/2);
  analogWrite(LeftWheelSpeed, WheelSpeed/2);
  delay(t1);
  analogWrite(LeftWheelSpeed, 0);
  analogWrite(RightWheelSpeed, 0);
  delay(t1);
  digitalWrite(LeftWheelDir, LOW);
  digitalWrite(RightWheelDir,LOW);
  analogWrite(LeftWheelSpeed, breakSpeed);
  analogWrite(RightWheelSpeed,breakSpeed);
  delay(tBreak);
  analogWrite(LeftWheelSpeed, 0);
  analogWrite(RightWheelSpeed,0);
}
 
  void Backward(){
  Serial.println("Go Backward");
  digitalWrite(LeftWheelDir, LOW);
  digitalWrite(RightWheelDir,LOW);
  analogWrite(RightWheelSpeed, WheelSpeed/2);
  analogWrite(LeftWheelSpeed, WheelSpeed/2);
  delay (t1);
  analogWrite(RightWheelSpeed, WheelSpeed);
  analogWrite(LeftWheelSpeed, WheelSpeed);
  delay (t2);
  analogWrite(RightWheelSpeed, WheelSpeed/2);
  analogWrite(LeftWheelSpeed, WheelSpeed/2);
  delay(t1);
  analogWrite(LeftWheelSpeed, 0);
  analogWrite(RightWheelSpeed, 0);
  delay(t1);
  digitalWrite(LeftWheelDir, HIGH);
  digitalWrite(RightWheelDir,HIGH);
  analogWrite(LeftWheelSpeed, breakSpeed);
  analogWrite(RightWheelSpeed,breakSpeed);
  delay(tBreak);
  analogWrite(LeftWheelSpeed, 0);
  analogWrite(RightWheelSpeed,0);
}
////////////move head////////////
void MoveHead(){       //create function move head// head go back anbd forth
  for(pos = 5; pos < 145; pos += 1)   //goes from 5 to 145degrees
  {                                  // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    Serial.println(pos);
    delay(15);                       // waits 15ms for the servo to reach the position
    if(pos == posFront){
      delay(600);
    }     
  }
  for(pos = 145; pos>=posFront; pos-=1)     // goes from 145 degrees to front
  {                               
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);     // waits 15ms for the servo to reach the position
    if(pos == posFront){
      delay(600);
    }
    }
}

Second Battery (or Third I Guess)


when both wheels are run at the same time - it does not work well.

I tried running each wheel of a seperate battery ---- but I did not do it correctly....

video (not much here):





Emma explains:
Video



Fabric Bend Sensors - Not Used

IMG_1353.JPG
Tried using fabric bend sensors to sens arm position - this will take some fine tuning.

Robot Claw - Premade

IMG_1372.JPG
IMG_1373.JPG
IMG_1374.JPG
IMG_1378.JPG
IMG_1380.JPG
IMG_1382.JPG
Tried a robot claw from spark fun.... did not read instructions..... 

Motor Sheild - Adafruit - Small Motors

IMG_1360.JPG
IMG_1362.JPG
IMG_1365.JPG
IMG_1366.JPG
IMG_1367.JPG
IMG_1370.JPG
This motor shield would be very good for face and hand movements.

Messed Up the Wheels

Well - I've done something to mess up the wheels.  The relays are responding but no action.  I swapped out the mosfet for the left wheel - not sure if that is the problem.


Video:
[bad wheels]



Paint!

IMG_1440.JPG
IMG_1435.JPG
IMG_1437.JPG
IMG_1438.JPG
IMG_1433.JPG
IMG_1432.JPG
Time to paint the shell - this is fun and easy.

Unlike the direction control - which has become difficult and tedious.