How to Acquire Data from more than one Sensor on I2C

  1. My goal is: To be able to acquire data from two bme280 sensors on one I2C bus.

  2. My actions are: I have started a project using esp8266 with bme280 connected for i2c communication. I have one bme280 set to address 0x76 and the other set at address 0x77. I have setup the mos.yml, a main.c code template and have been able to successfully build and run the project for one sensor at a time.

  3. The result I see is: I am able to set a sensor address in my code, compile and read that sensor. However, I have not been able to get both sensors to read with the same compile. I am getting errors when I try.

  4. My expectation & question is: Can someone help me understand, if it is possible, and if so how to code in C to read both sensors. I am using the library “https://github.com/mongoose-os-libs/bme280”. I want to avoid using a multiplexer if possible.

Thank you

uint8 addr_1 = 0x76;
uint8 addr_2 = 0x77;
static struct mgos_bme280 *bme = NULL;
(double) mgos_bme280_read_temperature(bme),
(double) mgos_bme280_read_humidity(bme),
(double) mgos_bme280_read_pressure(bme),
if ((bme = mgos_bme280_i2c_create(addr_1)) == NULL) {
 LOG(LL_INFO, ("Unable to initialize BME280")); 
  }

First off you have to set the sensors to have the desired I2C address. Some ready made modules allow the user to set it, others not. Some of them are preset with 0x76, others with 0x77.

When you have 2 sensors with different addresses, you could do:

  bme76 = mgos_bme280_i2c_create(0x76);
  bme77 = mgos_bme280_i2c_create(0x77);
...
  double temp76 = mgos_bme280_read_temperature(bme76);
  double temp77 = mgos_bme280_read_temperature(bme77);

Hello, I have both sensors at the desired I2C addresses 0x76 and 0x77 and I am able to read both, each with its own compile, but not both in one compile. I tried this code and I get compiler errors for the pointers bme76 and bme77. I think I need to declare/define the structure and the two pointers and this is where I am having problems.

Changing:

static struct mgos_bme280 *bme = NULL;

to

static struct mgos_bme280 *bme76 = NULL;

or

static struct mgos_bme280 *bme77 = NULL;

compiles and runs one at a time (commenting out alternate function calls), but I am getting errors trying to declare both pointers at the same time.

uint8 addr_1 = 0x76;
uint8 addr_2 = 0x77;
static struct mgos_bme280 *bme76 = NULL;
/* static struct mgos_bme280 *bme77 = NULL; */
(double) mgos_bme280_read_temperature(bme76);
/* (double) mgos_bme280_read_temperature(bme77); */
bme76 = mgos_bme280_i2c_create(addr_1);
/* bme77 = mgos_bme280_i2c_create(addr_2); */

Thank you for your help

#include "mgos.h"
#include "mgos_bme280.h"

static struct mgos_bme280 *bme76 = NULL;
static struct mgos_bme280 *bme77 = NULL;

static void timer_cb(void *arg) {
  double temp76 = mgos_bme280_read_temperature(bme76);
  double temp77 = mgos_bme280_read_temperature(bme77);
  LOG(LL_INFO, ("Uptime: %.2lf, free_heap: %lu, min_free_heap: %lu, temp76: "
                "%.2lf, temp77: %.2lf",
                mgos_uptime(), (unsigned long) mgos_get_free_heap_size(),
                (unsigned long) mgos_get_min_free_heap_size(), temp76, temp77));
  (void) arg;
}

enum mgos_app_init_result mgos_app_init(void) {
  bme76 = mgos_bme280_i2c_create(0x76);
  bme77 = mgos_bme280_i2c_create(0x77);

  mgos_set_timer(10000, MGOS_TIMER_REPEAT, timer_cb, NULL);
  return MGOS_APP_INIT_SUCCESS;
}
1 Like

Dear nliviu,
Thank you very much.
Much appreciated, Jim