Bluemote – remote control of a 8051 robot with bluetooth

Pedro Vicente

About the author:

Pedro Vicente, 21 years old,  is a 3rd year Electrical Engineering student at Institutto Superior Tecnico (IST), Lisbon, Portugal. During the Summer of 2010 spent a month at ALIATRON as a trainee, when among other projects did the one being presented here.  His main interestes are obviously electronics and robotics. His hobby is to play music: he plays piano, and trombone. Pedro is also member of a choir group.

 Introduction

The aim of this project was to experiment with a control system using bluetooth communication, firstly with simple PC control, and then with web control, after setting up a webserver.

A practical example was used: a 8051 robot “Robo-51“, from Inex, and distributed in Portugal by Aliatron. The bluetooth device used was a serial type “ZX-Bluetooth“, also from Inex, and a product sold by Aliatron.

The Experimental Setup

– Robot-51, Inex
–  Zx-Bluetooth, Inex
–  Bluetooth Micro Adapter Class I,Sweex
–  BlueSoleil 5.4 (software)
–  Termite 2.4 (software)
–  SerialTerm (software)
–  XAMPP server (software)
–  RIDE 51 V6.1 compiler, Raissonance (software)
–  FLIP V2.2, programmer Atmel (software)

Robo-51

Robo-51 from Inex

ZX-Bluetooth

Serial Bluetooth “ZX-Bluetooth” from Inex

Bluetooth Micro Adapter

Class I Bluetooth Micro Adapter from Sweex

The Experiment Itself

An original library of “Robo-51” for infrared control was modified to interpret the data received from serial bluetooth device “ZX-Bluetooth”. The library named as remoteb.h, has the following code:


/*--------------------------------------------------------------------------*/

// Program             : Decode command from Bluetooth

// Description       : receive command from Bluetooth to control robot

// Filename            : remoteb.h

// C compiler         : RIDE 51 V6.1

// Adapted to bluetooth with baudrate 9600 bps by Pedro Vicente

/*--------------------------------------------------------------------------*/

sbit irm_data = P3^2;          // Define port input remote sensor

unsigned char ir_command=0;         // Define for buffer command from Easy remote

/*****************************************************************************/

/****************** Function Delay for baudrate 9600 *************************/

/*****************************************************************************/

void delay_baud9600()      {                              // Delay baudrate 9600 bps

unsigned int x,a;                                 // Keep for counter loop

for(x=0;x<1;x++) {

for(a=0;a<91;a++);              // Loop for delay 104 us  // inicially at 833 us

}

}

/*****************************************************************************/

/****************** Function Delay for baudrate 9600(for start bit) **********/

/*****************************************************************************/

void start_9600()  {                                            // Delay baudrate 9600 while start bit

unsigned int x,a;                                 // Keep for counter loop

for(x=0;x<1;x++) {

for(a=0;a<46;a++);              // Loop for delay 53us //inicially at 416 us

}

}

/*****************************************************************************/
/************* Service interrupt routine for receive command ******************/
/*****************************************************************************/
void service_ex0(void) interrupt 0 {
unsigned char i;   // Define for counter loop
if(irm_data==0) {   // Check start bit true?
  		start_9600();  		// Delay for start bit
  		for(i=0;i<8;i++)  {		// For loop count 8 time(for receive data 8 bit)
  			delay_baud9600(); 		// Delay for data 1 bit
  			ir_command = ir_command>>1;		// Shift data bit to right 1 time
  			if(irm_data)				// If data bit = high
  			ir_command = ir_command | 0x80;		// Config data bit = "1"
  		}
		delay_baud9600();				// Delay for stop bit
	}
}
/*****************************************************************************/
/************** Function read Command from Bluetooth ***********************/
/*****************************************************************************/
unsigned char get_remote(void) {
	return(ir_command);		// Return command
}
/*****************************************************************************/
/*********************** Function clear command ******************************/
/*****************************************************************************/
void clear_remote() {
	ir_command = 0;         // Clear command
}

/*****************************************************************************/
/*********************** Function initial for Bluetooth ********************/
/*****************************************************************************/
void remote_init(void) {
	irm_data = 1;   	// Configuration input P3.2
	EX0 = 1;        	// Enable External interrupt0
	IT0 = 1;         	 // Detect falling edge
	EA = 1;		// Enable interrupt all
}

Next a firmwware program in C was written for the 8051 microcontroller in “Robo-51”, named as act19_bl.c:


/*--------------------------------------------------------------------------*/

// Program: Remote control robot

// Description : Robot controlled by Bluetooth control

//Robot receive command  from bluetooth by serial communication at baudrate 9600 bps

// Filename: Bluemote.c

// C compiler: RIDE 51 V6.1

/*--------------------------------------------------------------------------*/

#include <C51ac2.h>                          // Header include register of T89C51AC2

#include <delay_robo51.h>              // Module function delay process

#include <dc_motor.h>                      // Module function drive DC motor

#include <remoteb.h>                        // Module function for remote

#include <sound_robo51.h>            // Module function drive sound

#include <lcd_robo51.h>                   // Module function LCD

#define pow 200                                  // Define constant for power drive DC motor

void run_fd(int time_spin) {

motor_fd(2,pow);                                // Motor channel 2 forward

motor_fd(1,pow);                                // Motor channel 1 forward

delay_ms(time_spin);                        // Delay time for robot drive forward

}

void run_bk(int time_spin) {

motor_bk(2,pow);                               // Motor channel 2 backward

motor_bk(1,pow);                               // Motor channel 1 backward

delay_ms(time_spin);                         // Delay time for robot drive backward

}

void turn_left(int time_spin) {

motor_fd(2,pow);                                // Motor channel 2 forward

motor_bk(1,pow);                               // Motor channel 1 backward

delay_ms(time_spin);                         // Delay time for robot spin turn left

}

void turn_right(int time_spin) {

motor_bk(2,pow);                               // Motor channel 2 backward

motor_fd(1,pow);                                // Motor channel 1 forward

delay_ms(time_spin);                         // Delay time for robot spin turn right

}

void main() {

beep();                                                  // Sound beep 1 time

remote_init();                                       // Initial remote

lcd_init();                                             // Initial Lcd

while(1)  {                                            // Infinite loop

switch(get_remote()) {       // Check command for receive

case 'a'  :run_bk(100);         // Drive robot backward when receive command "a"

clear_remote();     // Clear command

break;                    // Out from case

case 'b' : turn_right(100);                   // Turn right when receive command "b"

clear_remote();                    // Clear command

break;                                    // Out from case

case 'c' : turn_left(100);                      // Turn right when receive command "c"

clear_remote();                    // Clear command

break;                                    // Out from case

case 'd' : run_fd(100);                         // Turn right when receive command "d"

clear_remote();                    // Clear command

break;                                    // Out from case

case 's':  motor_stop(all);                  // robot stop

clear_remote();                    // Clear command

break;                                    // Out from case

default:  break;                                    // Out from case

}

}

For more details on the main program, plus programming the robot “Robo-51,” and many other applications for the robot, check the “Robo-51” manual  found at Inex’s online site. You will find there the other required libraries which will be needed to be included into the project.

We use the software RIDE from Raissonance to compile the above *.c file (plus the library *.h), and the Atmel’s software FLIP from Atmel to load the program into the 8051 microcontroller of “Robo-51”.

To test the program in 8051, Termite 2.4 and SerialTerm were used. Both programs are used to test serial communications in micrcontrollers, and were quite handy in this case. Commands were sent to the robot, by writing on the keyboard. (check below first part of the video)

Important Note:  Set serial ports with baudrate at 9600 bps as ZX-Bluetooth works only at this baud rate. In our case the serial port used was COM2.

The next step would be to make automatic the sending of commands, instead of writting the commands and pressing Click or ENTER. We used the following Visual Basic Scripts (VBS) to send the commands. This VBS  procedure was proposed by Bill Blanton in the GNT forum. These VBS send commands with ley letters “d”  for foward, “a” for backward, “c” for turning leftwards, “b” for turning rightwards and “s” for stopping.


/*--------------------------------------------------------------------------*/

// Program: Send letter to serial port

// Description: Send “d” to serial port to move foward

// Filename: fw.vbs

/*--------------------------------------------------------------------------*/

Set oShell = WScript.CreateObject("WScript.Shell")

oShell.Run("C:\r51\serialterm com2 9600")

WScript.Sleep(500) 'wait (0.5 seconds (# milliseconds))

oShell.Sendkeys "d"

oShell.Sendkeys"{ESC}"

 


/*--------------------------------------------------------------------------*/

// Program: Send letter to serial port

// Description: Send “a” to serial port to move backward

// Filename: bk.vbs

/*--------------------------------------------------------------------------*/

Set oShell = WScript.CreateObject("WScript.Shell")

oShell.Run ("C:\r51\serialterm com2 9600")

WScript.Sleep(500) 'wait (0.5 seconds (# milliseconds))

oShell.Sendkeys "a"

oShell.Sendkeys"{ESC}"

 


/*--------------------------------------------------------------------------*/

// Program: Send letter to serial port

// Description: Send “b” to serial port to turn rigth

// Filename: rg.vbs

/*--------------------------------------------------------------------------*/

Set oShell = WScript.CreateObject("WScript.Shell")

oShell.Run ("C:\r51\serialterm com2 9600")

WScript.Sleep(500) 'wait (0.5 seconds (# milliseconds))

oShell.Sendkeys "b"

oShell.Sendkeys"{ESC}"

 


/*--------------------------------------------------------------------------*/

// Program: Send letter to serial port

// Description: Send “c” to serial port to turn left

// Filename: lf.vbs

/*--------------------------------------------------------------------------*/

Set oShell = WScript.CreateObject("WScript.Shell")

oShell.Run ("C:\r51\serialterm com2 9600")

WScript.Sleep(500) 'wait (0.5 seconds (# milliseconds))

oShell.Sendkeys "c"

oShell.Sendkeys"{ESC}"

 


/*--------------------------------------------------------------------------*/

// Program: Send letter to serial port

// Description: Send “s” to serial port to stop

// Filename: st.vbs

/*--------------------------------------------------------------------------*/

Set oShell = WScript.CreateObject("WScript.Shell")

oShell.Run ("C:\r51\serialterm com2 9600")

WScript.Sleep(500) 'wait (0.5 seconds (# milliseconds))

oShell.Sendkeys "s"

oShell.Sendkeys"{ESC}"

Having achieved PC control of  “Robo-51”, a web server was setup in order to control de robot though Internet. The Internet control of “Robo-51” was achieved with an approach based on published work here Internet Control of a Picaxe by Tayeb Habib.

The main server

A Windows-based XAMPP server was installed in a PC. The server was hooked to a local network with a fixed local IP. The application being situated in a network that had no fixed public IP, DynDNS services were used. The router routes all external demands to the local fixed IP.

Windows XP and later do not allow easy RS232 control through Internet. To  overcome such a blockage, RS232 control was done through DOS, using SerialTerm as mentioned above. The VB scripts of above were run in php, and used to command “Robo-51”. All of following files were placed in c:\xampp\htdocs

index.php

<? php
echo "<head><title>Internet Control of a 8051 Robot</title></head>
<body>
<center>
<font face=\"arial, sans-serif\" color=>
<h2 align='center'><font color=\"#4992BB\">Internet Control of a 8051 Robot</font></h2>
<hr align='center' size=\"4\" color=\"#4992BB\"><center>
<TABLE WIDTH=150 BORDER=0 CELLPADDING=0>
<TR> <TH COLSPAN=3><font face=\"arial, verdana\" color=\"#4992BB\">Bluemote</font></TH> </TR>
<TR> <TD></TD>      <TD><a href='processing.php?action=fw'>
<img src='forw.gif' border='0'></a></TD> <TD></TD>   </TR>
<TR> <TD><a href='processing.php?action=rg'> <img src='right.gif' border='0'></a></TD>
<TD> <a href='processing.php?action=st'><img src='stop.gif' border='0'></TD>
<TD><a href='processing.php?action=lf'> <img src='left.gif' border='0'></a></TD></TR>
<TR> <TD></TD>  <TD><a href='processing.php?action=bk'>
<img src='back.gif' border='0'></a></TD> <TD></TD></TR>
</TABLE></center>
<hr align='center' size=\"4\" color=\"#4992BB\">

</center>
</body>

processing.php


<?php

//check the GET actions variable to see if something needs to be done

if (isset($_GET['action'])) {
//Action has been requested

if ($_GET['action'] == "fw") {

$page = "index.php";

header("Refresh: 2; URL=\"" . $page . "\"");

exec ('C:\r51\fw.vbs');

echo "
<hr align='center' size=\"4\" color=\"#4992BB\"><center>
<font face=\"arial, sans-serif\"><b>Moving Forward</b></font>";

}

else if ($_GET['action'] == "bk") {

$page = "index.php";

header("Refresh: 2; URL=\"" . $page . "\"");

exec ('C:\r51\bk.vbs');

echo "
<hr align='center' size=\"4\" color=\"#4992BB\"><center>
<font face=\"arial, sans-serif\"><b>Moving Backward</b></font>";
}
else if ($_GET['action'] == "st") {

$page = "index.php";

header("Refresh: 2; URL=\"" . $page . "\"");

exec ('C:\r51\st.vbs');

echo "
<hr align='center' size=\"4\" color=\"#4992BB\"><center>
<font face=\"arial, sans-serif\"><b>Stopping...</b></font>";
}
else if ($_GET['action'] == "rg") {

$page = "index.php";

header("Refresh: 2; URL=\"" . $page . "\"");

exec ('C:\r51\rg.vbs');

echo "
<hr align='center' size=\"4\" color=\"#4992BB\"><center>
<font face=\"arial, sans-serif\"><b>Turning Right</b></font>";
}
else if ($_GET['action'] == "lf") {

$page = "index.php";

header("Refresh: 2; URL=\"" . $page . "\"");

exec ('C:\r51\lf.vbs');

echo "
<hr align='center' size=\"4\" color=\"#4992BB\"><center>
<font face=\"arial, sans-serif\"><b>Turning Left</b></font>";
}
}
?>

Please note that *.vbs files must be in c:\r51  as can be seen in above VB scripts.

Finally the XAMPP server must be tested pointing the browser to http://localhost. If all is OK the server can be put online.

Hull report is available at:

Bluemote_English.pdf (18MB)

A simulation of the application (useful to see how the appplication will look like) can be viewed at:

http://aliatron.dynalias.com/r51 (now switched off!!)

The following video shows the application with “Robo-51”:

Acknowledgments

A special thank you is due to Tayeb Habib owner of Aliatron and my supervisor for Summer traineeship at that portuguese company. Also I thank my former workmate at Aliatron, Raquel, for all the support and her welcome spirit.

Published in RedAcacia by Tayeb

Advertisements

About Tayeb

Electronics engineer, part-time webmaster and owner of "Aliatron", a tech-oriented company registered in Portugal and Mozambique.
This entry was posted in Electronic Projects, Internet of Things, Programming, Robotic Projects and tagged , , , , , , . Bookmark the permalink.

2 Responses to Bluemote – remote control of a 8051 robot with bluetooth

  1. Pingback: Bluemote – A Virtual Gamepad for Bluetooth Control of a Robot | RedAcacia

  2. Pingback: Controlling a robot with bluetooth-enabled cell phone | RedAcacia

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s