Reworking Freefall example to Step Counter

edited November 2017 in Android
I wanted to implement a step counter with MetaMotionC and after reading the tutorials it seemed that refactoring the 'freefall' example might be a good approach.  Unfortunately, while I usually seem to establish a connection I get persistent 'Error setting up route java.util.concurrent.TimeoutException: Creating logger timed out ....".  (Note: the metamotion C works perfectly with the metawear app so the device is not the problem.)

I think I understand the overall process: Android's onCreate() sets up the UI where I place the methods reacting to clicks, and implements ServiceConnection.  onServiceConnected() takes care of connecting to the device, creating the data producer, and establishing the route for the data.  I don't understand how to set up the route both in the big picture (what is it and how it should be behaving) and little picture (how is it constructed).  Any answers or guidance to relevant info would be appreciated,  I've included what I think is the code relevant to this question below.

import com.mbientlab.metawear.module.AccelerometerBmi160;
private AccelerometerBmi160 accelerometer;
public void onServiceConnected(ComponentName name, IBinder service) {
    BtleService.LocalBinder serviceBinder = (BtleService.LocalBinder) service;
    String mwMacAddress= "C1:84:A2:1A:45:DF";   ///< Put your board's MAC address here
    BluetoothManager btManager= (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
    BluetoothDevice btDevice= btManager.getAdapter().getRemoteDevice(mwMacAddress);
    mwBoard= serviceBinder.getMetaWearBoard(btDevice);
    mwBoard.connectAsync().onSuccessTask(task -> {
        accelerometer = mwBoard.getModuleOrThrow(AccelerometerBmi160.class);
        return accelerometer.stepCounter().addRouteAsync(source ->
            source.log((data, env) -> Log.i(LOG_TAG, data.toString())));
    }).continueWith((Continuation<Route, Void>) task -> {
        if (task.isFaulted()) {
            Log.e(LOG_TAG, mwBoard.isConnected() ? "Error setting up route" : "Error connecting", task.getError());
        } else {
            Log.i(LOG_TAG, "Connected");
            debug = mwBoard.getModule(Debug.class);
            logging= mwBoard.getModule(Logging.class);
        return null;


  • You need to release the allocated resources in the firmware when you are done using the board.  The freefall app already has a button on the screen to reset the board.
  • Hi Eric.  Thank you for the response.  I'm new to Java/Android so on a very steep learning curve and I'm not sure I understand the answer.  What I think is going on is: in onServiceConnected I define the route that the data producer will use.  My only experience with routes is node.js/express and this seems to be similar ie. a function is applied to the output of the 'source'.  From your answer, the route I set up is correct and the data should be appearing in Logcat but the problem is not with the route.  So then the trouble is in onCreate() (see below) where I must not be releasing the resource?  If so, why is the error thrown from connectAsync().onSuccess(...) ?  How do I release the resource?

    protected void onCreate(Bundle savedInstanceState) {

            getApplicationContext().bindService(new Intent(this, BtleService.class), this, Context.BIND_AUTO_CREATE);

            findViewById( -> {

            findViewById( -> {

            findViewById( -> debug.resetAsync());

  • This is the compete route failure error.  What might cause route creation to time out (battery is good, range is a few centimetres, metawear iOS app connects problem free)?

    11-02 15:16:40.930 19025-19058/com.mbientlab.metawear.tutorial.freefalldetector E/stepCounter: Error setting up route
                                                                                                   java.util.concurrent.TimeoutException: Creating logger timed out
                                                                                                       at com.mbientlab.metawear.impl.LoggingImpl$
                                                                                                       at java.util.concurrent.Executors$
                                                                                                       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(
                                                                                                       at java.util.concurrent.ScheduledThreadPoolExecutor$
                                                                                                       at java.util.concurrent.ThreadPoolExecutor.runWorker(
                                                                                                       at java.util.concurrent.ThreadPoolExecutor$
  • edited November 2017
    The error occurs because you repeatedly requested the firmware allocate resources for the logger but have never released any of resources.  

    Simply press the reset button before closing the app.
  • Thanks Eric.  Pressing reset just caused the app to display the error "Unfortunately, FreeFall Detector has stopped."  The stack trace indicated that was due to a null object reference (because onServiceConnected error'ed out so no instance of debug? ).  But given what you said, I popped the battery and that did the trick.
This discussion has been closed.