Sunday, December 23, 2012

Arduino Line Follower part 1: H Bridge

I thought I would build an Arduino based Line Follower using a couple of DC motors so that it can move around a bit quicker than the servo motor based sumo bots. Here I will discuss the basic platform construction.
Parts List:
9 cm x 15 cm dense 5mm plastic
Solarbotics GM8 Gear Motor (143:1), 6V, 80r/min x 2
Solarbotics 69mm GMPW wheel x 2
Solarbotics GMB28 metal bracket x 2
4-40 bolt, 3/4 inch x 4
4-40 bolt, 1/2 inch x 4
4-40 nut, x 8
6mm standoff x 4
4AA battery holder
22 gauge hook up wire
2N3904 x 8
1k ohm x 8
Arduino Uno
DFRobot ProtoShield
nylon bolt (found)

Attach the mounting brackets to the motors. The motors are mounted such that the axle line is 5 cm from the rear of the platform using 1/2 inch bolts and nuts. Take care to mark and drill holes so that the wheels end up true and parallel. The wiring tabs on the motors are delicate so carefully hook and pinch your wires in place and solder quickly so as not to over-heat them. Use cable ties to secure the wires to the body of the motor so that any further strain is kept away from the tabs. I used an old nylon bolt (found) for the third idler wheel at the front.


I hot-glued a popsickle stick between the motors and glued the battery holder on top. I also added a small found DPST slide switch onto the battery holder so that I can easily switch the unit on and off. Most of the weight is over the axle line so that later on it can turn its nose easily to find the line.



After mounting the Arduino in place I considered the H Bridges needed to interface to the motors. I did not have any spare 293 chips on hand but I did have lots of 2N3904 transistors. I drew out the H bridge schematic on a scrap of paper and messed around with setting up the breadboard. I realized that the 4 transistors could be lined up, 2 facing one way and 2 facing the other such that the last leg of one transistor overlapped the first leg of the next. Thus: E B C-E B C-C B E-C B E. The 2 outer Es go to ground and the C-C connected to Vin (6V). C-E and E-C connect to the motor and each B connects to a 1K resistor. It's a simple matter to make sure the other ends of the resistors pair up.


Building 2 of these circuits on a tiny breadboard became possible. The wiring is not very neat but with colour coding and careful planning it is fairly robust and easy to trouble shoot. Here is the same circuit drawn as clearly as possible using Fritzing:
In this diagram again you can see how the transistors are essentially in a line with the last leg of one connected to the first on the next. 

Here is the code I used to test the motors. Each motors accelerates from minimum (80) to maximum (255) and then decelerates back to minimum first in one direction and then the other. Notice that I made sure each transistor is fully off before moving on. Remember that turning on both inputs to the H bridge will short out your power supply!

/* M Druiven, Dec. 23, 2012
   This program tests 2 DC motors connected to 2 H bridges.
   M1 is controlled from analog out pins 5 and 6.
   M2 is controlled from analog out pins 10 and 11. */

int M1F = 5; // motor 1 forward
int M1R = 6; // motor 1 reverse
int M2F = 10; // motor 2 forward
int M2R = 11; // motor 2 reverse

void setup()  { 
  // Make sure everything is off
  analogWrite(M1F, 0);
  analogWrite(M1R, 0);
  analogWrite(M2F, 0);
  analogWrite(M2R, 0);

void loop()  { 
  // fade M1 in from min to max in increments of 5 points:
  for(int fadeValue = 80 ; fadeValue <= 255; fadeValue +=5) { 
    analogWrite(M1F, fadeValue);           
    delay(20);                            
  } 
  // fade out from max to min in increments of 5 points:
  for(int fadeValue = 255 ; fadeValue >= 80; fadeValue -=5) { 
    analogWrite(M1F, fadeValue);          
    delay(20);                            
  } 
  analogWrite(M1F, 0); // reset output to off
  //************************************************************
  
  // fade M1 in reverse from min to max in increments of 5 points:
  for(int fadeValue = 80 ; fadeValue <= 255; fadeValue +=5) { 
    analogWrite(M1R, fadeValue);           
    delay(20);                            
  } 

  // fade out from max to min in increments of 5 points:
  for(int fadeValue = 255 ; fadeValue >= 80; fadeValue -=5) { 
    analogWrite(M1R, fadeValue);          
    delay(20);                            
  } 
  analogWrite(M1R, 0);
  //***********************************************************
  
  // fade M2 in from min to max in increments of 5 points:
  for(int fadeValue = 80 ; fadeValue <= 255; fadeValue +=5) { 
    analogWrite(M2F, fadeValue);           
    delay(20);                            
  } 

  // fade out from max to min in increments of 5 points:
  for(int fadeValue = 255 ; fadeValue >= 80; fadeValue -=5) { 
    analogWrite(M2F, fadeValue);          
    delay(20);                            
  } 
  analogWrite(M2F, 0);
  //**********************************************************
  
   // fade M2 in reverse from min to max in increments of 5 points:
  for(int fadeValue = 80 ; fadeValue <= 255; fadeValue +=5) { 
    analogWrite(M2R, fadeValue);           
    delay(20);                            
  } 
  // fade out from max to min in increments of 5 points:
  for(int fadeValue = 255 ; fadeValue >= 80; fadeValue -=5) { 
    analogWrite(M2R, fadeValue);          
    delay(20);                            
  } 
  analogWrite(M2R, 0);
}