0

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);
  }
} 
1
  • 1
    So far, I am not able to solve the problem :'(
    – Kito312
    Commented Mar 30, 2015 at 8:56

2 Answers 2

1

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...

  1. 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!

  2. Though I have not had problems with Arduino bluetooth device, try changing that.

  3. Disable all logging on Android app. This will reduce burden on device.

  4. 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

0

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.

4
  • 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
    Commented 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
    Commented 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
    Commented 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
    Commented Mar 29, 2015 at 16:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.