Introduction: CRANE GAME

About: Married to Domestic_Engineer (but I call her Meghan).

This shows you how to build an arcade style crane game out of scrap parts.  The basic parts are: a motorized assembly that raises and lowers a claw,  a track for the assembly to move around on, and a ctontroller with some electronics. 

October 2013
https://www.tindie.com/products/marc_cryan/claw/
Actual claw on tindie.com fundraiser 
***

*** September 2013  **
I have a project running on tindie.com   for a real claw machine kit.
****


Here is a video of the machine in action.

Video -

Emma after some practice-


Controls -


Pick up and drop -



Overview -
I like to document my work as I go along, so this instructable contains multiple versions with varying components.   I think that this is useful because it seems unlickkly that you would happen to have all the same scrap peices as I do.  I have also tried to show how to build a moderatly complex system by  bulding one peice at a time and then combining them.  By keeping things modular you are able to swap out large peices without having to rebuild the whole thing. 

Here is a rough outline:
     - Get each motor working by itself,  I used a joystick with potentiameters to control the motors, one POT per motor
     - Get all the motors working at once - by wiring all the motor drivers to the Arduino at once and combing the control codes, we are able to run everything at once.  This same setup will be used l to control the whole machine.
     - Build a small test rig with just one axis - It is easier to work on something that you can put on a bench top then it is to work with something mounted the ceiling.  So I will show you how to cobble together a test set-up that will let us work out some of the details without having to build a large rig.
     - Build a large rig - once everything is working on the test rig, we can go ahead and make it bigger.  This required some different materials, but the wiring, code, and motor setup don't nned to change. 
    - Test and improve  - Once the system is working it is easy to see things that can be improved.  I wound up replacing the original joysticks with a larger controller from a kids game.  The whole thing is pretty flexible so there is alot of room for modification and impruovemnt.


Parts -
Most of the project is built with salvaged computer parts.   Here is a list of parts that you could salvage or buy. 

Power supply - I used a power supply salvaged from a server.  There are good instructions for hacking one of these here http://reprap.org/bin/view/Main/PCPowerSupply  I also pulled a 12volt power supply out of a printer that would have worked well.

Motors -  At least 3 motors are needed.  I used 2 DC motors and a pretty big stepper.  The DC motors are both pulled from an Epson Printer/Scanner.  The stepper is a NEM23 from Keling Technology.  A smaller one would be fine.   You can get one here http://www.sparkfun.com/commerce/product_info.php?products_id=9238.

Drivers -  You can build, buy, or salvage drivers for the motors.  Buying is the easiest and they are not two expensive. I used a  steppper driver and the DC motor driver from the RepRap Gen2 electornics.  The DC motor driver is here - DC Motor Driver v1.1 Kit  http://store.makerbot.com/electronics/electronics-kits.html.   Sparkfun as a good stepper driver here - http://www.sparkfun.com/commerce/product_info.php?products_id=9402

This motor sheild from Adafruit would work well - http://www.adafruit.com/index.php?main_page=product_info&cPath=34&products_id=81

Microcontroller -   The Arduino platform is fun and easy to use.  http://www.arduino.cc/  I used the
Arduino Duemilonove with a hefty screw sheild  http://store.makerbot.com/electronics/electronics-kits/arduino-breakout-shield-v1-4-kit.html

Controller - I started with thumb joystick controllers like  on a PS2 - but I found that a controller from Leap Frog Baby worked out better. http://www.amazon.com/LeapFrog-10210-LITTLE-LEAPS-PLATFORM/dp/B000EIV1OM

Claw - The claw is made from mouse shells and strips of plastics cut from a printer housing.

Wiring - Most of the wiring is discarded cat-5 network cable

Track  - For the test rig I used wooden tracks, for the larger set up I used metal J-trim 1/2" x 10' - this was in the drywall section of home depot - it is the only thing I bought specifically for this project.

Step 1: Control a DC Motor With Variable Resistor


The first thing we will do is to get each motor working with a controller. 

Use a joystick with potentiameter to controll the speed and direction of a DC motor. 

This will be used to:
                         - raise and lower the claw
                         - open and close the clow

Hardware chain:
Joystick (potentiameter) -> Arduino with code -> DC motor driver V1.1 (make.rrf.org\dcmd-1.1) - > motor

Relies on: http://www.reprap.org/bin/view/Main/DC_Motor_Driver_1_1#Wire_up_test_devices

Here is the arduino code:   
          note: this only runs one DC motor


********************ARDUINO*****************
//******* POT to control a DC motor speed and direction ******//


// define pins and variables
int potPin = 2;    // select the input pin for the potentiometer
int val = 0;       // variable to store the value coming from the sensor
int j = 0;
int Dir_A = 4;
int Speed_A = 5;

void setup() {
  pinMode(Dir_A, OUTPUT);
  pinMode(Speed_A, OUTPUT);

  Serial.begin(9600);
}

void loop() {

// Read location of joystick and calculate the distance and from center
  val = analogRead(potPin);    // read the value from the sensor
  j = val - 517;  // 517 is center positions - how far from center
  j = abs(j);      //absolute value

// put some bounds on j to keep PWM values useful
// below 100 the motor won't move and PWM max is 255
  if (j >= 510){
    j = 510;  //the most the PWM pin can do is 255
  }
  if (j <=200 && j>=10){
    j=200;    //below 100 PWM the motor makes a high pich sound and does not move
  }
  if (j <=10){
    j=0;    // below 10 the joystick is very close to center
  }


 //Run DC motor A based on analog input from joystick
  if (val >= 520){
    digitalWrite(Dir_A, HIGH);  // other direction
    analogWrite(Speed_A, j/2); // PWM out (divide by 2 because max is 255)
  }
  if (val <= 510){
    digitalWrite(Dir_A, LOW);  //
    analogWrite(Speed_A, j/2); //
  }

  if (val <=520 && val >= 510) { 
    analogWrite(Speed_A, 0);  // turn off if the joystick is in the center
  }

// print values for debugging
  Serial.print(val);        // send numbers to PC so you can see what it going on
  Serial.print(",");
  Serial.println(j);

}

Step 2: Control a Stepper With Joy Stick



Next we need to control a stepper motor the potentiometer on the joystick.

Hardware: 
Joystick -> Arduino (analog in) -> Arduino (digital out) -> Stepper driver -> stepper motor

I ran this using the EasyDriver from Sparkfun by www.SchmalzHaus.com/EasyDriver
It is well labeled and can run a medium sized stepper motor from the USB power supply. (in this example I am using a NEM17 from Keling Technology).

The screw sheild is by ZachHoeken: http://reprap.org/bin/view/Main/Arduino_Breakout_1_4

Code to control stepper motor from joystick potentiometer

///////////////////////   Arduino ///////////////////////

//******* POT to control a stepper speed and direction ******//

//declare pins
int potPin = 1;
int Step_X = 13;
int Dir_X = 12;
int Enable_X = 8;

//declare values
int Speed_X = 0;       //step speed (delay between steps) 
int val= 0;
int j = 0;

void setup() {
  pinMode(Step_X, OUTPUT);
  pinMode(Dir_X, OUTPUT);
  pinMode(Enable_X, OUTPUT);

  //Serial.begin(9600); // note that serial comm can be used to debug
                        // but it will slow down the code and slow down the stepper motor alot 
                       //(and be confusing to me)
}

void loop() {


  val = analogRead(potPin);    // read the value from the sensor

  j = val - 517;  // 517 is center positions - how far from center?
  j = abs(j);      //absolute value
  Speed_X = 70000/j;  //This math inverts the value and scales as needed 
                       //(value found through trial and error)
                      // The delay between steps will determine the speed of the motor
                       // So, delay up = speed down


  if (val >= 520){
    digitalWrite(Enable_X,LOW); // enable
    digitalWrite(Dir_X, HIGH);  // Set direction
    digitalWrite(Step_X,HIGH);
    delayMicroseconds(2);
    digitalWrite(Step_X,LOW);
    delayMicroseconds(Speed_X);

  }
  if (val <= 510) {
    digitalWrite(Enable_X,LOW);// enable
    digitalWrite(Dir_X, LOW);  // Other direction
    digitalWrite(Step_X,HIGH);
    delayMicroseconds(2);
    digitalWrite(Step_X,LOW);
    delayMicroseconds(Speed_X);
  }

  if (val <=520 && val >= 510) { 
    digitalWrite(Enable_X,HIGH);  // disable the stepper motor if the joystic is in the center
  }
}



Step 3: Do Two Things at Once!



The next thing to do code-wise is to jam together the controls for the stepper motor and DC motor so you can control both at once.

If you look at the code in the previus steps you'll see that I used diferent pins and variable names for each set of test code.  This lets us jam them togehter without much modification.

I've read that there are much better ways to combine blocks of code, but I am still learning, so all I have done is cut-and-past the two programs together.

I've incrased the anaolog values that are used as the 'center' position of the joystick.  This helps to stop you from accidently running the wrong motor.

Latter we will have to splice in another batch of code to control the motor to open and close the claw!

Here is the Arduino code to control one stepper motor and one DC motor (labeled DC motor A, because we will be adding B latter)


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

//******* joystickj with 2 POTS to control a stepper and DC motor speed and direction ******//

//declare pins for Stepper
int potPin_X = 1;
int Step_X = 13;
int Dir_X = 12;
int Enable_X = 8;

//declare values for stepper
int Speed_X = 0;       //step speed (delay between steps) 
int val_X= 0;
int h = 0;

// declare pins for DC motor A
int potPin_A = 2;    // select the input pin for the potentiometer
int val_A = 0;       // variable to store the value coming from the sensor
//Declare variables for DC A
int j = 0;
int Dir_A = 4;
int Speed_A = 5;


void setup() {
  // setup up stepper pins
  pinMode(Step_X, OUTPUT);
  pinMode(Dir_X, OUTPUT);
  pinMode(Enable_X, OUTPUT);

  //setup DC motor A pins
  pinMode(Dir_A, OUTPUT);
  pinMode(Speed_A, OUTPUT);


  //Serial.begin(9600); // note that serial comm can be used to debug
  // but it will slow down the code and slow down the stepper motor alot (and be confusing to me)
}

void loop() {

  /////////        STEPPER READ AND CONTROLL  /////////////

  // read location of joystick and calculate values for stepper motor
  val_X = analogRead(potPin_X);    // read the value from the sensor
  h = val_X - 517;  // 517 is center positions - how far from center?
  h = abs(h);      //absolute value
  Speed_X = 70000/h;  //This math inverts the value and scales as needed 
                                        // 70000 value found through trial and error
                                      // The delay between steps will determine the speed of the motor
                                   / / So, delay up = speed down

  // control the stepper motor //
  if (val_X >= 530){
    digitalWrite(Enable_X,LOW); // enable
    digitalWrite(Dir_X, HIGH);  // Set direction
    digitalWrite(Step_X,HIGH);
    delayMicroseconds(2);
    digitalWrite(Step_X,LOW);
    delayMicroseconds(Speed_X);
  }
  if (val_X <= 500) {
    digitalWrite(Enable_X,LOW);// enable
    digitalWrite(Dir_X, LOW);  // Other direction
    digitalWrite(Step_X,HIGH);
    delayMicroseconds(2);
    digitalWrite(Step_X,LOW);
    delayMicroseconds(Speed_X);
  }

  if (val_X <=530 && val_X >= 500) { 
    digitalWrite(Enable_X,HIGH);  // disable the stepper motor if the joystic is in the center
  }

  //////////////  DC MOTOR A - READ AND CONTROL ///////////////////
  // Read location of joystick and calculate the distance and from center
  val_A = analogRead(potPin_A);    // read the value from the sensor
  j = val_A - 517;  // 517 is center positions - how far from center
  j = abs(j);      //absolute value

  // put some bounds on j to keep PWM values useful
  // below 100 the motor won't move and PWM max is 255
  if (j >= 510){
    j = 510;  //the most the PWM pin can do is 255
  }
  if (j <=200 && j>=10){
    j=200;    //below 100 PWM the motor makes a high pich sound and does not move
  }
  if (j <=10){
    j=0;    // below 10 the joystick is very close to center
  }


  //Run DC motor A based on analog input from joystick
  if (val_A >= 530){
    digitalWrite(Dir_A, HIGH);  // other direction
    analogWrite(Speed_A, j/2); // PWM out (divide by 2 because max is 255)
  }
  if (val_A <= 500){
    digitalWrite(Dir_A, LOW);  //
    analogWrite(Speed_A, j/2); //
  }

  if (val_A <=530 && val_A >= 500) { 
    analogWrite(Speed_A, 0);  // turn off if the joystick is in the center
  }

  // print values for debugging
  //  Serial.print(val_A);        // send numbers to PC so you can see what it going on
  //  Serial.print(",");
  // Serial.println(j);

}

Step 4: Second Round of Code for Alternative Stepper Motor and Driver


I used the EasyDriver from SparkFun along with a NEME17 stepper motor during my initial testing.

I have a bigger motor and driver board from my old RepStrap, (NEM23 stepper with RepRap stepper motor driver v1.2 by Zach Hoeken).  Using this requires two minor adujstemnts to the code. 

1 - The enable pins are opposite.  
                      EasyDriver:  Low = Enable
                      Steper Driver v1.2 :  High = Enable
2 - I can't seem to drive the NEM23 as fast as the NEM17.  Both boards allow you to switch between full and half step.  I'm probably half stepping the NEM23 and full stepping the NEM17.   Instead of figuring out the actual difference, I've just adjusted the delay between steps in the code.


Here is the code.  I've added NOTES to the code to show where I have made changes.  


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

 //******* joystickj with 2 POTS to control a stepper and DC motor speed and direction ******//
//NOTE: modified to run NEM23 stepper with Stepper Motor Driver v1.2 from RepRap

//declare pins for Stepper
int potPin_X = 1;
int Step_X = 13;
int Dir_X = 12;
int Enable_X = 8;

//declare values for stepper
int Speed_X = 0;       //step speed (delay between steps) 
int val_X= 0;
int h = 0;

// declare pins for DC motor A
int potPin_A = 2;    // select the input pin for the potentiometer
int val_A = 0;       // variable to store the value coming from the sensor
//Declare variables for DC A
int j = 0;
int Dir_A = 4;
int Speed_A = 5;


void setup() {
  // setup up stepper pins
  pinMode(Step_X, OUTPUT);
  pinMode(Dir_X, OUTPUT);
  pinMode(Enable_X, OUTPUT);

  //setup DC motor A pins
  pinMode(Dir_A, OUTPUT);
  pinMode(Speed_A, OUTPUT);


  //Serial.begin(9600); // note that serial comm can be used to debug
  // but it will slow down the code and slow down the stepper motor alot (and be confusing to me)
}

void loop() {

  /////////        STEPPER READ AND CONTROLL  /////////////

  // read location of joystick and calculate values for stepper motor
  val_X = analogRead(potPin_X);    // read the value from the sensor
  h = val_X - 517;  // 517 is center positions - how far from center?
  h = abs(h);      //absolute value
  //Speed_X = 70000/h;  //This math inverts the value and scales as needed (value found through trial and error)
                     // The delay between steps will determine the speed of the motor
                     // So, delay up = speed down
                     //NOTE: Speed_X=70000/h worked well for this combination: EasyDriver -> NEM17 stepper
  Speed_X = 160000/h; //NOTE: Speed calculation for Stepper Motor Driver V1-2 (RepRap) -> NEM23 stepper
  // control the stepper motor //
              //NOTE:
              // for EasyDriver: HIGH = disable
             // for RepReap Stepper driver v1.2: LOW = Disable
  if (val_X >= 530){
    digitalWrite(Enable_X,HIGH); // enable
    digitalWrite(Dir_X, HIGH);  // Set direction
    digitalWrite(Step_X,HIGH);
    delayMicroseconds(2);
    digitalWrite(Step_X,LOW);
    delayMicroseconds(Speed_X);
  }
  if (val_X <= 500) {
    digitalWrite(Enable_X,HIGH);// enable
    digitalWrite(Dir_X, LOW);  // Other direction
    digitalWrite(Step_X,HIGH);
    delayMicroseconds(2);
    digitalWrite(Step_X,LOW);
    delayMicroseconds(Speed_X);
  }

  if (val_X <=530 && val_X >= 500) { 
    digitalWrite(Enable_X,LOW);  // disable the stepper motor if the joystic is in the center
                                 // for EasyStepper: HIGH = disable
                                 // for RepReap Stepper driver v1.2: LOW = Disable
  }

  //////////////  DC MOTOR A - READ AND CONTROL ///////////////////
  // Read location of joystick and calculate the distance and from center
  val_A = analogRead(potPin_A);    // read the value from the sensor
  j = val_A - 517;  // 517 is center positions - how far from center
  j = abs(j);      //absolute value

  // put some bounds on j to keep PWM values useful
  // below 100 the motor won't move and PWM max is 255
  if (j >= 510){
    j = 510;  //the most the PWM pin can do is 255
  }
  if (j <=200 && j>=10){
    j=200;    //below 100 PWM the motor makes a high pich sound and does not move
  }
  if (j <=10){
    j=0;    // below 10 the joystick is very close to center
  }


  //Run DC motor A based on analog input from joystick
  if (val_A >= 530){
    digitalWrite(Dir_A, HIGH);  // other direction
    analogWrite(Speed_A, j/2); // PWM out (divide by 2 because max is 255)
  }
  if (val_A <= 500){
    digitalWrite(Dir_A, LOW);  //
    analogWrite(Speed_A, j/2); //
  }

  if (val_A <=530 && val_A >= 500) { 
    analogWrite(Speed_A, 0);  // turn off if the joystick is in the center
  }

  // print values for debugging
  //  Serial.print(val_A);        // send numbers to PC so you can see what it going on
  //  Serial.print(",");
  // Serial.println(j);

}



Step 5: Build Test Rig


It is hard to work on something up over your head, so I built this smaller test rig.

This is made out of scrap parts, so I am not going to go into much detail about the construction.  The import thing is that the two wooden rails are spaced such that they will hold the stepper motor with some wheels on it.

Step 6: Mount the Motors

This steps shows the two motors mounted together on the test rig.

I am using small wooden weels that fit on the axis of the stupper motor.  I used a large hose clamp to attach the DC motor to the bottom of the stepper.  

I think the pictures are pretty clear. The details will depend on the motors you have.

Step 7: Spindle

We are going to raise and lower the claw by winding up a string on a spindle attached to this large white gear on the DC motor.

I found a dowel that seems about right.  I'll make it into a better shape in the next two steps.

Step 8: Shape the Spindle

The dowl might work fine as is, but it seems that it should be narrow in the middle and larger at each end.  I have a wood lathe so I used that to turn the dowl down into a shape that looked right. 

Step 9: Mount the Spindle


I used some very hot glue to attache the wooden spindle to the plastic gear. I applied the glue to the bottom of the wooden peice and then jamed it onto the gear.

I expect that this will break off at some point.

Step 10: Spindle Test

Here is my first test using the spindle.  My younger daughter was very excited to try this, but then gets very upset during the video....

This works but it points out some problems we'll have to deal with -
          1 - the thumb joystic is still little hard to control
          2  - the spindle needs some sort of endstop.  You can see that the little doll is flips over and comes down the other side.  This will be a problem once there is a big claw on the end of this string.


Here is a video:

Step 11: Planning the Claw

Before making the claw I did a little planning.  I drew a sketch of what I thought would work and then put together a cardboard mock up (made from an Amy's Vegatable Pie in a Pocket box  http://www.amys.com/products/category_view.php?prod_category=8)

This worked out well.  There is a little video here:

Step 12: Harvesting Computer Parts for the Claw.

I took my paper model down to the basement and looked for computer parts that might work. 

I used two mice along with strips of plastic cut from the case of an inkjet printer.


Here are the basic steps:

 - Find 2 mice
-Gut and clean the mice
- Keep the the top shells of the mice and put the guts aside
-Cut strips of plastic from a printer housing, this printer was flimsy so it cut easily with an utility knife.
-You need about a foot of plastic

Step 13: Prepare the Peices of the Claw

 Now that we have some strips of plastic they will need to be cut to useful sizes.  I am using some thin plastic so I cut them easly with light duty tin snips (we keep a pair in the kitchen).  I based the lengths roughly on the paper model. 

Here is the cut-list -
            - the peice that the motor mounts to is about 3.25" X 1.25"
            - the two side peices are about 4"X 0.75"

Then you need to drill some holes. 
The motor I am using is from a printer/scanner.  It has a gear already on it that is 10mm wide.  It also has 2 mounting holoes that are spaced 20mm apart. 

Step 14: Assemble the Claw

I used the cardboard model as a template when assembling the mouse claw. 

Steps -
- Hot glue a peice of plastic between the mouse parts to make a hinge
- Tape together the strips of duct tape to make more hinges
- Attach the motor to a scew - I used a peice of tubing which I filled with hot glue and quickly jammed over the motor shaft and the head of the screw.  The motor shaft already had a gear on it, I left that on.
-Mount the motor - I attached the motor to the plastic hinges with the small screws that where originally with the motor. The screw goes into a hole in the plastic hinge between the mice.
- Attach the hinges to the mice - I used some short sheet metal screws to attach the hinged plastic to the mice sheells.

Step 15: Claw Code and Testing




I found another thumb joystick, so we'll use that to control the opening and closing of the claw.
This is the same code used to control the spindle motor (for raising and lowering the claw), it just has different pin assignments and variable names.

If I dig up an old PS2 controller I will hack that and use it as the main controller.

After testing this it will be folded in with the rest of the code. 

Here is a video.  The code is below.




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

///Claw control/////

// declare pins for DC motor B  // claw open/close
int potPin_B = 3;    // select the input pin for the pot
int val_B = 0;       // variable to store the value coming from the sensor

//Declare variables for DC motor B
int k = 0;
int Dir_B = 7;
int Speed_B = 6;  //pwm

void setup(){
  //setup DC motor B pins
   pinMode(Dir_B, OUTPUT);
  pinMode(Speed_B, OUTPUT);
}
void loop() {
  //////////////  DC MOTOR B - READ AND CONTROL ///////////////////
  // Read location of joystick and calculate the distance and from center
  val_B = analogRead(potPin_B);    // read the value from the sensor
  k = val_B - 517;  // 517 is center positions - how far from center
  k = abs(k);      //absolute value

  // put some bounds on j to keep PWM values useful
  // below 100 the motor won't move and PWM max is 255
  if (k >= 510){
    k = 510;  //the most the PWM pin can do is 255
  }
  if (k <=200 && k>=10){
    k=200;    //below 100 PWM the motor makes a high pich sound and does not move
  }
  if (k <=10){
    k=0;    // below 10 the joystick is very close to center
  }


  //Run DC motor B based on analog input from joystick
  if (val_B >= 530){
    digitalWrite(Dir_B, HIGH);  // other direction
    analogWrite(Speed_B, k/2); // PWM out (divide by 2 because max is 255)
  }
  if (val_B <= 500){
    digitalWrite(Dir_B, LOW);  //
    analogWrite(Speed_B, k/2); //
  }

  if (val_B <=530 && val_B >= 500) { 
    analogWrite(Speed_B, 0);  // turn off if the joystick is in the center
  }
}

Step 16: Code for All the Parts



Here is all the code jamed together.  Now we can run the stepper motor back and forth along the track, raise and lower the claw, and open and close the claw.

I am getting a high pich squeal from somewhere...  I'll just watch for smoke for now.

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

//******* 2 joysticks with  POTS to control a stepper and two DC motors speed and direction ******//
//NOTE: modified to run NEM23 stepper with Stepper Motor Driver v1.2 from RepRap

//declare pins for Stepper
int potPin_X = 1;
int Step_X = 13;
int Dir_X = 12;
int Enable_X = 8;

//declare values for stepper
int Speed_X = 0;       //step speed (delay between steps) 
int val_X= 0;
int h = 0;

// declare pins for DC motor A
int potPin_A = 2;    // select the input pin for the potentiometer
int val_A = 0;       // variable to store the value coming from the sensor
//Declare variables for DC A
int j = 0;
int Dir_A = 4;
int Speed_A = 5;

// declare pins for DC motor B  // claw open/close
int potPin_B = 3;    // select the input pin for the pot
int val_B = 0;       // variable to store the value coming from the sensor

//Declare variables for DC motor B
int k = 0;
int Dir_B = 7;
int Speed_B = 6;  //pwm


void setup() {
  // setup up stepper pins
  pinMode(Step_X, OUTPUT);
  pinMode(Dir_X, OUTPUT);
  pinMode(Enable_X, OUTPUT);

  //setup DC motor A pins
  pinMode(Dir_A, OUTPUT);
  pinMode(Speed_A, OUTPUT);

  //setup DC motor B pins
  pinMode(Dir_B, OUTPUT);
  pinMode(Speed_B, OUTPUT);

  //Serial.begin(9600); // note that serial comm can be used to debug
  // but it will slow down the code and slow down the stepper motor alot (and be confusing to me)
}

void loop() {

  /////////        STEPPER READ AND CONTROLL  /////////////

  // read location of joystick and calculate values for stepper motor
  val_X = analogRead(potPin_X);    // read the value from the sensor
  h = val_X - 517;  // 517 is center positions - how far from center?
  h = abs(h);      //absolute value
  //Speed_X = 70000/h;  //This math inverts the value and scales as needed (value found through trial and error)
  // The delay between steps will determine the speed of the motor
  // So, delay up = speed down
  //NOTE: Speed_X=70000/h worked well for this combination: EasyDriver -> NEM17 stepper
  Speed_X = 160000/h; //NOTE: Speed calculation for Stepper Motor Driver V1-2 (RepRap) -> NEM23 stepper
  // control the stepper motor //
  //NOTE:
  // for EasyDriver: HIGH = disable
  // for RepReap Stepper driver v1.2: LOW = Disable
  if (val_X >= 530){
    digitalWrite(Enable_X,HIGH); // enable
    digitalWrite(Dir_X, HIGH);  // Set direction
    digitalWrite(Step_X,HIGH);
    delayMicroseconds(2);
    digitalWrite(Step_X,LOW);
    delayMicroseconds(Speed_X);
  }
  if (val_X <= 500) {
    digitalWrite(Enable_X,HIGH);// enable
    digitalWrite(Dir_X, LOW);  // Other direction
    digitalWrite(Step_X,HIGH);
    delayMicroseconds(2);
    digitalWrite(Step_X,LOW);
    delayMicroseconds(Speed_X);
  }

  if (val_X <=530 && val_X >= 500) { 
    digitalWrite(Enable_X,LOW);  // disable the stepper motor if the joystic is in the center
    // for EasyStepper: HIGH = disable
    // for RepReap Stepper driver v1.2: LOW = Disable
  }

  //////////////  DC MOTOR A - READ AND CONTROL ///////////////////
  // Read location of joystick and calculate the distance and from center
  val_A = analogRead(potPin_A);    // read the value from the sensor
  j = val_A - 517;  // 517 is center positions - how far from center
  j = abs(j);      //absolute value

  // put some bounds on j to keep PWM values useful
  // below 100 the motor won't move and PWM max is 255
  if (j >= 510){
    j = 510;  //the most the PWM pin can do is 255
  }
  if (j <=200 && j>=10){
    j=200;    //below 100 PWM the motor makes a high pich sound and does not move
  }
  if (j <=10){
    j=0;    // below 10 the joystick is very close to center
  }


  //Run DC motor A based on analog input from joystick
  if (val_A >= 530){
    digitalWrite(Dir_A, HIGH);  // other direction
    analogWrite(Speed_A, j/2); // PWM out (divide by 2 because max is 255)
  }
  if (val_A <= 500){
    digitalWrite(Dir_A, LOW);  //
    analogWrite(Speed_A, j/2); //
  }

  if (val_A <=530 && val_A >= 500) { 
    analogWrite(Speed_A, 0);  // turn off if the joystick is in the center
  }

  //////////////  DC MOTOR B - READ AND CONTROL ///////////////////
  // Read location of joystick and calculate the distance and from center
  val_B = analogRead(potPin_B);    // read the value from the sensor
  k = val_B - 517;  // 517 is center positions - how far from center
  k = abs(k);      //absolute value

  // put some bounds on j to keep PWM values useful
  // below 100 the motor won't move and PWM max is 255
  if (k >= 510){
    k = 510;  //the most the PWM pin can do is 255
  }
  if (k <=200 && k>=10){
    k=200;    //below 100 PWM the motor makes a high pich sound and does not move
  }
  if (k <=10){
    k=0;    // below 10 the joystick is very close to center
  }

  //Run DC motor B based on analog input from joystick
  if (val_B >= 530){
    digitalWrite(Dir_B, HIGH);  // other direction
    analogWrite(Speed_B, k/2); // PWM out (divide by 2 because max is 255)
  }
  if (val_B <= 500){
    digitalWrite(Dir_B, LOW);  //
    analogWrite(Speed_B, k/2); //
  }

  if (val_B <=530 && val_B >= 500) { 
    analogWrite(Speed_B, 0);  // turn off if the joystick is in the center
  }


  // print values for debugging
  //  Serial.print(val_A);        // send numbers to PC so you can see what it going on
  //  Serial.print(",");
  // Serial.println(j);

}

Step 17: Make It Big

The test rig is meant to be scalable.  All that you should need is longer strips of wood for the two tracks.  However, once I started looking at longer strips of wood, I got worried that the wood would bow out and the whole thing would fall on my head.  So I hit the Home Depot to look for something else I could use.

I found some J-channel in the drywall section.  It looks like it is made out of bent sheet metal.  It is just strong enough and comes in 10foot lengths (2$ for 10ft).

For the first large scale setup I am working in a large doorway.  It is about 5feet wide and happens to be right next to where I have been working.

So it is time to get to work!

The next few slides will show the build process for the larger setup.

Here is an image of what we are working towards.

Step 18: Cut the The Peices for the Rails

The first thing to do is to cut the J-channel rails to length. 

So, I measured the doorframe (about 5') and headed down to the basement.

When you cut thin pecies of metal like this, it is best to use a peice of wood for support.



Step 19: Drill Some Pilot Holes

The J-channel will be mounted to some MDF (wood) and then the MDF will be screwed to the door frame.  It is a good idea to drill some pilot holes in the metal.   About 50% of the time I drill my pilot holes in the wrong spots, so I have gotten in the habbit of drilling two sets of pilot holes. 

The images below show me carefully planning where the pilot holes will need to be.  Then I just drill a whole bunch, because I am frequently wrong.

I use a peice of wood to suport the metal when I drill the holes.  

Step 20: Make New Wheels

Now that I have changed the railes from strips of wood to J-channels I also need to change the wheels I have jammed onto the stepper motor.  

The new wheels will need to fit down into the channel.  I didn't find any good parts for this in my pile of computer guts, so I just cut them out of some scrap luan (fancy 1/4" plywood)  with a whole saw.

The hole saw cuts a 1-1/2" diameter circle with a 1/4" hole in the center.  This works out just right to jam onto the stepper motor shaft and it fits into the J-channel. 

Note:  It is sometimes hard to get the round peice out to the hole saw.  I have two tricks.  I lubricate the inside of the hole saw with a 'Cut-ease'.  I use this pretty much whenever I drill or cut anything, because it makes everything easier and quiter ( I am usually working at night).  I also have a tool I made that fits between the teeth of the saw so you can pry ou the plug.  I made this out of a screw driver, by grinding down the sides, bending over the tip, and then sharpening the tip.  This tool is also useufl if you are drilling a hole in drywall.  You can drill partially through the drywall, leaving the plug in teh wall, then stick thie tip of the modiefied srew driver into the pilot hole and pry out the plug.  This is handy if you are interested in the hole instead of the plug.

Step 21: Assemble the Rails

Now it is time to bring all the peices up out of the basement and put it all together. 

The J-rail will be mounted to peices of MDF.  Just like the strips of wood are mounted to the test rig.   I laid this all out on the floor.  The motor will sit between the rails, so there needs to be enough room to keep the shaft of the motor from hitting the wall of the J-channel.  This makes the whole assembly slighly wider then the test rig, so I have added some wooden shims. 

Also - once I laid everything out I realized that one of the J-channels was nearly on inch too long.  I found that this cut easily with sheers.  

While everthing is still on the floor you can screw the peices together.  This whole assembly can then be mounted in the doorway pretty easily.

Step 22: Motor Assembly

You will also need to take the motor off the test rig and reassemble to fit the J-channel rails.

The new 1-1/2" wheels are just pressed onto the motor shaft.  The whole thing is held together with a hose clamp.

I've shown the assembly clamped together on its own, but you will acutally need to assemble this directly onto the J-channel rails.  But this takes two hands, so I didn't get a picture!



Step 23: Mount the Assembly in the Doorway

Now it is time to mount the whole get-up in the doorframe.

I used a milk carton to mark the heights of the rails. Then I lifted up the assembly while my wife drove screws through the MDF spacers and into the door frame.  (this took 4 hands, so  there are no action pics)

Step 24: Wire-ing

All the wiring should be the same  as for the smaller test rig.  You just need longer wires!

Network cable (cat-5?) works well for this because it is reasonably flexible and gives you 8 wires in one cable.  I am keeping arduino and the driver boards on the bench for now, and just running the power up to the motors with about 10feet of cable
-4 wires to the stepper
-2 wires to the DC motor to raise and lower the claw
-2 wires to teh DC motor to open and close the claw.

- I used a cable from an AC/DC power adaptor to run power from the network cable down to the DC motor on the claw.




Step 25: Attach the Claw

I attached the claw to the wooden spindle like this -
- tie a loop of wire to the claw
- tie a string to this loop
- drive a short screw into the wooden spindle
-tie the string to the srew in the spindle

I ran the power down to the motor with a seperate cable.

Step 26: First Run



Test run


Here is a short video -


Here is a long video  - this was the first attempt





Step 27: Make It Better


This setup works pretty well. 

I want to make the whole thing fun and easy to use, so there are a few things that should be improved.

The controls are a little hard to handle.  As of this test run, I am using two thumb joysticks that are just loose and connected to the  electronics with jumper wires.  I will either need to mount these on something, or use something else fo the controler.

Once the claw is lowered, it swings like a pendulum when you run the stepper.

I am only working with one axis, so whatever you want to pick up as to be on the line directly below the rails.



Step 28: Trying a Different Controller

I'm going to try using a different controller.   I found a nice one that is for little kids.  It is the Leap Frog Baby Little Leaps.  This is a very sturdy controller and acutually has two sets of controls mounted back to back.  One set has

The joystick is made up of 4 buttons that are pressed by the joystick mechanism.

I cracked open the plastic case, and all the electronics out except for the 4 joystick buttons and the two other bottons.

Here are the pictures of the dessassembly:

    -- First I cleaned this thing off with a magic eraser, these are like very fine sanding sponges, except that they dissolve with use, so you have to keep buying more.

   --Then I took out all the screws and pryed off as much plastic as I could.  The key was taking off the grey faceplate which covered a dozen or so screws.

  -- The last image shows all the pecies spread out on the table

Step 29: Get Rid of Everything You Don't Need

The joystick is made up of a plastic.. well joystick, that presses 4 momentary switches, depening on which direction the joystick is pushed.   There are also 2 buton of to teh sides that are on their own little boards.

Since we are only interested in the switches, I stripped off all the other components with a heat gun (I used a Plastic Welder from Harbor Freight).

Step 30: Wire the Joystick


The wiring got a bit messy. 

Basically every pushbutton is connected to a 10K pull-down resistor on one side and 5V on the other.   The arduino pin for each button will be connected between the button and the resistor.

So each button goes like this:

Button  (one side)---> Arduino input pin  --> 10K resistor  -->ground on arduino
Button  (other side)---> 5V on Arduino

Now when a button is open, the output to arduino will be low.  When the button is pushed it will be high.

I used Cat-5 network cable for this.

Here is the wiring to the buttons on the controller and to the Arduino -

Wire - Button - Arduino Analog/Digital:

Blue - Up (joystick) - A0 / D14
Blue/white - Down (joystick) - A1 / D15
Orange - Left (joystick) - A2 / D16
Orange/white - Right (joystick) - A3 / D17
Green - Left button (claw open) - A4 / D18
Green/White - Right button (claw close) -A5 / D19
Brown - Ground (Arduino) - Ground
Brown/White - 5V (Arduino) - 5V

(note: the analog pins on the Arduino can be used as digital pins)


Step 31: Code Using Switches

Since this controller is just a bunch of switches, we can throw away all the code that had to do with the potentiameters that were in the thumb joysticks.  This means that we won't have control over the speed. 

Here is the controller in action:



Here is the code to run the Crane Game using the Leap Frog controller.  This just uses  6 push bottons to control the stepper motor and the two DC motors.


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

// Speeds
  int Delay_X = 1000;   //step delay: microseconds (up delay = slower speed
  int Speed_S = 255; // spindle speed 0-255
  int Speed_C = 255; //clow speed 0-255

//STEPPER PINS
  //Outputs
     int Step_X = 13;
     int Dir_X = 12;
     int Enable_X = 8;
  //Inputs
     int Left = 16;
     int Right = 17;
  // variables
     int val_Left = LOW;
     int val_Right = LOW;

//SPINDLE PINS  
   //Outputs
      int Dir_A = 4;
      int Speed_A = 5;
   //Inputs
       int Up = 14;
       int Down= 15;
   //variables
       int val_Up = LOW;
       int val_Down = LOW;

//CLAW PINS
    //Outputs
       int Dir_B = 7;
       int Speed_B = 6;
    //Inputs
       int Open = 18;
       int Close = 19;
    //variables
       int val_Open = LOW;
       int val_Close = LOW;

void setup (){
    // setup up stepper pins
        pinMode(Step_X, OUTPUT);
        pinMode(Dir_X, OUTPUT);
        pinMode(Enable_X, OUTPUT);
        pinMode(Left, INPUT);
        pinMode(Right, INPUT);

    //setup DC motor A pins - for spindle
        pinMode(Dir_A, OUTPUT);
        pinMode(Speed_A, OUTPUT);
        pinMode(Up, INPUT);
        pinMode(Down, INPUT);

    //setup DC motor B pins - for claw
        pinMode(Dir_B, OUTPUT);
        pinMode(Speed_B, OUTPUT);
        pinMode(Open, INPUT);
        pinMode(Close, INPUT);
}

void loop(){
// STEPPER READ AND CONTROL //
   val_Left = digitalRead(Left);
   val_Right = digitalRead(Right);

   if (val_Left == HIGH){
      digitalWrite(Enable_X,HIGH); // enable
      digitalWrite(Dir_X, HIGH);  // Set direction
      digitalWrite(Step_X,HIGH);
      delayMicroseconds(2);
      digitalWrite(Step_X,LOW);
      delayMicroseconds(Delay_X);
       }

    if (val_Right == HIGH){
      digitalWrite(Enable_X,HIGH); // enable
      digitalWrite(Dir_X, LOW);  // Set direction (other direction)
      digitalWrite(Step_X,HIGH);
      delayMicroseconds(2);
      digitalWrite(Step_X,LOW);
      delayMicroseconds(Delay_X);
      }

    if ((val_Left == LOW) && (val_Right == LOW))  {
     digitalWrite(Enable_X, LOW); //stepper off
        }

 // SPINDLE READ AND CONTROL //
   val_Up = digitalRead(Up);
   val_Down = digitalRead(Down);

   if (val_Up == HIGH){
     digitalWrite(Dir_A, HIGH);
     analogWrite(Speed_A, Speed_S);
     }

   if (val_Down == HIGH){
     digitalWrite(Dir_A, LOW);
     analogWrite(Speed_A, Speed_S);
     }

    if ((val_Up ==LOW) && (val_Down == LOW)){
      analogWrite(Speed_A, 0);
    }


// CLAW READ AND CONTROL //
   val_Open = digitalRead(Open);
   val_Close = digitalRead(Close);

   if (val_Open == HIGH){
     digitalWrite(Dir_B, HIGH);
     analogWrite(Speed_B, Speed_C);
     }

   if (val_Close == HIGH){
     digitalWrite(Dir_B, LOW);
     analogWrite(Speed_B, Speed_C);
     }

    if ((val_Open ==LOW) && (val_Close == LOW)){
      analogWrite(Speed_B, 0);
    }

}

Step 32: Try Out the New Controller


Now it is time for a test run with the new controller.

The whole thing is nice and sturdy, and the kids understand what it is. 

You can check out the videos.

You'll notice that the kids like to press one button over and over again.   So they end up spinning the spindle to much, so it either flips over and up becomes down - or it gets tangled from being lifted too high.  Also, right now there is one button to open the claw and another to close it, so they tend to open or close it too far and it gets jammed.

I think that adding some endstop style switches and mabye some automation to simplify the controls would help.

This shows my 4 your old after she has been practicing.

Step 33: Some More Video

I just think this is funny:

Step 34: Make Big, and in 3D

Dead Computer Contest

First Prize in the
Dead Computer Contest