BMI160 Accelerometer

The BMI160 accelerometer is the most commonly used accelerometer on the available MbientLab boards and has additional features not available on the BMA255. It also comes with a gyroscrope giving 6 degrees of freedom.

import com.mbientlab.metawear.module.AccelerometerBmi160;

AccelerometerBmi160 accBmi160 = board.getModule(AccelerometerBmi160.class);

Output Data Rate

Available output data rates for the BMI160 device is enumerated by its OutputDataRate enum. You can use these entries to set the ODR to a known quantity.

import com.mbientlab.metawear.module.AccelerometerBmi160.OutputDataRate;
import com.mbientlab.metawear.module.AccelerometerBmi160.AccRange;

accBmi160.configure()
        .odr(OutputDataRate.ODR_25_HZ)  // set odr to 25Hz
        .range(AccRange.AR_4G)          // set range to +/-4g
        .commit();

Step Detection

The BMI160 chip comes with a step detection algorithm that can either send an interupt for every step detected (async producer) or accumulate the steps in a counter that returns the value when requested (forced producer). The algorithm has 3 operational modes that modify the sensitivity and robustness of the detector. It is important that you set the mode before using the detection algorithm.

Mode

Description

Normal

Balanced between false positives and false negatives, recommended for most applications

Sensitive

Few false negatives but eventually more false positives, recommended for light weighted people

Robust

Few false positives but eventually more false negatives

Data from both the counter and detector are unsigned integers with the step counter able to count to 2^16 steps (2 bytes).

import com.mbientlab.metawear.module.AccelerometerBmi160.StepDetectorMode;

final StepDetectorDataProducer stepDetector = accBmi160.stepDetector();

// Configuration the algorithm to run as a detector
// using normal detection mode
accBmi160.stepDetector().configure()
        .mode(StepDetectorMode.NORMAL)
        .commit();

accBmi160.stepDetector().addRouteAsync(new RouteBuilder() {
    @Override
    public void configure(RouteElement source) {
        source.stream(new Subscriber() {
            @Override
            public void apply(Data data, Object... env) {
                Log.i("MainActivity", "Took a step"));
            }
        });
    }
}).continueWith(new Continuation<Route, Void>() {
    @Override
    public Void then(Task<Route> task) throws Exception {
        accBmi160.stepDetector().start();
        accBmi160.start();
        return null;
    }
});

Significant Motion

The BMI160 chip also has an additional motion detection algorithm that detects significant motion i.e. a change in location from walking or being in a moving vehicle. It detects this type of motion by sleeping for a period of time (skip time), when motion is first detected, then still detecting motion for a window of time (proof time) when waking up.

import com.mbientlab.metawear.module.AccelerometerBmi160.ProofTime;
import com.mbientlab.metawear.module.AccelerometerBmi160.SignificantMotionDataProducer;
import com.mbientlab.metawear.module.AccelerometerBmi160.SkipTime;

final SignificantMotionDataProducer significantMotion =
        bmi160Acc.motion(SignificantMotionDataProducer.class)
significantMotion.configure()
            .proofTime(ProofTime.PT_1_S)    // set proof time to 1s
            .skipTime(SkipTime.ST_1_5_S)    // set skip time to 1.5s
            .commit();
significantMotion.addRouteAsync(new RouteBuilder() {
    @Override
    public void configure(RouteComponent source) {
        source.stream(new Subscriber() {
            @Override
            public void apply(Data data, Object... env) {
                actual.set(data.bytes()[0]);
            }
        });
    }
}).continueWith(new Continuation<Route, Void>() {
    @Override
    public Void then(Task<Route> task) throws Exception {
        significantMotion.start();
        accBmi160.start();
        return null;
    }
});