Post

ENG | Zephyr RTOS: I2C Sensors, part II

Playing with 6-axis inertial measurement unit (acceleration, gyroscope)

ENG | Zephyr RTOS: I2C Sensors, part II

This is short article maybe expanded in the future. I have some ideas what to do with this sensor, but I don’t have a LiPo battery.

This time, Windows were used and XIAO-RP2040 board.

Bosch BMI160 inertial measurement unit

Files

CMakeLists.txt

1
2
3
4
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(project_name_placeholder)
target_sources(app PRIVATE src/main.c)

xiao_rp2040.overlay

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/ {
    aliases {
	    imu-sensor = &bmi160;
    };
};

&i2c1 {
    status = "okay";
    bmi160: bmi160@69 {
        compatible = "bosch,bmi160";
        reg = <0x69>;
        status = "okay";
    };
};

prj.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
CONFIG_BMI160=y
CONFIG_I2C=y
CONFIG_SENSOR=y

CONFIG_BMI160=y
CONFIG_BMI160_TRIGGER_NONE=y
# I guess either normal or low power, but i would prefer interrupt per revolution
CONFIG_BMI160_ACCEL_PMU_NORMAL=y
# CONFIG_BMI160_ACCEL_PMU_LOW_POWER is not set
CONFIG_BMI160_ACCEL_RANGE_16G=y
# Sampling freq 25Hz
CONFIG_BMI160_ACCEL_ODR_25=y
# Gyroscope not used
CONFIG_BMI160_GYRO_PMU_SUSPEND=y

This one was a bit tricky to create. I entered first three lines and then used west build -t menuconfig -b xiao_rp2040

![zephyr_menuconfig_bmi160.webp]

It created config file in file build/zephyr/.config and I copied some lines containing BMI160 back.

src/main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>

int main(void)
{
    const struct device *const sensor = DEVICE_DT_GET(DT_ALIAS(imu_sensor));
    
    if (!device_is_ready(sensor)) {
        printk("Sensor %s not ready!\n", sensor->name);
        return -1;
    }

    while (1) {
        int ret = sensor_sample_fetch(sensor);
        if (ret != 0) {
            printk("sensor_sample_fetch returned %d\n", ret);
            continue;
        }

        struct sensor_value accel[3];
        ret = sensor_channel_get(sensor, SENSOR_CHAN_ACCEL_XYZ, accel);
        if (ret == 0) {
            printk("x=%4d.%06d, y=%4d.%06d, z=%4d.%06d\n", 
                    accel[0].val1, accel[0].val2,
                    accel[1].val1, accel[1].val2,
                    accel[2].val1, accel[2].val2
            );
        }
	
        k_sleep(K_MSEC(200)); // 5Hz
    }
    return 0;
}

This file was based on my previous environmental sensors and example for similar sensor. Because I don’t have a clue how to quess which channel to read and that it reads three values at once.

Compiling this project on Windows this time:

1
2
3
west build -p -b xiao_rp2040 -S cdc-acm-console -- -DCONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y
west flash
mpremote connect COM16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Connected to MicroPython at COM16
Use Ctrl-] or Ctrl-x to exit this shell
*** Booting Zephyr OS build v4.1.0-5418-g98ba754013b0 ***
x=  -2.-954489, y=   0.-378289, z=   9.078951
x=  -2.-978432, y=   0.-373501, z=   9.136412
x=  -2.-988009, y=   0.-373501, z=   9.174720
x=  -2.-983220, y=   0.-373501, z=   9.174720
x=  -3.-02374, y=   0.-373501, z=   9.193874
x=  -3.-174759, y=   0.-402232, z=   9.136412
x=  -3.-136452, y=   0.-383078, z=   9.236970
x=  -2.-662392, y=   0.-397443, z=   9.481183
x=  -2.-940124, y=   0.-335193, z=   9.213028
x=   3.514741, y=   1.177965, z=  15.471567
x=   1.652024, y=  -1.-450908, z=   3.754165
x=   0.-181962, y=  -7.-407772, z=   5.870672

Value encoding is really interesting, but i guess it makes conversion easier by float value = raw_value.val1 + 1.0e-6 * raw_value.val2.

TODO acceleration vectors, pins, connection

flat = z=9.8 usb up y9 pins up x9

Some fun

This is only in attached files, I composed this from examples, board definition file and with help of Claude.AI. Main problem was enabling PIO (Raspberry Pico feature) and who would expect that floating point support for printf must be enabled.

Files

This post is licensed under CC BY 4.0 by the author.