Unable to get step counter data

Hi all, 

just recently looked into the mbientlab c / cpro again and I am currently evaluating the boards for a eHealth project. I want to do step counting, get double-taps, etc. 

So I started with a plain and easy android app, no UI right now, all I want is to get the total number of steps. While I get called for each step taken, the total number of steps is never called - I never see that log output. Can someone see what is wrong with the code?

public void detectSteps()
{
Log.i("MainActivity", "Starting to detect steps...");
try {
final Bmi160Accelerometer bmi160AccModule= mwBoard.getModule(Bmi160Accelerometer.class);
bmi160AccModule.start();
bmi160AccModule.enableStepDetection();
bmi160AccModule.routeData().fromStepCounter(true).stream("step_counter").commit().onComplete(new AsyncOperation.CompletionHandler<RouteManager>() {
@Override
public void success(RouteManager result) {
result.subscribe("step_counter", new RouteManager.MessageHandler() {
@Override
public void process(Message msg) {
Log.i("MainActivity", "Steps= " + msg.getData(Integer.class));
}
});
}
});

// Receive notifications for each step Eed
bmi160AccModule.routeData().fromStepDetection().stream("step_detector").commit()
.onComplete(new AsyncOperation.CompletionHandler<RouteManager>() {
@Override
public void success(RouteManager result) {
result.subscribe("step_detector", new RouteManager.MessageHandler() {
@Override
public void process(Message message) {
Log.i("MainActivity", "You took a step");
}
});
}
}
);
} catch (UnsupportedModuleException e) {
e.printStackTrace();
}

}


Comments

  • I just ran into a similar issue using a MetaWear C,  the device works fine when using IOS.  I'm guessing that the order of the commands is probably off.

    @Eric ,  do you have a snippet with the correct order that works for you?
  • Just adding some info with the order of method calls from the API

    onCreate() -> bind to metawear service
    onServiceConnected() -> get meta wear board with a bluetooth device
    once connected, call to enableButton() - that is the code that I posted.
  • sorry, not enablebutton (that was with regards to another problem), but detectSteps() is the method that I finally call (see above)
  • Yeah,  I'm having trouble getting this to work as well and am thinking that we probably have our order of events wrong with setting up the stepcounter.  I tried a few combinations to no avail,  hence asking Eric to see if he can shed some light on how to get this to work.

  • edited April 2016
    You need to enable the step counter, as outlined on the Android docs:
  •  
    Hey @Eric,  

    I tried this with a fresh example to make sure I'm not missing something.

    First of all in the example in the Android Docs the step detector method called is fromStepDetector but in the API documents and in the code this appears to be fromStepDetection().

    Also,  the method off of the configureStepDetection seems to have changed from this

    .setMode(Mode.SENSITIVTE)
    to 

    .setSensitivity(Bmi160Accelerometer.StepSensitivity.SENSITIVE)
    Is what I noticed correct or should we be using a different version of the API?  Currently I'm using 2.5.9.

    I was able to get the step detector woking in the example by calling start after all of the setup information and routing commands,  but that was not readily apparent looking at the docs.  I'm assuming that this is the correct order to call this?  Also,  I'm having trouble getting the step_counter to part to work.  

    If you go to this branch on one of my example projects you can see what I'm doing to start it.

    The call is located in the AccelerometerFragment in the startStepTracking method.  If you want to try running this you will need to first connect to the board via the connect workflow in the settings menu.  It goes through the blescanner to find your device along with blinking the device and a confirmation.  Once you are connected go to the accelerometer option in that menu and you will see a button to start step detection.  Right now I'm only sending the output to the logs and not displaying it on the screen.
  • Oh wow yeah, that documentation is not up to date nor complete.  Sorry about that.

    The step counter only sends the step data when requested.  You have to manually trigger the request by calling readStepCounter.
  • OK, so it seems some docs are out of data and the sequence seems very important. 

    I run this code now, but it still does not work.... Any ideas?

    final Bmi160Accelerometer bmi160AccModule= mwBoard.getModule(Bmi160Accelerometer.class);
    bmi160AccModule.start();


    bmi160AccModule.routeData().fromStepCounter(true).stream("step_counter").commit().onComplete(new AsyncOperation.CompletionHandler<RouteManager>() {
    @Override
    public void success(RouteManager result) {
    result.subscribe("step_counter", new RouteManager.MessageHandler() {
    @Override
    public void process(Message msg) {
    Log.i("MainActivity", "Steps= " + msg.getData(Integer.class));
    }
    });
    }
    });

    bmi160AccModule.enableStepDetection();
    bmi160AccModule.readStepCounter(false);
  • final Bmi160Accelerometer bmi160AccModule= mwBoard.getModule(Bmi160Accelerometer.class);
    final boolean silent= false;

    bmi160AccModule.routeData().fromStepCounter(silent).stream("step_counter").commit().onComplete(new AsyncOperation.CompletionHandler<RouteManager>() {
        @Override
        public void success(RouteManager result) {
            result.subscribe("step_counter", new RouteManager.MessageHandler() {
                @Override
                public void process(Message msg) {
                    Log.i("MainActivity", "Steps= " + msg.getData(Integer.class));
                }
            });

            bmi160AccModule.enableStepDetection();
            bmi160AccModule.readStepCounter(silent);
            bmi160AccModule.start();
        }
    });
  • Many thx, I am getting some log output now. I think I now just need to call it at a later time, I currently always get 0 steps. Is the step counter somehow reset with each "connection" to the board? 
  • Argh, sorry, here is somethign I still don't get.

    I am requesting the step counter data with each step that I take, e.g. within the step_detector callback. Somehow, that step_counter data is always 0:

    04-11 11:20:13.204 31166-31236/com.hybris.labs.fit I/MainActivity: You took a step
    04-11 11:20:13.294 31166-31236/com.hybris.labs.fit I/MainActivity: Steps= 0
    04-11 11:20:13.879 31166-31236/com.hybris.labs.fit I/MainActivity: You took a step
    04-11 11:20:13.969 31166-31236/com.hybris.labs.fit I/MainActivity: Steps= 0
    04-11 11:20:14.510 31166-31236/com.hybris.labs.fit I/MainActivity: You took a step
    04-11 11:20:14.603 31166-31236/com.hybris.labs.fit I/MainActivity: Steps= 0
    04-11 11:20:15.187 31166-31236/com.hybris.labs.fit I/MainActivity: You took a step
    04-11 11:20:15.277 31166-31236/com.hybris.labs.fit I/MainActivity: Steps= 0
    04-11 11:20:15.862 31166-31236/com.hybris.labs.fit I/MainActivity: You took a step
    04-11 11:20:15.952 31166-31236/com.hybris.labs.fit I/MainActivity: Steps= 0

    As I am interseted in many things from teh bmi160, I put this at the beginning of the method that enables all bmi160 features (not in the success method as in your example):

    final Bmi160Accelerometer bmi160AccModule= mwBoard.getModule(Bmi160Accelerometer.class);
    final boolean silent= false;

    bmi160AccModule.enableTapDetection(Bmi160Accelerometer.TapType.DOUBLE);
    bmi160AccModule.enableMotionDetection(Bmi160Accelerometer.MotionType.NO_MOTION);

    bmi160AccModule.configureNoMotionDetection().setDuration(10000).commit();

    //threshold?
    bmi160AccModule.configureTapDetection().setDoubleTapWindow(Bmi160Accelerometer.DoubleTapWindow.DTW_50_MS).setShockTime(Bmi160Accelerometer.TapShockTime.TST_75_MS).setQuietTime(Bmi160Accelerometer.TapQuietTime.TQT_30_MS).commit();

    bmi160AccModule.start();
    Could that be the issue? Is there a guide to follow if one is interested in double-tap detect, (no) motion detection and step counting?

    thx!
    Sven

  • You need to enable the step counter with the StepDetectionConfigEditor as mentioned in the Step Detection.  There is sample code at the bottom in the second code section that demonstrates this.  Also, I don't think the BMI160 handles both step counting and step detection simultaneously.  You should be using either the counter or the detector, not both.  

    I have not found any examples on how to use these features.  It is trial and error and reading the documentation to understand how the BMI160 detects various motion types.

  • HI @Eric, many thx for the comments. I've reduced the code to just do step counting now. I wrapped the readStepCounter  method call in a task, that is currently requesting the step count every 5 seconds. But currently no results, 0 steps.  
    I am enabling it like this:
    bmi160AccModule.configureStepDetection().enableStepCounter().setSensitivity(Bmi160Accelerometer.StepSensitivity.ROBUST);
    bmi160AccModule.enableStepDetection();bmi160AccModule.start();

    I am also using (no) motion detection at the same time. If that is not possible, it would be a bummer as my use case requires that.

    Thx!
    Sven
  • I've changed the code now and disabled all other BMI160 functions. I am just trying to get the step count every 10 seconds. Code is below, does anyone see an issue here? I seem to be calling the readStepCounter method every 10 seconds, I get a callback to teh Steps= Log output. But the result is always 0  - any ideas? 

    Thx a lot!







    final Bmi160Accelerometer bmi160AccModule= mwBoard.getModule(Bmi160Accelerometer.class);

    final boolean silent= false;


    bmi160AccModule.configureStepDetection().enableStepCounter().setSensitivity(Bmi160Accelerometer.StepSensitivity.ROBUST).commit();

    bmi160AccModule.enableStepDetection();


                bmi160AccModule.routeData().fromStepCounter(silent).stream("step_counter").commit().onComplete(new AsyncOperation.CompletionHandler<RouteManager>() {

                    @Override

                    public void success(RouteManager result) {

                        result.subscribe("step_counter", new RouteManager.MessageHandler() {

                            @Override

                            public void process(Message msg) {

                                Log.i("MainActivity", "Steps= " + msg.getData(Integer.class));

                            }

                        });



                   
    }

                });


    bmi160AccModule.start();





    AsyncOperation<Timer.Controller> taskResult= mwBoard.getModule(Timer.class)

    .scheduleTask(new Timer.Task() {

        @Override

        public void commands() {

            bmi160AccModule.readStepCounter(silent);

        }

    }, 10000, false);



    taskResult.onComplete(new AsyncOperation.CompletionHandler<Timer.Controller>() {

        @Override

        public void success(Timer.Controller result) {

            // start executing the task

           
    result.start();

        }

    });

  • edited April 2016
    Not sure what could be wrong with your code. Have you tried only enabling the step counter?

    This code works for me on my CPro.
    final boolean silent= false;
    final Bmi160Accelerometer accModule = mwBoard.getModule(Bmi160Accelerometer.class);

    accModule.routeData().fromStepCounter(silent).stream("counter_stream").commit()
    .onComplete(new CompletionHandler<RouteManager>() {
    @Override
    public void success(RouteManager result) {
    result.subscribe("counter_stream", new RouteManager.MessageHandler() {
    @Override
    public void process(Message msg) {
    Log.i("test", "Step= " + msg.getData(Integer.class));
    }
    });
    accModule.resetStepCounter();
    accModule.configureStepDetection()
    .setSensitivity(Bmi160Accelerometer.StepSensitivity.NORMAL)
    .enableStepCounter()
    .commit();
    accModule.enableStepDetection();
    accModule.start();
    }
    });

    mwBoard.getModule(Timer.class).scheduleTask(new Timer.Task() {
    @Override
    public void commands() {
    accModule.readStepCounter(silent);
    }
    }, 10000, false).onComplete(new CompletionHandler<Timer.Controller>() {
    @Override
    public void success(Timer.Controller result) {
    result.start();
    }
    });
  • Hi @Eric, many thx. the above code works - also on my CPRO. 

    I think my problem could be this: with multiple streams, you cannot start the addModule in the success method like you did above. You need to do this outside of that method and once all other parts of that BMI160 have been configured.

    So how and when should I configure and start the module if I need to listen to multiple streams?

    --

    I just got in another issue now, sorry that it keeps pouring. It works with my CPRO, but the that I have does not even connect any more. I get Board Connection Timed out. Do I maybe need to reset the C somehow?
  • edited April 2016
    You can configure everything before you create the data routes, then, start the accelerometer in the final route's CompleteHandler.


    // Configure things here

    accModule.routeData() ... // route 1
    accModule.routeData() ... // route 2
    accModule.routeData() ... // route 3

    accModule.routeData() ... commit().onComplete(new CompletionHandler<RouteManager>() {
    @Override
    public void success(RouteManager result) {
    // start accelerometer here
    accModule.start();
    }
    });
This discussion has been closed.