Simultane gpio logging beta-03

edited January 2017 in Android
Hi Eric,

I testing to logging two analog divices with the Board at the beta version. For one device all works fine. Here the setup:
logging = mwBoard.getModule(Logging.class);
gpio = mwBoard.getModule(Gpio.class);
timer = mwBoard.getModule(Timer.class);
gpio.getPin((byte)0).analogAdc().addRoute(source ->
source.log((msg, env) -> {
Log.i("GPIO 0", "" + msg.value(Short.class));
})
).onSuccess(t -> t.getResult());

timer.schedule(33,false, () -> {
gpio.getPin((byte)0).analogAdc().read();
Log.i("GPIO","pin 0 ok");
}).continueWithTask(task -> {
scheduledTask = task.getResult();
Log.i("GPIO","schedule ok");
return null;
});

But if I logging a second sensor, I reveice an Error.

Here the source code:
logging = mwBoard.getModule(Logging.class);
gpio = mwBoard.getModule(Gpio.class);
timer = mwBoard.getModule(Timer.class);
gpio.getPin((byte)0).analogAdc().addRoute(source ->
source.log((msg, env) -> {
Log.i("GPIO 0", "" + msg.value(Short.class));
})
).continueWithTask(task -> {
gpio.getPin((byte) 1).analogAdc().addRoute(source ->
source.log((msg, env) -> {
Log.i("GPIO 1", "" + msg.value(Short.class));
})
).onSuccess(t -> t.getResult());
return null;
}).onSuccess(t -> t.getResult());

timer.schedule(33,false, () -> {
gpio.getPin((byte)0).analogAdc().read();
Log.i("GPIO","pin 0 ok");
gpio.getPin((byte)1).analogAdc().read();
Log.i("GPIO","pin 1 ok");
}).continueWithTask(task -> {
scheduledTask = task.getResult();
Log.i("GPIO","schedule ok");
return null;
});
and the Error:
01-20 09:36:58.351 24485-24496/com.mbientlab.metawear.starter I/GPIO: pin 0 ok
01-20 09:36:58.351 24485-24496/com.mbientlab.metawear.starter I/GPIO: pin 1 ok
01-20 09:36:58.441 24485-24496/com.mbientlab.metawear.starter W/BluetoothGatt: Unhandled exception in callback
java.lang.IllegalStateException: Cannot set the result of a completed task.
at bolts.TaskCompletionSource.setResult(TaskCompletionSource.java:63)
at com.mbientlab.metawear.impl.EventImpl.recordCommand(EventImpl.java:150)
at com.mbientlab.metawear.impl.EventImpl.access$600(EventImpl.java:43)
at com.mbientlab.metawear.impl.EventImpl$2.onResponseReceived(EventImpl.java:89)
at com.mbientlab.metawear.impl.MetaWearBoardImpl.handleNotifyCharResponse(MetaWearBoardImpl.java:989)
at com.mbientlab.metawear.android.BtleService$1.onCharacteristicChanged(BtleService.java:193)
at android.bluetooth.BluetoothGatt$1.onNotify(BluetoothGatt.java:485)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:399)
at android.os.Binder.execTransact(Binder.java:453)

Comments

  • You need to chain the async tasks together as outline in the Bolts documentation:
    gpio.getPin((byte) 0).analogAdc().addRoute(source -> source.log(...))
    .onSuccessTask(ignored -> gpio.getPin((byte) 1).analogAdc().addRoute(source -> source.log(...))
    .onSuccessTask(ignored -> mwBoard.getModule(Timer.class).schedule(33, false, () -> {
    gpio.getPin((byte) 0).analogAdc().read();
    gpio.getPin((byte) 1).analogAdc().read();
    }).continueWith(task -> {
    // check result of chain here
    });
  • Hi Eric,

    thank you for your help! Until this step all works fine. Now I want read two sensorfusion values and the gpio values but it dosn't work.
    I test this code first with only one value from the sensorfusion and it works. But if I add a second value nothing works.

    Here the source code with two gpio and one sensorfusion value:
    sensorFusion.eulerAngles().addRoute(source ->
    source.log((msg, env) -> {
    EulerAngle e = msg.value(EulerAngle.class);
    Calendar c = msg.timestamp();
    Log.i("FOOT LEFT", "EULER " + msg.timestamp().getTime() + e);
    }))
    .onSuccessTask(task ->
    gpio.getPin((byte) 0).analogAdc().addRoute(source -> source.log(
    (data, env) -> Log.i("GPIO 0", "" + data.value(Short.class))))
    .onSuccessTask(ignored -> gpio.getPin((byte) 1).analogAdc().addRoute(source -> source.log(
    (data, env) -> Log.i("GPIO 1", "" + data.value(Short.class)))))
    .onSuccessTask(ignored -> mwBoard.getModule(Timer.class).schedule(33, false, () -> {
    gpio.getPin((byte) 0).analogAdc().read();
    gpio.getPin((byte) 1).analogAdc().read();
    }))
    ).onSuccess(task -> scheduledTask = task.getResult());
    Here with two gpio and two sensorfusion values:
    sensorFusion.eulerAngles().addRoute(source ->
    source.log((msg, env) -> {
    EulerAngle e = msg.value(EulerAngle.class);
    Calendar c = msg.timestamp();
    Log.i("FOOT LEFT", "EULER " + msg.timestamp().getTime() + e);
    }))
    .onSuccessTask(task -> sensorFusion.linearAcceleration().addRoute(source ->
    source.log((msg, env) -> {
    Acceleration a = msg.value(Acceleration.class);
    Calendar c = msg.timestamp();
    Log.i("FOOT LEFT", "Accel " + msg.timestamp().getTime() + a);
    })))
    .onSuccessTask(task ->
    gpio.getPin((byte) 0).analogAdc().addRoute(source -> source.log(
    (data, env) -> Log.i("GPIO 0", "" + data.value(Short.class))))
    .onSuccessTask(ignored -> gpio.getPin((byte) 1).analogAdc().addRoute(source -> source.log(
    (data, env) -> Log.i("GPIO 1", "" + data.value(Short.class)))))
    .onSuccessTask(ignored -> mwBoard.getModule(Timer.class).schedule(33, false, () -> {
    gpio.getPin((byte) 0).analogAdc().read();
    gpio.getPin((byte) 1).analogAdc().read();
    }))
    ).onSuccess(task -> scheduledTask = task.getResult());
    and the stacktrace:

    01-24 11:53:07.340 26433-26433/com.mbientlab.metawear.starter E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.mbientlab.metawear.starter, PID: 26433
    java.lang.NullPointerException: Attempt to invoke interface method 'void com.mbientlab.metawear.module.Timer$ScheduledTask.start()' on a null object reference
    at com.mbientlab.metawear.starter.DeviceSetupActivityFragment.-com_mbientlab_metawear_starter_DeviceSetupActivityFragment_lambda$1(DeviceSetupActivityFragment.java:120)
    at com.mbientlab.metawear.starter.DeviceSetupActivityFragment$-void_onViewCreated_android_view_View_view_android_os_Bundle_savedInstanceState_LambdaImpl0.onClick(DeviceSetupActivityFragment.java)
    at android.view.View.performClick(View.java:5698)
    at android.widget.TextView.performClick(TextView.java:10888)
    at android.view.View$PerformClick.run(View.java:22570)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:158)
    at android.app.ActivityThread.main(ActivityThread.java:7231)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
  • edited January 2017
    You always need to check the result of the chained tasks.  Sounds like an error is being thrown by one of the tasks so you need to find what error it is.

  • I read the topics error handling and chaining at your link. Now I revice the status of the tasks but I don't know to handle this.
    The error is that the board has a time out. How can I solve this problem? I tested this error additional with other sensor values (Quternion), but I recive allways the same error. I hope you can help me.

    Here the link to the source code.

    The error message:

    01-25 13:30:44.358 4680-4778/com.mbientlab.metawear.starter I/Results TASK 1:: =====================
    01-25 13:30:44.358 4680-4778/com.mbientlab.metawear.starter I/Results error:: null
    01-25 13:30:44.358 4680-4778/com.mbientlab.metawear.starter I/Results result:: com.mbientlab.metawear.impl.MetaWearBoardImpl$RouteInner@2e60e28
    01-25 13:30:44.358 4680-4778/com.mbientlab.metawear.starter I/Results isCancel:: false
    01-25 13:30:44.358 4680-4778/com.mbientlab.metawear.starter I/Results iscomplete:: true
    01-25 13:30:44.358 4680-4778/com.mbientlab.metawear.starter I/Results isFault:: false
    01-25 13:30:44.448 4680-4692/com.mbientlab.metawear.starter I/Results TASK 2:: =====================
    01-25 13:30:44.448 4680-4692/com.mbientlab.metawear.starter I/Results error:: null
    01-25 13:30:44.448 4680-4692/com.mbientlab.metawear.starter I/Results result:: com.mbientlab.metawear.impl.MetaWearBoardImpl$RouteInner@e0bf4e6
    01-25 13:30:44.448 4680-4692/com.mbientlab.metawear.starter I/Results isCancel:: false
    01-25 13:30:44.448 4680-4692/com.mbientlab.metawear.starter I/Results iscomplete:: true
    01-25 13:30:44.448 4680-4692/com.mbientlab.metawear.starter I/Results isFault:: false
    01-25 13:30:44.498 4680-4680/com.mbientlab.metawear.starter V/ActivityThread: updateVisibility : ActivityRecord{565a5d6 token=android.os.BinderProxy@13f8cdd {com.mbientlab.metawear.starter/com.mbientlab.metawear.starter.MainActivity}} show : false
    01-25 13:30:44.788 4680-5781/com.mbientlab.metawear.starter I/Results TASK 3:: =====================
    01-25 13:30:44.788 4680-5781/com.mbientlab.metawear.starter I/Results error:: java.util.concurrent.TimeoutException: Creating logger timed out
    01-25 13:30:44.788 4680-5781/com.mbientlab.metawear.starter I/Results result:: null
    01-25 13:30:44.788 4680-5781/com.mbientlab.metawear.starter I/Results isCancel:: false
    01-25 13:30:44.788 4680-5781/com.mbientlab.metawear.starter I/Results iscomplete:: true
    01-25 13:30:44.788 4680-5781/com.mbientlab.metawear.starter I/Results isFault:: true
  • You are trying to log too many sensors at once.  For your specific usage, you can only log euler angles + linear acc, or either one along with the the 2 gpio pins.
  • edited January 2017
    Thank you for your support. Will this be possible in a later firmware/api update or with the api 2.8? Is it possible to log the two sensorfusions data and stream the gpio values?
  • No API will let you log all of those sensors together.

    Yes, you can log both sensor fusion outputs and stream gpio data.
This discussion has been closed.