@RichardDL. The following source code should allow you to connect to a paired bluetooth device and retrieve asterisk delimited data. I have been using line() from the connect thread to plot the data, but I’m not real happy with it, so intentionally left it out of this demo. The thread will give you integer values which you can see by un-REM ing println(value). Currently it shows the input string which is of varying lengths so you can see what is going on (if you don’t already know). However, the device screen will be blank except for the buttons due to lack of plotting code. Hopefully you can devise your own method and it will be better than what I’ve been using. The connect button turns from gray to green when the connection has been made. Otherwise all output is in the console. Hitting ‘Disconnect’ will turn the button back to gray. The ‘Q’ button will exit() the app. I scrunched all the buttons up so it could be run on a cell phone, but will also work on a tablet. It’s a long post; the connection source is boilerplate Android code available on the web. The buttons are homemade and do not have to be used if you have others that you prefer.
/*
For use on Android devices.
Retrieves data transmitted by bluetooth.
*/
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import java.util.Set;
import java.util.UUID;
// Make sure sketch permissions are set for Bluetooth
// ACCESS_COARSE_LOCATION
// BLUETOOTH
// BLUETOOTH_ADMIN
// DropDownList control => a.)displayFld b.)arrow c.)list
BluetoothAdapter bluetoothAdapter = null;
final int _deviceDisplayX = 30;
final int _deviceDisplayY = 60;
final int _deviceDisplayW = 450;
final int _deviceDisplayH = 60;
final int _deviceItemH = 120;
final int _deviceArrwX = _deviceDisplayX + _deviceDisplayW;
final int _deviceArrwY = _deviceDisplayY;
final int _deviceArrwSize = _deviceDisplayH;
final int _baudDisplayX = 560;
final int _baudDisplayY = 60;
final int _baudDisplayW = 130;
final int _baudDisplayH = 60;
final int _baudItemH = 80;
final int _baudArrwX = _baudDisplayX + _baudDisplayW;
final int _baudArrwY = _baudDisplayY;
final int _baudArrwSize = _baudDisplayH;
final int _connectBtnX = 780;
final int _connectBtnY = 60;
final int _connectBtnW = 250;
final int _connectBtnH = 60;
final int _clearBtnX = 1060;
final int _clearBtnY = 60;
final int _clearBtnW = 100;
final int _clearBtnH = 60;
final int _quitBtnX = 1180;
final int _quitBtnY = 60;
final int _quitBtnW = 80;
final int _quitBtnH = 60;
int value = 0;
boolean deviceListDrop;
boolean baudListDrop;
boolean connectSelected;
color BLUE = color(64,124,188);
color GREEN = color(0,126,0);
String[] deviceArray = {};
String[] deviceAddress = {};
String[] baudArray = {"9600","14400","19200","28800","38400","57600","115200"};
int[] _deviceItemY;
int[] _baudItemY;
int selectedDevice = -1;
int selectedBaud = -1;
void findPairedBluetoothDevices() {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
println("Device doesn't support Bluetooth.");
} else {
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
// Get the name and address of each paired device.
for (BluetoothDevice device : pairedDevices) {
// device = append(device,device);
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
deviceAddress = append(deviceAddress, device.getAddress());
String deviceInfo = deviceName + "\n " + deviceHardwareAddress;
deviceArray = append(deviceArray, deviceInfo);
}
}
}
}
class DeviceDisplay {
void press() {
// device arrow touches
if(deviceListDrop){
deviceListDrop = false;
} else {
deviceListDrop = true;
}
}
void deviceDisplayString(String str) {
fill(255); // display field background color
noStroke();
rect(_deviceDisplayX,_deviceDisplayY,_deviceDisplayW,_deviceDisplayH);
fill(0); // text color
textSize(42);
text(str, _deviceDisplayX + 10, _deviceDisplayY + 15, _deviceDisplayW, _deviceDisplayH);
}
void display(){
// display field
if(selectedDevice == -1){
deviceDisplayString("Select device:");
} else {
deviceDisplayString(deviceArray[selectedDevice]);
}
// arrow
fill(255);
noStroke();
rect(_deviceArrwX, _deviceArrwY, _deviceArrwSize, _deviceArrwSize);
fill(GREEN);
triangle(_deviceArrwX+5,_deviceArrwY+5,_deviceArrwX+_deviceArrwSize-5,_deviceArrwY+5,_deviceArrwX+_deviceArrwSize/2,_deviceArrwY+_deviceArrwSize-5);
}
}
DeviceDisplay deviceDisplay;
class DeviceList {
void press(float mx, float my){
// device list touches
if (deviceArray.length > 0) {
for(int j = 0; j < deviceArray.length; j++){
if((mx >= _deviceDisplayX) && (mx <= _deviceDisplayX + _deviceDisplayW) && (my >= _deviceItemY[j] ) && (my <= _deviceItemY[j] + _deviceItemH)) {
selectedDevice = j;
deviceListDrop = false;
// erases list
fill(BLUE);
rect(_deviceDisplayX, _deviceDisplayY, _deviceDisplayW, _deviceDisplayY + _deviceDisplayH + deviceArray.length*_deviceItemH);
}
}
}
}
void display(){
// deviceListItems
if (deviceListDrop){
if (deviceArray.length > 0) {
_deviceItemY = new int[deviceArray.length];
for(int j = 0; j < deviceArray.length; j++) {
_deviceItemY[j] = (_deviceDisplayY + _deviceDisplayH) + j*_deviceItemH;
fill(255);
noStroke();
rect(_deviceDisplayX,_deviceItemY[j],_deviceDisplayW,_deviceItemH);
fill(0);
textSize(42);
text(deviceArray[j], _deviceDisplayX + 10, _deviceItemY[j] + 15, _deviceDisplayW, _deviceItemH);
}
}
}
}
}
DeviceList deviceList;
class BaudDisplay {
void press(){
// baud arrow touches
if(baudListDrop){
baudListDrop = false;
} else {
baudListDrop = true;
}
}
void baudDisplayString(String str) {
fill(255); // display field background color
noStroke();
rect(_baudDisplayX,_baudDisplayY,_baudDisplayW,_baudDisplayH);
fill(0); // text color
textSize(42);
text(str, _baudDisplayX + 10, _baudDisplayY + 15, _baudDisplayW, _baudDisplayH);
}
void display(){
// baudDisplay
if(selectedBaud == -1){
baudDisplayString("Baud:");
} else {
baudDisplayString(baudArray[selectedBaud]);
}
// arrow
fill(255);
noStroke();
rect(_baudArrwX, _baudArrwY, _baudArrwSize, _baudArrwSize);
fill(GREEN);
triangle(_baudArrwX+5,_baudArrwY+5,_baudArrwX+_baudArrwSize-5,_baudArrwY+5,_baudArrwX+_baudArrwSize/2,_baudArrwY+_baudArrwSize-5);
}
}
BaudDisplay baudDisplay;
class BaudList {
void press(float mx, float my){
// baud list touches
for(int j = 0; j < baudArray.length; j++){
if((mx >= _baudDisplayX) && (mx <= _baudDisplayX + _baudDisplayW) && (my >= _baudItemY[j] ) && (my <= _baudItemY[j] + _baudItemH)) {
selectedBaud = j;
baudListDrop = false;
// erases list
fill(BLUE);
rect(_baudDisplayX, _baudDisplayY, _baudDisplayX + _baudDisplayW, _baudDisplayY + _baudDisplayH + baudArray.length*_baudItemH);
}
}
}
void display(){
// baudListItems
if (baudListDrop){
if (baudArray.length > 0){
_baudItemY = new int[baudArray.length];
for(int j = 0; j < baudArray.length; j++){
_baudItemY[j] = (_baudDisplayY + _baudDisplayH) + j*_baudItemH;
fill(255);
noStroke();
rect(_baudDisplayX,_baudItemY[j],_baudDisplayW,_baudItemH);
fill(0);
textSize(42);
noStroke();
text(baudArray[j], _baudDisplayX + 10, _baudItemY[j] + 15, _baudDisplayW, _baudItemH);
}
}
}
}
}
BaudList baudList;
class ConnectBtn {
// Changes color from gray to green when bluetooth is connected
void display(){
if(connectSelected) {
fill(151,186,66,255); // background color - GREEN
noStroke();
rect(_connectBtnX, _connectBtnY, _connectBtnW, _connectBtnH, 15);
fill(0); // text color
textSize(42);
text("Disconnect", _connectBtnX + 20, _connectBtnY + 15, _connectBtnW, _connectBtnH);
} else {
fill(209); // background color - GRAY
noStroke();
rect(_connectBtnX, _connectBtnY, _connectBtnW, _connectBtnH, 15);
fill(0); // text color
textSize(42);
text("Connect", _connectBtnX + 20, _connectBtnY + 15, _connectBtnW, _connectBtnH);
}
}
void press() {
if(connectSelected == false){
// connectBluetooth();
connectSelected = true;
println("Connect selected.");
connectThread = new ConnectThread(bluetoothAdapter.getRemoteDevice(deviceAddress[selectedDevice]));
connectThread.run();
} else {
//disconnectBluetooth();
connectSelected = false;
println("Disconnect selected.");
connectThread.cancel();
}
}
}
ConnectBtn connectBtn;
class ClearBtn {
void display(){
fill(209); // background color - GRAY
noStroke();
rect(_clearBtnX, _clearBtnY, _clearBtnW, _clearBtnH, 15);
fill(0); // text color
textSize(42);
text("CLR", _clearBtnX + 15, _clearBtnY + 15, _clearBtnW, _clearBtnH);
}
void press(){
// clear plot rectangle
fill(BLUE);
noStroke();
rect(0, 150, width, height);
}
}
ClearBtn clearBtn;
class QuitBtn {
void display(){
fill(209); // background color - GRAY
noStroke();
rect(_quitBtnX, _quitBtnY, _quitBtnW, _quitBtnH, 15);
fill(0); // text color
textSize(42);
text("Q", _quitBtnX + 25, _quitBtnY + 15, _quitBtnW, _quitBtnH);
}
void press(){
exit();
}
}
QuitBtn quitBtn;
// **** Android Code for Bluetooth Connection **** //
class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
println("ConnectedThread: run() called.");
byte[] buffer = new byte[256]; // buffer store for the stream
int bytes; // bytes returned from read()
String dataStr = new String();
// Read from InputStream until an exception occurs
while (true) {
try {
bytes = mmInStream.read(buffer);
String inStr = new String(buffer, 0, bytes);
println(inStr);
dataStr = dataStr + inStr;
// Delimiter of data frame is an asterisk.
String[] items = dataStr.split("\\*");
// println(dataStr);
for (String item : items ){
if(item.length() == 3){
try {
value = Integer.parseInt(item);
// println(value);
} catch(NumberFormatException ex) {
println("Not an integer.");
}
}
}
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
ConnectedThread connectedThread;
class ConnectThread extends Thread {
final BluetoothSocket mmSocket;
final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket because mmSocket is final.
BluetoothSocket tmp = null;
mmDevice = device;
try {
// Get a BluetoothSocket to connect with the given BluetoothDevice.
// MY_UUID is the app's UUID string, also used in the server code.
tmp = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"));
} catch (IOException e) {
println("Socket's create() method failed");
}
mmSocket = tmp;
}
void manageConnectedSocket(BluetoothSocket socket) {
connectedThread = new ConnectedThread(socket);
connectedThread.start();
}
public void run() {
// Cancel discovery because it otherwise slows down the connection.
bluetoothAdapter.cancelDiscovery();
try {
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and return.
try {
mmSocket.close();
} catch (IOException closeException) {
println("Could not close the client socket: ", closeException);
}
return;
}
// Connection attempt succeeded; perform work associated with connection in separate thread.
manageConnectedSocket(mmSocket);
}
// Closes the client socket and causes the thread to finish.
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
println("Could not close the client socket");
}
}
}
ConnectThread connectThread;
void setup() {
fullScreen();
background(BLUE);
orientation(LANDSCAPE);
findPairedBluetoothDevices();
deviceDisplay = new DeviceDisplay();
deviceList = new DeviceList();
deviceListDrop = false;
baudDisplay = new BaudDisplay();
baudList = new BaudList();
baudListDrop = false;
connectBtn = new ConnectBtn();
connectSelected = false;
clearBtn = new ClearBtn();
quitBtn = new QuitBtn();
frameRate(60);
}
void draw() {
// maintains display of buttons
deviceDisplay.display();
deviceList.display();
baudDisplay.display();
baudList.display();
connectBtn.display();
clearBtn.display();
quitBtn.display();
}
// traps button touches
void mousePressed(){
if((mouseX >= _deviceArrwX) && (mouseX <= _deviceArrwX+_deviceArrwSize) && (mouseY >= _deviceArrwY) && (mouseY <= _deviceArrwY+_deviceArrwSize)){
deviceDisplay.press();
}
if(deviceListDrop) {
if((mouseX >= _deviceDisplayX) && (mouseX <= _deviceDisplayX + _deviceDisplayW) && (mouseY >= _deviceDisplayY + _deviceDisplayH) && (mouseY <= _deviceDisplayY + _deviceDisplayH + deviceArray.length*_deviceItemH)) {
deviceList.press(mouseX, mouseY);
}
}
if((mouseX >= _baudArrwX) && (mouseX <= _baudArrwX+_baudArrwSize) && (mouseY >= _baudArrwY) && (mouseY <= _baudArrwY+_baudArrwSize)){
baudDisplay.press();
}
if(baudListDrop) {
if((mouseX >= _baudDisplayX) && (mouseX <= _baudDisplayX + _baudDisplayW) && (mouseY >= _baudDisplayY + _baudDisplayH) && (mouseY <= _baudDisplayY + _baudDisplayH + baudArray.length*_baudItemH)) {
baudList.press(mouseX, mouseY);
}
}
if((mouseX >= _connectBtnX) && (mouseX <= _connectBtnX+_connectBtnW) && (mouseY >= _connectBtnY) && (mouseY <= _connectBtnY+_connectBtnH)){
connectBtn.press();
}
if((mouseX >= _clearBtnX) && (mouseX <= _clearBtnX+_clearBtnW) && (mouseY >= _clearBtnY) && (mouseY <= _clearBtnY+_clearBtnH)){
clearBtn.press();
}
if((mouseX >= _quitBtnX) && (mouseX <= _quitBtnX + _quitBtnW) && (mouseY >= _quitBtnY) && (mouseY <= _quitBtnY + _quitBtnH)){
quitBtn.press();
}
}