Robot Arm Hands Out Halloween Candy
by electric_piano_5k in Circuits > Robots
43 Views, 1 Favorites, 0 Comments
Robot Arm Hands Out Halloween Candy
I programmed a robot arm to hand out Halloween candy! I had red, blue, yellow, and white candy, and the game controller had red, blue, yellow, and white buttons. Press the yellow button, get a yellow candy, and so on. Press "down" to drop the candy when the kid has his/her bag in place. It was a big hit on Halloween night, every kid who came to my house said "That's so cool!"
Supplies
What you need:
Robot arm with Arduino compatible servo motors. Mine has servos type DS3115MG. These can be bought online for about $70.
A base for the robot arm if necessary. I used a scrap of wood for this.
An Arduino.to control the robot arm. I used Arduino Uno.
Game controller, or you could make your own controller with 8 pushbuttons. My program makes use of all 8 buttons on the Gravis PC Gamepad game controller (up, down, left, right, red, blue, yellow, green) to do various functions.
Holders to hold the candy in set positions. I made my holder using Lego bricks.
Power supplies (5V) for the robot arm (at least 12 amps capacity, I used an old computer power supply) and Arduino (I used a USB phone charger). It is a good idea to power the Arduino separately from high-current devices like servo motors.
Robot Arm and Candy Holder
I made a base for my robot arm using a scrap piece of 2x10 lumber. I used a router to make a cavity in the base to put the Arduino and other parts and connections required. I was given this robot arm, it was missing the bottom rotate servo and bearing, so I had to add the rotation bearing (I used a "lazy susan" bearing from Lee Valley, a woodworking supply store). I removed the wrist rotation servo (because I didn't need that rotation for this project) and moved that servo to control the arm rotation. You can see that servo in the base under the robot arm. A new robot arm should have all 6 servos including the rotation bearing and servo, so you won't need to do this.
I added rubber grips to the claw of the robot arm, so that there would be some compliance when the claw gripped the candy. This helped with holding the candy securely without crushing it. I had some trimmed off pieces of a "trim to fit" rubber car mat, this was ideal because it was sticky rubber and not too hard or soft. I cut two rectangles about 3 cm x 1 cm, drilled 2 holes and attached them to the claw using small nuts and bolts.
I had an old PC game controller, the type that used to connect to a joystick port on old PC's. This type of game controller has direct connections to the buttons on the DB15 connector, so it is easy to connect the controller to the Arduino. If you don't have this, you can make a controller with SPST momentary pushbuttons. See the next section on making connections between the controller and the Arduino. Luckily, I found a mating DB15 connector in my box of old computer parts, so I screwed this to the base to plug in the game controller.
I had some rubber feet scavenged from something, I screwed those to the base to help hold it steady.
The most important part of this project is the candy holder. I had 4 types of candy which happened to have wrappings that were red, blue, yellow, and white. I made color-coded holders using Lego bricks, with each holder cavity the right size for each candy type. The robot arm will be programmed to pick up a candy at a particular location (set of servo positions), so the candy must be held at a repeatable position for this to work. The position of the candy holder must be fixed relative to the robot arm. To accomplish this, I attached arms to the candy holder, these arms touch against the side and corner of the robot arm base to position the candy holder in exactly the right position relative to the robot arm This can be seen in the cover photo for this Instructable. The candy holder cavities must be far enough apart that the robot claw can reach between them in the open position. They must be located a convenient distance from the robot arm so that it can grab them. Generally, you want them to be as close as possible, because the servos have some position error, and the closer the candy is to the robot arm the smaller the position error will be.
Finally, I added some "hair" and eyes to my robot arm to decorate it. Of course this is optional, and you can add whatever decorations you like.
.
Connections
The servo connections to Arduino are straightforward. Just connect each servo's ground wire (black) to ground on the servo poiwer supply and ground on the Arduino, and connect each servo's control pin to a PWM capable pin on the Arduino. The 5V wire of each servo (red) connects to the 5V output of the power supply you are using for the servos. Be sure to use heavy gauge wire to connect between the servos and the 5V power supply, because the servos draw quite a bit of current. These are the Arduino pins I used for each servo:
Rotate servo: pin 8
Shoulder servo: pin 9
Elbow servo: pin 10
Wrist servo: pin 12
(note that I do not have a wrist rotation servo. Normally the robot arm will have one and you will have to connect this to an Arduino pin and set it to a fixed value to put the claw in the correct orientation.)
Claw servo: pin 11 (I mixed up the pin connections for Wrist and Claw, I meant to have them in order from bottom to top of the arm, but whatever, it was easier to change the proram than fix the wiring.)
I used a connector pin strip to attach the servo connectors to the Arduino. But, I found that this did not work well, the connections tended to be not reliable (intermittent, sensitive to movement, high resistance). I ended up cutting off the connectors from the servos and soldering the wires to the pin strip to get more reliable connections.
The connections to the game controller were somewhat more complicated. The connections are:
Red button: connector pin 2, Arduino pin 4
Blue button: connector pin 7, Arduino pin 5
Green button: connector pin 14, Arduino pin 6. (I placed a white sticker over the green putton to make it match the color scheme of my candy.)
Yellow button: connector pin 10, Arduino pin 7
Vertical control (up/down): connector pin 6, Arduino pin A0 with 47k ohm resistor to ground.
Horizontal control (left/right): connector pin 3, Arduino pin A1 with 47k ohm resistor to ground.
Ground: connector pin 4, Arduino pin GND
5V: connector pin 1, Arduino pin 5V.
The red/blue/green/yellow buttons are straightforward, just make the listed connections, and when each buttons is pressed the corresponding pin will be connected to ground inside the game controller and the pin voltage will go to LOW. The pinMode is set to INPUT_PULLUP for these inputs so that the voltage goes high when the buttons are not pressed. If you are making your own controller with pushbuttons, make the connections the same way so that the button connects the Arduino pin to ground when pressed.
Reading the up/down/left/right buttons on the directional controller is a bit more difficult. The old PC joystick controllers used potentiometers (variable resistors) to indicate the vertical and horizontal position of the joystick. 0 ohms would indicate that the joystick is all the way up or left, and 100k ohms would indicate that the joystick is all the way down or right. If the joystick is centered, the up/down and left/right potentiometers would each read about 50k ohms. The computer read the potentiometers using an oscillator that varied in frequency depending on the potentiometer resistance, because it is easy to measure frequency digitally. The Arduino has analog inputs, so we can read the resistance directly. But, we have to connect a bit of circuitry to the potentiometers to read the resistance. For more details, see https://hackaday.io/project/170908-control-freak/log/175891-pc-gameport-basic-circuit. I reproduce two figures from that web site here for convenience. The first figure shows the PC joystick connections. The second figure shows how the potentiometers can be read using the Arduino analog input (shown in the figure as "AVR"). A resistor needs to be connected between AVR and ground so that the voltage seen at AVR changes as the potentiometer resistance changes (graph on the left in the second figure). I used a 47k ohm resistor instead of the 39k ohm resistor shown in the diagram. In my case, the Gravis gamepad does not have an actual potentiometer for the horizontal and vertical directions, it has only 3 values of resistance: 0 ohms when up or left is pressed, 94k ohms when down or right is pressed, and 47k ohms when neither up nor down is pressed, or neither left nor right is pressed. With the 47k ohm resistor in my circuit, the Arduino will read 5V if up or left is pressed, 1.67V if down or right is pressed, and 2.5V if neither is pressed. So, reading the analog inputs A0 and A1 it is easy to tell which of up, down, left, or right are pressed on the directional pad. If I had a joystick with potentiometers, it would be possible to determine the resistance values of the potentiometers by doing some calculations after reading the voltages on A0 and A1. If you are using pushbuttons instead of the directional pad of a PC gamepad, you will connect these to digital input pins on the Arduino in the same way as the red/blue/green/yellow buttons of the gamepad.
Finally, connect a power supply to Vin on the Arduino. I used 5V from a USB phone charger for this. I tried using the same power supply that I was using for the servos, but it tended to be glitchy, sometimes resetting the Arduino when the servos were operating.
Arduino Control Program
My program is attached for reference. You will have to make some changes before using my program, most importantly is entering the correct servo positions for each candy pickup location and the "drop" and "wait" positions. To help with determining all the servo positions, I created a "manual" mode in the program. In the manual mode, left and right rotate the arm, up and down raise and lower the claw, red and blue move the claw inward and outward, yellow opens and closes the claw, and green operates a simple grab and drop sequence (press green to close claw and go to "drop" position, press green again to open claw and go to "pickup" position). In the manual mode, whenever a button is released, the positions of all servos are sent to the serial monitor. So, you can manually move the arm into one of the desired positions, then read on the serial monitor what the servo positions are for that arm position. Then the values can be entered into the program, in the definitions of the array variables rotatePickupN, shoulderPickupN, elbowPickupN, wristPickupN, and clawPickupN. To enter and exit "manual" mode, press up/left/blue simultaneously.
There are variables "ulnaLength" and "humerusLength" which are the lengths of the parts of the robot arm between wrist and elbow ("ulna") and between elbow and shoulder ("humerus") in millimeters. These distances are used when moving the claw up, down, in, and out. A variable "wristOffset" is used to keep the claw horizontal at all times, if your claw is not horizontal, adjust wristOffset. You will also have to adjust the values of shoulderOffset and elbowOffset, their function is explained in the program comments.
The basic operation of the program and the program flow is explained in comments in the program itself, I won't duplicate that here.