19 March 2013

Bluetooth Android Processing 2

PART TWO

If you happened to land on this page and missed PART ONE, I would advise you go back and read that section first. You may get lost coming in half way through the story. This is what you'll find in part one.
  • Downloading and setting up the Android SDK
  • Downloading the Processing IDE
  • Setting up and preparing the Android device
  • Running through a couple of Processing/Android sketches on an Andoid phone.
In the last sketch we checked to see if Bluetooth was enabled, if not, we then asked for permission to turn it on. The screen would then display a different colour depending on the Bluetooth state. So let's keep on going,


ToastMaster - the master of all Toasts

I will now introduce you to Toast. What does "Toast" have to do with programming ? Toast is used by Android to quietly display little messages on the screen.
Have a look here for a a quick introduction to Toast, otherwise have a look at the Android Developers Toast information.

I will be creating my own method that relies on Toast to make the process of displaying messages easier. I have named this method: "ToastMaster".
A word of warning. Calling ToastMaster from within setup() will cause errors in the DiscoverBluetooth sketch (further down this page).
This will not happen in every sketch, but the Discoverbluetooth sketch has subActivities which may cause some sort of conflict.. I did warn you.

Here is a quick look at my ToastMaster method (no need to compile this code):
1
2
3
4
5
6
7
8
/* My ToastMaster function to display a messageBox on the screen */
void ToastMaster(String textToDisplay){
Toast myMessage = Toast.makeText(getApplicationContext(),
textToDisplay,
Toast.LENGTH_LONG);
myMessage.setGravity(Gravity.CENTER, 0, 0);
myMessage.show();
}

Here is a breakdown of what this is doing:
  • Toast.makeText() - is used to construct the message to be displayed. 
  • getApplicationContext() - gets a handle on the Application
  • textToDisplay - is obvious, this is the text you want to display.
  • Toast.LENGTH_LONG - is how long you want the message to displayed for. (or LENGTH_SHORT)
  • setGravity() - sets the message position on the screen, in this case I have chosen to center the text.
  • show() - is used to actually show the message.

Broadcast Receivers : Looking out for Bluetooth devices
To listen/look out for any Bluetooth devices that are within range, we need to create and  register a Broadcast receiver.
When registering a BroadcastReceiver, you will need to tell the program what it is you are looking / listening out for. In our case we want to listen out for occasions whereby a Bluetooth device is FOUND.  This is represented by:
If a BluetoothDevice is found, then the designated BroadcastReceiver will be called. We make our own BroadcastReceiver in order to perform a task such as displaying the name of the discovered device on the phone. However, before you will find anything, you have to start Discovering. This is done by calling the startDiscovery() method of the default Bluetooth adapter.

Here are the relevant components:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
BroadcastReceiver myDiscoverer =
new myOwnBroadcastReceiver();

//Within Setup()
if (bluetooth.isEnabled()) {
registerReceiver(myDiscoverer,
new IntentFilter(BluetoothDevice.ACTION_FOUND));
if (!bluetooth.isDiscovering()){
bluetooth.startDiscovery();
}
}


/* This BroadcastReceiver will display discovered Bluetooth devices */
public class myOwnBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String discoveredDeviceName = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);

//Display the name of the discovered device
ToastMaster("
Discovered: " + discoveredDeviceName);
}
}





Discovering Bluetooth devices: putting it all together

You will notice that in the following sketch, we have to import a whole lot more. Which is why I have tried to break it down into bite size chunks, to help you digest it all. Now we will put it all together into a sketch which will
  • ask to turn Bluetooth ON if it happens to be disabled.
  • If you don't turn on Bluetooth, it will tell you that you need to turn it on.
  • If you turn on bluetooth (or if it was already on), it will try to discover any bluetooth devices in range. These devices need to be made "discoverable" before running this sketch.
  • If the phone finds a bluetooth device, it will display the name of the device and will change the background screen colour to GREEN.
Android/Processing Sketch 4: DiscoverBluetooth
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* DiscoverBluetooth: Written by ScottC on 18 March 2013 using 
Processing version 2.0b8
Tested on a Samsung Galaxy SII, with Android version 2.3.4
Android ADK - API 10 SDK platform */


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.Toast;
import android.view.Gravity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;

boolean foundDevice=
false; //When this is true, the screen turns green.

//Get the default Bluetooth adapter
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();


/*The startActivityForResult() within setup() launches an
Activity which is used to request the user to turn Bluetooth on.
The following onActivityResult() method is called when this
Activity exits. */

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode==0){
if(resultCode == RESULT_OK){
ToastMaster("
Bluetooth has been switched ON");
}
else {
ToastMaster("
You need to turn Bluetooth ON !!!");
}
}
}



/* Create a Broadcast Receiver that will later be used to
receive the names of Bluetooth devices in range. */

BroadcastReceiver myDiscoverer =
new myOwnBroadcastReceiver();



void setup(){
orientation(LANDSCAPE);
/*IF Bluetooth is NOT enabled, then ask user permission to enable it */
if (!bluetooth.isEnabled()) {
Intent requestBluetooth =
new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(requestBluetooth, 0);
}

/*If Bluetooth is now enabled, then register a broadcastReceiver to report any
discovered Bluetooth devices, and then start discovering */

if (bluetooth.isEnabled()) {
registerReceiver(myDiscoverer,
new IntentFilter(BluetoothDevice.ACTION_FOUND));
//Start bluetooth discovery if it is not doing so already
if (!bluetooth.isDiscovering()){
bluetooth.startDiscovery();
}
}
}



void draw(){
//Display a green screen if a device has been found
if(foundDevice){
background(10,255,10);
}
}



/* This BroadcastReceiver will display discovered Bluetooth devices */
public class myOwnBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String discoveredDeviceName = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);

//Display the name of the discovered device
ToastMaster("
Discovered: " + discoveredDeviceName);

//Change foundDevice to true which will make the screen turn green
foundDevice=
true;
}
}



/* My ToastMaster function to display a messageBox on the screen */
void ToastMaster(String textToDisplay){
Toast myMessage = Toast.makeText(getApplicationContext(),
textToDisplay,
Toast.LENGTH_LONG);
myMessage.setGravity(Gravity.CENTER, 0, 0);
myMessage.show();
}


Upgrading the Broadcast Receiver : More Device info

Ok, we have the device name. But what other information can we collect from the device? You can call
This will return the discovered BluetoothDevice, which can then be probed to find the following information.
  • .getName()   =  Which is a different way of getting the name of the BluetoothDevice.
  • .getAddress() = Returns the hardware address of the BluetoothDevice.  eg. "00:11:22:AA:BB:CC"
  • .getBondState() = Returns an integer which describes the BondState of the BluetoothDevice
These are the three possible BondStates 
Here is an updated version of the custom BroadcastReceiver class (myOwnBroadcastReceiver) from the DiscoverBluetooth sketch described above.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/* This BroadcastReceiver will display discovered Bluetooth devices */
public class myOwnBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

//Display the name of the discovered device
String discoveredDeviceName = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
ToastMaster("
Discovered: " + discoveredDeviceName);

//Display more information about the discovered device
BluetoothDevice discoveredDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
ToastMaster("
getAddress() = " + discoveredDevice.getAddress());
ToastMaster("
getName() = " + discoveredDevice.getName());

int bondyState=discoveredDevice.getBondState();
ToastMaster("
getBondState() = " + bondyState);

String mybondState;
switch(bondyState){
case 10: mybondState="BOND_NONE";
break;
case 11: mybondState="BOND_BONDING";
break;
case 12: mybondState="BOND_BONDED";
break;
default: mybondState="INVALID BOND STATE";
break;
}
ToastMaster("
getBondState() = " + mybondState);

//Change foundDevice to true which will make the screen turn green
foundDevice=
true;
}
}

If you replace the old version of  myOwnBroadcastReceiver with this one, you will know a little bit more about the devices discovered.


Connecting to the Bluetooth Device:
While we now have more information about the Bluetooth device, we don't really need it, and we will get rid of it by the end of the tutorial, however we will keep it here for the time being. In the next updated sketch we will be making a connection to the discovered device, and turning the background purple when the connection is made. In order to do this we will need to
  • Create a boolean variable to hold the connection status
  • Create and register a new BroadcastReceiver to notify us when a connection broadcast action has been received.
  • Create a new thread to handle the connection
  • Change the background screen colour when a successful connection has been made
First we need the boolean to hold the connection status:
  • boolean BTisConnected=false;
When the boolean is true, the screen will change to purple. The draw() method will be updated to accommodate this requirement.
Next we will create and register a new BroadcastReceiver, it is created using this:
  • BroadcastReceiver checkIsConnected = new myOwnBroadcastReceiver();
This broadcastreceiver will be used to notify us when a connection has been made. Therefore we need to register the (BluetoothDevice.ACTION_ACL_CONNECTED)
action with the BroadcastReceiver in the following way
  • registerReceiver(checkIsConnected, new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED));
We will need to update myOwnBroadcastReceiver() to be able to differentiate beween this action and the (BluetoothDevice.ACTION_FOUND) action used already. This is done by first getting the action from the intent variable described in the onReceive() method within myOwnBroadcastReceiver().
  • String action=intent.getAction();
We can differentiate the two actions using the following simplified code in myOwnBroadcastReceiver:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class myOwnBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();

//Notification that BluetoothDevice is FOUND
if(BluetoothDevice.ACTION_FOUND.equals(action)){
foundDevice=
true; //Change the screen to green
}

//Notification if bluetooth device is connected
if(BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)){
BTisConnected=
true; //turn screen purple
}
}
}

Now that we can be notified about the connection made to the Bluetooth Device, lets go through the code required to make the connection. We will only connect if we have actually discovered a device, so we will put this code within the FOUND section of myOwnBroadcastReceiver.

1
2
3
4
5
6
7
8
 //Connect to the discovered bluetooth device (SeeedBTSlave)
if(discoveredDeviceName.equals("SeeedBTSlave")){
unregisterReceiver(myDiscoverer);
ConnectToBluetooth connectBT =
new ConnectToBluetooth(discoveredDevice);
//Connect to the the device in a new thread
new Thread(connectBT).start();
}
}

We use the discoveredDeviceName variable to specifically target the Bluetooth device we wish to connect to. We then unregister the myDiscoverer BroadcastReceiver because we are going to stop discovering before we connect to the Bluetooth Device, plus if you don't, it will generate an error. We then pass our discovered device to a new Thread to connect to that device in the background.  The class used to handle the connection is the "ConnectToBluetooth" class as displayed below:

We will cancelDiscovery() on the bluetooth Adapter to prevent a slow connection.
Also we will need to use a specific UUID as per below:
  • private UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
I have tried changing the UUID, but changing it to a different number prevented it from establishing a connection.
Before you can connect to the Bluetooth shield you need to use the UUID to create a BluetoothSocket.
  • mySocket = btShield.createRfcommSocketToServiceRecord(uuid);
Once you have the socket, you can then try to connect using:
  • mySocket.connect();
Make sure you have some way of closing the socket, this is done in the cancel() method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class ConnectToBluetooth implements Runnable{
private BluetoothDevice btShield;
private BluetoothSocket mySocket = null;
private UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

public ConnectToBluetooth(BluetoothDevice bluetoothShield) {
btShield = bluetoothShield;
try{
mySocket = btShield.createRfcommSocketToServiceRecord(uuid);
}
catch(IOException createSocketException){
//Problem with creating a socket
}
}

@Override
public void run() {
/* Cancel discovery on Bluetooth Adapter to prevent slow connection */
bluetooth.cancelDiscovery();

try{
/*Connect to the bluetoothShield through the Socket. This will block
until it succeeds or throws an IOException */

mySocket.connect();
}
catch (IOException connectException){
try{
mySocket.close();
//try to close the socket
}
catch(IOException closeException){
}
return;
}
}

/* Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mySocket.close();
}
catch (IOException e){
}
}
}

The major structure of this code was made possible using the following site:
http://jayxie.com/mirrors/android-sdk/guide/topics/wireless/bluetooth.html

And the following sites were also useful in getting some of the information I needed:
http://stackoverflow.com/questions/13238600/use-registerreceiver-for-non-activity-and-non-service-class
http://developer.android.com/guide/topics/connectivity/bluetooth.html


While I have described all the major components required to connect to the Bluetooth Device, I will now put it all together in a new and updated version of the "DiscoverBluetooth" Android/Processing sketch and call it "ConnectBluetooth". There is some additional code in this sketch which I did not specifically go through, for example, the code used to turn the background to purple in the draw() method. Look out for that one. Anyway, read through the following code, and make sure that you understand what each section is doing.

Android/Processing Sketch 5: ConnectBluetooth
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/* ConnectBluetooth: Written by ScottC on 18 March 2013 using 
Processing version 2.0b8
Tested on a Samsung Galaxy SII, with Android version 2.3.4
Android ADK - API 10 SDK platform */


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.Toast;
import android.view.Gravity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;

import java.util.UUID;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.util.Log;

import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;

boolean foundDevice=
false; //When true, the screen turns green.
boolean BTisConnected=
false; //When true, the screen turns purple.



//Get the default Bluetooth adapter
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();


/*The startActivityForResult() within setup() launches an
Activity which is used to request the user to turn Bluetooth on.
The following onActivityResult() method is called when this
Activity exits. */

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode==0){
if(resultCode == RESULT_OK){
ToastMaster("
Bluetooth has been switched ON");
}
else {
ToastMaster("
You need to turn Bluetooth ON !!!");
}
}
}



/* Create a BroadcastReceiver that will later be used to
receive the names of Bluetooth devices in range. */

BroadcastReceiver myDiscoverer =
new myOwnBroadcastReceiver();

/* Create a BroadcastReceiver that will later be used to
identify if the Bluetooth device is connected */

BroadcastReceiver checkIsConnected =
new myOwnBroadcastReceiver();


void setup(){
orientation(LANDSCAPE);
/*IF Bluetooth is NOT enabled, then ask user permission to enable it */
if (!bluetooth.isEnabled()) {
Intent requestBluetooth =
new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(requestBluetooth, 0);
}

/*If Bluetooth is now enabled, then register a broadcastReceiver to report any
discovered Bluetooth devices, and then start discovering */

if (bluetooth.isEnabled()) {
registerReceiver(myDiscoverer,
new IntentFilter(BluetoothDevice.ACTION_FOUND));
registerReceiver(checkIsConnected,
new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED));

//Start bluetooth discovery if it is not doing so already
if (!bluetooth.isDiscovering()){
bluetooth.startDiscovery();
}
}
}



void draw(){
//Display a green screen if a device has been found,
//Display a purple screen when a connection is made to the device
if(foundDevice){
if(BTisConnected){
background(170,50,255);
// purple screen
}
else {
background(10,255,10);
// green screen
}
}
}



/* This BroadcastReceiver will display discovered Bluetooth devices */
public class myOwnBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
ToastMaster("
ACTION:" + action);

//Notification that BluetoothDevice is FOUND
if(BluetoothDevice.ACTION_FOUND.equals(action)){
//Display the name of the discovered device
String discoveredDeviceName = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
ToastMaster("
Discovered: " + discoveredDeviceName);

//Display more information about the discovered device
BluetoothDevice discoveredDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
ToastMaster("
getAddress() = " + discoveredDevice.getAddress());
ToastMaster("
getName() = " + discoveredDevice.getName());

int bondyState=discoveredDevice.getBondState();
ToastMaster("
getBondState() = " + bondyState);

String mybondState;
switch(bondyState){
case 10: mybondState="BOND_NONE";
break;
case 11: mybondState="BOND_BONDING";
break;
case 12: mybondState="BOND_BONDED";
break;
default: mybondState="INVALID BOND STATE";
break;
}
ToastMaster("
getBondState() = " + mybondState);

//Change foundDevice to true which will make the screen turn green
foundDevice=
true;

//Connect to the discovered bluetooth device (SeeedBTSlave)
if(discoveredDeviceName.equals("SeeedBTSlave")){
ToastMaster("
Connecting you Now !!");
unregisterReceiver(myDiscoverer);
ConnectToBluetooth connectBT =
new ConnectToBluetooth(discoveredDevice);
//Connect to the the device in a new thread
new Thread(connectBT).start();
}
}

//Notification if bluetooth device is connected
if(BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)){
ToastMaster("
CONNECTED _ YAY");
BTisConnected=
true; //turn screen purple
}
}
}

public class ConnectToBluetooth implements Runnable{
private BluetoothDevice btShield;
private BluetoothSocket mySocket = null;
private UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

public ConnectToBluetooth(BluetoothDevice bluetoothShield) {
btShield = bluetoothShield;
try{
mySocket = btShield.createRfcommSocketToServiceRecord(uuid);
}
catch(IOException createSocketException){
//Problem with creating a socket
}
}

@Override
public void run() {
/* Cancel discovery on Bluetooth Adapter to prevent slow connection */
bluetooth.cancelDiscovery();

try{
/*Connect to the bluetoothShield through the Socket. This will block
until it succeeds or throws an IOException */

mySocket.connect();
}
catch (IOException connectException){
try{
mySocket.close();
//try to close the socket
}
catch(IOException closeException){
}
return;
}
}

/* Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mySocket.close();
}
catch (IOException e){
}
}
}


/* My ToastMaster function to display a messageBox on the screen */
void ToastMaster(String textToDisplay){
Toast myMessage = Toast.makeText(getApplicationContext(),
textToDisplay,
Toast.LENGTH_SHORT);
myMessage.setGravity(Gravity.CENTER, 0, 0);
myMessage.show();
}


The Arduino Sketch

Most of the Android/Processing code used so far has depended on a Bluetooth Device being discoverable. Our ultimate aim it to connect to a Bluetooth Shield on an Arduino UNO or compatible board such as the Freetronics Eleven. The following sketch was essentially taken from one of my previous posts (here), however, I have stripped it down to the bear essentials so that it will only be discoverable, and will not send or receive data. I will provide this functionality later. I just wanted to show you the essential bits to establish the connection to the Shield.

ARDUINO Sketch 1: Bluetooth Pair and Connect
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/* This project combines the code from a few different sources.
This project was put together by ScottC on the 22/03/2013
http://arduinobasics.blogspot.com/

Bluetooth slave code by Steve Chang - downloaded from :
http://www.seeedstudio.com/wiki/index.php?title=Bluetooth_Shield

This sketch does nothing more than setup bluetooth
connection capabilities. It does not send or receive data.

*/


#include <SoftwareSerial.h>
//Software Serial Port

#define RxD 6
// This is the pin that the Bluetooth (BT_TX) will transmit to the Arduino (RxD)
#define TxD 7
// This is the pin that the Bluetooth (BT_RX) will receive from the Arduino (TxD)

#define DEBUG_ENABLED 1

SoftwareSerial blueToothSerial(RxD,TxD);

/*----------------------SETUP----------------------------*/
void setup() {
Serial.begin(9600);
// Allow Serial communication via USB cable to computer (if required)
pinMode(RxD, INPUT);
// Setup the Arduino to receive INPUT from the bluetooth shield on Digital Pin 6
pinMode(TxD, OUTPUT);
// Setup the Arduino to send data (OUTPUT) to the bluetooth shield on Digital Pin 7
pinMode(13,OUTPUT);
// Use onboard LED if required.
setupBlueToothConnection();
//Used to initialise the Bluetooth shield
}

/*----------------------LOOP----------------------------*/
void loop() {
digitalWrite(13,LOW);
//Turn off the onboard Arduino LED
}


//The following code is necessary to setup the bluetooth shield ------copy and paste----------------
void setupBlueToothConnection()
{
blueToothSerial.begin(38400);
//Set BluetoothBee BaudRate to default baud rate 38400
blueToothSerial.print("
\r\n+STWMOD=0\r\n"); //set the bluetooth work in slave mode
blueToothSerial.print("
\r\n+STNA=SeeedBTSlave\r\n"); //set the bluetooth name as "SeeedBTSlave"
blueToothSerial.print("
\r\n+STOAUT=1\r\n"); // Permit Paired device to connect me
blueToothSerial.print("
\r\n+STAUTO=0\r\n"); // Auto-connection should be forbidden here
delay(2000);
// This delay is required.
blueToothSerial.print("
\r\n+INQ=1\r\n"); //make the slave bluetooth inquirable
Serial.println("
The slave bluetooth is inquirable!");
delay(2000);
// This delay is required.
blueToothSerial.flush();
}




Please make sure to setup the Bluetooth jumpers as per the picture below, otherwise you will not have much luck with the sketch above.

Jumpers on Shield




Well that brings us to the end of part TWO.

PART THREE
In part three we will attempt to actually send some data from the Android phone to the Arduino via Bluetooth, and vice versa. This will be when the real fun starts.


or GO BACK
Click on the link if you missed PART ONE

45 comments:

  1. Hi man! First of all, congratulation for your blog!
    Secondly, sorry for my english, but i'm french :)

    I'm following your tutorial, it learn me a lot.
    I'm at the part 2, but i'm stuck. About "to know more about material" (name, MAC adresse etc...)

    At this point, when I compile, Android apps get's automatically closed...

    ReplyDelete
    Replies
    1. Hi Ginizi
      Have a look at part three of the tutorial. I explain briefly how to debug your code using adb.exe. Find this program on your hard drive and then create a shortcut to this adb.exe program on your desktop. Right click the newly created shortcut and select properties. Change the target to "c:\......\Android\android-sdk\platform-tools\adb.exe" logcat *:E. Once you get your shortcut working. You can doubleclick on the shortcut immediately after getting an Error from running your Android/Processing program. This may help identify where the program is failing

      Delete
    2. Hi Scott, thanks for your answer, I will check soon as possible.

      I'm very impressive about your work, really. I want know, how old are you, what is your studies's level? You told "Basic Arduino", I think it's not basic at all... To understand all you mean, we need know "C", JAVA and to finish some basics of android.

      I work actually on a project, a robotic turret, i create an App on my computer that controls. I use processing IDE, and it work great!

      Recently, I thought about migrate Apps on android to control it with my
      phone with bluetooth. I was fall on your blog yesterday.

      In real, I just want send some datas on my arduino to control my turret,
      is for you the good way to follow?

      Delete
  2. Thanks for the advice and good information, very specific in your instruction.
    I have another question about that, what its the way if I want to use in a device with Android 2.3, because we try and doesnt sync, just with the ver 4.0

    ReplyDelete
    Replies
    1. All my examples have worked with Android v2.3.4 on my Samsung Galaxy SII. So not sure why you are not getting connectivity.
      See if you can successfully connect using this tutorial (yes/no), and then come back to this one and identify using the methods I described for Ginizi (above), where the program is going wrong for you.

      Regards Scott

      Delete
  3. Friend thanks for your help, the connection with Bluetooth SPP app is successful, I see that not every app has no connection, I see that sending data from my pc and get my smarthphone, but I can not do otherwise, appears sent but on the screen of my pc does not show the data sent from the smartphone, which I can do?

    my smarthphones is SONY XPERIA PLAY whit android 2.3.4

    ReplyDelete
    Replies
    1. Hi LUIS,
      Which specific sketch are you having problems with? And did you get any of the other sketches to work as expected? This tutorial is progressive so it will help to know where it started to go wrong for you.

      Also what kind of Arduino board/Bluetooth shield are you using?

      It sounds strange that you can send data from the Arduino to the Android device but not the other way around.

      Scott

      Delete
  4. Hi;
    thanks a lot about your excellent tutorial,
    I'm trying to make my own home automation in my house using Android..
    when trying to make test sketch 5 received" error from inside the android tools,check the console." taskdef class com.android.ant.setuptask cannt be found

    note: my phone samsung galaxy y pro

    ReplyDelete
    Replies
    1. Hi Khalil,

      Was sketch 5 the first sketch you tried to run, or have you started from the beginning? Which version of ADK are you using? I have also heard that sometimes the location of the JAVA classpath may cause some issues, but not 100% sure.

      And have you tried the troubleshooting tips that I provided for Ginizi (above) ? And make sure that you are not trying to do this in the Emulator, because the Emulator does not have Bluetooth.

      Scott

      Delete
  5. Scott C,

    Thank you very much from this tutorial, this is very helpful!

    I just want to verify some things. I noticed something, could you please elaborate on this. The thing is, I noticed that when you started running the sketch when your bluetooth was off, the sketch will request that you turn it on. The problem is upon turning on or pressing yes, nothing happened. It doesn't seem to discover any device, but when I close the sketch and run it again (not turning the bluetooth back off), it does discover other devices. This is fine though technically, I could just do that again, but I feel like cheating that way.

    I tried to gawk for a second, then I tried putting the registerReceiver() and bluetooth.startDiscovery() inside the if(resultCode==RESULT_OK) clause, and it does remedied my concern.

    I just want to ask, after calling the overridden method onActivityResult() when does it continue execution? does it continue on the point where startForActivity() method finished? Or does it start running setup again? Or it starts running the draw() method? according to the Activity Life Cycle on the android developers documentation, activities are being stacked on top of another when a new activity was called. when a new activity is called, the recent activity prior to new activity will be stopped (or paused? it does also say on the documentation that if the new activity don't occupy the whole screen, it just pauses, like what the request for bluetooth is doing, Im guessing in this particular situation, paused?) then the onActivityResult() will be executed when that foreground activity closes. When does it return execution?

    Could you correct me if i am wrong? I'm kind of new to this android and reading documentations, massive documentations. Thank you, I just can't sleep without knowing, I may doubt myself in the future if I just continued this without my questions being answered.

    Thank you very much. More power. Sorry for the long post.
    yev

    ReplyDelete
    Replies
    1. Hi Yev - sorry for the delayed reply. Hope you didn't lose too much sleep in the mean-time. I am new to this android/arduino thing aswell, and I think this question is best put to the forums... I don't enough time at the moment - and I don't want you to lose more sleep. Really sorry - but when I get more time - I might come back to your question and see if I can provide you with an answer.
      Good luck

      Delete
    2. Hey yev, are you also working on the android <-> BLE project? I got some problems here...

      I am trying to build an Android App(4.3) that can communicate with UNO+BLE Shield via bluetooth. A demo of UNO+BLE <=> IOS App is officially provided (http://redbearlab.com/bleshield/). The code on UNO+BLE also provided on that page. Yet I am trapped in searching device. My app can discover BT from tablet or other phones. But it cant find UNO+BLE. I tried your arduino sketch too(http://arduinobasics.blogspot.com/2013/03/arduinobasics-bluetooth-android.html). But still doesnt work...I'm a little bit confused now.

      Delete
  6. I don't really understand how you setup bluetooth on BLE in your sketch1. It seems you use the SoftwareSerial file. Yet does the serial refer to the com with PC via USB cable? How does it relate to the bt on BLE?

    My Email is sctracy03@gmail.com......Really need your help here.

    ReplyDelete
  7. Hi, i think this tutorial is brilliant and is the best i come across so far for arduino <> andriod. I have followed all the tutorial and attempted all the sketches and have had no problems until sketch 5 (connect bluetooth) where i got a "application stopped unexpectedly" error on the android device and the following output on the processing console when trying it in the emulator:

    FATAL EXCEPTION: Animation Thread
    java.lang.NullPointerException
    at processing.test.discoverbluetooth3.DiscoverBluetooth3.setup(DiscoverBluetooth3.java:94)
    at processing.core.PApplet.handleDraw(Unknown Source)
    at processing.core.PGraphicsAndroid2D.requestDraw(Unknown Source)
    at processing.core.PApplet.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:1019)

    smartphone is huawei X3 with android 2.3.3
    bluetooth shield is same as that in tutorial

    Any help is much appreciated.

    Cheers,

    Richard.

    ReplyDelete
    Replies
    1. Hi Richard, not sure how you managed to get so far in the emulator. Last time I looked, the emulator did not support Bluetooth at all. These projects should be run on the Bluetooth device.

      Delete
    2. By Bluetooth device I meant to say, android phone.

      Delete
    3. Hi Scott,
      Yes i run them on the android phone and the initial ones all worked until sketch 5 so i then ran it in the emulator becos when i do that i get error message in the console of the processing IDE. Anyway do you have any idea what the error relates to?

      Any help is much appreciated.

      Cheers,

      Richard.

      Delete
    4. Hi Richard,
      You cannot use the emulator to debug your Bluetooth issues because the emulator will generate errors that are not applicable to your phone. The emulator does not support Bluetooth. Having said that, there are a couple of ways to hunt down the problem. You can use logcat which is described in Bluetooth tutorial 3, or you can comment out sections of code to see if that restores functionality. The error you posted is pointing to setup. May be worth investigating your variables in there. I also made a warning about Toastmaster in this article. Make sure you read about that too.
      Hope that helps.

      Delete
  8. Will this software run on a Nexus7 tablet?

    ReplyDelete
    Replies
    1. Not sure - never tried - only blogged about my experience with a Samsung as described.

      Delete
    2. Running beautifully on my Nexus 7. Great tutorial and well documented. Had been using Eclipse but Processing 2.0 is so much easier. Tried 2.1 but had Java compile errors.
      Thanks for the fine presentation.

      Delete
    3. Great to hear thanks +stan

      Delete
  9. Replies
    1. It's "Clear Interrupts". An AVR GCC command to disable global interrupts.

      Delete
    2. Thanks Michael.
      You learn something new every day.
      Very much appreciated.

      Delete
  10. hi men . I need your help, look I get this error.
    the method run() of type connectTobluetooth must override a superclass method

    ReplyDelete
    Replies
    1. Did you use the @Override statement ?
      Did you copy this tutorial as above ?

      Delete
    2. I get the same error when attempting to use the @Override statement. It appears to be a java compiler level issue (1.5 vs 1.6?) but I haven't figured out how to fix it yet.

      Delete
    3. Same with me. So close... All the other code samples worked up to this point and now I'm stuck with " run() of type connectTobluetooth must override a superclass method"
      Does anyone have any pointers?

      Delete
    4. Are you all using the Processing IDE ? Version ?

      Delete
    5. Also check Capitalization consistency throughout your code.
      My code has this : ConnectToBluetooth
      Your error has this: connectTobluetooth

      So I am guessing you are either adapting my code, or re-typing ???
      Make sure your variables are consistent throughout your code.

      As there are now a few of you who have the same issue. It may be worth asking for help in the Processing forums. They have a section dedicated to Android programming:
      http://forum.processing.org/two/categories/android

      Feel free to come back a report the solution (for any others that may fall into the same boat).

      Delete
    6. Hi,I've solved the problem simply removing the @Override statement...

      Delete
  11. This is a great tutorial that explains things well. I have something to add about the UUID.
    The UUID is the unique identifier that the android app will use to tell the HC-05/06 what service it's performing. In the case of the HC-05/06 it need to be a "Serial Port Profile" which is identified by the UUID's second nibble being "1101".

    So if you get the standards base UUID. "00000000-0000-1000-8000-00805F9B34FB"
    and insert your service identifier so the HC-05/06 will let you pair.
    You get your tutorials basic identifier, the SPP UUID "00001101-0000-1000-8000-00805F9B34FB"

    ReplyDelete
    Replies
    1. Thanks Michael,
      Do you know if this UUID number can be changed in any way? Or does it have to be that specific code described above ?

      Delete
    2. Short answer: I don't think it can be changed.

      Long answer:
      From my limited understanding the UUID is to uniquely identify APPLICATIONS not devices. So for the SPP I would say it can't be changed as this is the unique UUID to specify that you want to use the serial port profile. The reason UUID generators exist is so you can generate your own unique UUID for your own unique application that doesn't currently exist.

      To put it simply It's a unique identifier for the syntax of your communication. You can define your own UUID just like making up your own language or use one that already exists to speak to all devices that speak that same language. Hence changing the UUID would change the name of your language even if the syntax is technically the same and so the device would reject your connection.

      Delete
  12. Hello Scott or Anyone.

    I am getting the following error after I copied in your final Android sketch.

    public class ConnectToBluetooth implements Runnable{
    ^^^^^^^^^^^^^^^^^^
    The type ConnectBlueTooth.ConnectToBluetooth must implement the inherited abstract method Runnable.run()

    I am just starting to learn Android programming (actually I know nothing about it except for what I have learned here, and also I am learning the Arduino UNO at the same time.

    Any help with the error would be wonderful,

    Thank you,
    Steve

    ReplyDelete
    Replies
    1. Hi Steve,
      It appears that something has broken with a software version upgrade. A few people have reported this problem. As suggested in previous comments, it might be worth asking for help in the forums until I can work out where the problem exists. Also, if you manage to figure it out, please let me know.

      Delete
    2. This tutorial works best with Processing version 2.0
      Higher versions seems to generate errors.

      Delete
  13. Hi this is Kathiresan i am having 3 years of experience as a dot net developer and i am certified. i have knowledge on OOPS concepts in .NET but dont know indepth. After learning android will be enough to get a good career in IT with good package? and i crossed Android Training in Chennai website where someone please help me to identity the syllabus covers everything or not??

    Thanks,
    kathiresan

    ReplyDelete
  14. Hello.
    I am new to this stuff. Great tutorial by the way.

    I keep getting this error:

    import java.io.InputStream;
    ^^^^^^^^^^^^^^^^^^^
    The import java.io.InputStream is never used
    ----------
    I googled, but couldn't find clear solution. It's probably really simple, but like I said, I'm new.

    Thanks!

    ReplyDelete
    Replies
    1. Just remove that line from the code.

      Delete
  15. Hey Scott,

    First thanks for a great tutorial.

    My Sketch 5 does'nt work, though I hav tried the different things you have answered the others in there comments. The adb says "E/Parcel < 378>: Reading a NULL string not supported here."

    ReplyDelete
    Replies
    1. Hi Thor,

      I am not sure why there would be a NULL string error. Perhaps you will need to systematically comment out various sections of the code to see when the error disappears. At least then you can focus your attention on the problem area.

      Delete
  16. Hi all,

    Thanks to Scott for a great tutorial.

    I'm having some trouble with Sketch 4. The reason for this trouble is that I'm running Processing 3, API 15. Can't set the target to API 10.

    I'm getting compile errors on lines 57 and 93 stating:

    The function "registerRevceiver(BroadcastReceiver, IntentFilter)" does not exist
    The function "getApplicationContext()" does not exist

    Does anyone have any ideas as to how to get this code example to work with Processing 3 for API 15? I suspect it's an issue to do with the API level and some library mismatching of sorts.

    Any help would be greatly appreciated!

    I had some similar errors with the earlier sketches in part 1, but managed to fix them with a bit of messing around and also referring to the comments.

    I realize that this tutorial is out of date by this point, but it would be great to try and get it working, as it's the best one I've found thus far and most suitable to my application!

    Thanks,
    Jono

    ReplyDelete

Feel free to leave a comment about this tutorial below.
Any questions about your particular project should be asked in the ArduinoBasics forum.

Comments are moderated due to large amount of spam.