Customizing the IMU triggers

Tracker Edge firmware has an easy to use configuration that allows you to select triggers based on the IMU. These triggers are done by setting interrupts on the IMU. Since Tracker Edge is open source, you can change the thresholds of what each configuration option means.

The Low, Medium, High, as well as the High-G settings are using the interrupts from the IMU for movement. You can find the specific settings for each threshold in the motion_service.cpp file:

Bmi160AccelMotionConfig bmi160MotionConfigs[] = {
    // Low sensitivity motion detection settings
    {
    .mode               = Bmi160AccelMotionMode::ACCEL_MOTION_MODE_SIGNIFICANT,
    .motionThreshold    = 1,      // g [up to range]
    .motionDuration     = 4,        // counts of rate period [1 -> 4]
    .motionSkip         = Bmi160AccelSignificantMotionSkip::SIG_MOTION_SKIP_1_5_S,      // seconds [1.5s, 3s, 6s, 12s]
    .motionProof        = Bmi160AccelSignificantMotionProof::SIG_MOTION_PROOF_0_25_S,   // seconds [0.25s, 0.5s, 1s, 2s]
    },
    // Medium sensitivity motion detection settings
    {
    .mode               = Bmi160AccelMotionMode::ACCEL_MOTION_MODE_ANY,
    .motionThreshold    = 0.5,      // g [up to range]
    .motionDuration     = 4,        // counts of rate period [1 -> 4]
    .motionSkip         = Bmi160AccelSignificantMotionSkip::SIG_MOTION_SKIP_1_5_S,      // seconds [1.5s, 3s, 6s, 12s]
    .motionProof        = Bmi160AccelSignificantMotionProof::SIG_MOTION_PROOF_0_25_S,   // seconds [0.25s, 0.5s, 1s, 2s]
    },
    // High sensitivity motion detection settings
    {
    .mode               = Bmi160AccelMotionMode::ACCEL_MOTION_MODE_ANY,
    .motionThreshold    = 0.1,      // g [up to range]
    .motionDuration     = 1,        // counts of rate period [1 -> 4]
    .motionSkip         = Bmi160AccelSignificantMotionSkip::SIG_MOTION_SKIP_1_5_S,      // seconds [1.5s, 3s, 6s, 12s]
    .motionProof        = Bmi160AccelSignificantMotionProof::SIG_MOTION_PROOF_0_25_S,   // seconds [0.25s, 0.5s, 1s, 2s]
    },
};
Bmi160AccelHighGConfig bmi160HighGConfig = {
    .threshold          = 4.0,          // g [up to range]
    .duration           = 0.0025,       // seconds
    .hysteresis         = 16.0 / 16.0,  // g [up to range]
};

You can change those thresholds to whatever your application needs.

When those events happen, they are placed in a Queue. If you look at the tracker_motion.cpp , you can see where events are taken from the Queue, and the switch statement that publishes when an event happens:

void TrackerMotion::loop()
{
    MotionEvent motion_event;
    size_t depth = MotionService::instance().getQueueDepth();
    do {
        MotionService::instance().waitOnEvent(motion_event, 0);
        switch (motion_event.source)
        {
            case MotionSource::MOTION_HIGH_G:
                TrackerLocation::instance().triggerLocPub(Trigger::NORMAL, "imu_g");
                break;
            case MotionSource::MOTION_MOVEMENT:
                TrackerLocation::instance().triggerLocPub(Trigger::NORMAL,"imu_m");
                break;
        }
    } while (--depth && (motion_event.source != MotionSource::MOTION_NONE));
}

This is what causes the publish. You can modify this to do what you need when an event happens. Maybe even not publish, or publish and do something else!

What if you don’t want to use the interrupts, and instead want to get the values from the accelerometer for your application directly? For that, you can use the getAccelerometer() function.

Here’s something I just tested. In main.cpp, add:

#include "bmi160.h"

Then in loop():

void loop()
{
    static uint32_t timer = System.uptime();
     Tracker::instance().loop();
     // Execute every ~5 seconds
     if (System.uptime() - timer > 5) {
         timer = System.uptime();
         Bmi160Accelerometer data;
         int ret = BMI160.getAccelerometer(data);
         if (ret == SYSTEM_ERROR_NONE) {
             Log.info("Accel data. x: %f, y: %f, z: %f", data.x, data.y, data.z);
         }
     }
}

This will print the raw accelerometer data to the Log handler.

1 Like

Helpful post! While in hindsight it seems like it would go without saying, you need to turn on Movement Sensitivity in the Motion subsection of the Asset Tracking settings in console. Having spent several hours not getting this to work, turning that on solved the problem.

2 Likes

Thank you for the added information! You’re correct, I missed that on the original post. Yes, you do need to enable the IMU in the configuration.