Introduction: Automated Navigation Robot With Gas (MQ-2), Temperature & Humidity (DHT11) Sensors

Hello everyone! The purpose of this project was to make a robot capable of navigating around obstacles in a room using the ultrasonic module HC-SR04 mounted on a Servo, this allowed the robot to look around to determine the best route to follow once an obstacle had been encountered.

This has been done 100's of times so i wanted to mix it up a bit, to do this i wanted to include some additional sensors in combination with a Bluetooth module, this allows the robot to gather environmental condition data then relay it back to an Android Application, from the Android Application you can also change the state of the robot from Navigation mode to idle where the robot will remain stationary but will still transmit sensor data.

What you will need for this project is:

MQ-2 Gas Sensor Module - £4.99

DHT11 Temperature & Humidity - £1.35

Bluetooth Transceiver Module - £6.99

HC-SR04 Ultrasonic Distance Rangefinder Module - £1

Arduino Uno R3 Rev3 - £3.39

L293D Motor Drive Shield Expansion Board - £2.89

9g Mini Servo of any kind ~ £0.99 - £1.99

20X4 Character LCD Module - £2.99

LCD Display I2C Adapter - £1.99

9V Battery Button Clip - £1.99

Rechargeable 9V Battery - £4.99

2WD V8 Smart Car Chassis (Any robot chassis should be fine assuming that it has 2 or more separate motors) - £12.99

Black ABS Box100x76x41mm - £5.29

On/Off Switch ~ £0.99 - £3.00

Male to Female Jumper Wire - £1.02

Female to Female Jumper Wire - £1.02

Solder Finished Prototype PCB - £2.08

To purchase everything required for this project it should cost around £60 although its likely you have lots of these parts already if your a bit of an Arduino hobbyist so odd are it will cost you much less!

If you have any questions of what parts to buy or anything else please feel free to comment or email me at js702@kent.ac.uk, now lets begin!

Step 1: Building the Chassis

The first thing you want to do is to build the chassis, in my case this meant following the instructions for my 2WD V8 Smart Car Chassis other chassis will work fine assuming they have at least two separate motors one for each wheel.

I apologies again that i do not have any images of me constructing the chassis!

Step 2: Circuit Diagram

The circuit diagram can be seen above, its quite a mess i apologise.

First of all you want to mount the L293D Shield onto the Arduino UNO.

M1 should be connected to the left motor.

M2 should be connected to the right motor.

(If you do this the other way around you just want to switch the motors around in the code later)

Servo 1 should be connected to Serv1 on the L293D Shield

The HC-06 Bluetooth Module you want to connect the Rx to the Tx of the Arduino, then the Tx of the HC-06 to the Rx of the Arduino as shown above.

The MQ-2 AOUT (Analogue Out) should connect to Pin A0

The DHT11 Modules OUT should connect to Pin 5

The I2C Modules SCL & SDA should connect directly to the SCL & SDA of the Arduino.

The HC-SR04 Modules Trig Pin should connect to Pin 13 & the Echo Pin should connect to pin 12

Step 3: Mounting the Servo & HC-SR04 Module on the Chassis

Now that the chassis has been constructed, the first step is to mount the Servo and HC-SR04 for obstacle avoidance.

Depending on the chassis you have chosen, the placement may vary.

In my case my chassis was symmetrical so i decided to mount my servo with hot glue, i then supported the servo with a cardboard cut out mounted using two of the floating wheel screws to mount it seen in the images above.

Using more Hot Glue i attached the HC-SR04 Module to the double armed servo attachment seen above.

Step 4: Connecting the Arduino Shield, Servo & Motors

Once you have connected the L293D Motor Shield to the Arduino UNO, you can begin connecting the motors. You may need to solder connections to the positive and negative terminals.

Then you connect the servo directly to the servo 1 port on the L293D Motor Shield.

Step 5: Connecting the I2C Module to the LCD Display & Power Supply

The I2C Module will have to be soldered to the LCD Display, this is extremely simple the final outcome can be seen above.

I chose to add an on/off switch to my 9V Battery Button Clip i added it to the positive cable of the connection as it is best to terminate a power supply on the positive connection to reduce the risk of components being damaged. Image 3 above shows how i did this, i used Heat Shrink Tubing to reduce the risk of a short.

Step 6: Connecting the MQ-2, DHT11 & Bluetooth Transceiver Modules

I connected all of the Modules with Female to Male Jumper Cables this meant that i had the freedom to move them to any position i wanted on the robots chassis. This meant that i had the freedom to position the Gas, Temperature and Humidity reading positions that could affects their accuracy. The Soldering connections as shown in the next step.

Step 7: Connecting All Sensors to the Boards

The image above shows all of the connections excluding the MQ-2 Modules. These connections follow that of the Circuit diagram shown in Step 2.

I have soldered all of the connections excluding the I2C LCD Module connections directly onto the L293D Motor Shield.

As the L293D Motor Shield does not pass through the SDA & SCL connections i had to directly input them into the Arduino UNO as seen above.

Step 8: The Code

The Libraries required for this code to work are:

  1. dht.h Library for the DHT11 Module.
  2. LiquidCrystal_I2C.h Library for controlling the LCD using the I2C Module.
  3. Servo.h Library for control of the Servo
  4. AFMotor.h Library for use of the L293D Motor Shield
  5. Wire.h Library which allows communication with I2C Modules
  6. LCD.h Library for general LCD usage.

The code: (Note please put < > around #include library's E.G #include dht.h should be #include or instead download the attached file named "FinalAutoNavBotCode.ino" Thanks :D)

#include dht.h

dht DHT; 

#include LiquidCrystal_I2C.h

#include Servo.h

#include AFMotor.h

#include Wire.h

#include LCD.h


//tells the arduino what each pin use is connected to
#define trigPin 13
#define echoPin 12
#define servoMainPin 10
#define BACKLIGHT_PIN  7
#define LED_ON  1
#define DHT11_PIN 5</p><p>Servo servoMain; // Define our Servo
AF_DCMotor motor2(2, MOTOR12_64KHZ); // create motor #2, 64KHz pwm
AF_DCMotor motor1(1, MOTOR12_64KHZ); // create motor #1, 64KHz pwm
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlighpin, polarity
int i = 0;
int state = 0;

void setup() //Sets each defined pin as an input or output so that the arduino what to expect at each pin
{
  Serial.begin(9600); // set up Serial library at 9600 bps
    servoMain.attach(servoMainPin); // servo on digital pin 10
  pinMode(trigPin, OUTPUT); //Unltrasonic output
  pinMode(echoPin, INPUT); //Ultrasonic input
    motor2.setSpeed(200); // set the speed to 200
    motor1.setSpeed(200); // set the speed to 200
    lcd.begin (16,4); // initialize the lcd
    lcd.setBacklight(LED_ON); // Switch on the backlight
    state = 0;
  delay(2000); //wait 2 seconds
}

//Ping Function to get the distance from the HC-SR04


unsigned long ping()
{
   // Trigger the uSonic sensor (HC-SR04) to send out a ping
   long duration, distance; //Initial Distance measure
   digitalWrite(trigPin, LOW);  // Added this line
     delayMicroseconds(1); // Added this line
   digitalWrite(trigPin, HIGH); //  delayMicroseconds(1000); - Removed this line
     delayMicroseconds(1); // Added this line
   digitalWrite(trigPin, LOW);
   duration = pulseIn(echoPin, HIGH);
   distance = (duration/2) / 29.1;
   delay(100);
   //clearlcd();
   return (distance);
}

//Forward Fuction sets motors to go forward


void forward()
{
      //Serial.println("Forward");    
      motor2.setSpeed(200);     // set the speed to 200
      motor1.setSpeed(200);     // set the speed to 200
      motor2.run(FORWARD); // going FORWARD
      motor1.run(FORWARD); // going FORWARD  
      delay(200);
      botstopF();            
}

//Right Function sets motors for right


void right()
{
      //Serial.println("right");    
      motor2.setSpeed(200);     // set the speed to 200
      motor1.setSpeed(200);     // set the speed to 200
      motor2.run(BACKWARD); // going BACKWARD
      motor1.run(FORWARD); // going FORWARD 
      delay(200);
      //botstopR();     
}

// Left Function sets motors for left


void left()
{        
      //Serial.println("left");    
      motor2.setSpeed(200);     // set the speed to 200
      motor1.setSpeed(200);     // set the speed to 200
      motor2.run(FORWARD); // going FORWARD
      motor1.run(BACKWARD); // going BACKWARD
      delay(200);
      //botstopL(); 
}

// Back Function sets motors going backwards


void back()
{
      //Serial.println("back");    
      motor2.setSpeed(200);     // set the speed to 200
      motor1.setSpeed(200);     // set the speed to 200
      motor2.run(BACKWARD); // going BACKWARD
      motor1.run(BACKWARD); // going BACKWARD  
      delay(100);
      botstopB();
}

//Function used to stop motors when going forward


void botstopF()
{ 
      motor2.setSpeed(0);     // set the speed to 200
      motor1.setSpeed(0);     // set the speed to 200
      motor2.run(FORWARD); // going forward
      motor1.run(FORWARD); // going forward
      delay(100);
}

//Function used to stop motors when going backwards, due to issue with general stop


void botstopB()
{   
      motor2.setSpeed(0);     // set the speed to 200
      motor1.setSpeed(0);     // set the speed to 200
      motor2.run(BACKWARD); // going forward
      motor1.run(BACKWARD); // going forward
      delay(100);
}

// Clear the LCD Display


void clearlcd()
{
  lcd.clear();
  lcd.home();
}

// Function to gather DHT11 sensor data for temp, returns reading


unsigned long DHTTemp()
{
  int chk = DHT.read11(DHT11_PIN);
  Serial.println("Temparature ");
  Serial.println(DHT.temperature, 1);
  return (DHT.temperature);
}

// Function to gather DHT11 sensor data for humi, returns reading


unsigned long DHTHum()
{
  int chk = DHT.read11(DHT11_PIN);
  Serial.println("Humidity " );
  Serial.println(DHT.humidity, 1);
  return (DHT.humidity);
}

// Function to gather data from the MQ-2 sensor, converts to voltage returns converted value as float


float MQ2()
{
  float sensor_volt;
  float sensorValue;
    sensorValue = analogRead(A0);
    sensor_volt = sensorValue/1024*5.0;
  Serial.println("MQ-2 Volt: " );
  Serial.println(sensor_volt);
  return (sensor_volt);
}

void loop()
{ 
  
  long int forwdis, leftdis, rightdis, temp, hum;
  float gas;
  
  // Used for connecting bluetooth device through bluetooth module
  if(Serial.available() > 0)
  {
    state = Serial.read();
    Serial.print("I received: ");
    Serial.println(state);
    delay(10);
  }
  
// When bluetooth connection sends 0 enters this state which is self navigation
if (state == '0') 
{
  gas = MQ2(); // Runs MQ2 function saves value in gas
  lcd.setCursor(6,1);
  lcd.print("Gas:"); // Display gas on LCD display
  lcd.print(gas); // Prints gas
  
  temp = DHTTemp(); // Runs DHTTemp function saves value in temp
  lcd.setCursor(6,2); 
  lcd.print("Temp:"); // Displays temp on LCD display
  lcd.print(temp); // Prints temp
  
  hum = DHTHum(); // Runs DHTHum function save value in hum
  lcd.setCursor(16,2);
  lcd.print("Humi:"); // Displays hum on LCD
  lcd.print(hum); // Prints Hum
  
  servoMain.write(90); // Centre Servo
  delay(150);
  forwdis = ping(); // Runs Ping fucntion reurns distance saves as forward distance
  Serial.println (forwdis); // Print forward distance
  
  i++;
  if (i == 8) // Used as LCD screen would ocasionally break, this could clear it fixing problem comment out if no issues
  {
    clearlcd();
    i = 0;
  }

if (forwdis >= 12) //If the forward dis is greater than 12 cm keep going forward
  {
      forward();
      clearlcd();
      lcd.setCursor(7,0); 
      lcd.print("FORWARD"); // Display direction of movment
      lcd.setCursor(12,4); 
      lcd.print(forwdis); // Print distance in cm
      lcd.print("CM");    
  }

else if (forwdis < 12)  //If distance is less than 12 cm then
  {
    back();
    
    // Look left and get left distance
    servoMain.write(165); 
    delay(150);
    leftdis = ping();
    Serial.println (leftdis);
    
    // Look right and get right distance
    servoMain.write(15);
    delay(150);
    rightdis = ping();
    Serial.println (rightdis);
    
    // Reset servo centre possition
    servoMain.write(90);
    delay(150);
      
      // If Left distance is greater than right then go left
      

if (leftdis > rightdis) 
      {
        clearlcd();
        lcd.setCursor(7,0); 
        lcd.print("LEFT"); // Display direction of movment
        lcd.setCursor(13,4); 
        lcd.print(leftdis); // Print distance in cm
        left();
        
      }

// If right distance is greater than left distance go right
      

else if (rightdis > leftdis) 
      {
        clearlcd();
        lcd.setCursor(7,0); 
        lcd.print("RIGHT"); // Display direction of movment
        lcd.setCursor(13,4); 
        lcd.print(rightdis); // Print distance in cm
        right();
        
    }
    
      // If each are the same then go backwards and clear LCD
      else if (rightdis == leftdis) 
      {
        clearlcd();
        back();  
      }   
  }
}


// If Bluetooth connection sends 1 change state into idle mode in this mode motors pause while sensors still read


else if (state == '1')      // If 1 Forwards
    {
      motor2.run(RELEASE);  
      motor1.run(RELEASE);  
      
      clearlcd();
        lcd.setCursor(7,0); 
        lcd.print("IDLE"); // Display direction of movment
        Serial.println ("IDLE");
        
      gas = MQ2();
      lcd.setCursor(6,1);
      lcd.print("Gas:"); 
      lcd.print(gas);
        
      temp = DHTTemp();
      lcd.setCursor(6,2); 
      lcd.print("Temp:");
      lcd.print(temp);
      
      hum = DHTHum();
      lcd.setCursor(16,2);
      lcd.print("Humi:"); 
      lcd.print(hum);
      
      motor2.run(RELEASE);   
      motor1.run(RELEASE);  
      delay(1000);
      
    }
    
}

Step 9: Measuring Out Enclosure & Key Components

The enclosure i chose to house the electronics for this project was an ABS Box100x76x41mm from Maplins this was probably a little smaller than i should have gone with as it really gave me very little room to fit all the electronics but i did manage it do so.

I measured the Height of the Arduino UNO & L293D Motor Shield to ensure that i had the headroom for my other connections.

Step 10: Drilling Holes for Module, Motor and Power Supply Connections

I First fit all the key components into the enclosure to get an idea of the best positions for drilling holes for external Module connections.

As the Arduino UNO will be housed inside the enclosure i needed to drill holes for the motor connections, the 2nd image above shows the two 4mm holes drilled one for each motor.

On the Right side of the enclosure a larger hole was made for the I2C LCD Displays connections as well as the 9V Battery Button Clip, this can be seen in the 3rd & 4th image above.

At the front of the enclosure again another large hole had to be drilled to allow the Female to Male Jumper Cables for the MQ-2 Gas Sensor, DHT11, Servo & the HC-SR04 Modules, this can be seen in the third image above.

Step 11: Android Application

So now that you hopefully have your robot working its time to find a way or receiving the sensor data and changing the robots state from navigation mode to idle

On the Google Play store there are many options for Bluetooth serial communication applications that would be capable of controlling your tank such as BlueTerm or ArduDroid and many more.

If you wish to download my application that currently offers 8 directional controls you can download it from the Play Store here: AutoNavBot

This application was created through App Inventor 2, which is an really great site for quickly developing Android Applications.

I have included the Designer and Block view above to show how the front and back-end of the application works so you can build this yourself and make any modifications you wish.

If you have never used App Inventor 2 before here's a link to some helpful tutorials to get you started: App Inventor Tutorials

Once you have the application installed there are a few steps before it will work. The images above show all the steps needed to get the AutoNavBot Application working. Make sure that the Arduino is powered on before attempting this!

  1. Go to setting
  2. Click on the Bluetooth Tab
  3. Turn Bluetooth on

  4. Wait for your phone to find the HC-06 Bluetooth module

  5. Once it has been found click it and input the password by default it should be either "1234" or "1111"

  6. Now it should say the time that you were last paired with the HC-06 module

  7. Now enter the AutoNavBot Application and click the "Select Bluetooth Device" button

  8. You should see the HC-06 Module (If not re-try the steps above) click on the Module

  9. The Application will then return automatically to the main screen with directional controls and now under the "Select Bluetooth Device" Button it should now say "connected"

  10. At this point the HC-06 Modules Red LED should now be constantly on instead of pulsing meaning a device is currently connected

Step 12: Project Conclusion

At this point you should have an Automated Navigation Robot that can relay sensor data back to your Android device indicating the environmental conditions around the robot. Now if you don't want to use the same sensors or want to add more this project give you a base to build upon, simply add another sensor include the code in the statements in a similar fashion and play. If you have any difficulties doing this please feel free to ask and i will do my best to help out!

Please share some images of your attempts i love seeing people trying this out for themselves!

If you had any issues or questions about this project please feel free to ask, i will do my best to help you!

Thanks for reading!

I have a few ideas for other future projects so i hope you hear from me again soon!

Comments

author
krunals8 made it! (author)2017-06-16

Automatic movement means we can provide coordinates of destination via bluetooth and robot will reach there . Am i correct ?

author
JackSoldano made it! (author)JackSoldano2017-07-25

Hi Krunals8, with the way I have set the code up no this would not be possible. I did think about this when starting this project but it seemed hard to implement but it would be possible with some dramatic changes. Key issue would be knowing how far you have moved from starting possition could possibly use hall effect sensors and magnets on the wheels to do this?

author
gltaccone made it! (author)2016-11-08

I have one dubt. Do you use pin 12 in two fuctions:

#define echoPin 12 and DIR_LATCH for Motor Shield?

How it works?

or I am wrong?

Thanks

author
Koushikngn made it! (author)2016-07-31

Thank You

author
Koushikngn made it! (author)2016-07-29

Can you tell me how to improve the code if I use servos instead of motors

author
JackSoldano made it! (author)JackSoldano2016-07-30

Hey Koushikngn, so what exactly is the issue, if you use servos instead you wound need to change the functions for robot movement, for Forward, Left, Right & Backwards if you wrote / found this code simply replace the code in each these functions to the corresponding new code and the robot should function in the same way but instead with Servos, if you need more helps feel free to ask & thanks for the comment!

author
kehaldoshi made it! (author)2016-07-13

Nice project. I also build one. But I want to write code that run robot in auto and manual mode. In auto mobe robot detect obstacle autometic and in manual mode I can control it from mobile .can you please help me.

author
JackSoldano made it! (author)JackSoldano2016-07-14

Hello and thanks! Yeah this is possible and should be very easy to do, if you look at my previous instructables "Bluetooth Arduino Tank" i made an app where you could control the tank from your phone, by asigning each direcrion a different value, you would need to merge the code from this project and my bluetooth tank project to achieve what you just described, it should be pretty easy :) if you want more guidance just ask! Thanks again and good luck!

author
kehaldoshi made it! (author)kehaldoshi2016-07-14

I trried to write code. Please suggest me if should I change anything.


#include //
#include //
String voice;
#define left_motor_A 6
#define left_motor_B 5
#define right_motor_A 10
#define right_motor_B 9
#define tx 1
#define rx 0
#define Trigger 3
#define Echo 2
#define max_distance 200
Servo servo;
NewPing sonar(Trigger, Echo, max_distance);
int inputPin = 2; // ECHO
int outputPin =3; // TRIG
unsigned int distance;
unsigned int front_distance;
unsigned int left_distance;
unsigned int right_distance;
unsigned int time;
int state = 0;

void setup(){
Serial.begin(9600);
pinMode(left_motor_A, OUTPUT);
pinMode(left_motor_B, OUTPUT);
pinMode(right_motor_A, OUTPUT);
pinMode(right_motor_B, OUTPUT);
servo.attach(7);
state = 0;
delay(2000); //wait 2 seconds
}

void forward()
{
digitalWrite(left_motor_B, LOW);
digitalWrite(left_motor_A, HIGH);
digitalWrite(right_motor_B, LOW);
digitalWrite(right_motor_A, HIGH);
}

void backward()
{
digitalWrite(left_motor_A, LOW);
digitalWrite(left_motor_B, HIGH);
digitalWrite(right_motor_A, LOW);
digitalWrite(right_motor_B, HIGH);
}

void left()
{
digitalWrite(left_motor_A, HIGH);
digitalWrite(left_motor_B, LOW);
digitalWrite(right_motor_B, HIGH);
digitalWrite(right_motor_A, LOW);
}

void right()
{
digitalWrite(left_motor_B, HIGH);
digitalWrite(left_motor_A, LOW);
digitalWrite(right_motor_A, HIGH);
digitalWrite(right_motor_B, LOW);
}

void stop()
{
digitalWrite(left_motor_B, LOW);
digitalWrite(left_motor_A, LOW);
digitalWrite(right_motor_A, LOW);
digitalWrite(right_motor_B, LOW);
}
void sensor_measure()
{ time = sonar.ping();
distance = time / US_ROUNDTRIP_CM;
}
void loop() {
if(Serial.available() > 0)
{
state = Serial.read();
Serial.print("I received: ");
Serial.println(state);
delay(10);
}

if (state == '0')
{
servo.write(90);
sensor_measure();
front_distance = distance;
if(front_distance > 15 || front_distance == 15)
{

forward();
}
else
{
stop();
servo.write(180);
delay(500);
sensor_measure();
left_distance = distance;
servo.write(0);
delay(500);
sensor_measure();
right_distance = distance;
servo.write(90);
delay(500);
if(right_distance < left_distance)
{

left();
delay(500);
forward();
}
else if(left_distance < right_distance)
{

right();
delay(500);
forward();
}
else
{
backward();
}
}
}

else if (state == '1') {
Serial.println("Forward");
forward();
state = 0;
}

else if (state == '2') {
Serial.println("Left");
left();
state = 0;
}

else if (state == '3') {
Serial.println("Right");
right();
state = 0;
}

else if (state == '4'){
Serial.println("Backward");
backward();
state = 0;
}

else if (state == '5') {
Serial.println("Stop");
stop();
state = 0;
}
}

author
kehaldoshi made it! (author)kehaldoshi2016-07-14

Thank you for quick response. I tryied many codes to merge but not successful due to can't write whole code in loop. Can you please write that code ?

author
Rahul - S made it! (author)2016-06-22

Nice Robot !!!
I didn't thought arduino can handle these many stuffs at a time.
4 Sensors + 2 DC motors + 1 Servo + Bluetooth + LCD Display
well explained :)

author
JackSoldano made it! (author)JackSoldano2016-06-22

Hey Rahul, yeah i think i was starting to push how much i could fit onto one Arduino Uno with just a 9V battery :) glad you like the guide Thanks!

About This Instructable

4,190views

118favorites

License:

Bio: I'm currently studying my MEng in Electronic & Communications Engineering, i have always been interested in how stuff works with a focus on electronics.
More by JackSoldano:Automated Navigation Robot with Gas (MQ-2), Temperature & Humidity (DHT11) SensorsCheap Smart RFID Packet for Moisture DetectionArduino Bluetooth Tank with Custom Android Application (V1.0)
Add instructable to: