One-Armed Bandit
Use an Arduino Mega to manage a 4-motor robot arm and a 2-motor car chassis. The MIT App Inventor package was used to create an Android app that controlled-the robot.
Use an Arduino Mega to manage a 4-motor robot arm and a 2-motor car chassis. The MIT App Inventor package was used to create an Android app that controlled-the robot.
There are a number of robot arms available. We were able to find a used OWI-535 robot arm [1], but new ones can be purchased for between $30 and $60. For this project we wanted the robot arm to be mobile so we used duct tape to mount it on top of an Arduino car chassis [2].
To build this project we used (Figure 2) :
Our biggest challenge was to figure out how to connect all the motors. Because the DC motors are bidirectional, we couldn't wire them directly to the Arduino pins. Instead we needed to use motor shields or some switching circuits.
Finding a suitable motor shield can be hard. The lower cost shields are based on the version 1 libraries that use dedicated pin connects. Stacking version 1 shields will probably cause pin conflicts. The newer and more expensive shields use the version 2 libraries that use IC2 connections (SDA/SCL). This seemed promising but finding a version 2 motor shield that is both stackable and whose I2C address can be changed is difficult.
Unfortunately we only had version 1 shields, so we wanted to see if we could come up with a solution without buying new hardware. After some trial and error we ended up using an Arduino Mega module; we mounted a 4-motor shield on top of it. We next remapped some pins to a "floating" 2-motor shield (Figure 3). Some of the key wiring connections are:
The OWI-535 has 5 motors to control the robot arm: hand, wrist, elbow, shoulder, and waist (Figure 4). We decide not to use the waist motor, instead we used the wheels to position the arm. Inside the robot's hand was a small light that we wired to pin 50.
To power this project we found that a portable USB charger was enough. If however you find that this doesn't deliver enough power, the OWI-535 robot arm has a built in power pack with exposed connections.
To make our testing a little easier we wired the robot motors to the 4-motor shield on top of the Mega module, and then wired the wheel motors to the "floating" motor shield.
Our next challenge was to come up with a set of simple commands to control all the actions. For this we used:
The 4-motor shield covered the default RX0/TX0 (0/1) pins on the Mega module so we wired a JY-MCU Bluetooth module to RX1 and TX1 on pins 19 and 18. Wire RX1 on the Mega to TX on the Bluetooth module, and TX1 on the Mega to RX on the Bluetooth module.
The motor terminals on the car chassis are a little fragile, so rather than soldering the wires, we used alligator clips. We also duct taped the wires under the car chassis to keep them secure.
The Arduino wiring was pretty ugly so we stuffed all the loose components into a small box. The box was duct taped to the back of the robot arm, and 2 cuts were made to feed the wires through them.
For this project only one extra library is called – AFMotor.h. It can be installed from the AdaFruit Motor Shield Library [6].
RX1/TX1 is wired to the JY-MCU Bluetooth module so the Serial1 object (note this is Serial1, not Serial), is used for the Bluetooth communications. We found that the receiving Bluetooth commands improved greatly when we added the line:
pinMode( 19, INPUT_PULLUP );
Incoming Bluetooth commands are captured by the statement:
inByte = Serial1.read();
Rather than having lots of big if statements, we created two functions to simplify our code.
The direction and speed of the wheels were controlled with the runwheels
function. With this function we could set the direction of wheel 1 (M1dir
) or wheel 2 (M2dir
). HIGH
would rotate the wheels forward and LOW
would rotate them backwards. The wheel 1 speed (E1speed
) and wheel 2 speed (E2speed
) could be set to 0 for stop or 255 for full speed. In this project we only used full speed.
To control the robot arm we created the function runmotor
. With this function we passed the motor object motor1
, and the direction as either BACKWARD
or FORWARD
. Unlike the wheels, which could run continuously, the robot motors were only moved for 250 milliseconds before stopping. To fully move a joint in the robot arm you would need to send the command a number of times.
The full code is shown in Listing 1.
Listing 1
Robot_arm.ino
01 // 02 // Bluetooth control of a mobile robot arm 03 // 04 #include <AFMotor.h> 05 06 char inByte; 07 // Define remapped pins for ,floating' motor shield 08 int E1 = 45; 09 int M1 = 44; 10 int E2 = 46; 11 int M2 = 47; 12 int LIGHTpin = 50; 13 14 // DC motor on M1 15 AF_DCMotor motor1(1); // hand 16 AF_DCMotor motor2(2); // wrist 17 AF_DCMotor motor3(3); // elbow 18 AF_DCMotor motor4(4); // shoulder 19 20 21 void setup() { 22 pinMode(M1, OUTPUT); 23 pinMode(M2, OUTPUT); 24 25 pinMode( 19, INPUT_PULLUP ); // For better Bluetooth stability 26 Serial1.begin(9600); 27 Serial1.println("Robot Commands"); 28 Serial1.println("Menu..."); 29 Serial1.println("Enter: 0-7 for robot arm, g/s/l/r/b for wheels "); 30 } 31 32 void loop() { 33 34 if (Serial1.available() > 0) { 35 36 // read the incoming byte: 37 inByte = Serial1.read(); 38 if (inByte == ,0') { runmotor(motor1,FORWARD); } 39 if (inByte == ,1') { runmotor(motor1,BACKWARD); } 40 if (inByte == ,2') { runmotor(motor2,FORWARD); } 41 if (inByte == ,3') { runmotor(motor2,BACKWARD); } 42 if (inByte == ,4') { runmotor(motor3,FORWARD); } 43 if (inByte == ,5') { runmotor(motor3,BACKWARD); } 44 if (inByte == ,6') { runmotor(motor4,FORWARD); } 45 if (inByte == ,7') { runmotor(motor4,BACKWARD); } 46 if (inByte == ,g') { runwheels(HIGH,HIGH,255,255); } 47 if (inByte == ,s') { runwheels(HIGH,HIGH,0,0); } 48 if (inByte == ,r') { runwheels(HIGH,HIGH,0,255); } 49 if (inByte == ,l') { runwheels(HIGH,HIGH,255,0); } 50 if (inByte == ,b') { runwheels(LOW,LOW,255,255); } 51 if (inByte == ,o') { digitalWrite(LIGHTpin, HIGH); } 52 if (inByte == ,f') { digitalWrite(LIGHTpin, LOW); } 53 } 54 } 55 //-------------------------------------------------- 56 void runwheels (int M1dir,int M2dir,int E1speed, int E2speed) { 57 // For control of wheels direction and speed 58 digitalWrite(M1, M1dir); 59 digitalWrite(M2, M2dir); 60 analogWrite(E1, E1speed); 61 analogWrite(E2, E2speed); 62 } 63 //-------------------------------------------------- 64 void runmotor(AF_DCMotor themotor, int direction) { 65 // Robot Arm motor control 66 themotor.setSpeed(250); 67 themotor.run(direction); 68 delay(250); 69 themotor.run(RELEASE); 70 }
Pages: 5
Price $15.99
(incl. VAT)