Tuesday, May 28, 2013

Robot Arm: Part 1

In Part 0, I covered the motivation for this project as well as a general outline for how I will proceed. In this part, I'll try to cover the hardware modifications and basic electronics I've used to control the robot arm.

To start, how does the arm work once it is assembled? There are 5 DC motors that control the different joints. There is one motor to control the base swivel, three to bend the arm joints up and down, and one to open and close the gripper. Each motor is driven by applying a voltage across the leads, positive for one direction, negative for the other. There is a hand controller with rocker switches to apply these voltages in either direction. The whole thing is loaded with 4 D-size batteries in series. Each cell provides about 1.5V, but the motors are not driven with the full 6V possible with all of them in series. Instead, 'ground' is taken as half way up this stack, so that the hand controller can apply +/- 3V to each battery depending on the position of the switches.

I've chosen to use an Arduino Pro Mini as the on-board controller for this project, so the first step is to find a way to supply each motor with the proper voltage and current using 5V logic. The Arduino IO pins can't provide enough current to move the motors, so I use a couple H-Bridge drivers instead. Each driver can apply a given voltage to two DC motors in either direction based on input from a microcontroller. With five motors to control, I hook up 3 of these drivers to a protoboard and wire the control lines to the Arduino IO pins.


It's a mess of wires, but some of that is to allow the arm to move freely.


Instead of sticking with the original 3V for each motor, I've gone ahead and allowed for the full 6V of the batteries to be used. The danger here is probably overheating the motors, so I'll have to be cautious. If this turns out to be a problem, I can always get the Arduino to pulse the drivers instead of having them continuously on.

With this step done, I have full control over the movement of the arm. I can either program the Arduino to move the arm in some regular way, or use my laptop to send commands and have the Arduino interpret them and drive the motors. The issue here is that I have no way of knowing where the arm is at a given moment. There is no feedback in the motors that tells the Arduino how far it has been moved, I need to figure that out myself.

There are a few ways I can think of off the top of my head that will allow me to know what position the arm is in:
1) Dead-reckoning - If you know the position at one point and you know how long you've run one of the motors, you can estimate how far it has moved. This still requires knowing the position once, and imperfections in the gearing will cause this method to be very inaccurate.
2) Accelerometers - Each arm segment makes some angle relative to gravity, and knowing each angle allows you to find the arm position. In theory this is fine, but it seems like overkill. Also it does not work for rotation around the base.
3) Potentiometers - Each joint is connected to a potentiometer so that as the arm bends, the potentiometer is turned, causing a variable resistance corresponding to the angle. The Arduino measures this as an analog voltage.
4) Rotary Encoder - Open up the gear boxes and attach a rotary encoder to each motor that sends a signal for every few degrees of gear rotation. Add up the clicks and you get how much the motor has turned. Unfortunately the gear boxes are a pain to open.

The third option seemed like the most reasonable, so I bought a couple 10K potentiometers and glued them to each joint. I'm a fan of using hot glue for projects that don't need to last forever, but if the potentiometers start to come loose I can always switch to epoxy. Each was wired to the main board as a voltage divider with the variable lead being read by the Arduino analog inputs.


Sensor for base rotation. The black sticks are left over from the arm kit.


Second joint. The wire lashing is for safety, or something.


Third joint.


Last sensor. Not the best position, but it works well enough.


With everything hooked up, I check the sensors by letting a single motor turn back and forth while printing the analog input value to the serial port:


Analog reading directly from the Arduino every 10 ms. Bottom axis is around 18 seconds total. I rotated the base from one end to the other, so this is the total range I can get for this sensor.

As you can see, the sensor readings look clean and fairly stable. With some calibration, I'm able to convert these analog values to the angle of each joint. With some simple forward kinematics, I can figure out the 3D position of the claw with reasonable accuracy.

The next part of this project will be sorting out the input method for controlling the arm. I'm hoping to have some sort of physical input using my own arm, but we'll see how things work out!


Maybe after some clever programming I will remove the dunce hat.