Android Arduino Bluetooth communication - android

I can send data from a phone phone to an Arduino, but I can't see the data sent in from the Arduino in the phone. I think that the program never enters in the handler part but I don't know how to solve it.
This is the Android code:
void beginListenForData() {
final Handler handler = new Handler();
final byte delimiter = 10; //This is the ASCII code for a newline character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable() {
public void run() {
while(!Thread.currentThread().isInterrupted() && !stopWorker) {
try {
int bytesAvailable = mmInputStream.available();
if(bytesAvailable > 0) {
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for(int i=0;i<bytesAvailable;i++) {
byte b = packetBytes[i];
if(b == delimiter) {
///Here is the problem
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable() {
public void run() {
myLabel.setText(data);
texto.setText("data");
}
});
} else {
readBuffer[readBufferPosition++] = b;
}
}
}
}
catch (IOException ex) {
stopWorker = true;
}
}
}
});
workerThread.start();
}
And this is the Arduino code:
char val; // variable to receive data from the serial port
int ledpin = 13; // LED connected to pin 48 (on-board LED)
void setup() {
pinMode(ledpin, OUTPUT);
// pin 48 (on-board LED) as OUTPUT
Serial.begin(9600);
// start serial communication at 9600bps
}
void loop() {
if(Serial.available()) {
// if data is available to read
val = Serial.read();
// read it and store it in 'val'
}
if(val == 'H') {
// if 'H' was received
digitalWrite(ledpin, HIGH);
// turn ON the LED
delay(1000);
Serial.print("Recibido");
} else {
//digitalWrite(ledpin, LOW);
// otherwise turn it OFF
}
delay(100);
// wait 100ms for next reading
}

Related

RealTime Graph Entry

Please understand that I am using Google Translator because I do not understand English well.
I am currently working on an application that draws an EMG sensor value sent by Arduino via Bluetooth communication and a smartphone draws a graph based on that value.
Currently the application configuration has one activity and one fragment.
The Bluetooth function is in the activity and the graph is in the fragment.
I want to have the graph drawn only when the value comes in via Bluetooth communication. What should I do?
The code now depends on the fact that the fragment receives a value, even though the fragment is requesting a value.
Fragment
private void feedMultiple() {
if (thread != null)
thread.interrupt();
final Runnable runnable = new Runnable() {
#Override
public void run() {
addEntry();
}
};
thread = new Thread(new Runnable() {
#Override
public void run() {
while (loop) {
// Don't generate garbage runnables inside the loop
getActivity().runOnUiThread(runnable);
try {
Thread.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
break;
}
}
}
});
thread.start();
}
Activity
void beginListenForData() {
final Handler handler = new Handler();
readBufferPosition = 0;
readBuffer = new byte[1024];
mWorkerThread = new Thread(new Runnable()
{
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()) {
try {
int byteAvailable = mInputStream.available();
if(byteAvailable > 0) {
byte[] packetBytes = new byte[byteAvailable];
mInputStream.read(packetBytes);
for(int i=0; i<byteAvailable; i++) {
byte b = packetBytes[i];
if(b == mCharDelimiter) {
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes,"UTF-8");
readBufferPosition = 0;
handler.post(new Runnable(){
#Override
public void run() {
//raw = data.split("#");
bundle.putString("yValue1", data);
}
});
}
else {
readBuffer[readBufferPosition++] = b;
}
}
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "데이터 수신 중 오류가 발생 했습니다.", Toast.LENGTH_LONG).show();
finish();
}
}
}
});
mWorkerThread.start();
}

delay in receiving data from Android to Arduino

I'm connecting my android device to arduino via USB and I receive data immediately from arduino by using bulkTransfer, but when I'm going to send acknowledge signal back to arduino using the same command, it receives that some seconds later.
My arduino model is DUE, and the arduino side code is:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(49, OUTPUT);
}
void loop() {
String a;
int sensorValue[64];
for (int i = 0; i <= 63; i++)
{
sensorValue[i] = analogRead(A0) / 4;
a = a + char(sensorValue[i]);
}
char b;
while (1) {
Serial.print(a);
Serial.flush();
delay(2);
b = Serial.read();
if (b == '1')
{
break;
}
}
digitalWrite(49, HIGH);
delay(2000);
digitalWrite(49, LOW);
}
My android side code is:
public void onClick(View v) {
synchronized (this) {
if (usbDeviceConnection != null) {
Thread myThread = new Thread(new Runnable() {
#Override
public void run() {
try {
int chunkCounter = 0;
String strTemp = null;
while (chunkCounter < 1) {
byte[] message = new byte[64];
final int result = usbDeviceConnection.bulkTransfer(endpointIN, message, 64, 10);
if (result == 64) {
for (int intTemp = 0; intTemp < 64; intTemp++) {
strTemp += String.valueOf((char) message[intTemp]);
}
byte[] ack = new byte[1];
ack[0] = 1; //1 means I've got this chunk
synchronized(this) {
int resultAck = 0;
while (resultAck <= 0) {
resultAck = usbDeviceConnection.bulkTransfer(endpointOUT, ack, 1, 10);
}
}
chunkCounter++;
if (chunkCounter == 1) {
final String strTempFinal = strTemp;
tempflag = true;
runOnUiThread(new Runnable() {
#Override
public void run() {
txtGetData.setText(strTempFinal);
}
});
}
}
}
} catch (final Exception e){
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
});
myThread.start();
}
Any help would be appreciated.
thanks in advance.

Transferring data from bluetooth to the android app

I have the following code in android studio, we have a arduino with a bluetooth module HC-05 and we are trying to send a data from a sensor via the bluetooth to the android app:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_temperature);
btnOn = (Button) findViewById(R.id.measure);
sensorView0 = (TextView) findViewById(R.id.temp);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
CheckBlueToothState();
btnOn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
sendData();
} catch (IOException ex) {
}
Toast.makeText(getBaseContext(), "Start Measuring", Toast.LENGTH_SHORT).show();
}
});
}
void openBT() throws IOException {
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard //SerialPortService ID
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
bluetoothIn = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) { //if message is what we want
String readMessage = (String) msg.obj; // msg.arg1 = bytes from connect thread
recDataString.append(readMessage); //keep appending to string until ~
int endOfLineIndex = recDataString.indexOf("%"); // determine the end-of-line
if (endOfLineIndex > 0) { // make sure there data before ~
String dataInPrint = recDataString.substring(0, endOfLineIndex); // extract string
int dataLength = dataInPrint.length(); //get length of data received
if (recDataString.charAt(0) == '*') //if it starts with # we know it is what we are looking for
{
String sensor0 = recDataString.substring(1, endOfLineIndex); //get sensor value from string between indices 1-5
sensorView0.setText( sensor0 ); //update the textviews with sensor values
}
recDataString.delete(0, recDataString.length()); //clear all string data
dataInPrint = " ";
}
}
}
};
beginListenForData1();
Handler myHandler = new Handler();
myHandler.postDelayed(mMyRunnable, 1000);//Message will be delivered in 1 second.
// myLabel.setText("Bluetooth Opened");
}
void beginListenForData1() {
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable() {
public void run() {
byte[] buffer = new byte[256];
int bytes;
// Keep looping to listen for received messages
while (true) {
try {
bytes = mmInputStream.read(buffer); //read bytes from input buffer
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity via handler
bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
break;
}
}
}
});
workerThread.start();
}
private Runnable mMyRunnable = new Runnable()
{
#Override
public void run()
{
//Change state here
}
};
private void CheckBlueToothState() {
if (mBluetoothAdapter == null) {
} else {
if (mBluetoothAdapter.isEnabled()) {
if (mBluetoothAdapter.isDiscovering()) {
} else {
}
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if(pairedDevices.size() > 0) {
for(BluetoothDevice device : pairedDevices) {
if(device.getName().equals("HC-05")) {
mmDevice = device;
break;
}
}
try {
openBT();
}
catch (IOException ex) {
Toast.makeText(getBaseContext(), "Connection Failure", Toast.LENGTH_LONG).show();
finish();};
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (requestCode == REQUEST_ENABLE_BT) {
{CheckBlueToothState();
}
}
}
void sendData() throws IOException
{
String msg = "1";
msg += "\n";
mmOutputStream.write(msg.getBytes());
//myLabel.setText("Data Sent");
}
void sendData0() throws IOException
{
String msg = "0";
msg += "\n";
mmOutputStream.write(msg.getBytes());
//myLabel.setText("Data Sent");
}
#Override
public void onBackPressed() {
super.onBackPressed();
try {
sendData0();
} catch (IOException e) {
e.printStackTrace();
}
try {
closeBT();
} catch (IOException e) {
e.printStackTrace();
}
//System.exit(0);
this.finish();
}
void closeBT() throws IOException
{
stopWorker = true;
mmOutputStream.close();
mmInputStream.close();
mmSocket.close();
}
}
The code works for the second time only, so when i press the button in the app for the first time it does not show the data, but when i press it at the second time it shows the data, why is that happening?

How do I send data from thread back to main UI?

void beginListenForData() {
//final Handler handler = new Handler();
final Handler handler = new Handler(Looper.getMainLooper());
final byte delimiter = 10; //This is the ASCII code for a newline character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[2048];
workerThread = new Thread(new Runnable() {
public void run() {
while (!Thread.currentThread().isInterrupted() && !stopWorker) {
try {
int bytesAvailable = mmInputStream.available();
if (bytesAvailable > 0) {
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for (int i = 0; i < bytesAvailable; i++) {
byte b = packetBytes[i];
if (b == delimiter) {
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable() {
public void run() {
//myLabel.setText(data);
dataArray = new String []{data};
//Log.d("dataArray", data);
}
});
} else {
readBuffer[readBufferPosition++] = b;
}
}
}
} catch (IOException ex) {
stopWorker = true;
}
}
}
});
public class Bluetooth_dataDisplay extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
String MAC = getIntent().getStringExtra("MAC");
mAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice bluetoothDevice = mAdapter.getRemoteDevice(MAC);
// Initiate a connection request in a separate thread
ConnectingThread t = new ConnectingThread(bluetoothDevice);
t.start();
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
adapter = new RecyclerAdapter(dataArray);
recyclerView.setAdapter(adapter);
}
Begindata() is call in the connected thread. I trying to get the dataarray back to the Bluetooth_dataDisplay extends AppCompatActivity and call it in the oncreate. How do I senddataarray back to main activity? Please help any expert. I had look at post that talked about thread data send back to main UI. But I am very new to it, so it quite confusing. :( Help please.
Replace handler call under your beginListenForData() function
handler.post(new Runnable() {
public void run() {
//myLabel.setText(data);
dataArray = new String[]{data};
//Log.d("dataArray", data);
}
});
with runOnUiThread()
runOnUiThread(new Runnable() {
#Override
public void run() {
//myLabel.setText(data);
dataArray = new String[]{data};
//Log.d("dataArray", data);
}
});
Everything under runOnUiThread() runs on UI/Main thread.

The response time to a Bluetooth connection between Arduino and Android is proportional to the distance?

I'm trying to get the distance between an Android device and a Arduino. To do this, I thought I'd use the formula of calculating networks latency, as seen in this link:
How to calculate packet time from latency and bandwidth
where the propagation time would be given to obtaining the time I spent to send a signal to the Arduino and get the answer divided by 2 (one-way time care). However, the time I have got varies even when not moving the Android device, and even increasing the distance, remains in the same range, between 1 and 11 milliseconds. My idea is wrong or the way I am doing it? I can even make these deductions have I done? Here is my code:
My button click
public void onLedOnClick(View v)
{
long avg = 0;
for(int i = 1; i < 31; i++){
long t1 = System.currentTimeMillis();
sendData("1");
beginListenForData();
long t2 = System.currentTimeMillis();
avg = (avg + (t2-t1)) / i;
txtAnswerTime.setText("Answer time:" + String.valueOf((t2-t1)) + "ms");
}
sendData("3");
}
my sendData method:
public void sendData(String data){
if (btSocket != null) {
try {
// allows the output data from a socket
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Error: "+e.getMessage(), Toast.LENGTH_SHORT).show();
}
String mensagem = data;
byte[] msgBuffer = mensagem.getBytes();
try {
// sends content by bluetooth
outStream.write(msgBuffer);
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Error: "+e.getMessage(), Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getApplicationContext(),
"Bluetooth is not connected", Toast.LENGTH_SHORT).show();
}
}
My getData method:
public void beginListenForData()
{
if (btSocket != null) {
final Handler handler = new Handler();
final byte delimiter = 10; //This is the ASCII code for a newline character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
try {
mmInputStream = btSocket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
workerThread = new Thread(new Runnable()
{
public void run()
{
while(!Thread.currentThread().isInterrupted() && !stopWorker)
{
try
{
int bytesAvailable = mmInputStream.available();
if(bytesAvailable > 0)
{
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for(int i=0;i<bytesAvailable;i++)
{
byte b = packetBytes[i];
if(b == delimiter)
{
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable()
{
public void run()
{
txtBytesSize.setText("Received data: "+data);
}
});
}
else
{
readBuffer[readBufferPosition++] = b;
}
}
}
}
catch (IOException ex)
{
stopWorker = true;
}
}
}
});
workerThread.start();
} else {
Toast.makeText(getApplicationContext(),
"Bluetooth is not connected", Toast.LENGTH_SHORT).show();
}
}
My Arduino code:
const int ledPin = 7;
byte serialA;
void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
}
void loop() {
if (Serial.available() > 0) {serialA = Serial.read();Serial.println(serialA);}
switch (serialA) {
case 49://49 is the bytes of "1"
digitalWrite(ledPin, HIGH);
Serial.println(serialA);
break;
case 50: //50 is the bytes of "2"
digitalWrite(ledPin, LOW);
Serial.println(serialA);
break;
break;
}
}

Categories

Resources