Why do Arduino Accelerometer Examples limit range to -/+ 2G?

I’m working on an impulse that uses an accelerometer with a range of +/- 16G (the LSM6DSO). And my impulse has recorded data using that range. Here is a typical feature sample:

(Note I have 2 IMUs on this project. This is collecting accX1,accY1,accZ1,accX2,accY2,accZ2; hence the 6 lines.)

Now in the exported Arduino examples, there is this line near the top:

#define MAX_ACCEPTED_RANGE  2.0f        // starting 03/2022, models are generated setting range to +-2, but this example use Arudino library which set range to +-4g. If you are using an older model, ignore this value and use 4.0f instead

Which later down in the example code is used to cap the data that is saved into the buffer:

        IMU.readAcceleration(buffer[ix], buffer[ix + 1], buffer[ix + 2]);

        for (int i = 0; i < 3; i++) {
            if (fabs(buffer[ix + i]) > MAX_ACCEPTED_RANGE) {
                buffer[ix + i] = ei_get_sign(buffer[ix + i]) * MAX_ACCEPTED_RANGE;
            }
        }

I’m trying to figure out why this is. The nano_ble33_sense-accelerometer.ino example does this, but the Nano BLE33 Sense uses a LSM9DS1 IMU, which is also capable of +/-16G.

Why does the cap used in the examples set such a low max range?

The code comment implies that the model itself is limited to +/-2G. But if a model is a “Fusion” model like mine (since there are 6 axes rather than 3), does that limit somehow get applied anyway?

1 Like

I think I figured out the question to my own answer. The inference example code is limited to +/-2G because the firmware for data collection also caps the Arduino Nano BLE 33 Sense to the same limit.

See the ei_lsm9ds1.cpp file in the GitHub Repository for the Nano 33 BLE Sense. This line in particular:

  writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG6_XL, 0x60); // 119 Hz, 2G

Setting that register configures the LSM9DS1 to limit itself to +/-2G.

I also did not realize that the this firmware does conversion from Gs to MS2, with this section:

    if (ei_IMU.accelerationAvailable()) {
        ei_IMU.readAcceleration(imu_data[0], imu_data[1], imu_data[2]);

        imu_data[0] *= CONVERT_G_TO_MS2;
        imu_data[1] *= CONVERT_G_TO_MS2;
        imu_data[2] *= CONVERT_G_TO_MS2;
    }

I thought Edge Impulse was doing something special in the model to convert data to MS2, but it turns out the data is converted to MS2 before its even collected.

But if a model is a “Fusion” model like mine (since there are 6 axes rather than 3), does that limit somehow get applied anyway?

The answer is no. The limit to 2Gs only applies if the data fed into the model was also limited to 2Gs. Since my ingested data is up to 16Gs, the MAX_ACCEPTED_RANGE should also be changed to 16.0f. Or because I know the IMU will never record more than 16 anyway, I can remove the entire block of code.

So, if you’re like me and are ingesting from a non-supported board and are sending in raw G-values (not MS2 values) and your range is not limited to 2G, then this example code from the Arduino examples:

        IMU.readAcceleration(buffer[ix], buffer[ix + 1], buffer[ix + 2]);

        for (int i = 0; i < 3; i++) {
            if (fabs(buffer[ix + i]) > MAX_ACCEPTED_RANGE) {
                buffer[ix + i] = ei_get_sign(buffer[ix + i]) * MAX_ACCEPTED_RANGE;
            }
        }

        buffer[ix + 0] *= CONVERT_G_TO_MS2;
        buffer[ix + 1] *= CONVERT_G_TO_MS2;
        buffer[ix + 2] *= CONVERT_G_TO_MS2;

Can be shortened down to simply:

        IMU.readAcceleration(buffer[ix], buffer[ix + 1], buffer[ix + 2]);

I’d be curious to know why Edge Impulse does all of this manipulation when going into the model and then again when collecting the data to be inferred; when it could use the values right out of the accelerometer. But I think my primary question has been solved.

1 Like

Hi @quicksketch

Thats a great question, I know there are variations in hardware for the BLE33 v1 / v2 perhaps thats the reason. Let me check with one of the embedded team that worked on the firmware. @ei_francesco or @Arjan can you comment here?

Best

Eoin

Hi @quicksketch,

It’s indeed a great question. We limit the range of the accelerometer to match the public projects we created. These motion projects using the accelerometer are all based on a range of -/+ 2G. In order to make them work on all hardware we support, we have to configure the range for the hardware likewise.

When building your own model, with data using a different range you should off course adjust the range settings in the hardware.

1 Like

Thanks @Eoin and @Arjan!

Figuring this out took me a day and a half. If there was just a little better cross-linking between the Arduino examples and the sensor input values that probably would have saved me a lot of time.

Instead of the current line:

#define MAX_ACCEPTED_RANGE  2.0f        // starting 03/2022, models are generated setting range to +-2, but this example use Arudino library which set range to +-4g. If you are using an older model, ignore this value and use 4.0f instead

It would help if instead it said something like:

// When data is collected by the Edge Impulse Arduino Nano 33 BLE Sense
// firmware, it is limited to a 2G range. If the model was created with a
// different sample range, modify this constant to match the input values.
// See https://github.com/edgeimpulse/firmware-arduino-nano-33-ble-sense/blob/master/src/sensors/ei_lsm9ds1.cpp
#define MAX_ACCEPTED_RANGE  2.0f

That’s a little verbose but it would help reduce the “magic” that happens. EI is a great convenience tool but it’s often difficult to tell how it gets to the final result.

2 Likes

Thanks for the feedback @quicksketch

Took a look at your bio, very interesting background! What is the current aim for your work with Edge AI? If its for writing content let me know, also if you have some suggestions of where you would expect to find this information we are always looking for ways to improve our docs and tutorials, blogs etc.

As an author too it would be great to hear more general feedback from you, we have a feedback channel on the forum or you can PM directly and I can log it to the team. Have you read the TinyML Cookbook and AI at the Edge ? They are great resources for general content and some technical examples but our API guides and tutorials etc for enterprise features are constantly growing with our feature set.

Best

Eoin

Thanks @quicksketch for your reply.

This feedback is very valuable. We will update code and comments to give more clarity on the example implementation.

Updated comments are in production.
Thanks again @quicksketch