2

I receiving 3 data from Arduino and the data just keep coming in. My problem is the data doesn't update to the new received values.

Here is the screenshot from the logcat: Screenshot from Log cat So D/BPM is the value in the textview 68 D/SPo2 is the value in the textview 99 D/temp is the value in textview 28.0

D/read: 71 is for BPM 99 is for SPo2 and 28.11 is for temp. But the textview values just stuck at 68 99 and 28.0. :(

Here are my code for the Android part:

 public class Bluetooth_dataDisplay extends Activity {
    //declaration
    BluetoothAdapter mAdapter;
    private ArrayAdapter adapter;
    TextView myLabel;
    TextView myLabel1;
    TextView myLabel2;
    Thread workerThread;
    byte[] readBuffer;
    int readBufferPosition;
    volatile boolean stopWorker;
    private ListView listview;
    private BluetoothSocket bluetoothSocket;
    private ConnectedThread mConnectedThread;
    final int handlerState = 0;
    private StringBuilder recDataString = new StringBuilder();

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case Constants.MESSAGE_READ:
                    byte[] readBuf = (byte[]) msg.obj;
                    // construct a string from the valid bytes in the buffer
                    String readMessage = new String(readBuf, 0, msg.arg1);
                    recDataString.append(readMessage);
                    Log.d("read",readMessage);
                    if (recDataString.charAt(0) == '#')
                {
                    String BPM = recDataString.substring(1,3);
                    String SPO2= recDataString.substring(3,5);
                    String Temp= recDataString.substring(5,9);
                    Log.d("BPM", BPM);
                    Log.d("SPO2", SPO2);
                    Log.d("Temp", Temp);
                    myLabel.setText("BPM" + "  " + BPM);
                    myLabel1.setText("SPO2" +"  "+ SPO2);
                    myLabel2.setText("Temp"+"  " + Temp);
                }
                    //recDataString.delete(0, recDataString.length());


                    break;


            }
        }
    };




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.bluetooth_datadisplay);
        myLabel = (TextView)findViewById(R.id.label);
        myLabel1 = (TextView)findViewById(R.id.label1);
        myLabel2= (TextView)findViewById(R.id.label2);






    }//end oncreate

    @Override
    public void onResume() {
        super.onResume();  // Always call the superclass method first
        //Get MAC address from BluetoothActivity using intent and Extra
        String MAC = getIntent().getStringExtra("MAC");
        //must declare every time on a new activity if not will result in null error
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        //create device and set the MAC address
        BluetoothDevice bluetoothDevice = mAdapter.getRemoteDevice(MAC);
        // Initiate a connection request in a separate thread
        ConnectingThread t = new ConnectingThread(bluetoothDevice);
        t.start();

    }

    @Override
    public void onPause()
    {
        super.onPause();
        try {
            bluetoothSocket.close();
        } catch (IOException e) {
            Log.e("error", "terminate thread");
            e.printStackTrace();
        }
    }

    /**
     * Start the ConnectedThread to begin managing a Bluetooth connection
     *
     * @param socket The BluetoothSocket on which the connection was made
     * @param device The BluetoothDevice that has been connected
     */
    public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {

        // Start the thread to manage the connection and perform transmissions
        mConnectedThread = new ConnectedThread(socket);
        mConnectedThread.start();

    }

    private class ConnectingThread extends Thread {
        private final BluetoothSocket bluetoothSocket;
        private final BluetoothDevice bluetoothDevice;

        public ConnectingThread(BluetoothDevice device) {

            BluetoothSocket temp = null;
            bluetoothDevice = device;

            // Get a BluetoothSocket to connect with the given BluetoothDevice
            try {
                temp = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
            } catch (IOException e) {
                e.printStackTrace();
            }
            bluetoothSocket = temp;
        }

        public void run() {
            // Cancel any discovery as it will slow down the connection
            mAdapter.cancelDiscovery();

            try {
                // This will block until it succeeds in connecting to the device
                // through the bluetoothSocket or throws an exception
                bluetoothSocket.connect();
            } catch (IOException connectException) {
                connectException.printStackTrace();
                try {
                    bluetoothSocket.close();
                } catch (IOException closeException) {
                    closeException.printStackTrace();
                }
            }

            // Code to manage the connection in a separate thread
            connected(bluetoothSocket, bluetoothDevice);
        }

        // Cancel an open connection and terminate the thread
        public void cancel() {
            try {
                bluetoothSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 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 bluetoothSocket;
        private final InputStream mmInputStream;
        //private final OutputStream mmOutputStream;

        public ConnectedThread(BluetoothSocket socket) {
            bluetoothSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the BluetoothSocket input and output streams
            try {
                tmpIn = socket.getInputStream();
                //tmpOut = socket.getOutputStream();
            } catch (IOException e) {
            }

            mmInputStream = tmpIn;
            //mmOutputStream = tmpOut;
        }//endofConnectedThread(BluetoothSocket socket)


        public void run() {
            byte[] buffer = new byte[1024];
            int bytes;

            // Keep listening to the InputStream while connected
            while (true) {
                try {
                    // Read from the InputStream
                    bytes = mmInputStream.read(buffer);

                    // Send the obtained bytes to the UI Activity
                    mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
                            .sendToTarget();
                } catch (IOException e) {
                    break;
                }
            }
        }//end of void run

    }//end of connectecthread

}

Because Arduino will be sending in data eg #719928.11 so the index will be in this order (0123456789)

Which is why I did it this way to extract the data:

 if (recDataString.charAt(0) == '#')
            {
                String BPM = recDataString.substring(1,3);
                String SPO2= recDataString.substring(3,5);
                String Temp= recDataString.substring(5,9);
                Log.d("BPM", BPM);
                Log.d("SPO2", SPO2);
                Log.d("Temp", Temp);
                myLabel.setText("BPM" + "  " + BPM);
                myLabel1.setText("SPO2" +"  "+ SPO2);
                myLabel2.setText("Temp"+"  " + Temp);
            }

Just to add more details regarding the data: BPM and SPO2 are in int (pulse oximeter) Temp is in float format So if my pulse oximeter is not on. My data look like this #0028.28 where the first 0 is BPM and the second 0 is SPO2. 28.28 is temp

So if the pulse oximeter is on. My data look like this #669928.28 where 66 is BPM and 99 is SPO2. 28.28 is temp. Below is data displayed in Arduino serial monitor:

pulse oximeter off pulse oximeter on

logcat when oximeter is on logcat when oximter is off

Spotty
  • 197
  • 2
  • 2
  • 14
  • Can you plz include more details so that I can know from where you are posting data to Handler . – Shishupal Shakya Dec 28 '15 at 12:03
  • Hi @AndroidDev I edited the post with the whole of data transmission – Spotty Dec 28 '15 at 12:09
  • Why you are appending readMessage to StringBuilder ? Is there any specific reason ? – Shishupal Shakya Dec 28 '15 at 12:53
  • so that I can extract the data I want. I got this idea from this tutorial https://wingoodharry.wordpress.com/2014/04/15/android-sendreceive-data-with-arduino-using-bluetooth-part-2/comment-page-2/#comment-309 – Spotty Dec 28 '15 at 13:12
  • I am seeing that you are extracting the data one time for one iteration of code only . If you are extracting the data only once for one iteration then just use String , No use of StringBuilder . – Shishupal Shakya Dec 28 '15 at 13:14
  • Try the answer I have given and let me know If you are facing same issue again . – Shishupal Shakya Dec 28 '15 at 13:18

2 Answers2

1

Try this

1 . replace

 private StringBuilder recDataString = new StringBuilder();

with this one

private String recDataString = "";

2 . replace

recDataString.append(readMessage);

with this one

recDataString = readMessage ;

Data Parsing for different-2 situations :

if(recDataString.lenth > 0){
   //If Oxiometer is OFF
   if(recDataString.startsWith(#00) && recDataString.length == 8){
    //Do Parsing here  #0028.14
     String BPM = "0";
     String SPO2= "0";
     String temp = recDataString.split("00")[1];

     myLabel.setText("BPM" + "  " + BPM);
     myLabel1.setText("SPO2" +"  "+ SPO2);
     myLabel2.setText("Temp"+"  " + Temp);
  }

   //If Oxiometer is on 
  if(recDataString.startsWith(#) && recDataString.length() == 10){
    //Do Parsing here  #779928.08
     String BPM = recDataString.substring(1,3);
     String SPO2= recDataString.substring(3,5);
     String temp = recDataString.substring(5,recDataString.lenth());

     myLabel.setText("BPM" + "  " + BPM);
     myLabel1.setText("SPO2" +"  "+ SPO2);
     myLabel2.setText("Temp"+"  " + Temp); 
  }

   //If String contains # only .
  if(recDataString.startsWith(#) && recDataString.length == 1){
   //Do nothing or you can decide

  }

}
Shishupal Shakya
  • 1,632
  • 2
  • 18
  • 41
  • Process: course.examples.bluetoothapp, PID: 24151 java.lang.StringIndexOutOfBoundsException: length=1; regionStart=1; regionLength=2 – Spotty Dec 28 '15 at 13:18
  • Actually I need to keep getting the value updated. So I need to extract in a loop or? Because data will keep coming in and I need to have the data updated with new value each time it comes in. – Spotty Dec 28 '15 at 13:19
  • You need to put checks for length of recDataString , You are getting this error since recDataString has only 1 character and you are trying to substring from position 1 ,So it is giving you StringIndexOutOfBoundsException . – Shishupal Shakya Dec 28 '15 at 13:23
  • Hi Spotty Are you there ? – Shishupal Shakya Dec 28 '15 at 16:45
  • For your simplicity ,I have included code to parse Oxiometer data . – Shishupal Shakya Dec 28 '15 at 17:51
  • Hi @AndroidDev. Sorry was out. Anyway I tested it. I put a Log.e("do nothing","do nothing") under if(recDataString.startsWith(#) && recDataString.length == 1). Most of the time it is just doing nothing. So the data is updating very very very slow. Only 1 or twice the data changed or it just stuck at same value. I don't know why the data is coming in as # then after that the as 779928.08. Refer to above Logcat image. I put a Log.e("enter recdata","enter recdata"); after this line: if(recDataString.length() > 0) – Spotty Dec 29 '15 at 09:03
  • Maybe the way the data come in as sometime # sometime 779928.08. That why it doesn't update? :( should I send my data in a packet? – Spotty Dec 29 '15 at 09:05
  • Is it giving any Exception now ?As it was giving StringIndexOutOfBoundsException . – Shishupal Shakya Dec 29 '15 at 09:49
  • no. No exception. It just do nothing. So nothing was displayed in the textbox just now. – Spotty Dec 29 '15 at 10:00
  • Are you sure , You are getting data continuously right now .? – Shishupal Shakya Dec 29 '15 at 10:13
  • I am getting a impression that you are getting data in some other formats ,and those formats are not matching three conditions which I have included in the code . – Shishupal Shakya Dec 29 '15 at 10:24
  • What do you mean in other formats? Erm in this part of the android code: public void run() { byte[] buffer = new byte[1024]; int bytes; bytes is in int. But my data at Arduino side BPM & SPo2 is in int only temp is in float. Will this affect? – Spotty Dec 29 '15 at 10:32
  • 1
    Hi AndroidDev. I changed my Arduino code. I removed serial.print(\n) and also reduced the delay from 1000 to 150. I getting the values updated but updating need to wait a while then it will update. – Spotty Dec 29 '15 at 10:54
  • If you want a delay between updates then increase delay period let say 500 in place 150 – Shishupal Shakya Dec 29 '15 at 11:29
  • Hi I changed the Arduino code. Instead of adding delay I removed the delay. As I observed the log cat again if I add delay. My data that comes in will sometimes read # only sometimes read 779928.08 only. Now without delay and in a for loop like that. The data is coming in like #0028.0 in row. So is updating fast now. – Spotty Dec 29 '15 at 12:03
  • But for now. The code is working good. Just a few rare time wrong value display as the data coming in is too fast. :) Thanks for your help! – Spotty Dec 29 '15 at 12:11
0

Before recDataString.append(readMessage); try to reset the recDataString first, like this:

recDataString.setLength(0);

Because if it does not reset, it will continue append new strings:

#689928.0
#689928.06899719928.11 ...
NamNH
  • 1,752
  • 1
  • 15
  • 37
  • Hi @John I pasted recDataString.setLength(0); before recDataString.append(read message) and I got the following error 2-28 20:13:41.365 10610-10610/course.examples.bluetoothapp E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: course.examples.bluetoothapp, PID: 10610 java.lang.StringIndexOutOfBoundsException: length=1; regionStart=1; regionLength=2 – Spotty Dec 28 '15 at 12:16
  • Hi John I added more details of the data being send from Arduino to phone. :( Not sure does my logic of receiving data is right? – Spotty Dec 28 '15 at 12:25
  • Can you use debug with your Android studio? Try it whenever your `Handler` got the new `message`. One more, you need to check messages conditions before using them (check null, length...) – NamNH Dec 29 '15 at 02:41
  • Hi @John I tested with AndroidDev answers above. I realised the data coming it sometimes read # only and sometimes read 649927.94 if the pulse oximeter is on. Log cat image above. :( So most of the time is just doing nothing. maybe this is why the values are not updated? – Spotty Dec 29 '15 at 09:14
  • Hi @John. Problem solved for now. Thanks for your help too! :) – Spotty Dec 29 '15 at 12:15
  • Glad to hear that, this week I'm too busy with new project :) – NamNH Dec 30 '15 at 04:03