Automated Navigation Robot With Gas (MQ-2), Temperature & Humidity (DHT11) Sensors
by JackSoldano in Circuits > Electronics
11573 Views, 132 Favorites, 0 Comments
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!
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!
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
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.
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.
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.
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.
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.
The Code
The Libraries required for this code to work are:
- dht.h Library for the DHT11 Module.
- LiquidCrystal_I2C.h Library for controlling the LCD using the I2C Module.
- Servo.h Library for control of the Servo
- AFMotor.h Library for use of the L293D Motor Shield
- Wire.h Library which allows communication with I2C Modules
- 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); } }
Downloads
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.
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.
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!
- Go to setting
- Click on the Bluetooth Tab
Turn Bluetooth on
Wait for your phone to find the HC-06 Bluetooth module
Once it has been found click it and input the password by default it should be either "1234" or "1111"
Now it should say the time that you were last paired with the HC-06 module
Now enter the AutoNavBot Application and click the "Select Bluetooth Device" button
You should see the HC-06 Module (If not re-try the steps above) click on the Module
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"
At this point the HC-06 Modules Red LED should now be constantly on instead of pulsing meaning a device is currently connected
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!