perseus_android_bluetooth_atmega_robot In a previous article, I've shown that it is possible to connect a bluetooth module to an ATMega micro controller via the UART serial interface and even further, discover it using a bluetooth enabled computer or smartphone.
The 9600bps serial link established, can than be used to exchange data.

Using an Android phone for this purpose is no exception. I will use it to control the Perseus 3 robot platform. What I'm doing is directly interfacing the Android with the ATMega microcontroller via the serial bluetooth link. So you can use this technology for other purposes than robots, since the ATMega has a large range of possible uses: control the light in your home using the Android phone, read various sensors and gather the data on the Android, and more.

Keep in mind that the technology presented here can easily be extended: instead of an Android phone you can use any bluetooth enabled programmable device (a Windows Mobile Smartphone, an iPhone, etc) and instead of this robot you can use any other hardware system. The idea is to show how far automation can go.


Note: Part 2 is available here: Android controlled robot – Part 2

Android Software

Using Bluetooth on Android is still problematic, meaning that you have access only to very basic functionality.
The PROs are that they are evolving, and improving, while keeping their platform simple and accessible. So I am confident Android will be in a short time a complete alternative for advanced applications.

To control Bluetooth on Android, there are two possibilities:
1) Rely on BlueZ and Native C code. You can do this either with the Android Tool-chain, or more comfortable, using JNI. Take a moment to read both my articles for a better understanding.
This approach works on all Android platforms.
2) Use the Bluetooth SDK that Google introduced in Android 2.0. It is incomplete, but will probably get better (soon?) and for Serial connections is enough. I will use this approach, but will also provide an example for BlueZ and JNI.

Bluetooth on Android using BlueZ and JNI
First you need to setup your software tools like presented here.
For this example, I will only show how to write C code for the BlueZ stack, and the JNI interface, so that you would be able to do a Bluetooth device discovery. This technique works on all older Android devices.
The interface is using TABs, one for Bluetooth Discovery and another one for controlling the ROBOT. The tabs are created dynamically, as presented in this article.
The discovery results are displayed in a listview. The listview is also created dynamically (no XML), using a simple technique presented here.
From the multitude of Bluetooth devices detected, the Robot is identified based on its Bluetooth Address, in my case 00:1D:43:00:E4:78 .
Here are some pictures with the result:

1 android JNI bluetooth discovery 2 android discover bluetooth atmega uart module 3 android bluetooth discovery

The code, both Java and C JNI is available here:
android bluetooth discovery sample (604KB)
If you want to recompile the Java part, please see this tutorial.
If you want to recompile the JNI C code, you will find this article useful.
The code defines an array of devices (BTDev BTDevs[];), then when the button is pressed, it calls the native (intDiscover) function to populate the array BTDevs, and using it , adds content to the Listview.

Bluetooth on Android using the Bluetooth SDK
To move forward with this project, we will skip the native BlueZ approach and use the Bluetooth SDK introduced with Android 2.0. So the code above is to be modified to do the discovery using the Android Bluetooth SDK. It will only work on Android 2.0 or newer.
So we delete the BTNative class, and of m_BT we will use m_BluetoothAdapter defined as BluetoothAdapter m_BluetoothAdapter;. However we're still keeping the BTDevs structure, to handle the discovered bluetooth devices.
To do the bluetooth discovery, we define two events:

  1.  
  2. // Register for broadcasts when a device is discovered
  3. IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
  4. this.registerReceiver(mReceiver, filter);
  5.  
  6. // Register for broadcasts when discovery has finished
  7. filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
  8. this.registerReceiver(mReceiver, filter);
  9.  

ACTION_FOUND is sent when a new device is discovered, and ACTION_DISCOVERY_FINISHED when the discovery process is complete.
Pressing the ROBOT entry in the list of the discovered devices, opens a socket for data exchange. The ROBOT sends sensor data and the Android sends commands for moving the ROBOT around, for turning on the lights, the laser pointer, etc.
Please note that before attempting to connect a serial bluetooth socket from code to the ROBOT, you will need to manually go to Android's Bluetooth Settings Panel, and pair the ROBOT Bluetooth device. For my BTModule, the pin code is 1234:

device07 device08 device11 device12

Again, this is an unforgivable limitation of the current Android Bluetooth SDK, and prohibits current applications from having full control over the device's functionality.
Being connected we are taken automatically to the "Control" TAB. In code we will need to obtain two handlers, one to incoming data, and one for outgoing data to manage the connection.
The "Control" TAB offers an interface that can be used to move the robot. Since Perseus 3 is a differential robot platform, we will need to control each side Forward and Backwards. So to move forward, we will have each side set to FORWARD. To move backwards, both must be set to BACKWARD, and finally to turn around, one side must be set FORWARD and the other BACKWARD. Exactly like in the case of a military tank.
For easier use the interface provides 4 buttons that support all movement.
device13
Download the Android Source code here:
android robot control (736KB)

The code currently only controls the robot. No sensor reading yet. I need to leave something for the next part of this article as well :-)

The ROBOT Microcontroller software

It's not enough to write code for the Android. I also had to write code for the ATMega8 controlling the ROBOT. This microcontroller has several functions:
- commanding the HBridges that control the powerful geared motors
- reading data from the sensors (PING Ultrasonic sensors, PIR sensors)
- commanding the robot LIGHTs
- commanding the laser pointer and other instruments
- interfacing the BLuetooth Radio Module via UART (TX/RX/TTL)

So I will try to keep things simple. I need to setup the 9600 baud rate with the Bluetooth Module then listen from commands comming via the Bluetooth serial socket. In this first version the commands are very simple:
character 'w' - moves forward, 'd'- moves right, 'a'-moves left, and 's' move backward.

  1.  
  2. int g_nMove = 0, g_nTurn = 0;
  3.  
  4. void uartRxHandler(unsigned char c)
  5. {
  6. char xs[255] = {0};
  7. sprintf(xs, "[%c]\n\r",c);
  8. uartSendBuffer(xs, strlen(xs));
  9.  
  10. if (c == 'w') g_nMove = 1;
  11. if (c == 's') g_nMove = -1;
  12. if (c == 'd') g_nTurn = -1;
  13. if (c == 'a') g_nTurn = 1;
  14. }
  15.  
  16. int main(void)
  17. {
  18. //general index
  19. int i=0;
  20. DDRB |= 0x1E;
  21. LEDInit();
  22. LEDSet(1);
  23.  
  24. timerInit(); // initialize the timer system
  25.  
  26. a2dInit(); // initialize analog to digital converter (ADC)
  27. a2dSetPrescaler(ADC_PRESCALE_DIV32); // configure ADC scaling
  28. a2dSetReference(ADC_REFERENCE_AVCC); // configure ADC reference voltage
  29.  
  30. //uart
  31. uartInit(); // initialize the UART (serial port)
  32. uartSetBaudRate(9600);// set the baud rate of the UART for our debug/reporting output
  33. uartSetRxHandler(uartRxHandler);
  34. uartSendBuffer("Serial on.\n\r",12);
  35. //main loop
  36. while(1)
  37. {
  38. delay_us(1000000);
  39. i++;
  40. if (i>255) i = 0;
  41. LEDSet(i%2); // flash the board led
  42.  
  43. int nPINGL = a2dConvert8bit(5); // info sensor PING front-left >0 means obstacle detected
  44. int nPINGR = a2dConvert8bit(4); // info sensor PING front-right >0 means obstacle detected
  45.  
  46. //PORT_ON(PORTB, 1);
  47. //PORT_ON(PORTB, 3);
  48.  
  49. if (g_nMove == 1)
  50. {
  51. PORT_ON(PORTB, 1);
  52. PORT_ON(PORTB, 3);
  53. delay_us(2600000);
  54. PORT_OFF(PORTB, 1);
  55. PORT_OFF(PORTB, 3);
  56. g_nMove = 0;
  57. }
  58. if (g_nMove == -1)
  59. {
  60. PORT_ON(PORTB, 2);
  61. PORT_ON(PORTB, 4);
  62. delay_us(2600000);
  63. PORT_OFF(PORTB, 2);
  64. PORT_OFF(PORTB, 4);
  65. g_nMove = 0;
  66. }
  67. if (g_nTurn == 1)
  68. {
  69. PORT_ON(PORTB, 1);
  70. PORT_ON(PORTB, 4);
  71. delay_us(1500000);
  72. PORT_OFF(PORTB, 1);
  73. PORT_OFF(PORTB, 4);
  74. g_nTurn = 0;
  75. }
  76. if (g_nTurn == -1)
  77. {
  78. PORT_ON(PORTB, 2);
  79. PORT_ON(PORTB, 3);
  80. delay_us(2000000);
  81. PORT_OFF(PORTB, 2);
  82. PORT_OFF(PORTB, 3);
  83. g_nTurn = 0;
  84. }
  85. }
  86. return 0;
  87. }
  88.  

Download the complete source code here:
ATMega8 Android ROBOBrain-1

To learn how to compile this code and to program the microcontroller, see this tutorial. As you can see, I've explained everything you need to know to achieve this project in a few easy steps.
mcu_1
Here's the Perseus-3 platform during code upload process (connected to my PC):

P1110200 atmega8 upload code robot

About part 2

This article needs to be continued. A better robot platform, better Android software, reading data from sensors (it's actually easy, but I already wasted one full day for this part only), better ROBOT ATmega software, etc, and not to forget, more pictures and videos.

EDIT: Here are some variants created by my readers

Bryan, from Singapore:, created a very nice Meccano robot that can be controlled with an Android phone:

Note: Part 2 is available here: Android controlled robot – Part 2

(Visited 167 times, 31 visits today)
facebooktwittergoogle_plusredditpinterestlinkedinmailfacebooktwittergoogle_plusredditpinterestlinkedinmail
Tagged on: