Receiving I2C Errors

Android SDK: 2.4.0
RPro Firmware: 1.1.1

I am successfully reading from a BNO055 device over I2C when the device is connected to the RPro.  However I am testing for when the board is not available (damaged, not connected, etc) and sending data to the I2C address.  I was expecting my CompletionHandler.failure to be triggered but that never happens.

Here is the code:

i2cModule
  .routeData()
  .fromId(1, 70)
  .stream("bno_available")
  .commit()
  .onComplete(new CompletionHandler[RouteManager] {
    override def failure(error: Throwable): Unit = {
      Log.e(TAG, "Failure in RouteManager", error)
    }

    override def success(result: RouteManager): Unit = {
      Log.w(TAG, "BNO: RouteManager Configured")
      result.subscribe("bno_available", new MessageHandler {
        override def process(message: Message): Unit = {
          Log.w(TAG, "BNO: isAvailable message: " + message)
        }
      })
    }
  })

Log.w(TAG, "BNO: isAvailable sending data")
i2cModule.readData(address, 0x00, 1, 70)

And here is the stacktrace:

01-28 09:28:03.237  19912-19940/ E/MetaWear﹕ Background task reported an error
    java.util.concurrent.ExecutionException: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.mbientlab.metawear.MetaWearBleService$AsyncOperationAndroidImpl.setResult(java.lang.Object, java.lang.Throwable)' on a null object reference
            at java.util.concurrent.FutureTask.report(FutureTask.java:93)
            at java.util.concurrent.FutureTask.get(FutureTask.java:163)
            at com.mbientlab.metawear.MetaWearBleService$3.run(MetaWearBleService.java:1260)
            at java.util.Timer$TimerImpl.run(Timer.java:284)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.mbientlab.metawear.MetaWearBleService$AsyncOperationAndroidImpl.setResult(java.lang.Object, java.lang.Throwable)' on a null object reference
            at com.mbientlab.metawear.MetaWearBleService$AndroidBleConnection.setResultReady(MetaWearBleService.java:490)
            at com.mbientlab.metawear.impl.DefaultMetaWearBoard$24.process(DefaultMetaWearBoard.java:3244)
            at com.mbientlab.metawear.impl.DefaultMetaWearBoard.receivedResponse(DefaultMetaWearBoard.java:3830)
            at com.mbientlab.metawear.MetaWearBleService$2$7.run(MetaWearBleService.java:1037)
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)

The SDK throws a runtime with the message "Received I2C data less than 4 bytes" which is fine but I never know of the error.

Is the RouteData not yet completed to pass exceptions to the CompletionHandler.failure method?

Comments

  • The CompletionHandler for the commit call refers to whether or not the route was able to be created.  The failure event will be called if the route could not be created, which will rarely happen.

    You can use the MetaWearBoard class to check if there is an active connection with either the ConnectionStateHandler callbacks or ths isConnected function.


  • I believe that you misread the question.

    Exceptions are thrown but no callback that is under my control has any knowledge of the exception.  In my example I am attempting to communicate to a non-existent I2C device.  The SDK rightfully throws an exception.

    How am I supposed to capture that exception when no callback method gets fired?

    My exploration of the ConnectionStateHandler is only about the Gatt communications between the phone and the RPro.  The only instances of the ConnectionStateHandler.failure() method firing are related to the Gatt communications.
  • edited January 2016
    What is the data that is coming back?  The rest of the "Received I2C data less than 4 bytes" message has the contents of the array. I will have to refactor the I2C class to pass back exceptions to the caller for the  readData function that accepts a user index.

    As a side note, are you building an app with Scala?
  • edited January 2016
    Thanks for looking into this, Eric.  The data returned is always [13, 1, 70] from both boards when the RPro is unable to communicate to the BNO.  The last two bytes appear to match my fromId call.

    I am using Scala as my development language.  It was simply two additional configuration lines in the app/build.gradle to be off and running.  I am also using RxScala/RxAndroid to manage UI interactions between fragments, MetaWear communications, GPS, calculations, persistence to disk and error handling.

    It is quite liberating to not write procedural-like code on the Android.  By using Rx, everything is a stream and enabling any kind of transformation.  I'm sure you would appreciate that freedom too after seeing the operations available in the DataSignal class.  :)
  • Oh that's cool!  I was not aware Scala could be used in Android developement.  The last I had looked into this was a while ago when people were trying to use Groovy.  I am not a Scala expert by any means but I do have a working knowledge of the language and am familiar with the functional programming paradigm.

    I have used Rx in the past but that was mostly from the Reactive Programming class on Coursera.
This discussion has been closed.