Introduction: PuttDuino Putt-putt Hole With Arduino

My company has annual events where we all get together for fun - to blow off steam and have a little competition. In the past we have had softball and bowling competitions. This year someone had an inspiration: each department would build a putt-putt 'hole' in the officed and we would all compete to make the best hole. There were some amazing contributions. This is my contribution to the IT department's hole:
"Fire in the hole"
This was a multi-part obstacle course kind of hole. First was the "windmill" (a ceiling fan on its side!)making it past that put your ball in front of my ramp of action. The ramp of action gave your ball either a boost to the hole bypassing the dreaded sand trap of styrofoam, put your in a good position to make it past the sand trap, or dropped your ball into a bad position. Past the sand trap was the goal hole. This instructable will show you how to make your own ramp of action.

This instructable will illustrate a few basic arduino control concepts. Take any that appeal - all or just some or only one could be used to make another awesome puttputt hole.

In this instructable I will show
how to activate an electric nail gun from an arduino
how to activate a fog machine from that arduino
how to run servos from the arduino
how to activate a 10Amp, 3/4HP electric motor from that same arduino
I will also be showing how I read infrared sensors, and base the activation of the above components on the reading of the infrared sensors.

Let's start with a brief overview of the idea:

I wanted to incorporate stuff I had lying around in this impressive putt-putt hole.
The main idea I had was to have the ball go into one of several random holes lying in your path which would send your ball flying either closer to the goal hole or farther away from it.
I had electric motors, an electric nail gun, and a fog machine on hand.
Additionally I had a teensy-duino and 3 servos on hand as well as a couple of infrared emitters and detectors from disassembled computer mice.
I thought that the best thing would be to have the ball shoot out at a high enough velocity to be shot through tubes which would make the ball travel far enough to bypass the sandtrap.

Ultimately what I finished up with is a ramp up to a sloped surface. On the sloped surface are 2 plastic "wipers" driven by servos. These each wipe the ball into a hole which is located at the base of each servo. There is a third hole which the ball will get to if it is missed by the other two wipers. Each hole sends the ball out the side at varying velocities. The first hole just lets the ball roll out. The second hole has an electric nail gun in it and shoots the ball out of the side. The third and final hole has a 3/4hp electric motor with a propellor like attachment which smacks the ball out to the side. The third hole also has a fog machine connected to it so that when the ball comes out of the side, it pushes fog out with it for added smoke effect!


This instructable will walk through my thought processes as well as my discoveries, work-arounds, trials and errors. I will include some improvements which I have not made but I think would enhance the project if they were to be added or used instead.

A laser cutter will be a huge enhancement to my shop - I have great ideas that would benefit from the use of a laser cutter - much more intricate parts could be involved, engraving of fine details, the possibilities are endless and I can't wait to start exploring them!

Step 1: Prototype Ball Sensor

The first step was to decide whether or not the IR emitter / detector pair would be sensitive enough to tell when a golf ball went through the tube. The infrared detector I found at radioshack is a photodiode which has 2 legs and is essentially an LED that operates in reverse - when exposed to IR, it produces voltage. I would have liked to attach an interrupt to this setup but did not realize what was necessary, so in this case, the loop() is fast enough to detect a ball moving fairly quickly.

the video below shows the prototype circuit in action.
Also I have attached an image showing the emitter/detector setup, the pins connected to the teensyduino and the arduino code I used to test the setup.

It works pretty well.

An improvement would have been to get some phototransistors. These would have allowed me to use interrupts in the code which may have made detecting the balls faster but overall the results are good.

Step 2: Technique for Fastening Plywood Together


I used crossdowels and machine screws to join the plywood pieces together for the motor mount mostly.
To to this involves drilling a hole through the face of the plywood. The hole needs to be large enough for the crossdowel to fit into and far enough from the edge of the wood that the wood will not be weakened. I leave a space at least the thickness of the plywood for strength.
Then a hole is drilled into the edge of the plywood so that it intersects with the hole drilled above.
Next a hole is drilled through the face of the plywood piece that you want to connect to the above piece. This hole and the hole through the edge of the other piece should be the same size - large enough for the machine screw.

Probably I am making this overly complicated but I think this is a very strong and simple way to join plywood together.

If you wanted to make many joints you would want a jig, but I found that with only a minimal jig it is possible to make perfectly good joints.

Hopefully the photos will make the process clear

Step 3: Build a Motor Mount

I decided to use this motor I have for the ball impeller. I really thought it would shoot the golf balls out at a really impressive speed.
Imagining a mounting which would hold the motor vertically with 4 feet on the ground, I drew up a wooden plate with slots in it to mount the motor to, and drew up some legs which could form a solid base using sketchup first, then I redrew the parts using my CAD software in order to change all the polylines into circles and arcs for better cutting on the CNC.

I used 1/2-inch plywood for all of the parts in this project. some is birch, some is sanded grade plywood stuff from home depot.

To Join all of the wooden parts together I decided to use the technique used to assemble the designs on buildyourcnc.com - I used crossdowels and small bolts to hold the parts together.
This kind of fastening is good for wood that is weak on it's end and side grain like plywood. If you just screw directly into the edge of a piece of plywood, even with pre-drilling, it will split like crazy.

With this joint, the edge of the plywood is pulled against the face of the part to be joined to with a bolt and the crossdowel.

If you have assembled IKEA furniture, then you have seen this technique used.

In most of my parts, I cut the flat face holes with the CNC, and the edge holes I used a scrap of plywood for the jig. I drilled a hole the diameter of my drill bit - 3/16" through the edge of a scrap of plywood the same plywood used for the actual parts. Then I drew a line on the side of the scrap jig indicating the center of the hole. I then drew a line on the piece that needs to be edge-drilled indicating the center line of the hole on the face of the part. Placing the two pieces (the scrap jig and the part to be edge-drilled) on a flat table and clamping them down so the lines align, I could then drill into the edge of the piece knowing the hole would be close enough to centered on the edge.

Even though I used a CNC router to cut out these parts, that is not necessary. These parts could easily be cut out using a jigsaw. The holes can easily be drilled by hand, although a drill press is nice.

The crossdowels I got online here: http://www.woodpeck.com/crossdowels.html - the ones I used are listed as:
Steel Cross Dowel 10-24 x1/2 Length (10 pack)
13-CD010
Steel cross dowel. 10-24 thread. 1/2" length. Use with 7/16" drill. Sold in 10 pack.

the machine screws I got at my local Home Depot. They also sell cross-dowels, but only in 4-packs and not small enough for the 1/2-inch plywood I was using.

Step 4: Build the Ball Impeller

The First mechanical part I built was the ball impeller.

I had a motor in my shop - 3/4 hp, 3450RPM - I figured this would Blast the ball out at a high speed.

The motor has an adapter mounted on the shaft which is 2 halfs which screw together like a clamp. I figured I could cut out a fan-like blade and mount it on there.

The first impeller I cut out had 4 blades. It was basically a 4 lobed gear. I bought the geargenerator from woodgears.cahttp://woodgears.ca/gear/index.html If you have not seen his site, you definitely should check it out. Anyway the gear generator program is really slick. I have a CNC router that I built with the design from buildyourcnc.com and I used it to cut out the impeller. The dxf that is exported from the gear generator is all polylines and no arcs. This makes the cnc kind of jerky when cutting, but it cut it out quickly. I am attaching the .dxf file if you are interested.

However after attaching it to the motor and firing it up, I realized that there was no way a golf ball would actually be able to get between the lobes and be propelled. I needed fewer blades. So I drew a rectangle with a hole in it which works quite well.
I am also attaching the dxf file for the final impeller design.

the overall impeller section of the puttputt thing here consists of several parts
1. the electric motor
2. the motor mount/housing
3. the impeller attached to the motor
4. the tube which the ball falls through and then into
5. the sensor on the opening
6. the tubing which carries the fog

The main part of the tubing is a piece of 2-inch ABS drain tubing. I sliced out about a 3/4-inch slot in it for the impeller blade to run through. I mounted it to the motor mount frame using the same crossdowels and machine screw technique. This makes a really solid mounting.

The ball sensor is the same deal as in the first step. There is an infrared LED (emitter) and a photodiode. They are mounted on the entry point.
When the ball is sensed, the fog machine is started, there is a 750ms delay, then the motor is started and run for about 1/2 a second, then the fog machine is turned off.
I'll detail those parts in the next "steps"

Step 5: Build the Ramp

the ramp and platform are made of 1/-inch plywood.
The top of the ramp is 36" x 18"
the top of the platform is 48" x 18"
the ramp slopes up from 0 to 7 inches
the platform also slopes but the sides are all one dimension - 4 inches tall. Its slope is due to being attached to the higher end of the ramp and its lower side is resting on the floor.

The sides are cut from solid pine. The sides are simply screwed to the surfaces using 1 5/8" drywall screws

the ramp's leading edge I sanded down to make as small a lip as possible for the balls to roll over.

The ramp and the platform are edged with flames which I cut using my CNC router.
I painted them as well.

I have attached the dxf files I used to cut the flames.

The flames are simply screwed onto the platform and the ramp to keep the balls from rolling off. An improved design would make these flame walls taller so the balls would be less able to bounce over them.

Step 6: Attach and Configure the Servos

I decided that moving arm obstacles would be the best.

I had on hand 3 servos from a non-started remote control project years ago so I thought this would be the perfect time to use them.
They are futaba servos - all three are the kind that go only so far in one direction then stop.
One had the 4-way head on it the other two have circles attached.
Hopefully the photos will provide good detail as to what I am about to describe.

I had on hand some white plastic about 1/4" thick and 16" long which I cut 2 strips from about 3/4" wide.
These I drilled through the edges holes for the tiny machine screws to fit through. I think I found those tiny screws with some limit switches I bought from a surplus store.
I drilled the holes through the servo head mounts at the same time so that the holes would line up. Then it was a matter of mounting the servos in the plywood.

To mount the servos in the plywood, I cut rectangles in the wood and screwed the servos in with some small screws. I think they are screws from light switches. the kind that mount switches and outlets into their junction boxes.

I put the servos spaced apart so that the wipers would almost touch each other but not quite. Then once the servos were in, I put the ball holes in place.
I tried to position the holes so that the servo "wipers" would scoop the ball into the hole.
Under the holes is ABS 2-inch plastic piping to direct the balls out the sides.

Here is how I configured the servos.
1. clocking the servos
The servos are able to accept a number as a degree of turn.
I used the built in servo library for the arduino http://www.arduino.cc/en/Reference/Servo
So to clock them, I connected them to the arduino, and set them to go to 0.
then I put the arms on so that they were pointing across the board.
When the servos receive power, they seem to move themselves to -90 or some such. I could not figure out why they do this but I wanted to be sure they did not burn themselves up because -90 makes them push their arms against the wall - I put them in the board at the wrong angle. You should clock the servos before mounting them. I did the opposite...

2. run the servos
Using the servo library, I wanted to make the wipers behave somewhat randomly, so I generate a random degree of movement, a random number to decide which wiper to move, and a random delay to pause between wipes.
During the pause cycle, I have the code check all the input sensors so that if a ball goes in one of the two sensored holes, the machine will react - this is a manual attempt at an interrupt.

so here is the code I am currently using to run the wipers.(this is an extract from the overall code)

#include
long rndSrvoPos; // variable to store the servo position
long rndPause; // random pause time
long whichServo; // choose which servo to move
Servo wiper1; // first servo wiper object
Servo wiper2; // second servo wiper object
void setup()
{
wiper1.attach(14); // attaches the servo on pin 14 to the servo object
wiper2.attach(15); // attaches the servo on pin 14 to the servo object

// blink 3 times to indicate startup

Blink3x();
}


void loop()
{
// sweep the servos a random amount up to 80 degrees
// pause a random length of time from between 10 and 250 ms
rndSrvoPos = random(0,22);
rndPause = random(250,500);
whichServo = random(100);

MoveServo(whichServo,0,rndPause);
MoveServo(whichServo,80,rndPause);

}


void MoveServo (int servoNum, long pos , int pause)
{
if (servoNum>=50)
{
wiper1.write(pos);
}else{
wiper2.write(pos);
}

for (i=0;i {
ReadandReport();
if (analogRead(impSensorPin) <90 ) {StartMotor();}
ReadNailPin();
delay (1);
}

}

void Blink3x()
{
// Power On Self Test cycle
wiper1.write(80);
wiper2.write(80);
}

Step 7: Hack the Nailgun

I took the electric nailgun apart and found that the trigger switch was attached to a small circuit board. I believe that this circuit is what makes the nailgun only energize the solenoid momentarily rather than have it energized the whole time the trigger is depressed. Leaving this circuit board in place is a good idea - it means you don't have to think about how long to energize the switch circuit. Probably saves wear and tear on the solenoid.

remove the trigger switch and connect wires in its place. I used removable connectors if possible so I can restore the nailgun to its previous functionality if I need to. After replacing the switch with wires I put the gun back together (minus the trigger parts and the safety parts)

To actuate the nail gun from the arduino I needed to put a relay in place of the trigger switch.
allectronics.com has a relay that is perfect for this and is very cheap.
It can control 120Vac at about 1 Amp. and is triggered by 3-8vDC which is perfect for controlling by an arduino
here is a link to it
http://www.allelectronics.com/make-a-store/item/SRLY-19/1A-SOLID-STATE-RELAY-3-8-VDC-CONTROL/1.html

I connected the 120v side of the relay up to the nail gun in place of the trigger switch, and the control side to the arduino. I have read that it is important to connect the control side with the correct polarity which is marked clearly so it should be no problem

Hopefully the image below adequately describes how the parts are connected.

Step 8: Attach the Nail Gun

The ball falls down the hole, directed by the servo wiper, and then rolls into the nail gun sensors, which trigger the nail gun to punch the ball out the tube running under the platform

In order for the nail gun to shoot the ball, it must be in the end of the tube.
I fastened the tube against the end of the nail gun with zip ties as illustrated.

Into the attached tubing, I drilled holes across from one another for the IR emitter/detector pair.

Everything is held together with zip ties and hot glue.

My nail gun had a hole in the handle where the nail clip (the piece that holds the line of nails) was removed. I fastened a piece of wood to that hole and fastened that piece to the platform with crossdowels and machine screws.

Step 9: Control 12VAC / 10Amp Motor With Arduino

This step is mostly described by the attached schematic image.

I arrived at this configuration through some trial and error, though, which I will try to describe here.
In deciding to use this motor, I ordered a solid state relay from allelectronics.com The nail gun hacking step describes one of the relays I bought, but the one I planned to use in this step was only rated for 3.5Amps which I did not realize was not going to work until I wired it all up and turned it on
- it literally caught on fire! -

not to be daunted by a little flame like that, I searched around my shop for another option. I found a holiday light, outdoor extension cord that I had left from last season's solstice lights. I got it from Target on clearance for about $8 - it is a 25 foot extension cord that ends in a box with a stake in it which you push into the ground. The box also contains a timer, and a light sensor so you could set your holiday lights to turn on at dusk and off at dawn, or you could set the time for it to turn on and off. I figured that there must be a relay in there, opened it up and found that indeed there was a relay. However the relay needed 24 volts DC to trigger the relay. Rather than reverse-engineer the circuit board, I grabbed a DC power brick from my pile of old power supplies and a momentary switch.
The momentary switch turns on the 24VDC to the relay which then in turn energizes the 120VAC circuit turning on the 10Amp electric motor with no problem!
To push the button, I wired up my remaining servo to the arduino, attached a short bar of plastic to the rotating part of the servo and so now when the arduino senses a ball at the opening to the "impeller" it rotates the servo which pushes the button, which sends the 24VDC to the relay which energizes the motor, spinning the impeller and driving the golf ball out of the ABS tube!

A bit of a Rube-Goldbergian solution to be sure but it works really well!

If I had a bit more time, I might have shaped the plastic arm like a finger ....

The diagram below shows all of the pin connections and the schematic describing the DC power to button to relay to motor configuration.

Step 10: Control Fog Machine With Arduino

This circuit is linked to the sensors that trigger the ball impeller motor. It is linked via the arduino software. When the sensors see the ball go into the impeller area, the arduino triggers the fog for a second and then turns on the ball impeller, then turns off the fog machine.

The hardware is wired like the photo below shows.

The fog machine has a switch ( I think intended to be a footswitch) which causes the fog to emit from the machine when pressed. The machine takes a while to warm up before it will emit fog and the switch also has an indicator light.
I wanted to maintain the switch as it was originally and also be able to trigger the fog from the arduino, so I used automotive style wire "taps" to tap into the wires going to the switch. These I wired to the same kind of relay used on the nail gun.

The fog is sent down a copper tube into the tube where the ball will be shot by the impeller. This produces an effect as if the ball is being shot out by some kind of explosive that makes smoke - it looks pretty cool. If the fog machine could make fog faster and in slightly greater quantities the effect would be even better.

This is the last step in the process. The source code is attached.
Thanks for reading along!

Step 11: Code Review

I want to go over the arduino code to maybe show my thought process around the sensors and how to react to them as quickly as possible. I wanted to use interrupts attached to the sensors, but...

Because I did not have photo-transistors which produce digital signal either on or off, I was unable to use interrupts in the software. Interrupts would allow me to run the wipers constantly and at any point there was a ball rolling past an emitter/detector sensor pair, some action could be taken.

As it is I used photodiodes which produce an analog rather than digital on/off signal so I had to check the status of the sensors while also sending values to the servos running the wipers.

This is what I did.
The wipers run constantly. I made that action its own function
the function is called "MoveServo" and takes 3 inputs.
- which servo to move (randomly generated)
- how far to move the wiper (randomly generated)
- how long to pause before returning to "home" position
INSIDE of the function, I put code which checks the status of the sensors between everything.
The delay loop is I think where it checks the most.
Normally a delay would be one command: delay();
in my case I made the delay command only one millisecond and loop the number of milliseconds over that one millisecond delay so that every millisecond I could tell the arduino to check the status of the sensors.
I think that is the closest to an interrupt that I could come with this kind of setup.

The result is that the arduino reacts almost instantly when a ball crosses a sensor, which is what I wanted.

Here is the MoveServo function with some comments added

void MoveServo (int servoNum, long pos , int pause)
{
// before anything else I read the sensors
ReadandReport(); // this calls out to another function which reads the status of the sensors and writes the values to serial for debugging
if (analogRead(impSensorPin) <90 ) {StartMotor();} // this reads the impeller sensor and jumps to the StartMotor function if the ball is there
ReadNailPin(); // this reads the nailgun pin and jumps out to that function if the ball is there

if (servoNum>=50) // the random number sent is between 1 and 100
{
wiper1.write(pos); // tell the servo #1 how far to move
ReadandReport(); // debug output
if (analogRead(impSensorPin) <90 ) {StartMotor();} // as above check the impeller sensor
ReadNailPin(); // check the nail gun sensor
}else{ // gets here if the random wiper choice was less than 50 so move the servo#2 and check the sensors
wiper2.write(pos);
ReadandReport();
if (analogRead(impSensorPin) <90 ) {StartMotor();}
ReadNailPin();
}

// this is the loop which checks the sensors every millisecond
for (i=0;i // this pause is to wait for the servo to move and also for it to pause at the end before returning "home"
{
ReadandReport();
if (analogRead(impSensorPin) <90 ) {StartMotor();} // same as above
ReadNailPin(); // same as above
delay (1); // this is the actual delay
}

}

// BELOW HERE IS THE WHOLE SOURCE CODE

#include

int nailPin = 0; // this is the pin used to activate the nail gun
int LEDpin = 13; // indicator LED indicates that the machine is running
int fogPin = 20; // this pin activates the fog machine
int nailSensorPin=17; // this is connected to the IR Detector in front of the nail gun
int impSensorPin=16; // this is connected to the IR detector in front of the Ball Impeller

long rndSrvoPos; // variable to store the servo position
long rndPause; // random pause time
long whichServo; // choose which servo to move

int i=0; //generic integer variable
int nailTriggerValue; // value read from ir LED trigger for nailGun
int pos; // servo position variable

Servo wiper1; // first servo wiper object
Servo wiper2; // second servo wiper object
Servo impellerServo; // servo for impeller button pusher

void setup()
{

randomSeed(analogRead(3)); // seed the random number generator
Serial.begin(9600); // setup serial
pinMode(LEDpin, OUTPUT); // set up the pin modes
pinMode(fogPin,OUTPUT);
pinMode(nailPin,OUTPUT);
pinMode(nailSensorPin,INPUT);
pinMode(impSensorPin,INPUT);

wiper1.attach(14); // attaches the servo on pin 14 to the first wiper servo object
wiper2.attach(15); // attaches the servo on pin 15 to the second wiper servo object
impellerServo.attach(12); // attach to servo on pin 12 for the impeller button pusher


Blink3x(); // blink 3 times to indicate startup - sort of a power on self test

}

void loop()
{
// sweep the servos a random amount up to 80 degrees
// pause a random length of time from between 10 and 250 ms
rndSrvoPos = random(0,22);
rndPause = random(250,500);
whichServo = random(100);

ReadandReport();

if (analogRead(impSensorPin) <90 ) {StartMotor();}
ReadNailPin();
MoveServo(whichServo,0,rndPause);
MoveServo(whichServo,80,rndPause);

}
void StartMotor()
{
// start fog
digitalWrite(fogPin,HIGH);
delay(750);
impellerServo.write(112);
delay(450);
impellerServo.write(90);
digitalWrite(fogPin,LOW);

for(i=0;i<2000;i++) // this delay is an attempt to keep the motor from running too often asp when the ball bounces out
{
ReadandReport();
ReadNailPin();
delay(1);
}

ReadandReport();
}

void FireNailGun()
{
ReadandReport();
Serial.println("Firing Cycle");
delay(250);
digitalWrite(nailPin,HIGH);
delay(10);
digitalWrite(nailPin,LOW);

}

void MoveServo (int servoNum, long pos , int pause)
{
ReadandReport();
if (analogRead(impSensorPin) <90 ) {StartMotor();}
ReadNailPin();
if (servoNum>=50)
{
wiper1.write(pos);
ReadandReport();
if (analogRead(impSensorPin) <90 ) {StartMotor();}
ReadNailPin();
}else{
wiper2.write(pos);
ReadandReport();
if (analogRead(impSensorPin) <90 ) {StartMotor();}
ReadNailPin();
}

for (i=0;i {
ReadandReport();
if (analogRead(impSensorPin) <90 ) {StartMotor();}
ReadNailPin();
delay (1);
}

}

void ReadNailPin()
{
// read pins and respond - just the nail pin...
// this is an attempt at a manual interrupter
if (analogRead(nailSensorPin) <60 ) {FireNailGun();}
}

void Blink3x()
{
// Power On Self Test cycle
ReadandReport();
digitalWrite(nailPin,HIGH);
delay(250);
digitalWrite(nailPin,LOW);

digitalWrite(fogPin,HIGH);

digitalWrite(LEDpin,HIGH);
delay(250);
digitalWrite(LEDpin,LOW);
delay(250);
digitalWrite(LEDpin,HIGH);
delay(250);
digitalWrite(LEDpin,LOW);
delay(250);
digitalWrite(LEDpin,HIGH);
delay(250);
digitalWrite(LEDpin,LOW);
digitalWrite(fogPin,LOW);

wiper1.write(80);
wiper2.write(80);
impellerServo.write(90);
impellerServo.write(112);
delay(250);
impellerServo.write(90);
}

void ReadandReport()
{
// Serial.print("impSensorPin: ");
// Serial.println(analogRead(impSensorPin));
Serial.print("nailSensorPin: ");
Serial.println(analogRead(nailSensorPin));
}

Step 12: Source Code

4th Epilog Challenge

Participated in the
4th Epilog Challenge

Hack It! Challenge

Participated in the
Hack It! Challenge