I am trying to read from a bluetooth module connected to arduino Uno. My application is a simple counter where the values are displayed on the arduino and the android app. The problem is that my android application get readings for some time (40-50 sec) and then stop at a random reading. When I check on the arduino serial monitor, the counter keeps counting and doesn't stop. Can someone please help?
Note: Ignore the buttons that I created :D
Java code:
package com.example.ibm.bluetooth_3;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.UUID;
import com.example.ibm.bluetooth_3.R;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final String TAG = "bluetooth2";
Button btnOn, btnOff;
TextView txtArduino;
Handler h;
final int RECIEVE_MESSAGE = 1; // Status for Handler
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder sb = new StringBuilder();
private ConnectedThread mConnectedThread;
// SPP UUID service
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// MAC-address of Bluetooth module (you must edit this line)
private static String address = "00:06:66:68:30:D6";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnOn = (Button) findViewById(R.id.btnOn); // button LED ON
btnOff = (Button) findViewById(R.id.btnOff); // button LED OFF
txtArduino = (EditText) findViewById(R.id.txtArduino); // for display the received data from the Arduino
h = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case RECIEVE_MESSAGE: // if receive massage
byte[] readBuf = (byte[]) msg.obj;
String strIncom = new String(readBuf, 0, msg.arg1); // create string from bytes array
sb.append(strIncom); // append string
int endOfLineIndex = sb.indexOf("\r\n"); // determine the end-of-line
if (endOfLineIndex > 0) { // if end-of-line,
String sbprint = sb.substring(0, endOfLineIndex); // extract string
sb.delete(0, sb.length()); // and clear
txtArduino.setText(sbprint); // update TextView
}
//Log.d(TAG, "...String:"+ sb.toString() + "Byte:" + msg.arg1 + "...");
break;
}
};
};
btAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter
checkBTState();
btnOn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
btnOn.setEnabled(true);
mConnectedThread.write("1"); // Send "1" via Bluetooth
//Toast.makeText(getBaseContext(), "Turn on LED", Toast.LENGTH_SHORT).show();
}
});
btnOff.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
btnOff.setEnabled(true);
mConnectedThread.write("0"); // Send "0" via Bluetooth
//Toast.makeText(getBaseContext(), "Turn off LED", Toast.LENGTH_SHORT).show();
}
});
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
if(Build.VERSION.SDK_INT >= 10){
try {
final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class });
return (BluetoothSocket) m.invoke(device, MY_UUID);
} catch (Exception e) {
Log.e(TAG, "Could not create Insecure RFComm Connection",e);
}
}
return device.createRfcommSocketToServiceRecord(MY_UUID);
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "...onResume - try connect...");
// Set up a pointer to the remote node using it's address.
BluetoothDevice device = btAdapter.getRemoteDevice(address);
// Two things are needed to make a connection:
// A MAC address, which we got above.
// A Service ID or UUID. In this case we are using the
// UUID for SPP.
try {
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
}
/*try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
}*/
// Discovery is resource intensive. Make sure it isn't going on
// when you attempt to connect and pass your message.
btAdapter.cancelDiscovery();
// Establish the connection. This will block until it connects.
Log.d(TAG, "...Connecting...");
try {
btSocket.connect();
Log.d(TAG, "....Connection ok...");
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
}
}
// Create a data stream so we can talk to server.
Log.d(TAG, "...Create Socket...");
mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "...In onPause()...");
try {
btSocket.close();
} catch (IOException e2) {
errorExit("Fatal Error", "In onPause() and failed to close socket." + e2.getMessage() + ".");
}
}
private void checkBTState() {
// Check for Bluetooth support and then check to make sure it is turned on
// Emulator doesn't support Bluetooth and will return null
if(btAdapter==null) {
errorExit("Fatal Error", "Bluetooth not support");
} else {
if (btAdapter.isEnabled()) {
Log.d(TAG, "...Bluetooth ON...");
} else {
//Prompt user to turn on Bluetooth
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
private void errorExit(String title, String message){
Toast.makeText(getBaseContext(), title + " - " + message, Toast.LENGTH_LONG).show();
finish();
}
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket 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); // Get number of bytes and message in "buffer"
h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget(); // Send to message queue Handler
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(String message) {
Log.d(TAG, "...Data to send: " + message + "...");
byte[] msgBuffer = message.getBytes();
try {
mmOutStream.write(msgBuffer);
} catch (IOException e) {
Log.d(TAG, "...Error data send: " + e.getMessage() + "...");
}
}
}
}
Android XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:focusable="true">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="On"
android:id="@+id/btnOn"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="52dp"
android:enabled="true"
android:focusable="true"
android:focusableInTouchMode="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Off"
android:id="@+id/btnOff"
android:layout_below="@+id/btnOn"
android:layout_centerHorizontal="true"
android:layout_marginTop="63dp"
android:enabled="true"
android:focusable="true"
android:focusableInTouchMode="true" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="10"
android:id="@+id/txtArduino"
android:layout_below="@+id/btnOff"
android:layout_centerHorizontal="true"
android:layout_marginTop="65dp" />
</RelativeLayout>
Android Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.ibm.bluetooth_3" >
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Arduino code:
#include <SoftwareSerial.h>
SoftwareSerial mySerial (3, 2);
void setup()
{
Serial.begin (57600);
mySerial.begin (115200);
}
void loop()
{
for (int i=0; i < 1000000; i++)
{
mySerial.println (i);
Serial.println (i);
delay (100);
}
}
-
1So far, I am not able to solve the problem :'(Kito312– Kito3122015年03月30日 08:56:51 +00:00Commented Mar 30, 2015 at 8:56
2 Answers 2
I am not sure if you have found the answer. Here are my observation. Those who are searching for same problem can refer to these...
Change your Android device. Devices will have different bluetooth stack provided by bluetooth chip makers. Cheap ones will have problems. I had this. When I tested with another couple of devices, they seem to have handled it very well. It is all in the bluetooth stack on Android device!
Though I have not had problems with Arduino bluetooth device, try changing that.
Disable all logging on Android app. This will reduce burden on device.
Disable Serial communication on Arduino used for debugging purpose. This way you can make sure that only one serial communication channel is active communicating with Android.
If you follow this, surely you will have solved your problem as I have solved the same.
-Sachin
On the Arduino side, try increasing the delay or decreasing the baud rate. I have an application that dumps a stored history to a Bluetooth module talking to Bluetooth Terminal/Graphics on a Google Nexus 7. At 57600 baud, I've seen the same thing happen. My solution was to delay for 50ms after every 100 lines of output. While your Arduino code should be sending even slower than mine does, your Android system including your application code, might need an even slower input.
-
I made the delay 100 ms and it didn't work. Changing the baud rate of the bluetooth module is not an option because it works at high baud rate. I am using BlueSmirf Gold.Kito312– Kito3122015年03月29日 15:01:51 +00:00Commented Mar 29, 2015 at 15:01
-
Unless I misunderstood something, you said it stopped working after a time and you're trying to find out why. I've suggested 2 experiments that may help you find out.JRobert– JRobert2015年03月29日 15:14:07 +00:00Commented Mar 29, 2015 at 15:14
-
I used your app. It's very nice and it works perfectly when it comes to reading. When I choose "Terminal and Graph" I see the readings without stopping which is exactly what I am seeking for. Instead of using a listview that you are using I want to use an editext. Can you please tell me how?Kito312– Kito3122015年03月29日 15:22:12 +00:00Commented Mar 29, 2015 at 15:22
-
The app isn't mine, just one I bought for graphing logged data from my instruments, and as you said, a very nice one. If you select "start logging" from its menu, it will capture its input to a text file, at which point you can do anything you want to with it. I don't know any way to interact with the data within the app other than using its terminal screen to send commands back to the Arduino/.JRobert– JRobert2015年03月29日 16:38:43 +00:00Commented Mar 29, 2015 at 16:38