[Tutorial #2] Line Follower Robot with Android and Arduino

Welcome, Aron here!

In the last year I worked in a Line Follower Robot with Android and Arduino, or the project Timótheo.

To complete this project, we created a Framework, .PNG Arduino Framework.

Using it we created an autonomous robot that uses an Android device to analyze the environment using the Camera, and then send commands to the robot.

And now, you’ll be able to check a full tutorial to learn how to create a similar project and how to hack it and add custom features.

Check the video bellow and let’s start.

I - About this tutorial

In this tutorial I’ll explain you everything about the project while we code it together.

I’ll show you the logic used, components, tips, and after when finished, you’ll see how to hack it to have some nice extra features.

The tutorial is divided in 4 parts:

You’ll need the following components:

The full project will cost something around $60 :)

Source code:

Get updates Follow @aron-bordin
Star it: Star
Contribute: Fork
Download: Download

This project was developed by:

  • Aron Barreira Bordin, Felipe Kutait, Hugo Fernando Waki, Mateus L. Mazziero, Matheus B. de Moraes, Raul Pelegrini Neto, Vinicius F. J. Moretto, Vitor C. Costanzo

With the orientation of:

  • André Bicudo and Rene Pegoraro

II - How this project works

Before start coding it, let me explain you how it works. We have to separated modules, Android and Arduino.

  1. Arduino - Arduino has a simple communication layer. It can receive and send bluetooth messages through bluetooth. When Arduino receives a new message, the message is analyzed and an action is executed(I’ll be using a communication protocol, explained in the part #2). This action can be something related with movement(turn right, stop, etc) or something related with sensors(read the ultrasonic value, for example). Nothing related with the robot logic will be coded in the Arduino. Arduino only execute action received by bluetooth, nothing more. But why? It’s simple! If we are using a simple an abstract code in the Arduino, we’ll be able to use the same robot to do anything, without recoding it!

  2. Android - All the robot logic is here. When hacking it or creating a new project, we’ll code a new Android project and keep the same source code in the Arduino. In this project, Android will be constantly reading raw camera data to follow the line. Depending the position of the line, Android will send commands to the connected Arduino. When necessary, Arduino ask sensor data. For example, each 500ms we can as the robot to measure the ultrasonic distance.

III - Robot Schematics

I’ll not be covering a completed and detailed electronic tutorial here, because my main objective is to show how to code it, the code is the most important part in this project.

So if you have any question about the electronics, feel free to comment here and ask about it :)

But let’s see how to connect each component individually.

1) Keyes L298

We are going to use this item to control the motors:

We’ll use 6 PINs. Check this image:

Connect the PINs ENA, IN1, IN2, IN3, IN4 and ENB with your Arduino board, and add a 5V power supply.

I’m using these PINs:

Arduino PIN Dual H-Bridge L298
6 IN1 (Controls motor 1 direction)
7 IN2 (Controls motor 1 direction)
5 ENA (Enable motor 1)
8 IN3 (Controls motor 2 direction)
9 IN4 (Controls motor 2 direction)
11 ENA (Enable motor 2)

If you don’t know how to use this component, please take a look in some tutorial about it, and if you have any question, just comment.

Some useful links:

http://blog.whatgeek.com.pt/arduino/l298-dual-h-bridge-motor-driver

https://billwaa.wordpress.com/2012/06/06/arduino-l298-dual-h-bridge-motor-driver/

2) Bluetooth HC-05

Check this image, you need to connect your bluetooth module like this one:

I’m using different PINs.

Arduino PIN Bluetooth HC-05
3 TX PIN(Purple)
2 RX PIN(Blue)

Just make sure to use the right PINs here.

The RX PIN from Arduino will be connected in the TX on HC-05, and TX PIN on HC-05. The RX PIN on HC-05 supports 3.3V, so you’ll need to use a voltage divisor to convert 5V to 3V.

3) Ultrasonic HC-SR04

Check this image:

You’ll need to connect the HC-SR04 with a power supply and connect it with Arduino.

The HC-SR04 has two PINs, ECHO_PIN and TRIGGER_PIN. In this tutorial, I’m using these Arduino PINs:

Arduino PIN HC-SR04
A4 ECHO
A5 TRIGGER

Just a tip, if you are not experienced with these items, test them individually to learn more about it. If you are a little confused here, I’m really sorry, but I’m trying to cover the logic and programming in this project. I’ll be publishing a separated tutorial about each item, so keep connected with the blog to learn more :)

Here is a table with all PINs used:

Arduino PIN Dual H-Bridge L298
6 IN1 (Controls motor 1 direction)
7 IN2 (Controls motor 1 direction)
5 ENA (Enable motor 1)
8 IN3 (Controls motor 2 direction)
9 IN4 (Controls motor 2 direction)
11 ENA (Enable motor 2)
Arduino PIN Bluetooth HC-05
3 TX PIN(Purple)
2 RX PIN(Blue)
Arduino PIN HC-SR04
A4 ECHO
A5 TRIGGER

IV - Communication protocol(Optional)

This step is optional, you can jump to the next one if you don’t want to see how the communication works. I recommend you to read it and try to understand, but if you skip, you’ll be able to follow the tutorial.

We created a communication protocol to be easier to connected any device with this robot using bluetooth, radio, wifi, etc. I’m not going to show the whole protocol, major part of it it’s not necessary here, so this step is optional, just to help you to understand why we are using this format in the messages.

The Arduino will receive messages in the format “[NUMBER]@[NUMBER]#” or “[NUMBER]@[NUMBER]@[NUMBER]#”, where @ is a parameter delimiter and “#” is the end of the message. Let me show you how it works.

The first number will represent one of the following options:

First number Action
1 Set a value to an Arduino PIN
2 Get a value from an Arduino PIN
3 Call a method

We’re not using all options, to keep this tutorial easier, let’s do everything with the number 3.

The second number represents which method we want to run. One of the following:

Second number Action
1 goFront
2 goRight
3 goRightStrong
4 goLeft
5 goLeftStrong
6 goBack
7 goStop
8 readDistanceCM
9 delay
99 Alert when finish the delay

The third parameter is optional.

It’ll be used to send an parameter to the method, for example the number of delay.

And it’ll be used when we request a value, for example, read the ultrasonic distance.

So, if the Arduino receives the message “3@1#”, for example, this message means Go Front.

If Arduino receive the message “3@8@[ANY-NUMBER]#”, it well read and send the distance read by the Ultrasonic.

To return a value, this protocol has some rules too. The Arduino will only send a value if it was requested.

To request a value, in this tutorial we are using the format “3@[METHOD]@[REQUEST_ID]#”.

The request_id is important, it’s an unique int value to identify the request. So, the Android device can ask the ultrasonic value with the message: “3@8@1#”.

To return a value, Arduino will send in this format “[REQUEST_ID]@[VALUE]#”.

So, if we ask the distance with “3@8@5#”, Arduino will send the message “5@[VALUE]#”.

You can think “Why do I need to do it?”. Let me show you an example. Let’s say the the Android ask to read the ultrasonic value 5 times, run the delay and read it again twice. The bluetooth communication is asynchronous, so when the Android receives the value 30, for example, it’s necessary to know which call this value represents. We made 7 requests, so, to identify each request we use an unique id.

V - Arduino Code

The complete project will have less the 100 lines of code :) And the most important part, using the communication protocol explained in the previous step, we can use this robot with new projects, without editing the source code :)

Perfect, right? So, let’s see how the code works.

To code the project, we’re using .PNG Arduino Framework. You can read more about in this link: http://png-arduino-framework.readthedocs.org/

This framework will help us with objects to allow the control of each component. You can read the documentation for more details if necessary.

1) Creating the necessary objects

This first step is simple, we’ll just create each Arduino Object with the correct PIN value and run the setup(). Check the necessary code:

  

#include <SoftwareSerial.h>
#include "Bluetooth.h"
#include "Motor.h"
#include "Ultrasonic.h"

Ultrasonic *ult = new Ultrasonic(A5, A4); //TRIGGER_PIN, ECHO_PIN
Motor *motor = new Motor(6, 7, 5, 8, 9, 11); //IN1, IN2, ENA, IN3, IN4, ENB
Bluetooth *blue = new Bluetooth(2, 3); //RX PIN, TX PIN

void setup(){
	Serial.begin(9600);

	blue->setName("Timotheo"); //Set the bluetooth name
	blue->setPIN(6666); //set the PIN NUMBER
	blue->setMessageEnd('#'); //use the # as the end of the message
	blue->setupBluetooth();  //applay the changes to the bluetooth module

	motor->setSpeed(180); //set the motor speed, value from 0 to 255
}

2) Arduino loop()

The loop() is really simple. The Arduino robot only receives Bluetooth messages and analyze it.

Check the code bellow:

void loop(){
	String msg = blue->read();
	if(msg.length() > 1) //check the length of the message
		Serial.println(msg); //shows it on serial
		readMsg(msg); //analyze the message
	delay(20); //wait 20 ms
}

We just receive a message from bluetooth, show in the Serial and call the readMsg to analyze it.

3) readMsg()

This is the most complicated code in this post. If you want to understand how this function works, please make sure to read about the communication protocol. It’s commented to help you.

  
void readMsg(String msg){
	String SB, TB; //second byte and third byte, the parameters in the message
	int iSB, iTB;
	int i;
	switch (msg.charAt(0)) { //we read the first number to check the action
	    case '1'://not used in this tutorial. Set an Android PIN value
	      break;
	    case '2'://not used in this tutorial. Get an Android PIN value
	      break;

	    case '3': //call a method
	    	for(i = 2; i < msg.length(); i++){//we start at pos 2, because the msg[0] is 3 and msg[1] is '@'
	    		if(msg.charAt(i) == '#') //end of the message
	    			break;
	    		if(msg.charAt(i) == '@') //read the next parameter
	    			for(int k = i+1; k < msg.length(); k++){
	    				if(msg.charAt(k) == '#')
	    					break;
	    				TB += msg.charAt(k);
	    			}
	    		SB += msg.charAt(i);
	    	}
	    	iSB = SB.toInt();
	    	iTB = TB.toInt();
	    	callMethod(iSB, iTB); //we call the method sending the second and third value received
	    break;
	}
}

4) returnValue()

This method will send a value to the Android device using the communication protocol explained above.

void returnValue(int id, int value){
	char Id[5], Val[5], msg[1024];
	sprintf(Id, "%d", id);
	sprintf(Val, "%d", value);
	strcpy(msg, Id);
	strcat(msg, "@");
	strcat(msg, Val);
	strcat(msg, "#");

	blue->send(msg); //send the message in the format "ID@VALUE#"
}

5) callMethod()

And finally, we call the desired method.

void callMethod(int cod, int arg1){
	switch (cod) {
		case 1: motor->goFront(); break;
		case 2: motor->goRight(); break;
		case 3: motor->goRightStrong(); break;
		case 4: motor->goLeft(); break;
		case 5: motor->goLeftStrong(); break;
		case 6: motor->goBack(); break;
		case 7: motor->goStop(); break;
		case 8: returnValue(arg1, (int)ult->readDistanceCM()); break;
		case 9: delay(arg1); break;
		case 99: returnValue(1, 99); break;
	}
}

In the case 8 and case 99, we return an value using the REQUEST_ID. The case 99 just returns 1. We can use it just to know if the communication is ready to run a command, for example.

The code in this step of the tutorials can be found here.

That’s it. We finished the second part of the tutorial. In the next part we’ll code the Android app to send commands to Arduino with bluetooth, and then we’ll have finished this project :)

So, see you in the next post and thx for reading.

Aron Bordin.

Aron Bordin

Aron Bordin
Computer Science Student and AI researcher. Always coding something fun :)

[Tutorial] Developing Android Background Services

### Welcome!In this post, I'll show you how to develop background services on Android Studio. We'll see two type of services: `Service` a...… Continue reading