Introduction: The Multi-functional Autonomous Robot: 'Asset'

About: I just love to make new things. Like things dealing with micro-controllers, mechanical engineering, Artificial Intelligence, Computer Science and anything at all that interests me. And here you'll find all the…

It was some time ago when I was in a quest for ideas to make an autonomous robot which would help me at home, which could be remotely controlled and also which would give me sensor information through wireless means. After much of pondering and thinking, I came up with a plan for my project. And in the trials to pursue it, i also changed my plans and attempted to make it function better from various aspects until finally I was able to build it(Asset - my robot's name) as best as i could.

It is an autonomous robot which could perform only limited functions but just as so, quite helpful too. Basically, Asset operates in three basic modes,

1. Control Mode.

2. Line following mode

3. Object following Mode

4. Object avoiding mode

Let me elaborate about the three modes to you.

Control Mode

This mode enables you to wirelessly control the movement of your robot with the help of HC - 05 or HC - 06 bluetooth modules more or less like a remote control car.

Line Follow Mode

The robot is made to follow a line or any highlighted path.

Object Follow Mode

When at this mode, the robot, with the help of it's 3 ultrasonic sensors, tries keep track of a moving obstacle (could be your hand) by actually following it.

Object avoiding Mode

Perhaps you'd already grasped what this mode would enable Asset to do. It can avoid obstacles and also be able to judge which direction to divert after the later being done.

You could configure and toggle between the modes by the two push buttons i have provided Asset with. The push buttons and the LCD display will become the intermediary interfaces between you and Asset.

Additional features

I have provided Asset with temperature and humidity sensor module(DHT11) which will tell you the temperature and humidity. I have also provided it with an LCD screen to display any kind of information and the same will be used to display the temperature and humidity. In addition to it, Asset could deliver the required sensor information to your smartphone with just a click of a button.

Yet still Asset could also toggle its lights ON whenever it's surroundings darken(with the help of a photoresistor).

Step 1: Getting Started

Things you will need:

Major components:

  • Arduino Uno
  • Arduino Nano
  • LCD display
  • DHT11(Temperature and Humidity sensor)
  • Servo motors - 2
  • HC-SRO4 (Ultrasonic sensor) - 3
  • DC motors (Geared) - 2
  • HC-05 or HC-06 Bluetooth modules (I am using the HC-05 module)
  • L298N - Full H bridge motor driver
  • Photoresistor
  • Pushbuttons(2 will suffice)
  • IR proximity sensor (1 will do our job)

Minor components:

  • Resistors(1 K ohm)
  • Jumpers(male to male and male to female)
  • Chasis
  • Mini size breadboard(preferably two)
  • Wheels - 2
  • Castor wheel
  • LEDs

Step 2: Connecting I/O Devices to the UNO

First, let us connect the l298n motor driver to the Arduino UNO.

As you could've seen in the picture, i used 3, 4, 5, and 6 respective arduino pins to operate the motor driver. As we will be using the l298n, the supply voltage could range up to 46V of DC. Therefore I will be giving it 18V and you could decide as per your necessity.

NOTE: Please make sure you connect the both the grounds together, else don't be surprised if it's not functioning as expected.

Also, I haven't used the ENA and ENB pins of the l298n IC in order to minimize the consumption of I/O pins. Enable pins can be used to control the speed of your motor; when set to LOW or 0, the speed is maximum.

Secondly, let us connect the HC-SR04 sensor modules to the UNO.

Here, I have connected the trigger and echo pins on 2 of the sensors together and set them on two of the digital pins on the Arduino (7 and 2). It is to save I/O pins, i did so and yet the distance could still be measured with the same accuracy had both the pins been connected individually. Also, we will be using a library in order to make matters simpler. The library is called NewPing and you can download it from the given link.

Since we only have 14 I/O pins on the UNO board, we will be connecting the third sensor to Arduino NANO and then establish an I2C bus connection between the both the boards.

Thirdly, let us connect the LCD display to the UNO.

As you could've seen in the image above how i connected the LCD to my Arduino.

GND - ground

VCC - 5 volts

Vo (display contrast adjustment) - OUT pin from the potentiometer

RS - digital interface 9 on the UNO

R/W - goes to ground

E - digital interface 8 on the UNO

D0 to D3 - are left open

D4 - pin 13

D5 - pin 12

D6 - pin 11

D7 - pin 10

Anode - 5 volts

K (cathode) - ground

And hence, the connection are confined to thus much. We only use 6 I/O pins and rest either go to 5V or GND. Also to put, we are interfacing the LCD 4 bit mode in order to minimize the use of I/O pins. If you want to know how an LCD display works, click here to watch this enthralling video.

Fourthly, let us learn to connect the HC-05 Bluetooth module to the UNO.

As you could've seen in the picture we have made a pull-down circuit for the Rx pin on the HC-05 in order to regulate voltage as the HC-05 operates on 3.3V level. Any higher than that could become harmful or may permanently damage it. Plus, the module and the UNO use Serial communication for interaction. So you can use the Serial.begin() function to initialize this with the specified baud rate.

NOTE: The Rx pin on the UNO goes to the Tx pin on the module. And the Tx pin on the Uno goes to the Rx pin on the module but with a pull-down resistor.

And that's all are the digital connections for the Arduino UNO. In the next 'step' we will discuss the analog connections.

Step 3: Pairing Your HC-05 Module With Your Android.

When arduino is powered, you might see that the HC-05 module blinks an in-built led. That is to signify that it is currently not paired with anything. Switch on your smart phone and download a bluetooth terminal application. Any app for that matter works fine.

Switch on your bluetooth also.

Open the application and try pairing it with the nearby devices. HC-05 must also be in the lists.

In case it asks you a pin code, it's typically 1234 or 0000. Once it's done entering, your module is paired with your phone and you could send and receive information via wireless means.

In case, it shows 'Unable to pair' which has often occurred with me, try changing the name of the module from HC-05 to any other in the settings. Then try once again to pair and it should result in success.

Step 4: Making the Analog Connection to the UNO.

So far we've done with our digital I/O connections. And it's time to lay hands on analog devices. I must tell you that, since we will be using the I2C bus connection between the two Arduino(s), we cannot make use of the two analog pins A4 and A5.

Pin A4 on the UNO corresponds to SDA. And pin A5 on the UNO corresponds A5. Same goes with the NANO.

Pin A4 on the NANO corresponds to SDA and pin A5 on the NANO corresponds SCL. And that's simple to get going with.

Now, the first picture which i have posted tells you exactly how we connect the DHT11. The middle out pin connects with A1 and the extremes go either to 5V or GND. We will also be implementing a library to get the sensed value. The line is right here.

A1 and A2 pins will be connected to push buttons which will only help us toggle between in the modes. Push button connections are very simple, perhaps you don't know then click right here.

A3 pin will be connected to the OUT pin of the IR proximity sensor. The IR proximity sensor is what will help ASSET to follow a highlighted path. We must also give importance to the theory based on which the sensor works. If you know this then you skip forward.

The IR proximity sensor has two diodes. One which emits the IR rays and the other which receives the reflected IR rays. If sufficient amount of IR rays have been reflected, then the OUT pin goes high otherwise low. When the sensor comes closer to any surface, say the floor, it's natural and expectable that the IR rays must be reflected off the surface. But there is some science involved here. Do you know which colour gains most heat when subjected to the sun? It's black. And heat in the sun's rays is possessed by the IR rays. And because black colour absorbs the most IR rays compared to other colours, it becomes the hottest.

So when the surface comes in proximity of the sensor and it is black, the IR rays won't be reflected because they get absorbed. And that means the OUT pin goes low. And when the surface is not black(say white), the OUT pin goes HIGH. So the next time your science teacher asks you about this, then you can bold speak yourself out.

In the end, all you must know is that, when the black surface is detected, then the OUT pin goes low. If the surface is light and not very dark, then the OUT pin goes high.

So that's all compromising the analog connections. Now let us see what we've got with the NANO that's to be done.

Step 5: Connecting the NANO With the Digital I/O Devices.

First, we will be making use of 2 servo motors upon which will be mounted our 2 ultrasonic sensors for ASSET to acquire information from various directions. Upon the command of the master device (Arduino UNO) the slave device (Arduino NANO) will tilt the servos to a particular angle where the sensors could measure the distances and the data shall thence be processed.

We will be using two digital I/O pins on the nano and because there is now abundance of I/O ports, you can choose any two of them and I've chosen 12 and 11. Make sure which servo goes where because you may get confused when you will type the code for them. That's why i've named my servos as servoL and servoR while configuring them in the code.

Connecting servos is the most easiest thing to do. And I can only hope that you know how to connect servo motors because it gets tedious for me to prepare images in Photoshop.

"Servo motors have three wires: power, ground, and signal. The power wire is typically red, and should be connected to the 5V pin on the Arduino board. The ground wire is typically black or brown and should be connected to a ground pin on the Arduino board. The signal pin is typically yellow, orange or white and should be connected to a digital pin on the Arduino board." - From the Arduino website.

https://www.arduino.cc/en/Reference/Servo

The next thing to do will be for us to connect a series of LEDs to digital pin 13 of the nano.

And finally, the third ultrasonic sensor of which the trigger pin will go to the digital pin 5 and of which the echo pin will go to the digital pin 4. This time we won't be using the library because of two reasons: one because we have no need to conserve I/O pins, and two is that the library can't function in the onRecieve function of the Wire library. And you mightn't want to try it yourself because i spent 2 whole days figuring it out.

And that is it for the digital I/O connections to be made with the NANO.

Step 6: Analog Connections With the Arduino NANO

We will just make one analog connection, and this is connecting the photoresistor to the A7 analog input pin on the NANO.

Since photoresistor is a resistance based sensor we will use it as one component of the voltage divider circuit. I a basic voltage divider circuit, there are two resistors needed; in our case the sensor itself acts one of the resistors. First, we will connect one of its lead (doesn't matter which) to 5V. The other lead will be connected to the A7 interface and also with a decent resistance of 1KΩ to ground. I have posted an image which you could make use of.

Step 7: Building the Robot.

I don't really want to advise you on how to build and put all thing together over 3 wheels. It's because i myself have done it really bad and i don't want all of you to follow my example. The reason is that i was hasting this project so as to submit my entry before the deadline of this contest. In the above pictures, you could get some inspiration or idea of building the structure with your own creativity and if you can't find any, then simply go by mine. Also, I've made all connections purely with jumpers.

I have also used two mini sized breadboards to make connecting easier. I used them also to give all components common power and ground. One of the bread boards was dedicated to the Arduino NANO itself. I used ice cream sticks to make the frame stronger and sturdy. I used a chassis for the base to which i also screwed the dc motors and the caster wheel. Also, i used double sided tape to stick the components. By my experience, I shall say that double sided tapes are not very reliable for very long.

That's all about building the structure. Asset is almost on it's way to life. . . .

Step 8: The Code

//code for the Master device.
#include

#include

#include

dht DHT;//assigning a reference name for the dht library. #include LiquidCrystal lcd(9, 8, 13, 12, 11, 10);/*assigning a reference name and configuring the pins for the Liquid Crystal library*/ boolean mode1 = false, mode2 = false, mode3 = false, mode4 = false; //assigning four boolean variables for 4 differnt modes. boolean one, two, three, four;//variables for mode toggling. You'll understand as you proceed. int select, change; // variables to store the push button values.

int in1 = 3, in2 = 4, in3 = 5, in4 = 6;//integer variables for the motordriver input pins. NewPing sensor2(7, 7, 500); // NewPing setup of pin and maximum distance. NewPing sensor1(2, 2, 500); // NewPing setup of pin and maximum distance. int n;

void setup() { // put your setup code here, to run once: Serial.begin(9600); Wire.begin();// initailizing the Wire library lcd.begin(16, 2);// initializing the LiquidCrystal library. lcd.write("Hello World"); lcd.setCursor(0, 2); lcd.write("My name is Asset"); delay(3000); lcd.clear(); pinMode(2, INPUT);

}

int Get(){ // the Master device requests the sensor info.(i.e) The distance measured by the third ultrasonic sensor. Wire.requestFrom(1, 2); if (Wire.available()){ n = Wire.read(); return n; } }

//seperate functions to drive the robot in different directions. int goStraight(){ digitalWrite(in1, HIGH); digitalWrite(in2, LOW); digitalWrite(in3, HIGH); digitalWrite(in4, LOW); }

int stopp(){ digitalWrite(in1, LOW); digitalWrite(in2, LOW); digitalWrite(in3, LOW); digitalWrite(in4, LOW); }

int turnRight() { digitalWrite(in1, HIGH); digitalWrite(in2, LOW); digitalWrite(in3, LOW); digitalWrite(in4, LOW); }

int backRight() { digitalWrite(in1, LOW); digitalWrite(in2, HIGH); digitalWrite(in3, LOW); digitalWrite(in4, LOW); }

int turnLeft(){ digitalWrite(in1, LOW); digitalWrite(in2, LOW); digitalWrite(in3, HIGH); digitalWrite(in4, LOW); }

int backLeft() { digitalWrite(in1, LOW); digitalWrite(in2, LOW); digitalWrite(in3, LOW); digitalWrite(in4, HIGH); }

int goBack() { digitalWrite(in1, LOW); digitalWrite(in2, HIGH); digitalWrite(in3, LOW); digitalWrite(in4, HIGH); } void loop() { // put your main code here, to run repeatedly: select = analogRead(A0);//to read analog interface A0 for the first push button.

if (select > 500) { mode1 = false; mode2 = false; mode3 = false; lcd.clear(); lcd.setCursor(2, 0); lcd.write("MODE SELECT"); change = analogRead(A2);// to read the analog interface for the second push button which will toggle between the modes. while(change < 500) {// waits until the the push button is pressed. change = analogRead(A2); } lcd.clear(); lcd.write("Control Mode"); one = true;//makes the boolean variable true. delay(100); wait: // a particular section where the program will jump as you toggle between the modes. select = analogRead(A0); /* read both the inputs*/ change = analogRead(A2); while (select < 500 && change < 500){// waits until anyone of the buttons are pressed. select = analogRead(A0); change = analogRead(A2); } delay(200);// this delay is very important because this is what which gives you the time to toggle between another mode before you go on to the next. if (select > 500){// checks wheather the first push button is high. lcd.setCursor(1, 1);// sets the cursor and writes 'selected' lcd.write("Selected"); if (one == true){ mode1 = true; } else if (two == true){// checks if the boolean variable two is true. If it's true, the mode2 shall be selected. mode2 = true; } else if (four == true){// checks if the boolean variable four is true. If yes then the mode 4 will be selected. mode4 = true; } else if (three == true){//checks wheather the boolean variable three is selected. If yes then the mode 3 will be selected. mode3 = true; } } else if (change > 500){// checks wheather the second push button was pressed. The second push button will help you to toggle between the modes. if (one == true){//checks if one was true. If yes then, makes it false and makes two true. one = false; lcd.clear(); lcd.write("Line follower"); two = true; } else if (two == true){//if one wasn't true then checks for two. If yes then, makes it false and makes three true. two = false; lcd.clear(); lcd.write("Obj follow mode"); three = true; } else if(four == true){//checks if four was true. If yes then makes it false and make one again true. four = false; lcd.clear(); lcd.write("Control Mode"); one = true; } else if (three == true){//checks if three is true. If yes then makes it false and makes four true. three == false; lcd.clear(); lcd.write("Obj avoid mode"); four = true; } goto wait;//jumps back to the particular portion of the program and waits until any pushbutton is pressed. } }

while(mode1 == true){// if mode1 is true then, the program enters this while loop and is executed until the reset button it pressed on the arduino. if(Serial.available() > 0){//if thing is communicating through serial interface. int setBit = Serial.parseInt(); if (setBit == 1){ goStraight(); } else if (setBit == 2){ turnRight(); } else if(setBit == 3){ goBack(); } else if (setBit == 4){ turnLeft(); } else if (setBit == 5){ stopp(); } else if (setBit == 10){ lcd.clear(); DHT.read11(A1); Serial.print("Current humidity = ");// prints the values on the serial monitor/ Serial.print(DHT.humidity); Serial.println("% "); Serial.print("temperature = "); Serial.print(DHT.temperature); Serial.println("C "); lcd.write("Humidity: ");// also prints the values on the lcd. lcd.print(DHT.humidity); lcd.write("%"); lcd.setCursor(0, 2); lcd.write("Temp: "); lcd.print(DHT.temperature); lcd.write("C"); } else{}//if Serial.available() function returns 0, then nothing happens. } } boolean r = false, l = false, start = true; while(mode2 == true){// this mode enables the robot to follow a line. if (analogRead(A3) > 500){ turnLeft(); } else { turnRight(); } } boolean first = false;//this variable enables to execute something only once. while(mode3 == true){ if (first == false){ Wire.beginTransmission(1); Wire.write(3); Wire.endTransmission(); first = true;//permanently makes the variable true so that the above is not executed again. } if (Get() < 30 && Get() > 7){// if the sensor on the Left shows the distance between 30cms and 7cms, then the robot turns left. turnLeft(); } else if(sensor1.ping_cm() < 30 && sensor1.ping_cm() >7){//if the sensor on the Right shows the distance between 30cm and 7cm, then the robot turns Right. turnRight(); } else if(sensor2.ping_cm() < 30 && sensor2.ping_cm() > 7){// if the sensor in the middle senses the distance between 30cm and 7cm, then the robot goes forward. goStraight(); } else if (sensor2.ping_cm() < 5){// if the sensor in the middle senses the distance lesser than 5 then the robot goes backward. goBack(); } else {// otherwise the robot does not move. stopp(); } } boolean checkit = true;// this variable again enables you to execute a particular part of the program only once. while (mode4 == true){ if (checkit = true){ Wire.beginTransmission(1); Wire.write(4);//writes '4' to the slave device. When the slave recieves the info, it tilts the servos perpendicular to the middle servo in the opposite direction. Wire.endTransmission(); delay(500); checkit = false; } goStraight();//goes forward. boolean direct = true;// its another variable which will help you to execute a part of the program only once. int a,b,c; c = sensor2.ping_cm(); while(c < 17){//checks if any object if in the front. if(direct == true){ a = Get(); b = sensor1.ping_cm(); if (a>b){ turnLeft(); } else { turnRight(); } } direct = false; delay(400); c = sensor2.ping_cm(); } } }//thus the program confined to the master device ends.

Here is the code for the slave device.

#include
#include Servo servoL; Servo servoR; NewPing sensor(5, 4, 500);

void setup() { // put your setup code here, to run once: Wire.begin(1); servoL.attach(11); servoR.attach(12); servoL.write(0); servoR.write(180); delay(1000); servoL.write(165); servoR.write(5); delay(200); Serial.begin(9600); Wire.onReceive(function); Wire.onRequest(req); pinMode(13, OUTPUT); pinMode(4, INPUT); pinMode(5, OUTPUT); } void function(int n){ if (Wire.read()== 3){//checks wheather the recieved bit from the I2C bus is equal to 3. servoL.write(140);//if yes then it tilts the servos to the paricular angle. servoR.write(25); delay(700);// delays a bit. } else {// if not then it does something else. servoR.write(85); servoL.write(90); delay(700); digitalWrite(13, HIGH); } }

void req(){ servoR.detach();//i am using this function because something was causing the servo motor to abruptly change it's angle. Maybe for you, it's not needed. digitalWrite(5, LOW);// measures the distance. delayMicroseconds(5); digitalWrite(5, HIGH); delayMicroseconds(10); digitalWrite(5, LOW); int n = (pulseIn(4, HIGH)/2)/29.1; Wire.write(n); Serial.println(n); }

void loop() { // put your main code here, to run repeatedly: Serial.println(analogRead(A7));//the values from the photoresistor actually measured from the following program. if (analogRead(A7) < 100){// the values go low, then the led goes high. digitalWrite(13, HIGH); } else {// otherwise the led goes low. digitalWrite(13, LOW); } }

Step 9: How the Code Works:

In this step, I will be explaining to you how each mode works and also how the robot will cope with each senario.

1. The control mode basically waits until it receives an integer through the serial interface. Based on whatever the number is, the robot will decide to go forward, backward, left,right or stop. When the robot receives the integer 10, it clears the lcd screen and displays the temperature and humidity; and also it print the temp and humidity on the Serial monitor.

That is how you receive sensor info on your phone.

2. Line following mode uses a IR proximity sensor which as you know has been attached at the bottom of the robot. If the sensor gives a HIGH output , the robot turns to Left. Otherwise Right. Based on whether the surface is white or black, Asset toggles its direction to result itself in following the line.

3. The third mode is the object following mode. When the executable program enters this mode, the master device gives a signal to the slave device, through the I2C bus, to tilt the servos to a particular angle. That also makes the ultrasonic sensors acutely change their angle.

CASE 1:

When the object comes in range(7cm to 30cm) of the sensor on the right, it turns right.

CASE 2:

When the object comes in range(7cm to 30cm) of the sensor in the middle, it goes forward.

CASE 3:

When the object comes in range(7cm to 30cm) of the sensor on the Left, it turns left.

CASE 4:

If the sensor in the middle senses the object below 5cm, it retreats backward.

CASE 5:

If the object is in range of none of the sensors, it remains still.

Also, we must note that the third sensor is wired to the NANO, so the master device will request 1 byte from the slave device. And hence the slave device sends the distance measured from the third sensor back to the master device. That's how the third sensor could be implemented by the master device.

4. The last mode is the object avoid mode. Similar to the previous mode, the master device will send a signal to the slave device, through the I2C bus, to tilt the servos perpendicularly opposite. Therefore, the distance could be measured from all the three directions.

The algorithm:

  • When an object is detected in front of the robot, it waits.
  • It evaluates the distances on it's right and it's left.
  • Whichever side shows a greater distance from an obstacle, it turns to that direction.
  • It turns until the distance in front of the robot changes to more than the specified value.
  • When the distance in the front changes to greater than the specified value, it goes forward again.
  • And this keeps looping.

Step 10: Conclusion:

In conclusion, i would like to say that to make this project come true, i spent a lot of energy. I had to design it first. My plan wasn't very good at first. I discarded it. I tried to do something better. I had to fail brutally sometimes. At times i almost gave up hope. But at such times i always knew that giving up was no option.

I am a teenage boy and i had to tackle my way through exams in building this. It was a wonderful experience for me while i made this.

This robot may not be chosen for any professional use but however, it displays and proves that such ideas and principles could be implemented in real life for industrial and home-guiding machines. It also proves that as many functions as possible could be integrated under three wheels with the help of the most basic micro controllers. For learners and intermediates, this would be a fun task to try as it may be a creative and an educational experience for them too.

Also i would like to put in that i called this beast of a machine as ASSET because it is my friend which gives me the hope that i could do something better in future. There's still a long way to trudge.

Finally, to all the people who to want make this, I would like to tell them, "Keep not this machine confined to just as much as i have given it the capability of but upgrade it to your best potential."

I must be extremely glad even if one person learns something from this instructable.

And last, please vote me for the circuit contest if you like my project. Thanks and goodbye!! :)

Epilog Contest 8

Participated in the
Epilog Contest 8

Circuits Contest 2016

Participated in the
Circuits Contest 2016