Accelerometer Bosch - concurrent nomotion and acceleration modules usage; Bluetooth reconnect

Hi,
we are using MetaMotion R sensor, Model Number 5, firmware 1.4.4, hw rev. 0.3
We use BarometerBosch, AmbientLightLtr329 and AccelerometerBosch modules at the same time on the device. Sometimes it happens, that only barometer and ambientlight work, but AccelerometerBosch doesn't report anything for some reason.

I wonder if I'm using it in a correct way - I followed Mbientlab FreeFall example and other tutorials here - and if route on acceleration() can be used together with nomotion.

Here is how we use it:

module in following code is AccelerometerBosch, noMotion is it's nomotion
freeFallDuration - calculated and set to duration of freefall based on the height of fall
...

@Override
public void configure() {
module.configure().odr(50f).commit();

    noMotion.configure()
            .duration(noMotionTime * 1000)
            .threshold(0.1f)
            .commit();
}

@Override
public void start() {
    module.acceleration().addRouteAsync(new RouteBuilder() {
        private long enterTime;

        @Override
        public void configure(RouteComponent source) {

            source.map(Function1.RSS)
                    .average((byte) 4)
                    .filter(ThresholdOutput.BINARY, 0.5f)
                    .multicast()
                    .to()
                    .filter(Comparison.EQ, -1)
                    .stream(new Subscriber() {
                        @Override
                        public void apply(Data data, Object... env) {
            // FREEFALL ENTERED
                            enterTime = System.currentTimeMillis();
                        }
                    })
                    .to()
                    .filter(Comparison.EQ, 1)
                    .stream(new Subscriber() {
                        @Override
                        public void apply(Data data, Object... env) {
                            if (  ((System.currentTimeMillis() - enterTime) > freeFallDuration)) {

                // CALL FREEFALL  ACTION

                            }
            // FREEFALL EXIT
                        }
                    })
                    .end();
        }
    }).continueWith(new Continuation<Route, Void>() {
        @Override
        public Void then(Task<Route> task) throws Exception {
            if (task.isFaulted()) {

        // SOMETIMES IT GETS HERE with java.util.concurrent.TimeoutException: Did not received timer id within 1000ms

            }

            noMotion.addRouteAsync(new RouteBuilder() {
                @Override
                public void configure(RouteComponent source) {
                    source.stream(new Subscriber() {
                        @Override
                        public void apply(Data data, Object... env) {

            // CALL MANDOWN action here                               
                        }
                    });
                }
            }).continueWith(new Continuation<Route, Void>() {
                @Override
                public Void then(Task<Route> task) throws Exception {

                    module.acceleration().start();
                    noMotion.start();
                    module.start();
                    return null;
                }
            });

            return null;
        }
    });

}

@Override
public void stop() {
    module.acceleration().stop();
    noMotion.stop();
    module.stop();
}

....

Callbacks I have at places of "// CALL ..." in above code sometimes do not get called although I can see that
...
module.acceleration().start();
noMotion.start();
module.start();
...
sequence passed.

Sometimes I can see java.util.concurrent.TimeoutException: Did not received timer id within 1000ms in module.acceleration().addRouteAsync().continueWith(). How to avoid this / how to handle it properly?

I also have an issue that I'm sometimes not able to connect to board after turning bluetooth off and back on on phone. What is the correct order of calls when bluetooth gets disabled/enabled on the phone so that nothing leaks on the board or in SDK ... ?

Thanks a lot for any help.

Regards
Oldrich

Comments

  • Please wrap your code with 3 backticks (```).

    @Oldrich said:
    Hi,
    we are using MetaMotion R sensor, Model Number 5, firmware 1.4.4, hw rev. 0.3
    We use BarometerBosch, AmbientLightLtr329 and AccelerometerBosch modules at the same time on the device. Sometimes it happens, that only barometer and ambientlight work, but AccelerometerBosch doesn't report anything for some reason.

    I wonder if I'm using it in a correct way - I followed Mbientlab FreeFall example and other tutorials here - and if route on acceleration() can be used together with nomotion.

    Since you are already using motion detection, you should instead use the low/high g detector to watch for freefall events:
    https://mbientlab.com/androiddocs/3/accelerometer_bosch.html#low-high-detection

    It is not recommended to use both raw acceleration data with the on-board detection algorithms.

    Sometimes I can see java.util.concurrent.TimeoutException: Did not received timer id within 1000ms in module.acceleration().addRouteAsync().continueWith(). How to avoid this / how to handle it properly?

    Odd, you shouldn't getting that error as I don't see any timer code in your snippets. Are you creating a timer elsewhere in your code?

    What other MetaWear API calls are you making?

    I also have an issue that I'm sometimes not able to connect to board after turning bluetooth off and back on on phone. What is the correct order of calls when bluetooth gets disabled/enabled on the phone so that nothing leaks on the board or in SDK ... ?

    That is norma and happens from time to time. You need to implement some retry logic in your app.

  • @Eric
    Hi Eric, thank you for you help.

    For each of the modules I'm calling mwBoard.getModule(moduleClass).
    For Light module.configure() .gain(AmbientLightLtr329.Gain.LTR329_8X) .integrationTime(AmbientLightLtr329.IntegrationTime.LTR329_TIME_250MS) .measurementRate(AmbientLightLtr329.MeasurementRate.LTR329_RATE_2000MS) .commit();
    module.illuminance().addRouteAsync(new RouteBuilder() { @Override public void configure(RouteComponent source) { source.stream(new Subscriber() { @Override public void apply(Data data, Object... env) { // HERE WE JUST READ DATA data.value(Float.class)); } }); } }).continueWith(new Continuation<Route, Void>() { @Override public Void then(Task<Route> task) throws Exception { module.illuminance().start(); return null; } });
    and when stoping
    module.illuminance().stop();

    For Pressure I set it
    module.configure() .filterCoeff(BarometerBosch.FilterCoeff.AVG_16) .pressureOversampling(BarometerBosch.OversamplingMode.ULTRA_HIGH) .standbyTime(500f) .commit();
    and start(), stop() in similar manner as for light module.

    For other SDK calls I do yet mwBoard.tearDown() when I connect to the board before setting my routes. Other calls - serviceBinder.getMetaWearBoard(btDevice), mwBoard.disconnectAsync().continueWith(... { ... serviceBinder.clearSerializedState(btDevice); serviceBinder.removeMetaWearBoard(btDevice); ... } ) and that's probably all.

    I will try to reimplement freefall using low/high as you suggest. What would be settings for this algorithm to have same results as in freefall above?

    For reconnection I basicaly do following - on unexpected disconnects I do new connectAsync() and also when task is faulted I do reconnect until it passes. When bluetooth is disabled on the device I do stop modules, teardown, discnnnectAsync, etc. When it is enabled again I get new mwBoard instance, connectAsync, teardown, setup modules and start them.

    When you refer to retry logics, do you mean it on level of SDK calls (connectAsync(), + reconnect calls until it passes ) or on android bluetooth service level? The problem is that sometimes I get to state when repeated connectAsync() calls never pass. When this happen, sometimes I'm not even able to connect to board with Metabase app.

    Thanks for your help.

    Oldrich

  • edited February 8

    Please check that your posts are formated correctly on the forum and readable, and edit them appropriately. All of the above code snippets are displayed as one liners making it difficult to read.

    @Oldrich said:
    @Eric
    Hi Eric, thank you for you help.

    For each of the modules I'm calling mwBoard.getModule(moduleClass).
    For Light...
    For Pressure ...

    These individually look fine. Are you properly chaining the routes together?
    I don't see any timer code so I'm still not sure why you are getting a timer id error msg.

    For other SDK calls I do yet ... and that's probably all.

    Looks fine.

    I will try to reimplement freefall using low/high as you suggest. What would be settings for this algorithm to have same results as in freefall above?

    The on-chip detection algorithm is different than the data processor version. You will have to experiment with different configurations to find what best suites your use case.

    For reconnection I basicaly do following - on unexpected disconnects I do new connectAsync() and also when task is faulted I do reconnect until it passes. When bluetooth is disabled on the device I do stop modules, teardown, discnnnectAsync, etc. When it is enabled again I get new mwBoard instance, connectAsync, teardown, setup modules and start them.

    If Bluetooth is disabled none of those functions will do anything.

    When you refer to retry logics, do you mean it on level of SDK calls (connectAsync(), + reconnect calls until it passes ) or on android bluetooth service level?

    Yes

    The problem is that sometimes I get to state when repeated connectAsync() calls never pass. When this happen, sometimes I'm not even able to connect to board with Metabase app.

    Could be an issue with your device's Bluetooth adapter. Maybe disabling then re-enabling the adapter will fix the problem.

  • @Eric said:
    Please check that your posts are formated correctly on the forum and readable, and edit them appropriately. All of the above code snippets are displayed as one liners making it difficult to read.

    Sorry for bad formatting.

    @Oldrich said:
    @Eric
    Hi Eric, thank you for you help.

    For each of the modules I'm calling mwBoard.getModule(moduleClass).
    For Light...
    For Pressure ...

    These individually look fine. Are you properly chaining the routes together?

    Do you mean chaining of routes for different modules? I think I probably don't.
    I do something like this (just pseudocode):

    module1.configure().blabla().commit();
    module1.addRouteAsync().continueWith(  module1.start()  )
    

    and then same for other modules

     module2.configure().blablabla().commit();
     module2.addRouteAsync().continueWith(  module2.start()  )
    

    Should I be doing it like this instead?

    module1.configure().blabla().commit();
    module2.configure().blablabla().commit();
    module1.addRouteAsync().continueWith(module2.addRouteAsync().continueWith( module2.start(); module1.start(); )
    

    Or could you, please, advice me some nice pattern for such chaining (I'm not very familiar with bolts yet)?

    I don't see any timer code so I'm still not sure why you are getting a timer id error msg.

    For other SDK calls I do yet ... and that's probably all.

    Looks fine.

    I will try to reimplement freefall using low/high as you suggest. What would be settings for this algorithm to have same results as in freefall above?

    The on-chip detection algorithm is different than the data processor version. You will have to experiment with different configurations to find what best suites your use case.

    Ok, thanks, I will experiment with this.

    For reconnection I basicaly do following - on unexpected disconnects I do new connectAsync() and also when task is faulted I do reconnect until it passes. When bluetooth is disabled on the device I do stop modules, teardown, discnnnectAsync, etc. When it is enabled again I get new mwBoard instance, connectAsync, teardown, setup modules and start them.

    If Bluetooth is disabled none of those functions will do anything.

    ok, thanks, I thought it could be the case, but was not sure if it doesn't clear some state also on phone side.

    When you refer to retry logics, do you mean it on level of SDK calls (connectAsync(), + reconnect calls until it passes ) or on android bluetooth service level?

    Yes

    The problem is that sometimes I get to state when repeated connectAsync() calls never pass. When this happen, sometimes I'm not even able to connect to board with Metabase app.

    Could be an issue with your device's Bluetooth adapter. Maybe disabling then re-enabling the adapter will fix the problem.

    I tried this before, but it didn't help. Also I do not want our app to break other apps which could be making use of bluetooth.

    Thanks for your help.
    Oldrich

  • @Oldrich said:

    @Oldrich said:
    @Eric
    Hi Eric, thank you for you help.

    For each of the modules I'm calling mwBoard.getModule(moduleClass).
    For Light...
    For Pressure ...

    These individually look fine. Are you properly chaining the routes together?

    Do you mean chaining of routes for different modules? I think I probably don't.
    I do something like this (just pseudocode):

    module1.configure().blabla().commit();
    module1.addRouteAsync().continueWith(  module1.start()  )
    

    and then same for other modules

     module2.configure().blablabla().commit();
     module2.addRouteAsync().continueWith(  module2.start()  )
    

    Should I be doing it like this instead?

    module1.configure().blabla().commit();
    module2.configure().blablabla().commit();
    module1.addRouteAsync().continueWith(module2.addRouteAsync().continueWith( module2.start(); module1.start(); )
    

    Or could you, please, advice me some nice pattern for such chaining (I'm not very familiar with bolts yet)?

    Typically, you only start the sensors once all of the routes are successfully added. Since adding routes is an async task, Bolts provides the framework for consuming async results and task chaining.

    Checkout the Bolts documentation for more details on their API.

    When you refer to retry logics, do you mean it on level of SDK calls (connectAsync(), + reconnect calls until it passes ) or on android bluetooth service level?

    Yes

    The problem is that sometimes I get to state when repeated connectAsync() calls never pass. When this happen, sometimes I'm not even able to connect to board with Metabase app.

    Could be an issue with your device's Bluetooth adapter. Maybe disabling then re-enabling the adapter will fix the problem.

    I tried this before, but it didn't help. Also I do not want our app to break other apps which could be making use of bluetooth.

    In this case, what is the error returned when connectAsync fails?

  • In this case, what is the error returned when connectAsync fails?

    Hi Eric,
    one of the scenarios which leads to unability to reconnect:
    I disable bluetooth manualy on the phone (via android bluetooth disable/enable soft button) . Sometimes it leads to bluetooth stack crash and in the debugger I can see this or similar exception:

        D/BluetoothAdapter: onBluetoothServiceDown: Sending callbacks to 1 clients
            onBluetoothServiceDown: Finished sending callbacks to registered clients
        D/BluetoothGatt: refresh() - device: F2:66:56:BC:EB:6E
        E/BluetoothGatt: android.os.DeadObjectException
                at android.os.BinderProxy.transactNative(Native Method)
                at android.os.BinderProxy.transact(Binder.java:758)
                at android.bluetooth.IBluetoothGatt$Stub$Proxy.refreshDevice(IBluetoothGatt.java:1405)
                at android.bluetooth.BluetoothGatt.refresh(BluetoothGatt.java:1349)
                at java.lang.reflect.Method.invoke(Native Method)
                at com.mbientlab.metawear.android.BtleService$AndroidPlatform.refresh(BtleService.java:248)
                at com.mbientlab.metawear.android.BtleService$AndroidPlatform.closeGatt(BtleService.java:259)
                at com.mbientlab.metawear.android.BtleService.onDestroy(BtleService.java:552)
                at android.app.ActivityThread.handleStopService(ActivityThread.java:3611)
                at android.app.ActivityThread.-wrap26(Unknown Source:0)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1732)
                at android.os.Handler.dispatchMessage(Handler.java:105)
                at android.os.Looper.loop(Looper.java:173)
                at android.app.ActivityThread.main(ActivityThread.java:6698)
                at java.lang.reflect.Method.invoke(Native Method)
                at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)
        D/BluetoothGatt: close()
            unregisterApp() - mClientIf=6
        E/BluetoothGatt: android.os.DeadObjectException
                at android.os.BinderProxy.transactNative(Native Method)
                at android.os.BinderProxy.transact(Binder.java:758)
                at android.bluetooth.IBluetoothGatt$Stub$Proxy.unregisterClient(IBluetoothGatt.java:1319)
                at android.bluetooth.BluetoothGatt.unregisterApp(BluetoothGatt.java:760)
                at android.bluetooth.BluetoothGatt.close(BluetoothGatt.java:651)
                at com.mbientlab.metawear.android.BtleService$AndroidPlatform.closeGatt(BtleService.java:260)
                at com.mbientlab.metawear.android.BtleService.onDestroy(BtleService.java:552)
                at android.app.ActivityThread.handleStopService(ActivityThread.java:3611)
                at android.app.ActivityThread.-wrap26(Unknown Source:0)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1732)
                at android.os.Handler.dispatchMessage(Handler.java:105)
                at android.os.Looper.loop(Looper.java:173)
                at android.app.ActivityThread.main(ActivityThread.java:6698)
                at java.lang.reflect.Method.invoke(Native Method)
                at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)
        D/BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@720a6ca
        D/BluetoothGatt: connect() - device: F2:66:56:BC:EB:6E, auto: false
            registerApp()
        D/BluetoothGatt: registerApp() - UUID=6992d553-4a31-42fe-830e-498e812dd7da
        D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
    

    usually when this happens and I reanable bluetooth, then connectAsync task is repeatedly faulted with TimeoutException: Failed to connect and discover services within 10000ms
    Although I redo init sequence in response to bluetooth availability:

        @Override
            public synchronized void onServiceConnected(ComponentName name, IBinder service) {
                serviceBinder = (BtleService.LocalBinder) service;
                btManager =
                            (BluetoothManager) applicationContext.getSystemService(BLUETOOTH_SERVICE);
    
                    btDevice = btManager.getAdapter().getRemoteDevice(macAddress);
    
                    mwBoard = serviceBinder.getMetaWearBoard(btDevice);
    
                // HERE I DO connectAsync(), etc.
            }
    

    Another exception after bluetooth disable, followed unability to connect again :

  • D/BluetoothGatt: onConnectionUpdated() - Device=F2:66:56:BC:EB:6E interval=36 latency=0 timeout=500 status=0
    D/BluetoothGatt: onConnectionUpdated() - Device=F2:66:56:BC:EB:6E interval=36 latency=0 timeout=500 status=0
    D/BluetoothGatt: discoverServices() - device: F2:66:56:BC:EB:6E
    D/BluetoothGatt: discoverServices() - device: F2:66:56:BC:EB:6E
    D/BluetoothGatt: onSearchComplete() = Device=F2:66:56:BC:EB:6E Status=0
    D/BluetoothGatt: onSearchComplete() = Device=F2:66:56:BC:EB:6E Status=0
    W/BluetoothGatt: Unhandled exception in callback
        java.lang.NullPointerException: Attempt to read from field 'com.mbientlab.metawear.impl.platform.TimedTask com.mbientlab.metawear.android.BtleService$AndroidPlatform.connectTask' on a null object reference
            at com.mbientlab.metawear.android.BtleService$AndroidPlatform.access$300(BtleService.java:201)
            at com.mbientlab.metawear.android.BtleService$1.onServicesDiscovered(BtleService.java:155)
            at android.bluetooth.BluetoothGatt$1$5.run(BluetoothGatt.java:306)
            at android.bluetooth.BluetoothGatt.runOrQueueCallback(BluetoothGatt.java:711)
            at android.bluetooth.BluetoothGatt.-wrap0(Unknown Source:0)
            at android.bluetooth.BluetoothGatt$1.onSearchComplete(BluetoothGatt.java:302)
            at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:110)
            at android.os.Binder.execTransact(Binder.java:681)
    D/BluetoothGatt: setCharacteristicNotification() - uuid: 326a9006-85cb-9195-d9dd-464cfbbae75a enable: true
    D/BluetoothGatt: refresh() - device: F2:66:56:BC:EB:6E
    D/BluetoothGatt: close()
    D/BluetoothGatt: unregisterApp() - mClientIf=10
    D/BluetoothGatt: onConnectionUpdated() - Device=F2:66:56:BC:EB:6E interval=6 latency=0 timeout=500 status=0
    D/BluetoothGatt: onConnectionUpdated() - Device=F2:66:56:BC:EB:6E interval=36 latency=0 timeout=500 status=0
    D/BluetoothGatt: refresh() - device: F2:66:56:BC:EB:6E
    D/BluetoothGatt: close()
        unregisterApp() - mClientIf=6
    D/BluetoothGatt: connect() - device: F2:66:56:BC:EB:6E, auto: false
    D/BluetoothGatt: registerApp()
    D/BluetoothGatt: registerApp() - UUID=5d075fbd-1b58-4d55-ac6d-6d954166ec31
    D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
    D/BluetoothGatt: refresh() - device: F2:66:56:BC:EB:6E
    D/BluetoothGatt: close()
        unregisterApp() - mClientIf=6
    D/BluetoothGatt: connect() - device: F2:66:56:BC:EB:6E, auto: false
        registerApp()
        registerApp() - UUID=0c9461f5-cd23-4131-a52a-96362ce8749e
    D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
    W/Choreographer: OPTS_INPUT: First frame was drawed before optimized, so skip!
    W/Choreographer: OPTS_INPUT: First frame was drawed before optimized, so skip!
    W/Choreographer: OPTS_INPUT: First frame was drawed before optimized, so skip!
    D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=F2:66:56:BC:EB:6E
    D/BluetoothGatt: onConnectionUpdated() - Device=F2:66:56:BC:EB:6E interval=6 latency=0 timeout=500 status=0
    D/BluetoothGatt: onConnectionUpdated() - Device=F2:66:56:BC:EB:6E interval=36 latency=0 timeout=500 status=0
    D/BluetoothGatt: discoverServices() - device: F2:66:56:BC:EB:6E
    D/BluetoothGatt: onSearchComplete() = Device=F2:66:56:BC:EB:6E Status=0
    D/BluetoothGatt: setCharacteristicNotification() - uuid: 326a9006-85cb-9195-d9dd-464cfbbae75a enable: true
    W/Choreographer: OPTS_INPUT: First frame was drawed before optimized, so skip!
    W/Choreographer: OPTS_INPUT: First frame was drawed before optimized, so skip!
    D/BluetoothGatt: refresh() - device: F2:66:56:BC:EB:6E
    D/BluetoothGatt: close()
        unregisterApp() - mClientIf=6
    D/BluetoothGatt: connect() - device: F2:66:56:BC:EB:6E, auto: false
        registerApp()
    D/BluetoothGatt: registerApp() - UUID=7e6b192b-3be2-470b-9127-dedc233186b4
    D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
    D/BluetoothGatt: refresh() - device: F2:66:56:BC:EB:6E
    D/BluetoothGatt: close()
        unregisterApp() - mClientIf=6
    D/BluetoothGatt: connect() - device: F2:66:56:BC:EB:6E, auto: false
    D/BluetoothGatt: registerApp()
    D/BluetoothGatt: registerApp() - UUID=4dd007c3-fc3c-472d-a32d-18d19d86949e
    D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
    D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=F2:66:56:BC:EB:6E
    D/BluetoothGatt: onConnectionUpdated() - Device=F2:66:56:BC:EB:6E interval=6 latency=0 timeout=500 status=0
    D/BluetoothGatt: onConnectionUpdated() - Device=F2:66:56:BC:EB:6E interval=36 latency=0 timeout=500 status=0
    D/BluetoothGatt: discoverServices() - device: F2:66:56:BC:EB:6E
    D/BluetoothGatt: onSearchComplete() = Device=F2:66:56:BC:EB:6E Status=0
    D/BluetoothGatt: setCharacteristicNotification() - uuid: 326a9006-85cb-9195-d9dd-464cfbbae75a enable: true
    D/BluetoothGatt: refresh() - device: F2:66:56:BC:EB:6E
    D/BluetoothGatt: close()
        unregisterApp() - mClientIf=6
    D/BluetoothGatt: connect() - device: F2:66:56:BC:EB:6E, auto: false
        registerApp()
    D/BluetoothGatt: registerApp() - UUID=45d3873d-efa6-4c01-86f1-618f29688d84
    D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
    D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=F2:66:56:BC:EB:6E
    D/BluetoothGatt: onConnectionUpdated() - Device=F2:66:56:BC:EB:6E interval=36 latency=0 timeout=500 status=0
    D/BluetoothGatt: discoverServices() - device: F2:66:56:BC:EB:6E
    D/BluetoothGatt: onSearchComplete() = Device=F2:66:56:BC:EB:6E Status=0
    D/BluetoothGatt: setCharacteristicNotification() - uuid: 326a9006-85cb-9195-d9dd-464cfbbae75a enable: true
    D/BluetoothAdapter: onBluetoothServiceDown: android.bluetooth.IBluetooth$Stub$Proxy@8ea85d7
    D/BluetoothAdapter: onBluetoothServiceDown: Sending callbacks to 1 clients
    D/BluetoothAdapter: onBluetoothServiceDown: Finished sending callbacks to registered clients
    D/BluetoothAdapter: onBluetoothServiceDown: null
    D/BluetoothAdapter: onBluetoothServiceDown: Sending callbacks to 1 clients
        onBluetoothServiceDown: Finished sending callbacks to registered clients
    D/BluetoothGatt: refresh() - device: F2:66:56:BC:EB:6E
    E/BluetoothGatt: android.os.DeadObjectException
            at android.os.BinderProxy.transactNative(Native Method)
            at android.os.BinderProxy.transact(Binder.java:758)
            at android.bluetooth.IBluetoothGatt$Stub$Proxy.refreshDevice(IBluetoothGatt.java:1405)
            at android.bluetooth.BluetoothGatt.refresh(BluetoothGatt.java:1349)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.mbientlab.metawear.android.BtleService$AndroidPlatform.refresh(BtleService.java:248)
            at com.mbientlab.metawear.android.BtleService$AndroidPlatform.closeGatt(BtleService.java:259)
            at com.mbientlab.metawear.android.BtleService.onDestroy(BtleService.java:552)
            at android.app.ActivityThread.handleStopService(ActivityThread.java:3611)
            at android.app.ActivityThread.-wrap26(Unknown Source:0)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1732)
            at android.os.Handler.dispatchMessage(Handler.java:105)
            at android.os.Looper.loop(Looper.java:173)
            at android.app.ActivityThread.main(ActivityThread.java:6698)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)
    D/BluetoothGatt: close()
        unregisterApp() - mClientIf=6
    
    • When your device is in this state, do other ble apps work, like "nRF Connect"?
    • Does restarting the app itself fix the problem?
    • Can you reliably put your Android device in this state?
      • what Android device / OS are you using?
      • Do other Android device exhibit the same issue?
  • @Eric said:

    • When your device is in this state, do other ble apps work, like "nRF Connect"?

    Yes. I tried and "Beacon scanner" app works with other device at the same time.

    • Does restarting the app itself fix the problem?

    Sometimes yes - i.e. after few connection timeouts it reconnects, sometimes it doesn't help.

    • Can you reliably put your Android device in this state?

    +/- yes. After several sequences of bluietooth disable/enable it usually happens.

    * what Android device / OS are you using?  
    

    We reproduce it on android 8.0 (Mi note 2), Google Pixel 2 XL (android 9), Nokia (Android 6.0) ,..

    * Do other Android device exhibit the same issue?  
    

    We have it reported fro our colleagues also, but I'm not sure what devices exactly they have.

  • @Oldrich said:

    @Eric said:

    • When your device is in this state, do other ble apps work, like "nRF Connect"?

    Yes. I tried and "Beacon scanner" app works with other device at the same time.

    Can you connect to the device with the "nRF Connect" app?

    • Can you reliably put your Android device in this state?

    +/- yes. After several sequences of bluietooth disable/enable it usually happens.

    Does this happen on its own i.e. you are not touching the BT adapter?

  • @Eric said:

    @Oldrich said:

    @Eric said:

    • When your device is in this state, do other ble apps work, like "nRF Connect"?

    Yes. I tried and "Beacon scanner" app works with other device at the same time.

    Can you connect to the device with the "nRF Connect" app?

    Yes, In my application it timeouts repeated connectAsync(), but I'm able to connect to same sensor using nRF Connect app from the same phone. When I connect to it from nRF Connect, it resurrects and connectAsync() in my app completes successfully.

    • Can you reliably put your Android device in this state?

    +/- yes. After several sequences of bluietooth disable/enable it usually happens.

    Does this happen on its own i.e. you are not touching the BT adapter?

    In the past I saw this inability to reconnect after leting it to run over night or so, but wasn't able to reproduce this in past two days. Given that I'd say it is related to adapter ON/OFF - at least it is very "reliable" way.

    I have yet another question. I thought, that tearDown() should "clear" the device to some default state. I turned green LED from MEtawear sample app. When I connect from our app to the device I call tearDown() to remove old routes, etc. I expected it will also turn the LED off, but it stays ON. What do I need to call on successfull connection to the device to be 100% sure, that there are no routes, all modules are stoped, ...

    Thanks
    Oldrich

  • @Oldrich said:

    @Eric said:

    @Oldrich said:

    @Eric said:

    • When your device is in this state, do other ble apps work, like "nRF Connect"?

    Yes. I tried and "Beacon scanner" app works with other device at the same time.

    Can you connect to the device with the "nRF Connect" app?

    Yes, In my application it timeouts repeated connectAsync(), but I'm able to connect to same sensor using nRF Connect app from the same phone. When I connect to it from nRF Connect, it resurrects and connectAsync() in my app completes successfully.

    Hrm...it would be interesting to see if you can connect to the board in question with another MetaWear based app. From our end, it might be worth swapping out the BLE code with Nordic's BLE library given the good stability of the nRF Connect app.

    • Can you reliably put your Android device in this state?

    +/- yes. After several sequences of bluietooth disable/enable it usually happens.

    Does this happen on its own i.e. you are not touching the BT adapter?

    In the past I saw this inability to reconnect after leting it to run over night or so, but wasn't able to reproduce this in past two days. Given that I'd say it is related to adapter ON/OFF - at least it is very "reliable" way.

    Might be fixed if we use different BLE code, as mentioned above

    I have yet another question. I thought, that tearDown() should "clear" the device to some default state. I turned green LED from MEtawear sample app. When I connect from our app to the device I call tearDown() to remove old routes, etc. I expected it will also turn the LED off, but it stays ON. What do I need to call on successfull connection to the device to be 100% sure, that there are no routes, all modules are stoped, ...

    tearDown is explained in the documentation:
    https://mbientlab.com/androiddocs/3/metawearboard.html#tear-down

    If you want a default, clean state, you can use the Debug module to reset the board.

  • @Eric said:

    @Oldrich said:

    @Eric said:

    @Oldrich said:

    @Eric said:

    • When your device is in this state, do other ble apps work, like "nRF Connect"?

    Yes. I tried and "Beacon scanner" app works with other device at the same time.

    Can you connect to the device with the "nRF Connect" app?

    Yes, In my application it timeouts repeated connectAsync(), but I'm able to connect to same sensor using nRF Connect app from the same phone. When I connect to it from nRF Connect, it resurrects and connectAsync() in my app completes successfully.

    Hrm...it would be interesting to see if you can connect to the board in question with another MetaWear based app. From our end, it might be worth swapping out the BLE code with Nordic's BLE library given the good stability of the nRF Connect app.

    Yes, I tried it and I'm able to connect with sample Metawear app as well. Connection in my app is reestablished then ,too. I have created a simple app which runs AmbientLight sensor and prints to debug console. It tries to reconnect on unexpected disconnects and on bluetooth off/on. I can send you the this project if you'd like to. I want to eliminate possibility that I'm doing something in a wrong way. Our problem is reproducible on this app.

    • Can you reliably put your Android device in this state?

    +/- yes. After several sequences of bluietooth disable/enable it usually happens.

    Does this happen on its own i.e. you are not touching the BT adapter?

    In the past I saw this inability to reconnect after leting it to run over night or so, but wasn't able to reproduce this in past two days. Given that I'd say it is related to adapter ON/OFF - at least it is very "reliable" way.

    Might be fixed if we use different BLE code, as mentioned above

    I have yet another question. I thought, that tearDown() should "clear" the device to some default state. I turned green LED from MEtawear sample app. When I connect from our app to the device I call tearDown() to remove old routes, etc. I expected it will also turn the LED off, but it stays ON. What do I need to call on successfull connection to the device to be 100% sure, that there are no routes, all modules are stoped, ...

    tearDown is explained in the documentation:
    https://mbientlab.com/androiddocs/3/metawearboard.html#tear-down

    If you want a default, clean state, you can use the Debug module to reset the board.

    I have read the documentation before and now again, but I still have some questions -
    1) when I remove all data routes with tearDown(), does it also stop sensor module? Is there a way to find out module state? If it's running, if there are active Routes, etc ? Or should I call stop(); each time before configure(); addRoute(); start(); ?
    2) Is there another way or just reset() ? I want to clean board on successfull connnectAsync() without droping connection. At least I want to make sure nothing runs on the device and consumes battery and if someone "played" with device (like he turned LEDs on, or some other modules) which are not needed in our app.

    Thanks for your help,
    Oldrich

  • @Oldrich said:

    @Eric said:

    @Oldrich said:

    @Eric said:

    @Oldrich said:

    @Eric said:

    • When your device is in this state, do other ble apps work, like "nRF Connect"?

    Yes. I tried and "Beacon scanner" app works with other device at the same time.

    Can you connect to the device with the "nRF Connect" app?

    Yes, In my application it timeouts repeated connectAsync(), but I'm able to connect to same sensor using nRF Connect app from the same phone. When I connect to it from nRF Connect, it resurrects and connectAsync() in my app completes successfully.

    Hrm...it would be interesting to see if you can connect to the board in question with another MetaWear based app. From our end, it might be worth swapping out the BLE code with Nordic's BLE library given the good stability of the nRF Connect app.

    Yes, I tried it and I'm able to connect with sample Metawear app as well. Connection in my app is reestablished then ,too. I have created a simple app which runs AmbientLight sensor and prints to debug console. It tries to reconnect on unexpected disconnects and on bluetooth off/on. I can send you the this project if you'd like to. I want to eliminate possibility that I'm doing something in a wrong way. Our problem is reproducible on this app.

    Yes, post the project.

    I have yet another question. I thought, that tearDown() should "clear" the device to some default state. I turned green LED from MEtawear sample app. When I connect from our app to the device I call tearDown() to remove old routes, etc. I expected it will also turn the LED off, but it stays ON. What do I need to call on successfull connection to the device to be 100% sure, that there are no routes, all modules are stoped, ...

    tearDown is explained in the documentation:
    https://mbientlab.com/androiddocs/3/metawearboard.html#tear-down

    If you want a default, clean state, you can use the Debug module to reset the board.

    I have read the documentation before and now again, but I still have some questions -
    1) when I remove all data routes with tearDown(), does it also stop sensor module?

    No

    Is there a way to find out module state? If it's running, if there are active Routes, etc ? Or should I call stop(); each time before configure(); addRoute(); start(); ?

    The simplest way is to reset the board.

    2) Is there another way or just reset() ? I want to clean board on successfull connnectAsync() without droping connection. At least I want to make sure nothing runs on the device and consumes battery and if someone "played" with device (like he turned LEDs on, or some other modules) which are not needed in our app.

    No, reset the board to put it in a clean state. It's OK to drop the connection when it is expected to happen.

  • @Eric
    Hi Eric,
    attaching simple app where I'm able to reproduce the reconnection problem. It only prints illuminance to console and tries to keep permanent connection with metawear. Several times turning bluetooth off / on usually leads to described problem. In MainActivity, there is hardcoded MAC of metawear sensor
    private final String macAddress =
    which needs to be changed before using app. Reconnection and other calls is pretty much same as what I do in our application. Can you, please, see it and optionaly advice me some enhancements for stabilization to see if it helps to reconnection timeout issue?

    Thanks.

    Oldrich

  • edited February 27

    @Oldrich said:
    @Eric
    Hi Eric,
    Can you, please, see it and optionaly advice me some enhancements for stabilization to see if it helps to reconnection timeout issue?

    Thanks.

    Oldrich

    Unfortunately I haven't had a chance to look over the project yet.

    I will update this thread when I have new information.

  • After running your project, it appears that doing a BLE scan fixes the connection issues that occur from toggling the Bluetooth adapter. So for your project, you should get the BluetoothDevice object from a BLE scan rather than directly instantiating it from a MAC address.

  • @Eric said:
    After running your project, it appears that doing a BLE scan fixes the connection issues that occur from toggling the Bluetooth adapter. So for your project, you should get the BluetoothDevice object from a BLE scan rather than directly instantiating it from a MAC address.

    Thanks Eric,
    I'll give it a try today / latest tomorrow and let you know how it went.

    Regards,
    Oldrich

  • @Eric
    Hi Eric,
    thank you very much for your help. I'm starting BLE scan when trying to connect and stoping it on sucessfull connection. Although we had a chance to test it only for several hours with toggling bluetooth state off/on, I think it realy solves our issue. As far as we were able to test it always connects now.

    I have a different question now. We use nomotion accelerometer-Bosch module to detect no motion for let's say 5 mins. Sometimes it happens, that when we reconnect to the sensor after long period without connection, we start getting these events immediately. It seems to me, that mwboard has these events buffered and sends them then right away. Does it work this way?

    Thank you!

    Regards,
    Oldrich

  • @Oldrich said:
    @Eric
    I have a different question now. We use nomotion accelerometer-Bosch module to detect no motion for let's say 5 mins. Sometimes it happens, that when we reconnect to the sensor after long period without connection, we start getting these events immediately. It seems to me, that mwboard has these events buffered and sends them then right away. Does it work this way?

    There's no buffering. It's possible the board was never reset and the Android object was never destroyed so it was already prepared to receive the events.

Sign In or Register to comment.