Bluetooth ASCII protocol - android

I'm trying to communicate with a bluetooth device. The information I have on the device states that
"The communications protocol is ASCII, commas separate output values. The message is terminated by carriage return and line feed pair. When saved as a file using a terminal emulator these results can be read into an Excel spreadsheet."
How do I send and receive from this device? I have tried using InputStreamReader and OutputStreamWriter, but I don't think that's working.
EDIT:
for sending data I'm trying:
public void send(String s){
try {
writer.write(s);
} catch (IOException e) {
e.printStackTrace();
}
}
where
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
inStream = tmpIn;
writer = new OutputStreamWriter(tmpOut);
You can also see there where I am using inStream that is a simple InputStream. I have also tried InputStreamReader, but I just got random characters back. With the InputStream I am only reading 4 bytes no matter what I send the device, so I'm not sure if even the sending is working.
What should I be using? Thanks!

You should take a look at Java documentation on IO Streams to make the whole picture.
For retrieval I assume you are using InputStream.read() method, which reads one byte at a time. To retrieve several bytes at a time you should use byte[] buffer. But that's not your case, just FYI.
In your case you don't need to use InputStream methods, but InputStreamReader instead, because
Reader operates on characters, not bytes. As stated in your quotation of protocol description, you have separate lines of ASCII. In this situation BufferedReader is handy, because it has readLine() method.
So you can just
in = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
And then
String line = br.readLine();
For sending data you should use OutputStreamWriter.
REMEMBER:Please close streams after use!!! in finaly{} clause

I am following up on this in case anyone else is having the same problems. One of the problems I was having was that the device I was trying to communicate with was expecting a specific order of /n and /r and would lock up if that was incorrect so I had no was of knowing if it was working or not.
Here is he code I use for sending and receiving, I have used it on a couple of devices now and it seems to work well.
/**
* This thread runs during a connection with a remote device.
* It handles all incoming and outgoing transmissions.
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket socket;
private final InputStream inStream;
private final OutputStream outStream;
private final DataInputStream datIn;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "create ConnectedThread");
this.socket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
inStream = tmpIn;
outStream = tmpOut;
datIn = new DataInputStream(inStream);
}
public void run() {
Log.i(TAG, "BEGIN ConnectedThread");
Bundle data = new Bundle();
// Keep listening to the InputStream while connected
while (true) {
Log.i(TAG, "Reading...");
try {
// Read from the InputStream
String results;
Log.i(TAG, "Recieved:");
results = datIn.readLine();
Log.i(TAG, results);
// Send the obtained bytes to the UI Activity
data.putString("results", results);
Message m = handler.obtainMessage(); // get a new message from the handler
m.setData(data); // add the data to the message
m.what = MESSAGE_READ;
handler.sendMessage(m);
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
handler.obtainMessage(MESSAGE_DISCONNECTED).sendToTarget();
setState(STATE_NONE);
// Start the service over to restart listening mode
break;
}
}
}
/**
* Write to the connected OutStream.
* #param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
outStream.write(buffer);
Log.i(TAG, "Sending: " + new String(buffer));
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
/**
* Write to the ConnectedThread in an unsynchronized manner
* #param out The bytes to write
* #see ConnectedThread#write(byte[])
*/
public void send(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (state != STATE_CONNECTED) return;
r = connectedThread;
}
// Perform the write unsynchronized
r.write(out);
}

Related

bluetooth InputStream in android gets corrupted after sending with OutputStream

So, I am using my arduino to collect some data and send it to my android app , so that I can store this data in a file, making my android a sort of datalogger.
I am using an hC-06 for this, working at 115200 bauds/sec. Seems to be allright when the arduino sends the data chunks ( 60bytes every chunk) every 100ms aprox.
The problem begins when I "query" the arduino for some special data, by sending a single byte with the OutputStream method. From the moment the app uses the "mmOutStream.write(buffer);" the data received by InputStream becomes unstable, varying the chunk size with random values ( 60 bytes, 45 butes, 100 bytes, etc...)
It seems like using OutputStream kind of corrupts the InputStream buffer...
Anyone has been through this? Thaks in advance
below the code:
// It handles all incoming and outgoing transmissions.
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private boolean send_request=false;
private byte[] send_buffer;
public ConnectedThread(BluetoothSocket socket, String socketType) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer;
ArrayList<Integer> arr_byte = new ArrayList<Integer>();
// Keep listening to the InputStream while connected
while (true) {
try {
int data = mmInStream.read();
if(data == 0x0A) {
}
else if(data == 0x0D) {
buffer = new byte[arr_byte.size()];
for(int i = 0 ; i < arr_byte.size() ; i++) {
buffer[i] = arr_byte.get(i).byteValue();
}
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(BluetoothState.MESSAGE_READ
, buffer.length, -1, buffer).sendToTarget();
arr_byte = new ArrayList<Integer>();
}
else {
arr_byte.add(data);
}
} catch (IOException e) {
connectionLost();
// Start the service over to restart listening mode
BluetoothService.this.start(BluetoothService.this.isAndroid);
break;
}
}
}
// Write to the connected OutStream.
// #param buffer The bytes to write
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
// mmOutStream.close(); //vdv , close after writing to see if liberates memeory . uncommenting this causes the phone not to connect
//TODO: investigate and solve why a single writing in the outstream causes the inputstream to get corrupted after a while.
// Share the sent message back to the UI Activity
mHandler.obtainMessage(BluetoothState.MESSAGE_WRITE
, -1, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.d(TAG,"write exception"); //vdv
}
}

Bluetooth Chat App answering back same text I sent

Im using one app to send data to the elm327 through bluetooth and I'm trying the AT Z command but everything I get back from the OBD2 is AT Z too, my code is missing something or its supposed to answer like that ? I expected the AT Z to return elm327 text (tested with playstore apps and thats what I got)
// runs during a connection with a remote device
private class ReadWriteThread extends Thread {
private final BluetoothSocket bluetoothSocket;
private final InputStream inputStream;
private final OutputStream outputStream;
public ReadWriteThread(BluetoothSocket socket) {
this.bluetoothSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
inputStream = tmpIn;
outputStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream
while (true) {
try {
// Read from the InputStream
bytes = inputStream.read(buffer);
// Send the obtained bytes to the UI Activity
handler.obtainMessage(MainActivity.MESSAGE_READ, bytes, -1,
buffer).sendToTarget();
} catch (IOException e) {
connectionLost();
// Start the service over to restart listening mode
ChatController.this.start();
break;
}
}
}
// write to OutputStream
public void write(byte[] buffer) {
try {
outputStream.write(buffer);
handler.obtainMessage(MainActivity.MESSAGE_WRITE, -1, -1,
buffer).sendToTarget();
} catch (IOException e) {
}
}
public void cancel() {
try {
bluetoothSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Perhaps you're not reading enough – make sure you concatenate all fragments you read until you receive the actual prompt \r>.
ELM327 usually starts out in echo mode, where it echos every command you are giving to it, that may explain why you're reading it back. Use ATE0 to turn off this behavior.
In general, https://www.sparkfun.com/datasheets/Widgets/ELM327_AT_Commands.pdf explains all that.

Read Bluetooth Message in External android app

I'am a newbie to android Bluetooth and I want to read and store the Bluetooth message in external android app(mine) using internal storage or sqlite. I have tried the android bluetooth-chat sample from GitHub but I don't know how to implement my idea.
Any help would be helpful and thanks
Exchange of bluetooth messages is covered in the android.bluetooth section of the api.
http://developer.android.com/guide/topics/connectivity/bluetooth.html#ManagingAConnection
Here is a basic example of managing a connection and sending/receiving messages:
private 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() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} 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) { }
}
}

Bluetooth - Receive data from multiple device in same time on android

I'm trying to receive data from multiple device in same time, i'm using createInsecureRfcommSocketToServiceRecord() and the SPP UUID 00001101-0000-1000-8000-00805F9B34FB to connect to non-android devices.
So i'm running 3 instance of ConnectedThread, i'm able to write to all device, but i can't receive from 2 device at same time.
Example : i'm connecting to 2 Pc using HyperTerminal, if i send a txt file on both at the same time, i will receive only one on my android device, the other one is ignored.
I'm looking this library : http://arissa34.github.io/Android-Multi-Bluetooth-Library/ seems i have to run a server on my android phone.
How can I achieve this?
Best regards.
private 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() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} 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) { }
}
}

How to serialize an object and then send it over bluetooth

I'm making a Battleships game and I want to send an Array of a class named Ships(which contains stuff like ship name, size, rotated or not and an arraylist for coordinates). I've googled this and looked on Stack overflow and I basically need to serialize the array, but this is where I'm stuck. I need to use ObjectOutputStream, but how do I encorporate that into the code below (taken from android dev site). Note I have already made the ship class implement serializable. Thanks in advance
public class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "connectedthread started");
// mHandler.obtainMessage(TEST).sendToTarget();
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) {
Log.e(TAG, "temp sockets not created");
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.i(TAG, "Begin mConnectedThread");
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
Log.i(TAG, "reaaaad msg");
mHandler.obtainMessage(SetUpGame.MESSAGE_READ2, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnectd");
break;
}
}
}
/*
* Call this from the main activity to send data to the remote
* device
*/
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
Log.i(TAG, "writeeee msg");
mHandler.obtainMessage(SetUpGame.MESSAGE_WRITE, -1,-1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write");
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close of connect socket failed");
}
}
}
and my handler:
final Handler mHandler = new Handler() {
#Override
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case MESSAGE_READ2:
byte[] readBuf = (byte[]) msg.obj;
String readMessage = new String(readBuf, 0, msg.arg1);
break;
case MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
String writeMessage = new String(writeBuf);
//Toast.makeText(getApplicationContext(),"Me:" + writeMessage, Toast.LENGTH_SHORT).show();
break;
In the code above you get input/output streams from the connected socket.
Now you can stream data to/from the socket using those streams.
How exactly you do this depends on the type of data you want to stream. In this case you have a serializable Object to send, so you will wrap your stream in a filter that adapts the stream for use with Objects: ObjectOutputStream/ObjectInputStream...
ObjectOutputStream oos = new ObjectOutputStream( mmOutStream );
for (Ship ship: ships)
oos.writeObject( ship );
This code iterates through the array of Ships, writing each ship to the stream (and hence, to the Bluetooth socket).
The receiving side is the same, with one additional complication: you don't necessarily know when to stop or what to read. There are various schemes for handling this, and there are SO questions dealing specifically with this. The Bluetooth page of the Android developer's guide has sample code for this:
http://developer.android.com/guide/topics/connectivity/bluetooth.html

Categories

Resources