Default-image

Sorry but you are on your own for a robot frame. you have two motors in your kit, you can actually do this with one motor if your frame is stable enough, but I recommend using two motors as you will get more torque allowing for faster response time when the robot starts to fall.

You can scale this up using larger motors and larger batteries and make a hover board or Segway with the same concepts.

We will be using the sonar sensor to measure a change in distance of the sensor from the ground to let us know if the robot is shifting from an upright position. You can use the same code from the Thermin project in Lesson 8 to figure out if the robot is leaning. In my sample circuit design I am using different pins for the sonar though so you will need to rewire it.

There is also a possibility that you can wind up with crossed wires on the two motor and the robot will spin and fall instead of correcting it’s balance, you can change it by moving wires, or modifying the motor direction code to compensate.

You can find the circuit below, the tool I used did not have the correct IC so I pick a random one with the same number of pins, you should be using the L239D from your kit, (the h-bridge motor controller).

The L239D has the following pin-out:

We will wire it this way in our project

IC PINArduino Pin
Enable 1,2 (1)Pin 3
Input 1 (pin 2)Pin 4
Output 1 (3)left motor one wire
GND (4)GND
GND (5)GND
Output 2 (6)left motor other wire
Input 2 (7)pin 5
Vcc2 (Vs) (8)9V positive
Enable 3,4 (9)pin 9
Input 3 (10)pin 7
Output 3 (11)right motor one wire
GND (12)GND
GND (13)GND
Output 4 (14)right motor other wire
Input 4 (15)pin 8
Vcc1 (Vss) (16)5VDC

The HC-SR04 Sonar sensor connects as follows:

PINArduino Pin
+Vcc5VDC
Trigpin 6
Echopin 10
GNDGND

Above you see the best drawing I could pull off for the circuit. I think my example works but I have a dead 9-Volt battery causing it to fail.

Because of the complexity of the circuit and the fact that if you want to make one you have to build a frame I am giving you my code below. Note that you may have to change the delay time or adjust lspeed and rspeed to make the motors respond fast enough depending on the weight of your frame. the lspeed and rspeed works from 0= motor stopped to 255 motor running full speed.

/* Comment block describing circuit
 *  GND goes to 
 *  * pin 1 of HC-SR04
 *  * pins 4,5 11, 12 of L293D
 * 5V goes to
 *  * pin 4 of HC-SR04
 *  * pin 16 of L293D
 * For best performance
 *  * 9v goes to pin 8 of L293D
 * Digital pin 6
 *  * goes to TRIG of HC-SR04
 * Digital pin 10
 *  * goes to ECHO of Hc-SR04
 * Left Motor connects to 
 *  * L293D pins 3 and 6
 * Right Motor connects to
 *  * L293D pins 11 and 14
 * Digtial pin 2 
 *  * goes to L293D pin 2
 * Digital pin 3 
 *  * goes to L293D pin 7
 * Digtial pin 4 
 *  * goes to L293D pin 10
 * Digital pin 5
 *  * goes to L293D pin 15
 * Digital pin 9
 *  * goes to pin 1 (left motor PWM)
 * Digital pin 3
 *  * goes to pin 9 (right motor PWM)
 */

int trig=6;
int echo=10;
int lfwd=4;
int lrev=5;
int rfwd=8;
int rrev=7;
int lpwm=3;
int rpwm=9;
int lspeed=256;
int rspeed=256;
float prevdist=0;

void setup() {
  pinMode(trig,  OUTPUT);  //trigger pin
  pinMode(echo, INPUT);  //echo pin
  pinMode(lfwd, OUTPUT);
  pinMode(lrev, OUTPUT);
  pinMode(rfwd, OUTPUT);
  pinMode(rrev, OUTPUT);
  pinMode(lpwm, OUTPUT);
  pinMode(rpwm, OUTPUT);
  //Turn motors off to start
  digitalWrite(lfwd, LOW);
  digitalWrite(lrev, LOW);
  digitalWrite(rfwd, LOW);
  digitalWrite(rrev, LOW);
  Serial.begin(9600);
  prevdist=distance();
}

void gozero() {
  analogWrite(lpwm, 0);
  analoglWrite(rpwm, 0);
  delay(500);
}

void gofwd() {
  digitalWrite(lrev, LOW);
  digitalWrite(lfwd, HIGH);
  digitalWrite(rrev, LOW);
  digitalWrite(rfwd, HIGH);
  analoglWrite(lpwm, lspeed);
  analoglWrite(rpwm, rspeed);
  Serial.print("fwd=");
  Serial.println(lspeed);
  delay(500);

}

void gorev() {
  digitalWrite(lrev, LOW);
  digitalWrite(lfwd, HIGH);
  digitalWrite(rrev, LOW);
  digitalWrite(rfwd, HIGH);
  analogWrite(lpwm, lspeed);
  analogWrite(rpwm, rspeed);
  Serial.print(" rev=");
  Serial.println(rspeed);
  delay(500);
}

float distance(){
  //Serial.println("Starting dist measurement");
  float  duration, cm;
  
  digitalWrite(trig,LOW);
  delayMicroseconds(2);
  digitalWrite(trig,  HIGH);
  delayMicroseconds(5);
  digitalWrite(trig, LOW);
  
  duration  = pulseIn(echo, HIGH);
  Serial.print(duration);
  return duration; //returns  distance in centimeters
}


void loop() {
  Serial.print("PREVDIS=");
  Serial.print(prevdist);
  Serial.print(" NEWDIST=");
  float dis = distance();
  Serial.print(dis);
  Serial.print(" DIFF=");
  float diff = prevdist-dis;
  Serial.print(diff);
  // prevent runaway from bad angle read.
  //adjust speed based on lean angle big angle requires faster correction
  lspeed = 0;
  rspeed = 0;
  if (diff > 0) {
     gorev();
  }
  if (diff < 0) {
     gofwd();
  }
  if (diff = 0) {
     gozero();
  }
}

You can probably build a robot frame out of a cardboard box and tape the motors to the inside of the box. You can use any kind of scrap round lid a plastic one off of an older peanut butter jar works great and put a whole directly in the center, slide it on the motor shaft and superglue or hot glue it. You want the weight at the top the robot for a reverse pendulum effect, which although it seems it would be the opposite will cause the robot to fall slower giving it more time to respond. The taller the robot the easier it is to get it to balance. You also want to put the sensor as far from the center of the robot as possible pointing at the ground my design has it a little too close so it doesn’t respond to the motion of the fall as well as it should. I suggest using a 12 inch ruler and mounting the sensor to the end of it and making the robot about one foot tall as well, mine is much smaller so probably won’t work really well.

I will bring it to class on Friday and help you wire your circuits your project will be to attempt to get it on a robot frame of some sort.

Share via
Copy link
Powered by Social Snap