Skip to content

How to set accelleration range on BMI270 on AtomS3R (C126)? #228

@marcindulak

Description

@marcindulak

https://m5stack.lang-ship.com/catalog/products/controller/c126_atoms3r/ links to https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/datasheet/core/K128%20CoreS3/BMI270.PDF, which contains this table on page 109

Image

I imagine that the acceleration range, and other IMU parameters are configurable from M5Unified.
I'm trying to change the acceleration range from 8g to 16g, using the program included below.

However, I see something surprising when testing the device by holding it in my hand,
with the USB-C cable connected, and shaking the device, first gently, then rather hard.
The maximum acceleration appears clamped at 8g.

I'm using https://github.com/m5stack/M5Unified/releases/tag/0.2.13.
Could this be due to some hard-coding of that value, e.g., in

float value[3] = { 8.0f / 32768.0f, 2000.0f / 32768.0f, 10.0f * 4912.0f / 32768.0f };

This is code:

/**
 * @file accel_range.ino
 * @brief Test to verify ±16g accelerometer range configuration
 *
 * Test procedure:
 * 1. Upload this sketch
 * 2. Open serial monitor (115200 baud)
 * 3. With the USB-C cable connected, shake sensor strongly by hand
 * 4. Check if accel values exceed ±8g
 *
 * Expected result:
 * - If ±16g works: values may exceed ±8g during strong shaking
 * - If clamped to ±8g (default): values will never exceed ±8g
 */

#include <M5Unified.h>

// BMI270 I2C configuration
// BMI270 I2C address from M5Unified:
// https://raw.githubusercontent.com/m5stack/M5Unified/4a1c5343330f7d54cfab38302ebf98dc9ef6de0f/src/utility/imu/BMI270_Class.hpp
static const uint8_t BMI270_ADDR = 0x68;
static const uint32_t I2C_FREQ = 400000;
static const uint8_t ACC_RANGE_REG = 0x41;

void setup() {
    auto cfg = M5.config();
    cfg.serial_baudrate = 115200;
    M5.begin(cfg);

    Serial.println("=== BMI270 ±16g Range Test ===");

    // Re-initialize I2C
    M5.In_I2C.begin((i2c_port_t)I2C_NUM_0, 45, 0);
    delay(100);
    M5.Imu.update();
    delay(100);

    // Configure BMI270 to ±16g range
    Serial.println("Configuring BMI270 ACC_RANGE to ±16g...");
    if (!M5.In_I2C.writeRegister8(BMI270_ADDR, ACC_RANGE_REG, 0x03, I2C_FREQ)) {
        Serial.println("ERROR: Failed to write ACC_RANGE");
    } else {
        Serial.println("Configuration complete: ±16g accel range");
    }

    Serial.println();
    Serial.println("SHAKE THE SENSOR STRONGLY!");
    Serial.println("Looking for accel values > ±8g...");
    Serial.println();
    Serial.println("Format: accel_raw(x,y,z) | accel_cal(x,y,z) g");
    Serial.println("---");

    // Disable M5Unified calibration to get raw readings
    M5.Imu.setCalibration(0, 0, 0);
}

void loop() {
    static uint32_t lastPrint = 0;
    static float maxAbsAccel = 0;

    uint32_t now = millis();

    // Update sensor
    if (M5.Imu.update()) {
        // Get data
        auto data = M5.Imu.getImuData();
        int16_t raw_x = M5.Imu.getRawData(0);
        int16_t raw_y = M5.Imu.getRawData(1);
        int16_t raw_z = M5.Imu.getRawData(2);

        float ax = data.accel.x;
        float ay = data.accel.y;
        float az = data.accel.z;

        // Track maximum
        float absMax = max(abs(ax), max(abs(ay), abs(az)));
        if (absMax > maxAbsAccel) {
            maxAbsAccel = absMax;
        }

        // Print at 10Hz
        if (now - lastPrint >= 100) {
            Serial.printf("raw:(%6d,%6d,%6d) | cal:(%7.3f,%7.3f,%7.3f) g | max: %.3f g",
                raw_x, raw_y, raw_z,
                ax, ay, az,
                maxAbsAccel);

            // Flag if we exceeded 8g
            if (absMax > 8.0f) {
                Serial.print(" *** EXCEEDED 8g! ±16g WORKS! ***");
            }

            Serial.println();
            lastPrint = now;
        }
    }

    delay(1);
}

Serial output:

01:42:33.725 -> === BMI270 ±16g Range Test ===
01:42:33.725 -> 
01:42:33.725 -> Configuring BMI270 ACC_RANGE to ±16g...
01:42:33.725 -> Configuration complete: ±16g accel range
01:42:33.725 -> 
01:42:33.725 -> SHAKE THE SENSOR STRONGLY!
01:42:33.725 -> Looking for accel values > ±8g...
01:42:33.725 -> 
01:42:33.725 -> Format: accel_raw(x,y,z) | accel_cal(x,y,z) g
01:42:33.725 -> ---
01:42:33.725 -> raw:( -3323,  1558,   938) | cal:(  0.380,  0.811,  0.229) g | max: 0.811 g
01:42:33.768 -> raw:( -1244,   770,   603) | cal:(  0.188,  0.304,  0.147) g | max: 0.860 g
01:42:33.846 -> raw:(  -965,   876,  1139) | cal:(  0.214,  0.236,  0.278) g | max: 0.860 g
01:42:33.942 -> raw:(  -673,  1153,  1818) | cal:(  0.281,  0.164,  0.444) g | max: 0.860 g
01:42:34.040 -> raw:(  -535,  1310,  1640) | cal:(  0.320,  0.131,  0.400) g | max: 0.860 g
01:42:34.135 -> raw:(  -328,  1114,  1801) | cal:(  0.272,  0.080,  0.440) g | max: 0.860 g
01:42:34.272 -> raw:(  -738,   749,  1998) | cal:(  0.183,  0.180,  0.488) g | max: 0.860 g
01:42:34.362 -> raw:(  -729,   763,  1724) | cal:(  0.186,  0.178,  0.421) g | max: 0.860 g
01:42:34.459 -> raw:(  -634,   767,  1728) | cal:(  0.187,  0.155,  0.422) g | max: 0.860 g
01:42:34.556 -> raw:(  -434,   989,  1770) | cal:(  0.241,  0.106,  0.432) g | max: 0.860 g
01:42:34.653 -> raw:(  -296,  1127,  1865) | cal:(  0.275,  0.072,  0.455) g | max: 0.860 g
01:42:34.653 -> raw:(  -296,  1127,  1865) | cal:(  0.275,  0.072,  0.455) g | max: 0.860 g
01:42:34.782 -> raw:(  -333,   844,  1858) | cal:(  0.206,  0.081,  0.454) g | max: 0.860 g
01:42:34.881 -> raw:(  -492,   898,  2092) | cal:(  0.219,  0.120,  0.511) g | max: 0.860 g
01:42:34.976 -> raw:(  -798,   492,  2012) | cal:(  0.120,  0.195,  0.491) g | max: 0.860 g
01:42:35.074 -> raw:(  -833,   643,  1810) | cal:(  0.157,  0.203,  0.442) g | max: 0.860 g
01:42:35.170 -> raw:( -1106,   817,  1215) | cal:(  0.199,  0.270,  0.297) g | max: 0.860 g
01:42:35.268 -> raw:( -1638,   607,   805) | cal:(  0.148,  0.400,  0.197) g | max: 0.860 g
01:42:35.397 -> raw:( -1389,  1206,   631) | cal:(  0.294,  0.339,  0.154) g | max: 0.860 g
01:42:35.494 -> raw:( -1693,   784,  -140) | cal:(  0.191,  0.413, -0.034) g | max: 0.860 g
01:42:35.595 -> raw:( -1465,   573,   284) | cal:(  0.140,  0.358,  0.069) g | max: 0.860 g
01:42:35.690 -> raw:( -1696,   429,  1057) | cal:(  0.105,  0.414,  0.258) g | max: 0.860 g
01:42:35.787 -> raw:( -1440,   805,  1790) | cal:(  0.197,  0.352,  0.437) g | max: 0.860 g
01:42:35.884 -> raw:( -1463,  1134,  1462) | cal:(  0.277,  0.357,  0.357) g | max: 0.860 g
01:42:36.014 -> raw:( -1363,   429,  1725) | cal:(  0.105,  0.333,  0.421) g | max: 0.860 g
01:42:36.111 -> raw:( -1410,    51,  1699) | cal:(  0.012,  0.344,  0.415) g | max: 0.860 g
01:42:36.208 -> raw:( -1716,   291,  1289) | cal:(  0.071,  0.419,  0.315) g | max: 0.860 g
01:42:36.307 -> raw:( -1965,    11,  1132) | cal:(  0.003,  0.480,  0.276) g | max: 0.860 g
01:42:36.403 -> raw:( -2043,  -119,   902) | cal:( -0.029,  0.499,  0.220) g | max: 0.860 g
01:42:36.500 -> raw:( -2078,  -118,   381) | cal:( -0.029,  0.507,  0.093) g | max: 0.860 g
01:42:36.631 -> raw:( -1926,   231,     8) | cal:(  0.056,  0.470,  0.002) g | max: 0.860 g
01:42:36.723 -> raw:( -2113,    53,   300) | cal:(  0.013,  0.516,  0.073) g | max: 0.860 g
01:42:36.820 -> raw:( -1900,   421,   239) | cal:(  0.103,  0.464,  0.058) g | max: 0.860 g
01:42:36.918 -> raw:( -1747,   965,   128) | cal:(  0.236,  0.427,  0.031) g | max: 0.860 g
01:42:37.015 -> raw:( -1867,   448,   595) | cal:(  0.109,  0.456,  0.145) g | max: 0.860 g
01:42:37.144 -> raw:( -1795,  1489,  -265) | cal:(  0.364,  0.438, -0.065) g | max: 0.860 g
01:42:37.241 -> raw:( -1763,   680,   379) | cal:(  0.166,  0.430,  0.093) g | max: 0.860 g
01:42:37.338 -> raw:( -1572,  1211,   503) | cal:(  0.296,  0.384,  0.123) g | max: 0.860 g
01:42:37.435 -> raw:(  -832,  2299,   412) | cal:(  0.561,  0.203,  0.101) g | max: 0.860 g
01:42:37.530 -> raw:(  -386,  3278,   551) | cal:(  0.800,  0.094,  0.135) g | max: 0.860 g
01:42:37.629 -> raw:( -2482, -7826,   934) | cal:( -1.911,  0.606,  0.228) g | max: 1.911 g
01:42:37.760 -> raw:( -1317,   -62,  -167) | cal:( -0.015,  0.322, -0.041) g | max: 1.911 g
01:42:37.855 -> raw:(  -124,  2031,   685) | cal:(  0.496,  0.030,  0.167) g | max: 1.911 g
01:42:37.952 -> raw:(   403,  4865,   310) | cal:(  1.188, -0.098,  0.076) g | max: 1.911 g
01:42:38.048 -> raw:( -3890,-10370,   860) | cal:( -2.532,  0.950,  0.210) g | max: 2.532 g
01:42:38.145 -> raw:( -1226,   133,   217) | cal:(  0.032,  0.299,  0.053) g | max: 2.532 g
01:42:38.275 -> raw:(   477,  4082,   686) | cal:(  0.997, -0.116,  0.167) g | max: 2.532 g
01:42:38.372 -> raw:(  -195,  1743,  -376) | cal:(  0.426,  0.048, -0.092) g | max: 2.532 g
01:42:38.469 -> raw:( -3855, -4533,    79) | cal:( -1.107,  0.941,  0.019) g | max: 2.532 g
01:42:38.566 -> raw:( -1091,  2005,   -86) | cal:(  0.490,  0.266, -0.021) g | max: 2.532 g
01:42:38.662 -> raw:(  -739,  3462,  -454) | cal:(  0.845,  0.180, -0.111) g | max: 2.532 g
01:42:38.791 -> raw:( -3563, -6396,  3031) | cal:( -1.562,  0.870,  0.740) g | max: 2.532 g
01:42:38.887 -> raw:( -1236,   299,   106) | cal:(  0.073,  0.302,  0.026) g | max: 2.532 g
01:42:38.983 -> raw:(   390,  4130,   168) | cal:(  1.008, -0.095,  0.041) g | max: 2.532 g
01:42:39.080 -> raw:( -1342,  -972,    58) | cal:( -0.237,  0.328,  0.014) g | max: 2.532 g
01:42:39.176 -> raw:( -1010,  -359,    81) | cal:( -0.088,  0.247,  0.020) g | max: 2.532 g
01:42:39.273 -> raw:(  1680,  7193,   592) | cal:(  1.756, -0.410,  0.145) g | max: 2.532 g
01:42:39.402 -> raw:( -5847,-11882, -2385) | cal:( -2.901,  1.427, -0.582) g | max: 4.338 g
01:42:39.498 -> raw:(  7649, 20628,  5632) | cal:(  5.036, -1.867,  1.375) g | max: 5.036 g
01:42:39.595 -> raw:(  4671,  -693, -1943) | cal:( -0.169, -1.140, -0.474) g | max: 8.000 g
01:42:39.693 -> raw:(  5063,-22066, -8290) | cal:( -5.387, -1.236, -2.024) g | max: 8.000 g
01:42:39.789 -> raw:( 10913, 18266, 10504) | cal:(  4.459, -2.664,  2.564) g | max: 8.000 g
01:42:39.918 -> raw:(  2049,  1771, -3083) | cal:(  0.432, -0.500, -0.753) g | max: 8.000 g
01:42:40.014 -> raw:( -2707,-31850,-19850) | cal:( -7.776,  0.661, -4.846) g | max: 8.000 g
01:42:40.111 -> raw:( 14881, 23445, 14769) | cal:(  5.724, -3.633,  3.606) g | max: 8.000 g
01:42:40.208 -> raw:(  6386,  1240,  3070) | cal:(  0.303, -1.559,  0.750) g | max: 8.000 g
01:42:40.305 -> raw:(-12005,-32768,-26427) | cal:( -8.000,  2.931, -6.452) g | max: 8.000 g
01:42:40.402 -> raw:( 16923, 28766, 15105) | cal:(  7.023, -4.132,  3.688) g | max: 8.000 g
01:42:40.531 -> raw:( 14395,  8961, 10771) | cal:(  2.188, -3.514,  2.630) g | max: 8.000 g
01:42:40.629 -> raw:( -5563,-14877,-15483) | cal:( -3.632,  1.358, -3.780) g | max: 8.000 g
01:42:40.725 -> raw:( 19418, 10198,  7290) | cal:(  2.490, -4.741,  1.780) g | max: 8.000 g
01:42:40.824 -> raw:( 20157, 23506, 18807) | cal:(  5.739, -4.921,  4.592) g | max: 8.000 g
01:42:40.920 -> raw:(  -615, -3815, -8656) | cal:( -0.931,  0.150, -2.113) g | max: 8.000 g
01:42:41.015 -> raw:( 13797,-23456,-26078) | cal:( -5.727, -3.368, -6.367) g | max: 8.000 g
01:42:41.145 -> raw:( 19016, 32767, 22780) | cal:(  8.000, -4.643,  5.562) g | max: 8.000 g
01:42:41.242 -> raw:(  8411, -3145, -4444) | cal:( -0.768, -2.053, -1.085) g | max: 8.000 g
01:42:41.339 -> raw:( -9110,-32768,-32768) | cal:( -8.000,  2.224, -8.000) g | max: 8.000 g
...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions