Arduino Basics: Bluetooth
Showing posts with label Bluetooth. Show all posts
Showing posts with label Bluetooth. Show all posts

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. */
@Overrideprotected 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. */
@Overrideprotected 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

18 March 2013

Bluetooth Android Processing 1


PART ONE


Introduction

This is a four part tutorial which will take you through step-by-step on how to create Android apps on your Mobile device that will allow you to communicate with your Arduino over Bluetooth. This tutorial is based upon the Windows environment and an Android device like the Samsung Galaxy S2 Phone.
I will take you through setting up your computer and phone, and will move through in stages so that you understand what each part of the bluetooth code is actually doing. Obviously you will need to ensure that you have a Bluetooth Shield on your Arduino to be able to walk through this tutorial with me.
If you are not interested in the step-by-step instructions, you can jump straight to the end (Part 4) which will have the complete Arduino and Android/Processing code that was used in the following video:

The Goal of this project (Video)


Setting up Processing for Android applications:
For the latest and most up to date version, please follow the instructions on this website: http://wiki.processing.org/w/Android

Step One:
Download the Android SDK from this website:
http://developer.android.com/sdk/index.html
Android SDK download link
Android SDK Download:
Make sure to select the "Use and Existing IDE" link, as per the picture below.



When you select the "Use an Existing IDE" link, it will then show you the appropriate download to use. This is what it should look like.

Select the "Download the SDK Tools for Windows" link.
Once you have downloaded the Android SDK, go ahead and install it as per the instructions below.
These instruction can also be found here.






Installing the necessary packages in the Android SDK Manager program
Make the following 3 selections:
  • Tools: Android SDK Platform-tools
  • API 10: SDK Platform
  • Extras: Google USB Driver
Then select the button on the bottom-right to install your selections.

Here is a picture of the Android SDK Manager selections:


While you may decide to download other packages,
you MUST download API 10: SDK Platform .
Do not leave this one out !!


Processing.org Download Link
Step Two: Processing Download

Download the latest Processing IDE (version 2.0 Beta 8) from this website:
http://processing.org/download/

I am using Windows 7, and have chosen to download the Windows 32 bit version as shown below.




Load Processing, and switch to Android mode, as per the image below.




You should now have an empty sketch window which looks something like this.





Step Three: Setting up the Android Hardware device (Phone)
For the latest steps you can have a look at this site:
http://developer.android.com/tools/device.html

However, these are the ones that I carried out:

Turn on USB debugging on your Android Phone:
To find out what Android Version you are on, have a look at
    Settings > About Phone : look for heading "Android Version".
  • My Android version is 2.3.4 on my Samsung Galaxy S2.
To Enable USB Debugging:
   
Settings > Applications > Development > Select (or Enable) USB debugging

For those of you who have a different Android version, have a look below:





Downloading the USB driver for your Android Phone (Windows Users)
If you are developing on Windows and would like to connect an Android-powered device to test your applications, then you need to install the appropriate USB driver. Have a look at this site for more information on how to download the USB driver for your phone:
http://developer.android.com/tools/extras/oem-usb.html

I have a Samsung Galaxy S2 phone, so I had to go to the Samsung Site here:
http://www.samsung.com/us/support/downloads

But because I am not in the USA, I had to click on the link for "non-US products":
http://www.samsung.com/us/support/downloads/global

You will need the model number of your phone:
On the Samsung Galaxy S2, you can go into
    Settings > About Phone => Model number. Otherwise, it is located behind the battery.
  • My Phone's Model Number is: GT-I9100
See the image below for the link to press if you have a non-US phone.



Then I continued with the install of the USB driver as per the document below:
http://developer.android.com/tools/extras/oem-usb.html







Step Four: Android-Processing Sketch
We will now test our our current setup and make sure that we can run a simple Processing Sketch on the Phone. Bluetooth functionality will be tested later on, so all we need for this step, is our computer, our Android phone, and a USB cable. While it is possible to run this sketch without an Android phone (by using the emulator), I personally do not have the patience to wait an eternity while the emulator boots up... (yes, it takes an eternity)... In this tutorial, we are going to test it on the device (phone).
This sketch has an orange background and a black circle which you can move around the screen with your finger (that's it) - I did say it was going to be a simple sketch.

Copy and paste the following Android-Processing sketch into the IDE, and then press the (Run on Device) button, which is the triangle button or press Ctrl-R.


Android/Processing Sketch 1: Circle Dragger

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*Circle Dragger: Simple Android-Processing Sketch written by ScottC on 13/03/2013.
 Visit: http://arduinobasics.blogspot.com/
*/
int circleWidth = 150;
void setup(){
 orientation(LANDSCAPE);
}
void draw(){
 background(255,100,0);
 fill(0);
 ellipse(mouseX,mouseY,circleWidth,circleWidth);
}


You should see an orange screen appear on your phone. Move your finger across the screen and watch as the black circle follows your finger.
No, not rocket science, but hopefully everything worked as planned. If you want to change the colour of the background or circle, this is a good site:
http://www.colorpicker.com/



Step Five: Bluetooth testing:
We are now going to walk through Bluetooth connectivity. While we could just use a library to do all the heavy lifting for us, I decided to explore Bluetooth functionality from scratch. This will hopefully provide greater returns in the long run. Ok, lets create a new Android/Processing Sketch which changes its behaviour depending on whether Bluetooth is enabled or disabled when the sketch is run. We will display a red screen when Bluetooth is switched off, and green when Bluetooth is switched on.

To enable Bluetooth on my Samsung Galaxy SII phone:
  • Settings >Wireless and Network > Bluetooth Settings > Bluetooth (Turn on Bluetooth) - check the box

To disable Bluetooth on my Samsung Galaxy SII phone:
  • Settings >Wireless and Network > Bluetooth Settings > Bluetooth - Uncheck the box

In the processing/android IDE, you need to make sure that you update the AndroidManifest.xml file to grant specific permissions. You can either edit the file manually in the sketch folder, however, it is much easier and safer to do the following. In the processing/android IDE, select:
  •   Android > Sketch permissions  (as per the picture below)

  • Make sure that BLUETOOTH and BLUETOOTH_ADMIN are selected (as per the picture below). Then press the OK button.


Then copy and paste the following sketch into the processing/android IDE:


Android/Processing Sketch 2: BluetoothChecker1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*BluetoothChecker1: Written by ScottC on 17 March 2013
 This will show a red screen if Bluetooth is off, 
 and a green screen when Bluetooth is switched on */

import android.bluetooth.BluetoothAdapter;

BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
void setup(){
 orientation(LANDSCAPE);
}
void draw(){
 if(bluetooth.isEnabled()){
 background(10,255,30);
 } else {
 background(255,10,30);
 }
}


When you run the BluetoothChecker1 sketch on the device, you will either see a red screen or a green screen depending on whether you had Bluetooth enabled or disabled at the time. Ok, pretty boring, but it is a start. What if we wanted to ask the USER if they would like to enable Bluetooth at the beginning? We could then change the appearance of the screen depending on their selected answer. Before we add this functionality, I would recommend that you read about the following concepts introduced in the next sketch.
While it is actually possible to turn bluetooth on without asking for permission, I thought I would retain my manners for the following sketch:

Android/Processing Sketch 3: BluetoothChecker2
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
/*BluetoothChecker2: Written by ScottC on 17 March 2013
 
 If Bluetooth is already ON when you run this sketch,
 the background will display BLUE.
 
 If Bluetooth is OFF when you run this sketch but you
 agree to turn it on, the background will display GREEN.
 
 If Bluetooth is OFF when you run this sketch and then
 choose to keep it off, the background will display RED. 
 
 =======================================================*/
 
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
int BACKGND=0; //Set the background to BLUE
//Get the default Bluetooth adapter
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();

/*The startActivityForResult() launches an Activity which is
 used to request the user to turn Bluetooth on. 
 The following onActivityResult() method is called when the 
 Activity exits. */
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data){
 if(requestCode==0){
 if(resultCode == RESULT_OK){
 BACKGND=2; //Set the background to GREEN
 } else {
 BACKGND=1; //Set the background to RED
 }
 }
}
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);
 }
}
void draw(){
 if(BACKGND==0){
 background(10,10,255); //Set background to BLUE
 } else if(BACKGND==1) {
 background(255,10,10); //Set background to RED
 } else {
 background(10,255,10); //Set background to GREEN
 }
}

I tried my best to explain the code via the comments within. I hope it made sense.


Useful Links:

Android Processing Wiki: http://wiki.processing.org/w/Android

Here is a good tutorial which helped me put Processing and Android together:
http://www.creativeapplications.net/android/mobile-app-development-processing-android-tutorial/

And most importantly:
The Android Developers site : Bluetooth



Click here for PART TWO

Click here for PART THREE

Click here for PART FOUR

 
 



If you like this page, please do me a favour and show your appreciation :

 
Visit my ArduinoBasics Google + page.
Follow me on Twitter by looking for ScottC @ArduinoBasics.
Have a look at my videos on my YouTube channel.


 
 

 
 
 


However, if you do not have a google profile...
Feel free to share this page with your friends in any way you see fit.

15 January 2013

Bluetooth Tutorial 1


Introduction:
The bluetooth shield used in this project is a great way to detach the Arduino from your computer. What is even better, is that the shield allows you to control your arduino from your mobile phone or other bluetooth enabled device through simple Serial commands. In this tutorial we will connect a Grove Chainable RGB LED to the bluetooth shield directly, and send simple commands using the Bluetooth SPP app on a Samsung Galaxy S2 to change the colour of the LED (Red , Green and Blue)



Parts Required:
Freetronics Eleven or any compatible Arduino.
Bluetooth shield
Grove Chainable RGB LED
Grove Wire connectors




The Video:





The Arduino Sketch:








Arduino Code:
You can download the Arduino IDE from this site.


 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
/* This project combines the code from a few different sources.
This project was put together by ScottC on the 15/01/2013
http://arduinobasics.blogspot.com/

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

Grove Chainable RGB code can be found here :
http://www.seeedstudio.com/wiki/Grove_-_Chainable_RGB_LED#Introduction

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

#define uint8 unsigned char 
#define uint16 unsigned int
#define uint32 unsigned long int

#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


int Clkpin = 9; //RGB LED Clock Pin (Digital 9)
int Datapin = 8; //RGB LED Data Pin (Digital 8)
 
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
 
 pinMode(Datapin, OUTPUT); // Setup the RGB LED Data Pin
 pinMode(Clkpin, OUTPUT); // Setup the RGB LED Clock pin
 
} 

/*----------------------LOOP----------------------------*/ 
void loop() { 
 digitalWrite(13,LOW); //Turn off the onboard Arduino LED
 char recvChar;
 while(1){
 if(blueToothSerial.available()){//check if there's any data sent from the remote bluetooth shield
 recvChar = blueToothSerial.read();
 Serial.print(recvChar); // Print the character received to the Serial Monitor (if required)
 
 //If the character received = 'r' , then change the RGB led to display a RED colour
 if(recvChar=='r'){
 Send32Zero(); // begin
 DataDealWithAndSend(255, 0, 0); // first node data
 Send32Zero(); // send to update data 
 }
 
 //If the character received = 'g' , then change the RGB led to display a GREEN colour
 if(recvChar=='g'){
 Send32Zero(); // begin
 DataDealWithAndSend(0, 255, 0); // first node data
 Send32Zero(); // send to update data 
 }
 
 //If the character received = 'b' , then change the RGB led to display a BLUE colour
 if(recvChar=='b'){
 Send32Zero(); // begin
 DataDealWithAndSend(0, 0, 255); // first node data
 Send32Zero(); // send to update data 
 }
 }
 
 //You can use the following code to deal with any information coming from the Computer (serial monitor)
 if(Serial.available()){
 recvChar = Serial.read();
 
 //This will send value obtained (recvChar) to the phone. The value will be displayed on the phone.
 blueToothSerial.print(recvChar);
 }
 }
} 


//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();
}


//The following code snippets are used update the colour of the RGB LED-----copy and paste------------
void ClkProduce(void){
 digitalWrite(Clkpin, LOW);
 delayMicroseconds(20); 
 digitalWrite(Clkpin, HIGH);
 delayMicroseconds(20); 
}
 
void Send32Zero(void){
 unsigned char i;
 for (i=0; i<32; i++){
 digitalWrite(Datapin, LOW);
 ClkProduce();
 }
}
 
uint8 TakeAntiCode(uint8 dat){
 uint8 tmp = 0;
 if ((dat & 0x80) == 0){
 tmp |= 0x02; 
 }
 
 if ((dat & 0x40) == 0){
 tmp |= 0x01; 
 }
 
 return tmp;
}
 
// gray data
void DatSend(uint32 dx){
 uint8 i;
 for (i=0; i<32; i++){
 if ((dx & 0x80000000) != 0){
 digitalWrite(Datapin, HIGH);
 } else {
 digitalWrite(Datapin, LOW);
 }
 
 dx <<= 1;
 ClkProduce();
 }
}
 
// data processing
void DataDealWithAndSend(uint8 r, uint8 g, uint8 b){
 uint32 dx = 0;
 
 dx |= (uint32)0x03 << 30; // highest two bits 1,flag bits
 dx |= (uint32)TakeAntiCode(b) << 28;
 dx |= (uint32)TakeAntiCode(g) << 26; 
 dx |= (uint32)TakeAntiCode(r) << 24;
 
 dx |= (uint32)b << 16;
 dx |= (uint32)g << 8;
 dx |= r;
 
 DatSend(dx);
}

The code above was formatted using hilite.me

Notes:
You don't need to download a library to get this project running. But if you plan to use bluetooth shields to get 2 Arduinos to communicate to each other, then I would advise that you download the library files (which are just examples) from the Seeedstudio site : here.

Visit this site to setup your phone or laptop for bluetooth communication to the shield - here

The app used on my Samsung Galaxy S2 phone was "Bluetooth SPP"

You will initially need to enter a pin of '0000' to establish a connection to the Bluetooth shield - which will appear as "SeeedBTSlave" or whatever text you place on line 90 of the Arduino code above.





Warning !

Not all phones are compatible with the bluetooth shield.
If you have used this shield before - please let me know what phone you used - so that we can build a list and inform others whether their phone is likely to work with this project or not. Obviously - those phones that do not have bluetooth within - will not work :).
And I have not tried any other apps either

I got it to work very easily with my Samsung Galaxy S2 using the free Bluetooth SPP app from the google play store.

This was fun, but I want to make my own app !
Have a look at my latest 4-part tutorial which takes you step-by-step through the process of building your own app using the Processing/Android IDE.
You can build your own GUI interface on your Android Phone and get it to communicate via Bluetooth to your Arduino/Bluetooth Shield. Click on the links below for more information:




 
 



If you like this page, please do me a favour and show your appreciation :

 
Visit my ArduinoBasics Google + page.
Follow me on Twitter by looking for ScottC @ArduinoBasics.
Have a look at my videos on my YouTube channel.


 
 

 
 
 



However, if you do not have a google profile...
Feel free to share this page with your friends in any way you see fit.