Arduino Project: Brum – Part 5

11/10/2016.Henrik.0 Likes.0 Comments

So the first test run with all front sensors and all the code have been done and yeah.. There was some problems. Tested it both indoor and outdoor, both resulting in problems so will go through them one by one.

The idea

The biggest problem I was having was that Brum didn't detect all objects in front of it so it avoided some and ran straight in to others. This, I realised, was because I had misunderstood the detection area of the sensors. It's ~30° in total and not ~60° as I believed, resulting in a to narrow detection field in front for it to notice obstacle on the sides(about wheel width). Making for a lot of crashing..

Also the "breaking"-feature I was using when switching between commands(drive forward, left, right etc) was useless and only resulting in lag and crashes. It didn't break it just coasted.. So yeah, brain fart. Also the drive speed was way to fast!

This was indoors. Outdoors resulted in even more strange problems. The ultrasonic sensors don't seem to like the cold and was giving no or lots of ghost results. Have been looking around for what the operational temperatures are for them but no luck, so if you know please enlighten me! Oh and on tarmac the drive speed was way to low due to the friction.

But this was results even if they wasn't the results I was hoping for. Only thing to do now is to find solutions for them!

Below is a demo video of Brum running, avoiding an obstacle and crashing.. The code is also below, same as last post.

/**
 * Self drivning RC-car code, Sensors: front, left front, right front
 * Author: Henrik Norberg
 * E-mail: henrik@dbhn.se
 */

/**  LCD Setup **/
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR    0x38 // <<----- Add your address here.  Find it from I2C Scanner
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

/**  Engines **/

//Drive Engine
int motorAPin_A = 10; //Arduino digital 8 is connected to HG7881's A-1A terminal
int motorAPin_B = 11; //Arduino digital 9 is connected to HG7881's A-1B terminal

//Steering Engine
int motorBPin_A = 12; //Arduino digital 8 is connected to HG7881's B-1A terminal
int motorBPin_B = 13; //Arduino digital 9 is connected to HG7881's B-1B terminal

/**  Ultrasonic sensors **/

// Ultrasonic Front
const int Trig0_pin = 1;
const int Echo0_pin = 2;
long duration0;

// Ultrasonic Front Left
const int Trig1_pin =  3;  // pin for triggering pulse    INPUT
const int Echo1_pin = 4;   // pin for recieving echo      OUPUT
long duration1;           // how long it takes for the sound to rebound

// Ultrasonic Front Right
const int Trig2_pin = 5;
const int Echo2_pin = 6;
long duration2;

/**  Misc settings **/

// Wall sensing or not (true or false for now)
boolean isFrontWall = false;
boolean isFrontLeftWall = false;
boolean isFrontRightWall = false;

//Starting values
int i = 150;                  // Initial engine speed
int motorState = 255;         // Drive motor direction

void setup(){
  lcd.begin (16,2); //  <<----- My LCD was 16x2

  // Switch on the backlight and print headline
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home (); // go home
  lcd.print("Engine Test"); 

  /**
   * When program starts set Arduino pinmode for 10 to 13 digital to be OUTPUT
   * so we can use analogWrite to output values from 0 to 255 (0-5V) (PWM) 
   */
  pinMode(motorAPin_A, OUTPUT); //direction
  pinMode(motorAPin_B, OUTPUT); //speed

  pinMode(motorBPin_A, OUTPUT); //direction
  pinMode(motorBPin_B, OUTPUT); //speed

  // ultrasonic Front
  pinMode(Trig0_pin, OUTPUT);        // initialize the pulse pin as output:
  pinMode(Echo0_pin, INPUT);         // initialize the echo_pin pin as an input:

  // ultrasonic Front Left
  pinMode(Trig1_pin, OUTPUT);        // initialize the pulse pin as output:
  pinMode(Echo1_pin, INPUT);         // initialize the echo_pin pin as an input:

  // ultrasonic Front Right
  pinMode(Trig2_pin, OUTPUT);        // initialize the pulse pin as output:
  pinMode(Echo2_pin, INPUT);         // initialize the echo_pin pin as an input:
}

void loop() {
  checkFront();
    if (isFrontWall == false) {
      turnReset();
      // Break if the car wasn't driving forward, saves on the engine and gears
      if (motorState != 255) {
        lcd.setCursor (0,1);
        lcd.print("Drive - Stop   "); 
        analogWrite(motorAPin_A, LOW);
        analogWrite(motorAPin_B, LOW);
        delay(1000);
        analogWrite(motorAPin_A, 255); //Drive forward
        motorState = 255;
        i = 150;
      }
      else { 
        analogWrite(motorAPin_A, 255); //Drive forward
        motorState = 255;
        lcd.setCursor (0,1);
        lcd.print("Drive - Forward"); 
        if (i << 180){                      // Speed up if not at max speed
          for(i;i<=180; i++){
            analogWrite(motorAPin_B, invertOurValue( i ));
            delay(40);
          }
        }
        analogWrite(motorAPin_B, invertOurValue( i ));
      }
    }
    else {
      checkFrontLeft();
      checkFrontRight();  
        if (isFrontRightWall == false && isFrontLeftWall == false) {
          //Sides are free, turn left
          analogWrite(motorBPin_B, 255 );
          // Break if the car was driving forward or reversing
          if (motorState != 1) {
                lcd.setCursor (0,1);
                lcd.print("Drive - Stop   "); 
                analogWrite(motorAPin_A, LOW);
                analogWrite(motorAPin_B, LOW);
                delay(1000);
                i = 150;
                analogWrite(motorAPin_A, 255); //Drive forward
                motorState = 1;
              }
          else {            
            analogWrite(motorAPin_A, 255); //Drive forward
            analogWrite(motorBPin_A, 0); //Turn left
            motorState = 1;
            lcd.setCursor (0,1);
            lcd.print("Drive - Left   "); 
            if (i << 180){                      // Speed up if not at max speed
              for(i; i<=180; i++){        
                analogWrite(motorAPin_B, i);
                delay(40);
              }
            }
             analogWrite(motorAPin_B, i);
             delay(500);
          }
        }
        else {
          if (isFrontRightWall == true && isFrontLeftWall == true){
            // Break if the car wasn't reversing, saves on the engine and gears
            turnReset();
              if (motorState != 0) {
                lcd.setCursor (0,1);
                lcd.print("Drive - Stop   "); 
                analogWrite(motorAPin_A, LOW);
                analogWrite(motorAPin_B, LOW);
                delay(1000);
                i = 150;
                analogWrite(motorAPin_A, 0); //Drive backward
                motorState = 0;
              }
              else {            
                analogWrite(motorAPin_A, 0); //Drive backward
                motorState = 0;
                lcd.setCursor (0,1);
                lcd.print("Drive - Reverse"); 
                if (i << 180){                      // Speed up if not at max speed
                  for(i; i<=180; i++){        
                    analogWrite(motorAPin_B, i);
                    delay(40);
                  }
                }
                 analogWrite(motorAPin_B, i);
                 delay(500);
              }
         }
        else {
          if (isFrontRightWall == true && isFrontLeftWall == false) {
              //Left is free, Right is blocked. Turn Left and go forward
             analogWrite(motorBPin_B, 255 );
              // Break if the car was driving forward or reversing
              if (motorState != 1) {
                    lcd.setCursor (0,1);
                    lcd.print("Drive - Stop   "); 
                    analogWrite(motorAPin_A, LOW);
                    analogWrite(motorAPin_B, LOW);
                    delay(1000);
                    i = 150;
                    analogWrite(motorAPin_A, 255); //Drive forward
                    motorState = 1;
                  }
              else {            
                analogWrite(motorAPin_A, 255); //Drive forward
                analogWrite(motorBPin_A, 0); //Turn left
                motorState = 1;
                lcd.setCursor (0,1);
                lcd.print("Drive - Left   "); 
                if (i << 180){                      // Speed up if not at max speed
                  for(i; i<=180; i++){        
                    analogWrite(motorAPin_B, i);
                    delay(40);
                  }
                }
                 analogWrite(motorAPin_B, i);
                 delay(500);
             }
          }
          else 
            if (isFrontRightWall == false && isFrontLeftWall == true) {
                //Right is free, Left is blocked. Turn Right and go forward
                analogWrite(motorBPin_B, 0 );
                // Break if the car was driving forward or reversing
                if (motorState != 2) {
                      lcd.setCursor (0,1);
                      lcd.print("Drive - Stop   "); 
                      analogWrite(motorAPin_A, LOW);
                      analogWrite(motorAPin_B, LOW);
                      delay(1000);
                      i = 150;
                      analogWrite(motorAPin_A, 255); //Drive forward
                      motorState = 2;
                    }
                else {            
                  analogWrite(motorAPin_A, 255); //Drive forward
                  analogWrite(motorBPin_A, 255); //Turn Right
                  motorState = 2;
                  lcd.setCursor (0,1);
                  lcd.print("Drive - Right   "); 
                  if (i << 180){                      // Speed up if not at max speed
                    for(i; i<=180; i++){        
                      analogWrite(motorAPin_B, i);
                      delay(40);
                    }
                  }
                   analogWrite(motorAPin_B, i);
                   delay(500);
               }
            }
        }   
    }
}
}

//Invert speed value
int invertOurValue(int input) {
  return 255 - input;
}

//Checking for obstacle in front of car
void checkFront() {
  digitalWrite(Trig0_pin, LOW);
  delayMicroseconds(2);
  digitalWrite(Trig0_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig0_pin, LOW);
  duration0 = pulseIn(Echo0_pin,10);
  if ((duration0 > 4000 || duration0 == 0)) {
    isFrontWall = false;
  }
  else {
    isFrontWall = true;
  }
}

void checkFrontLeft() {
  digitalWrite(Trig1_pin, LOW);
  delayMicroseconds(2);
  digitalWrite(Trig1_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig1_pin, LOW);
  duration1 = pulseIn(Echo1_pin,10);
  if ((duration1 > 4000 || duration1 == 0)) {
    isFrontLeftWall = false;
  }
  else {
    isFrontLeftWall = true;
  }
}

void checkFrontRight () {
  digitalWrite(Trig2_pin, LOW);
  delayMicroseconds(2);
  digitalWrite(Trig2_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig2_pin, LOW);
  duration2 = pulseIn(Echo2_pin,10);
  if ((duration2 > 4000 || duration2 == 0)) {
    isFrontRightWall = false;
  }
  else {
    isFrontRightWall = true;
  }
}

void turnReset() {
  analogWrite(motorBPin_A, LOW );
  analogWrite(motorBPin_B, LOW );
}

The Future

The future is actually already here but want to make one more video before showing it. Any how, Brum had to be totally reworked giving it wider detection range etc. Also A LOT of new code was needed but it have been worth the work so stay tuned!

Downloads

BrumRunning_rev1.zip
Categories: Project Brum

All rights reserved © Design by HN