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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions