Frequent disconnect()/setup() in IOIO Service

80 views
Skip to first unread message

Kevin Miller

unread,
Nov 30, 2016, 5:54:17 PM11/30/16
to ioio-users
Hello, 
I've got a really big project nearing completion, but now that I'm getting into the fine details of UART communication, I'm having a problem with frequent disconnect()/setup() cycles which is interfering with the serial communications. I'm using Bluetooth for developing, but I don't think that is the cause because when I run the basic HelloIOIOService example, it is rock solid. What other reasons could be causing the disconnect? Is there some way to dig deeper to see what is causing the disconnects?


Thanks,
Kevin

Kevin Miller

unread,
Dec 1, 2016, 8:22:36 AM12/1/16
to ioio-...@googlegroups.com
Perhaps I'm over-thinking the disconnect() function. What happens to the UART and the data in the UART buffers when the IOIO disconnects? I'm assuming that the UART configuration is lost, so I interrupt the thread that's handling the device communications and reset everything. I could set a flag when the setup() runs the first time and skip the UART config if setup() runs again. Is that possible?

Kevin

--
You received this message because you are subscribed to a topic in the Google Groups "ioio-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ioio-users/zDXx_-guywQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ioio-users+unsubscribe@googlegroups.com.
To post to this group, send email to ioio-...@googlegroups.com.
Visit this group at https://groups.google.com/group/ioio-users.
For more options, visit https://groups.google.com/d/optout.

Kevin Miller

unread,
Dec 3, 2016, 11:52:03 PM12/3/16
to ioio-users
It looks like the problem is related to Bluetooth after all. When I use the UART for several exchanges, the Bluetooth disconnects 6 times out of 10. See attached Logcat.I've tried two different phones.

I see others have had similar issues. Any suggestions? I only need Bluetooth for debugging, but I'm dead in the water now.

Kevin
BT_Disconnect.pdf

Ytai Ben-Tsvi

unread,
Dec 5, 2016, 12:05:59 AM12/5/16
to ioio-...@googlegroups.com
I would try a different dongle and/or recalibrate the IOIO oscillator as described in the wiki under calibration wipe. I've seen cases where data losses occur silently with some dongle/phone combination, resulting in a disconnect.
From your logs I see no evidence of disconnects though. Would you share your code?

--
You received this message because you are subscribed to the Google Groups "ioio-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ioio-users+unsubscribe@googlegroups.com.

Kevin Miller

unread,
Dec 5, 2016, 2:12:04 AM12/5/16
to ioio-users
On the log, the first highlighted lines, #921 - 924, say "IOIO disconnected, Physical disconnect, and V/BluetoothIOIOConnection: Client initiated disconnect" . That's not evidence of a disconnect? I don't know a lot about the very low-level stuff, so perhaps I'd made some incorrect assumptions.

I will include the methods that catch (sometimes just before _flush() is called and sometimes in _flush(), as this LogCat shows) the "java.io.IOException: Stream has been closed", but a couple notes on the Logcat:
  • Note: When I debug and single-step - it does not fail.
  • The IOIOService is on a separate thread from the main thread. 
  • The LogCat messages with the S2Handler.* tag are from the IOIOService.
  • The device handler is on another thread, and its Logcat tags are RpLidar.*
  • The IOIO Service loop calls RpLidar.connect(UART uart) via a messenger and passes a reference to the Uart configured in the IOIOService setup()
  • The RpLidar.connect sends a reset command to the Lidar and receives some ASCII info from the Lidar such as serial number, etc.
  • So far, so good.
  • At about this point, the "IOIODisconnected" message is thrown, line 921 on LogCat
  • It looks like the IOIO disconnected while receiving the data because there's only 20 bytes available when normally it's 57  (line 941)
  • In reset(), available() returns 20 just before _flush() is called. Sometimes, a NullPointer Exception is thrown on the InputStream.available() here.
  • In this LogCat, the error is in _flush().
  • Inside _flush() InputStream.available() and InputStream.read()are  called from the same try block and IOException "Stream has been closed" is thrown. (line 942)
Here is the flush method:
private void _flushInput()
{
String TAG = "RpLidar._flushInput";

final int arrSize = 1000; // assume no more than this many characters in response
byte[] readBuffer = new byte[arrSize];

try
{
while( _inputStream.available() > 0 )
_inputStream.read( readBuffer );
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG,e.getLocalizedMessage()); //line 956 in LogCat
}
}

Here is the reset() method that calls _flush(). It's go a lot of waits and sleeps and yields because of troubleshooting in progress:
    /**
* Reset(reboot) the RPLIDAR core
* No response is defined in documentation, but testing shows some text is returned
* and is flushed - See comments for details.
* @return true if command was placed in queue
*/
public synchronized boolean reset(){
String TAG = "RpLidar.reset";
Log.d(TAG, "Starting...");

//make sure IOIO is connected
if(!isOpen()) return false;

RplRequest req = getRplRequest(RequestTypes.RESET);
if(req==null){
Log.d(TAG,"FAIL: req = null");
return false;
}

if (!doRplRequest(req)) {
Log.d(TAG,"FAIL: doRplRequest failed");
return false;
}

//troubleshooting
// long timeoutMs = System.currentTimeMillis()+1000;
// while (System.currentTimeMillis() < timeoutMs){
// Thread.yield();
// }

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
Log.d(TAG,"FAIL: Sleep interrupted");
return false;
}

Log.d(TAG,"Before flush...");
try {
Log.d(TAG,"... inputStream.avail = "+_inputStream.available());
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG,"FAIL: IO Exception");
return false;
} catch (NullPointerException e){
//why is this happening? BT Disconnect?
e.printStackTrace();
Log.d(TAG,"FAIL: InputSteam NullPointerException");
return false;

}

_flushInput();
try {
_outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG,"FAIL: Sleep interrupted");
return false;
}

Log.d(TAG,"After flush...");
try {
Log.d(TAG,"... inputStream.avail = "+_inputStream.available());
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG,"FAIL: Sleep interrupted");
return false;
}


Log.d(TAG,"Return: SUCCESS");
return true;
}

Sometimes an exception is thrown in reset just before flush, so because the timing varies a little, it seems that the problem is external to _flush() because the exception is sometimes before _flush starts.

I will try the calibration when I can. I do not have another BT dongle that works with the IOIO, but I'll ask around.

I hope you see something.

Thanks,
Kevin


On Monday, December 5, 2016 at 12:05:59 AM UTC-5, Ytai wrote:
I would try a different dongle and/or recalibrate the IOIO oscillator as described in the wiki under calibration wipe. I've seen cases where data losses occur silently with some dongle/phone combination, resulting in a disconnect.
From your logs I see no evidence of disconnects though. Would you share your code?
On Dec 3, 2016 8:52 PM, "Kevin Miller" <ksmil...@gmail.com> wrote:
It looks like the problem is related to Bluetooth after all. When I use the UART for several exchanges, the Bluetooth disconnects 6 times out of 10. See attached Logcat.I've tried two different phones.

I see others have had similar issues. Any suggestions? I only need Bluetooth for debugging, but I'm dead in the water now.

Kevin

On Wednesday, November 30, 2016 at 5:54:17 PM UTC-5, Kevin Miller wrote:
Hello, 
I've got a really big project nearing completion, but now that I'm getting into the fine details of UART communication, I'm having a problem with frequent disconnect()/setup() cycles which is interfering with the serial communications. I'm using Bluetooth for developing, but I don't think that is the cause because when I run the basic HelloIOIOService example, it is rock solid. What other reasons could be causing the disconnect? Is there some way to dig deeper to see what is causing the disconnects?


Thanks,
Kevin

--
You received this message because you are subscribed to the Google Groups "ioio-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ioio-users+...@googlegroups.com.

P.S

unread,
Dec 5, 2016, 6:04:09 PM12/5/16
to ioio-users
Hi Kevin,
I have been facing similar issues.
1. I tried the code similar to the one you posted on Github. It seems to lower down the disconnects if I read from UART in one thread and process the read data on another thread.
2. At times I saw that whenever the stream got closed IOIO was still connected. Its just that the stream somehow got closed. You can test it with a TRY/Catch. A BRUTE solution I am using is to restart the thread in this situation which is reading the UART. So In the Main service setup() I start all the threads. Then in loop() function I Check if all the threads reading UART and IO's are alive. If any of them is dead due to an exception but IOIO is still connected I re-init the thread.
THis seems to reduce the number of times the system used to die.

YTai: I have 7-8 IOIO's working with 2-3 different makes of Bluetooth dongles. But it seems the disconnection still happens atleast 3-4 times each day(my systems run 24x7). The flow for disconnections is similar to what Kevin shared. You talked about Calibrating the Oscillators could you share the link or give pointers where to search?
PS

Ytai Ben-Tsvi

unread,
Dec 8, 2016, 12:30:34 AM12/8/16
to ioio-...@googlegroups.com
First, to both of you: I wouldn't use Bluetooth for something that needs to work flawlessly 24/7. Not sure if the problem is the standard, the Android stack, the IOIO stack, the dongles or whatever, but from my experience, connection is not 100% reliable. If your code is tolerant to occasional drops, you should be much better off.

Kevin, my hunch is that the exceptions you're seeing as result of the disconnects have to do with your threading model rather than a problem specific to the IOIO. Given that disconnects to happen, it is not clear to me how and when your thread would notice that and reopen its streams in a thread-safe way. Like PS proposes, spawning the UART reader threads from setup and killing them on disconnect (typically, when they get an IOException trying to read) is the recommended way to go about this. This way you never need to worry about changing their pointers under their feet, since the streams will not change throughout the lifetime of the thread.

To unsubscribe from this group and stop receiving emails from it, send an email to ioio-users+unsubscribe@googlegroups.com.

Kevin Miller

unread,
Dec 8, 2016, 2:37:05 PM12/8/16
to ioio-users
 I don't think I've seen the situation where the stream closed but the IOIO was still connected, but I will look for that specifically.

I'm not planning to use BT in production, I just need it for development because the phone's USB is connected to the computer for debugging. If there were some other way to debug Android while the phone is connected to the IOIO, I'd try that. I did try ADB over WiFi, but it seemed only useful for watching LogCat. Android Studio did not integrate with it. Has anyone tried a USB-OTG hub like this (https://www.amazon.com/Hittime-Adapter-Extension-Smartphone-Tablet/dp/B00FGKXY9S) with a IOIO & ADB? If only there'd be some special developer phone with 2 USB ports.

I'm new to multi-threading and I'm sure that there are better ways. I start the IOIO service and the Lidar service in the MainActivity.onCreate:

        //start the IOIO Service
Log.d(TAG,"Creating thread for IOIO service...");
thdIoioService = new Thread() {
public void run() {
startService(new Intent(getApplicationContext(), MyIoioService.class));
}
};
thdIoioService.setName("thdIoioService");
thdIoioService.start();

//start the Lidar Service
Log.d(TAG,"Creating thread for Lidar service...");
thdLidarService = new Thread() {
public void run() {
startService(new Intent(getApplicationContext(), RpLidarService.class));
}
};
thdLidarService.setName("thdLidarService");
thdLidarService.start();


The lidarSevice thread is message handler that creates the lidar controller object. I have all the exceptions caught in the controller and the error bubbles up to method called by the message handler so the app never crashes. I'm not sure how the BT can disconnect and the IOIO stays online - doesn't the IOIO run  disconnect/connect routines when the BT connects/disconnects? Perhaps you are referring to transient RF loss that BT can handle without disconnecting?

Kevin




Reply all
Reply to author
Forward
0 new messages