Hi all,

I already learned a lot about Zephyr from posts on this blog, thank you! I now have a question to which I could not find an answer to. It is about using the sensor API in sensor.h and having multiple sensors on the same i2c bus.

I started with one LIS2DH12 acceleremeter sensor and used Zephyr’s library for the LIS2DH group. Following different examples, I did this:

  1. add a lis2dh12 node to the i2c devicethree
    &i2c0 {
    compatible = "nordic,nrf-twi";
    status = "okay";
    pinctrl-0 = <&i2c0_default>;
    pinctrl-1 = <&i2c0_sleep>;
    pinctrl-names = "default", "sleep";
    lis2dh12: lis2dh12@19 {
    compatible = "st,lis2dh12", "st,lis2dh";
    reg = <0x19>;
    irq-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
    };
    };

  2. Include only sensor.h into the code (not lis2dh.h) and do the rest via the sensor API (initiate device, get data, …), like this:
    #include <sensor.h>
    ...
    const struct device *const sensor = DEVICE_DT_GET_ANY(st_lis2dh);
    ....
    struct sensor_value accel[3];
    int rc = sensor_sample_fetch(sensor);
    rc = sensor_channel_get(sensor, SENSOR_CHAN_ACCEL_XYZ, accel);
    ...

Now, how do I add another sensor e.g. for temperature measurement with a different address to the same i2c bus?

My understanding is that I would need to add another subnode to my i2c node in the devicetree like this:
&i2c0 {
compatible = "nordic,nrf-twi";
status = "okay";
pinctrl-0 = <&i2c0_default>;
pinctrl-1 = <&i2c0_sleep>;
pinctrl-names = "default", "sleep";
lis2dh12: lis2dh12@19 {
compatible = "st,lis2dh12", "st,lis2dh";
reg = <0x19>;
irq-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
someTempSens: someTempSens@20 {
...
};
};

And then also use the sensor API to access it.

But if I call the different sensors from different threads, how do I make sure there is no conflict on the bus? Is there a mutex integrated somewhere? If so, how is this done or if not, then where do I add it?
Until now, without the sensor-API, I had an extra i2c-driver layer that took care of this. But with the solution above, I do not acces i2c directly anymore, so I do not know how to handle this.

I would be very happy to get an answer and explanation on how the sensor API is meant to be used! I am sure it is cool, but I must be missing some point :-)

Best regards,
Joanna

Hi Joanna

You need to make sure you’re calling the I2C/Sensosr API from the same thread unless there are underlying mutex/control at the driver level (I wouldn’t count on it but check with your hardware specific I2C implementation).

I hope that helps.

Hi Jared,

thanks for the reply!

So, just for the deeper understanding of the API’s idea:
Is that the underlying “architectual principle” then, to have one thread per bus (i2c0, i2c1, …, spi0, spi1, …, uart0, …) in the program?
To me, that would be the consequence then. Which is fine, I see the advantages, just want to make sure, I understand it right.

Joanna

For multiple I2C buses you could throw them in one thread if you want since it’s more of a polling architecture. But depends on the device you’re using.

If you have a lot of data going over something time dependent like UART would dedicate a thread just for processing that data so the buffers stay freed up.

This is what I do. Your application may dictate otherwise!

Hi Jared,

thanks! Yes, that makes sense. Either each bus on its own thread or multiple buses on one thread, depending on timing, amount of data, etc.

The other thing, I wanted to know, but sorry, my question was not specific enough: What if, for example, one designs the program to have a thread A using an accelerometer and a thread B using a barometer, but both sensors are on the same I2C bus. Both threads could access the bus at the same time and cause data collision. Normally, this could be solved by a mutex in the I2C driver layer. But when using the sensor-API, I do not have access to this layer and can’t implement a mutex. To me this leads to the question: is the consequence of using the sensor-API that one must design the program such that different threads never use the same bus?

Regards,
Joanna

    greuljoSICKAG But when using the sensor-API, I do not have access to this layer and can’t implement a mutex. To me this leads to the question: is the consequence of using the sensor-API that one must design the program such that different threads never use the same bus?

    If you’re using the sensor API you can still use a mutex between the two threads (not recommended). Still the best way is to configure it as I mentioned before. Only my humble opinion from working with Zephyr for a few years though. There’s many ways to attack this problem.

    5 days later
    Terms and Conditions | Privacy Policy