Automated Newton's Cradle
This is my third effort to automate a Newton's Cradle, the first using a motor and custom built Newton's Cradle, the second using a custom built robot to pull the ball back and finally this one that uses an Arduino Nano, two servos and a magnet to pull the ball(s) back. This one is definitely the most interesting because it can pull one ball back, or two or three. Pulling multiple balls back also introduces a random element in how the balls will be released and therefore how they will "bounce" off one another. Most definitely another useless toy but love to automate these kinds of toys.
Assuming someone else would like to build one, the required parts are:
Arduino Uno or Nano
6 volt battery pack to power servos
9 volt to power Arduino
two micro servos
one magnet
some wood or fishing pole sections for servo arms
one piece of material to separate magnet from balls
hot glue and zip ties
Make Servo Arms and Mount to Cradle Frame
For the main arm I bolted a section of fishing pole to the servo arm. At the end of the arm I hotglued a magnet and a piece of foam onto the magnet. The foam keeps the magnet away from the steel ball enough that it can let loose if pulled back far enough. Without the padding of the foam, the ball will never let loose of the magnet. You just have to experiment with the padding to see how thick it should be. I then cut a piece of plywood to hold the servo, drilled a couple of holes, mounted it to the frame with zip ties. Then zip tile the main arm servo to the plywood mount and use hot glue to keep it all from moving around.
The small arm's purpose is to stop the balls from swinging. It is not really necessary but without it the balls will swing and affect how they bounce or you have to wait until they stop swinging before releasing the ball. I just zip tied and hot glued the servo to the frame. I made a ball stopper arm with a couple of pieces of fishing pole glued together.
That is all the fabrication that needs to be done. The rest is just wiring up the Nano, servos and power.
Wiring Up the Nano
I use a separate power supply for the Nano and the servos because the Nano cannot reliably power the servos with internal power. The only thing you have to do is wire the ground of the 6 volt power supply and the 9 volt power supply for the Nano together. The schematic shows how I wired it all up.
Arduino Program
Here is the simple sketch to run the Nano. myServo is used to be able to slow the servo speed down. This is a very useful subroutine anytime you need to control the speed of a servo.
#include <Servo.h>
Servo myservoLeft,myservoRight, myservoCenter,myservoWeight; // create servo object to control a servo
void myServo(int newAngle,int angleInc,int incDelay,int servoNum) {
int curAngle;
if (servoNum== 1) { curAngle = myservoLeft.read(); }
if (servoNum== 2) { curAngle = myservoRight.read(); }
if (servoNum== 3) { curAngle = myservoCenter.read(); }
if (servoNum== 4) { curAngle = myservoWeight.read(); }
if (curAngle < newAngle) {
for(int angle=curAngle;angle < newAngle;angle += angleInc) {
if (servoNum == 1) myservoLeft.write(angle);
if (servoNum == 2) myservoRight.write(angle);
if (servoNum == 3) myservoCenter.write(angle);
if (servoNum == 4) myservoWeight.write(angle);
delay(incDelay); }
}
else if (curAngle > newAngle) {
for(int angle=curAngle;angle > newAngle;angle -= angleInc) {
if (servoNum == 1) myservoLeft.write(angle);
if (servoNum == 2) myservoRight.write(angle);
if (servoNum == 3) myservoCenter.write(angle);
if (servoNum == 4) myservoWeight.write(angle);
delay(incDelay); }
}
}
void singleBall() {
myServo(30,1,5,1); //open ball stopper
delay(100);
myServo(150,1,25,3); // pull ball back
delay(8000);
myServo(95,1,5,3); // down to get ball
delay(100);
myServo(134,1,10,1); // stop balls swinging
delay(3000);
}
void doubleBall() {
myServo(30,1,5,1); //open ball stopper
delay(100);
myServo(150,1,30,3);
delay(9000);
myServo(85,1,5,3);
delay(1000);
myServo(129,1,10,1); // stop balls swinging
delay(3000);
}
void setup()
{
Serial.begin(9600);
delay(100);
myservoCenter.attach(3); // attaches the servo on pin 9 to the servo object
myservoCenter.write(90);
myservoLeft.attach(4); // attaches the servo on pin 9 to the servo object
myservoLeft.write(90);
delay(50); // waits for the servo to get there
}
void loop() {
//doubleBall();
singleBall();
//}
// delay(1000);
// exit(0); //pause program - hit reset to continue
}