Message received from Arduino showing up as boxed question marks. - android

I am working on a project that involves communication between an Android Uno and an Android phone. The phone sends a request signal "*" that once received, the Arduino sends random integers in a loop. Right now, the Android device is receiving the message but it is showing up as boxed question marks, and not receiving all of the messages. Any ideas? Thank you so much!
Arduino code:
#include <SoftwareSerial.h>
const int RX_PIN = 0;
const int TX_PIN = 1;
SoftwareSerial bluetooth(RX_PIN, TX_PIN);
char commandChar;
void setup (){
bluetooth.begin (9600);
Serial.begin(38400);
}
void loop () {
if(bluetooth.available()){
commandChar = bluetooth.read();
switch(commandChar){
case '*':
Serial.println("Got the request code");
for(int i = 0; i < 10; i++){
bluetooth.print(random(21));
}
break;
}
}
}
Android code:
public void run() {
initializeConnection();
byte[] buffer = new byte[256];
int bytes;
// Keep looping to listen for received messages
while (true) {
try {
bytes = mmInStream.read(buffer);//read bytes from input buffer
String readMessage = new String(buffer, 0, bytes);
Log.e("Received Message: ", readMessage);
} catch (IOException e) {
break;
}
}
}
public void initializeConnection() {
try {
PrintWriter out;
out = new PrintWriter(mmOutStream, true);
out.println("*");
out.flush();
}catch (NullPointerException NPE) {
}
}
Console output:
08-13 19:02:46.546 4019-4128/? E/Received Message:: �
08-13 19:02:46.596 4019-4128/? E/Received Message:: ����

Ah I think I spot the problem. Random numbers are being sent from the arduino to the app, and the app is logging these bytes as ascii literals. Instead of sending random numbers, try sending well-formed ascii (visual characters).
You can send the hex bytes [0x68,0x65,0x6c,0x6c,0x6f] for "hello", or use SoftwareSerialPrint's built-in HEX option.
So change it to this, see if that works.
bluetooth.print(random(21), HEX);
Edit:
Let's try this on the app side instead. This will convert the received bytes into a hexadecimal string representation so we can see it in ascii properly.
bytes = mmInStream.read(buffer);//read bytes from input buffer
StringBuilder sb = new StringBuilder(bytes * 2);
for(byte b: buffer)
sb.append(String.format("%02x", b));
Log.e("Received Message: ", sb.toString());

Related

Unreadable data from Bluetooth EEG device

I m trying to read data from ads1299 arduino module. I m able to connect device with my android application, but still get unreadable characters. I even tried decoding with UTF-8, US-ASCII, ISO-8859-1.
Here is my code
mmBuffer = new byte[1024];
int numBytes;
while (true) {
try {
// Read from the InputStream.
numBytes = mmInStream.read(mmBuffer);
String str = new String(mmBuffer, 0, numBytes);
//String str = new String(mmBuffer, "UTF-8");
} catch (IOException e) {
Log.d(LOG_TAG, "Input stream was disconnected", e);
break;
}
}
Sample encoded characters currently I m getting
����������D#����������Ѫ���w����w���$W���������W.����⪪��뚪���/U���

Merging byte[] that was transfered through bluetooth

So, I used this Android sample as a guide to make a bluetooth connection without any kind of validation (This app will have a very restrict userbase and will not be available to download at the store).
I was able to transfer string just fine, and it works like a charm. My problem is when trying to transfer images.
I have one activity that sends the byte[] of the image to the bluetooth service and a handler on the other activity that recieves the message and do wharever with the said message.
The thing is, because of the size of the buffer the handler receives parts of the original byte[]. What I'm tryng to do is to merge all the parts in one byte and save it.
This is the loop that I do inside my handler:
byte[] result = new byte[originalByteSize];
byte[] readBuf = (byte[]) msg.obj;
if (cont < byteTimes){
if (result == null) {
result = appendData(readBuf,readBuf);
} else {
result = appendData(result,readBuf);
}
} else {
new SavePhotoTask(cont).execute(result);
}
This is the appendData function
protected byte[] appendData(byte[] firstObject,byte[] secondObject){
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
try {
if (firstObject!=null && firstObject.length!=0)
outputStream.write(firstObject);
if (secondObject!=null && secondObject.length!=0)
outputStream.write(secondObject);
} catch (IOException e) {
e.printStackTrace();
}
return outputStream.toByteArray();
}
And here is where I write the file:
public class SavePhotoTask extends AsyncTask<byte[], String, String> {
int counter = 0;
public SavePhotoTask(int cont){
this.counter = cont;
}
#Override
protected String doInBackground(byte[]... jpeg) {
File photo = new File(Environment.getExternalStorageDirectory(), counter + "_photo.jpg");
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream fos = new FileOutputStream(photo.getPath());
fos.write(jpeg[0]);
fos.close();
} catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
return (null);
}
What I needed is just a tip in the right direction, thanks.
I solved my problem with this answer
The problem was in the way I was writing and reading the stream.
public static void writeItem(OutputStream out, String s) throws IOException
{
// Get the array of bytes for the string item:
byte[] bs = s.getBytes(); // as bytes
// Encapsulate by sending first the total length on 4 bytes :
// - bits 7..0 of length
out.write(bs.length); // modulo 256 done by write method
// - bits 15..8 of length
out.write(bs.length>>>8); // modulo 256 done by write method
// - bits 23..16 of length
out.write(bs.length>>>16); // modulo 256 done by write method
// - bits 31..24 of length
out.write(bs.length>>>24); // modulo 256 done by write method
// Write the array content now:
out.write(bs); // Send the bytes
out.flush();
}
public static String readItem(InputStream in) throws IOException
{
// first, read the total length on 4 bytes
// - if first byte is missing, end of stream reached
int len = in.read(); // 1 byte
if (len<0) throw new IOException("end of stream");
// - the other 3 bytes of length are mandatory
for(int i=1;i<4;i++) // need 3 more bytes:
{
int n = in.read();
if (n<0) throw new IOException("partial data");
len |= n << (i<<3); // shift by 8,16,24
}
// Create the array to receive len bytes:
byte[] bs = new byte[len];
// Read the len bytes into the created array
int ofs = 0;
while (len>0) // while there is some byte to read
{
int n = in.read(bs, ofs, len); // number of bytes actually read
if (n<0) throw new IOException("partial data");
ofs += n; // update offset
len -= n; // update remaining number of bytes to read
}
// Transform bytes into String item:
return new String(bs);
}

android bluetoothsocket receive zero-value bytes?

Got a problem at receiving bytes from bluetooth socket. I'm trying to send message created by arduino - couple of single bytes values i.e. 0x41, 0x05, 0xFF(...) into my phone with android. It works fine until one of these value is zero (0x00). Transmission hangs until new message comes. Anyone meet with that situation?
My "reader" works in separate thread, processBuffer() do sth with data that should be received:
public void run() {
while(stop == false){
try {
bytes = InStream.read(readbuffer);
for (int i = 0; i < bytes; i++){
Log.d("FRAME", "Read bytes "+readbuffer[i]);
}
Log.d("FRAME", "Read number of bytes "+bytes);
processBuffer(bytes);
} catch (Exception e){
Log.d("BT_debug", "Cannot read bytes");
Log.d("BT_debug", "iterator: "+iterator);
e.printStackTrace();
break;
}
}
}

Client-server socket communication

Problem
How to send UTF-8 data between the server and the client, if I can use on client only
inputStream.read()
?
Docs
Reads a single byte from this stream and returns it as an integer in
the range from 0 to 255. Returns -1 if the end of the stream has been
reached.
Without reader.readLine() and any another. (With reader I cant see end of stream)
Help please!
(full code:)
int c;
String str = new String();
while ((c = inputStream.read( )) != -1)
{
char ch = (char)c;
if(ch == '\n')
{
Log.v("", str);
final String data = str;
runOnUiThread(new Runnable()
{
#Override
public void run()
{
String put[] = data.split("#");
try
{
//cmd parsing
}
catch(Exception e)
{
//stop connection
}
}
});
str = "";
}else{
str += Character.toString(ch);
}
}
//Communication error
Help please
You might want to take a look at this previous post. There's a couple of good options on there. The read() method can be overloaded with different parameters, so you can read one byte, or n bytes. Check out the full documentation here. Basically, you'll have to read in the raw bytes, then convert them to ASCII characters. Also, I'm curious as to why you can't use BufferedReader or an equivalent class?

How to detect EOF on android bluetooth file transfer?

I have implemented a bluetooth connection using the now-classic Google Bluetooth Chat code. However, I have a question which I just cannot seem to wrap my brain around.
The reading of the input stream goes something like this:
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;
}
}
}
Now, that's fine if I was just printing out the characters I was receiving as in the original example. However, suppose I wanted to transfer an image file. I don't know the size of the file, so I cannot count the bytes received or anything like that. In my tests, I don't seem to be ever receiving a "-1" from the input stream, which appears to be the "norm" for reading from input streams. So how can I know that I have reached the end of the file that was being sent?
Thank you for your help and your time.
It seems Android bluetooth input streams never return -1.
I guess setup a simple protocol by sending file size in the first place and EOF signals at last will help.
No it does not. Android sends -1 only when the Socket is closed as far as I know. So a workaround could be to do a reconnect, but I was trying that for hours and did not get it working, since I do not understand this "special" Code here (copied from a Stackoverflow Thread) for setting up the socket:
BluetoothSocket tmp = null;
Log.d(TAG, "New Connection initialized");
Method m;
try {
m = device.getClass().getMethod("createRfcommSocket",
new Class[] { int.class });
tmp = (BluetoothSocket) m.invoke(device, 1);
} catch (Exception e) {
e.printStackTrace();
}
mmSocket = tmp;
This Socket only works, when my App is started for the first filetransfer. If I want to "Reconnect" with a completely new instantiated Object (and a new Socket created with that Code), the program freezes on the blocking method mmSocket.connect(). It seems like the Method never comes to an ending. This is driving me nuts...
Try
while ((bytes = mmInStream.read(buffer) != -1)
and see if that helps.
Try this:
public void run() {
byte[] buffer;
ArrayList<Integer> arr_byte = new ArrayList<Integer>();
while (true) {
try {
int data = mmInStream.read();
if(mmInStream.available()>0) {
arr_byte.add(data);
} else {
arr_byte.add(data);
buffer = new byte[arr_byte.size()];
for(int i = 0 ; i < arr_byte.size() ; i++) {
buffer[i] = arr_byte.get(i).byteValue();
}
Log.e("INPUT",new String(buffer));
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
arr_byte = new ArrayList<Integer>();
}
} catch (IOException e) {
break;
}
}
}

Categories

Resources