I am trying to learn esp-idf by using it for my first project.
I tested several components separately and prepared some example code to learn the esp-idf environment.
I am now starting on my first project, a greenhouse monitor, which will have 2 BME280 sensors and a light sensor.
The BME280 sensors i bought are a waterproof model which don't have an address pin, so i have to use both I2C ports to read the sensors.
I made a working example before with 1 sensor based on the code in this tutorial:
https://esp32tutorials.com/bme280-esp32-esp-idf-oled/
What i can't figure out is how to read the data from both sensors.
I adapted the code to have 2 init functions, each with a different i2c port (I2C_NUM_0 and I2C_NUM_1)
I also made 2 read and 2 write functions, each attached to the i2C ports.
In the task i created 2 bme280_t structs that contain the different functions pointed to the different i2C ports.
Now i am stuck on reading the values of the separate sensors, as there is no option in the bme280 read functions to address a specific sensor.
Can anyone help me with this issue?
I post my code here, but it's not finished:
Code: Select all
#include <stdio.h>
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/task.h"
#include "sdkconfig.h" // generated by "make menuconfig"
#include "bme280.h"
#define SDA1_PIN GPIO_NUM_16
#define SCL1_PIN GPIO_NUM_17
#define SDA2_PIN GPIO_NUM_21
#define SCL2_PIN GPIO_NUM_22
#define TAG_BME280_INDOOR "BME280 indoor"
#define TAG_BME280_OUTDOOR "BME280 outdoor"
#define TAG_LUXMETER "LUXmeter"
#define I2C_MASTER_ACK 0
#define I2C_MASTER_NACK 1
void i2c1_init()
{
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = SDA1_PIN,
.scl_io_num = SCL1_PIN,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = 1000000};
i2c_param_config(I2C_NUM_0, &i2c_config);
i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);
}
void i2c2_init()
{
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = SDA2_PIN,
.scl_io_num = SCL2_PIN,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = 1000000};
i2c_param_config(I2C_NUM_1, &i2c_config);
i2c_driver_install(I2C_NUM_1, I2C_MODE_MASTER, 0, 0, 0);
}
s8_t BME280_I2C_bus1_write(u8_t dev_addr, u8_t reg_addr, u8_t *reg_data, u8_t cnt)
{
s32 iError = BME280_INIT_VALUE;
esp_err_t espRc;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg_addr, true);
i2c_master_write(cmd, reg_data, cnt, true);
i2c_master_stop(cmd);
espRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
if (espRc == ESP_OK)
{
iError = SUCCESS;
}
else
{
iError = FAIL;
}
i2c_cmd_link_delete(cmd);
return (s8)iError;
}
s8_t BME280_I2C_bus2_write(u8_t dev_addr, u8_t reg_addr, u8_t *reg_data, u8_t cnt)
{
s32 iError = BME280_INIT_VALUE;
esp_err_t espRc;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg_addr, true);
i2c_master_write(cmd, reg_data, cnt, true);
i2c_master_stop(cmd);
espRc = i2c_master_cmd_begin(I2C_NUM_1, cmd, 10 / portTICK_PERIOD_MS);
if (espRc == ESP_OK)
{
iError = SUCCESS;
}
else
{
iError = FAIL;
}
i2c_cmd_link_delete(cmd);
return (s8)iError;
}
s8 BME280_I2C_bus1_read(u8_t dev_addr, u8_t reg_addr, u8_t *reg_data, u8_t cnt)
{
s32 iError = BME280_INIT_VALUE;
esp_err_t espRc;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg_addr, true);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_READ, true);
if (cnt > 1)
{
i2c_master_read(cmd, reg_data, cnt - 1, I2C_MASTER_ACK);
}
i2c_master_read_byte(cmd, reg_data + cnt - 1, I2C_MASTER_NACK);
i2c_master_stop(cmd);
espRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
if (espRc == ESP_OK)
{
iError = SUCCESS;
}
else
{
iError = FAIL;
}
i2c_cmd_link_delete(cmd);
return (s8)iError;
}
s8 BME280_I2C_bus2_read(u8_t dev_addr, u8_t reg_addr, u8_t *reg_data, u8_t cnt)
{
s32 iError = BME280_INIT_VALUE;
esp_err_t espRc;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg_addr, true);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_READ, true);
if (cnt > 1)
{
i2c_master_read(cmd, reg_data, cnt - 1, I2C_MASTER_ACK);
}
i2c_master_read_byte(cmd, reg_data + cnt - 1, I2C_MASTER_NACK);
i2c_master_stop(cmd);
espRc = i2c_master_cmd_begin(I2C_NUM_1, cmd, 10 / portTICK_PERIOD_MS);
if (espRc == ESP_OK)
{
iError = SUCCESS;
}
else
{
iError = FAIL;
}
i2c_cmd_link_delete(cmd);
return (s8)iError;
}
void BME280_delay_msek(u32_t msek)
{
vTaskDelay(msek / portTICK_PERIOD_MS);
}
void bme_read(void *arg){
struct bme280_t bme280_indoor = {
.bus_write = BME280_I2C_bus1_write,
.bus_read = BME280_I2C_bus1_read,
.dev_addr = BME280_I2C_ADDRESS1,
.delay_msec = BME280_delay_msek};
struct bme280_t bme280_outdoor = {
.bus_write = BME280_I2C_bus2_write,
.bus_read = BME280_I2C_bus2_read,
.dev_addr = BME280_I2C_ADDRESS1,
.delay_msec = BME280_delay_msek};
MDF_LOGI("BME task is running");
s32 bme1_rslt;
s32 bme2_rslt;
s32 v_uncomp_pressure_s32;
s32 v_uncomp_temperature_s32;
s32 v_uncomp_humidity_s32;
bme1_rslt = bme280_init(&bme280_indoor);
bme2_rslt = bme280_init(&bme280_outdoor);
bme1_rslt += bme280_set_oversamp_pressure(BME280_OVERSAMP_16X);
bme2_rslt += bme280_set_oversamp_pressure(BME280_OVERSAMP_16X);
bme1_rslt += bme280_set_oversamp_temperature(BME280_OVERSAMP_2X);
bme2_rslt += bme280_set_oversamp_temperature(BME280_OVERSAMP_2X);
bme1_rslt += bme280_set_oversamp_humidity(BME280_OVERSAMP_1X);
bme2_rslt += bme280_set_oversamp_humidity(BME280_OVERSAMP_1X);
bme1_rslt += bme280_set_standby_durn(BME280_STANDBY_TIME_1_MS);
bme2_rslt += bme280_set_standby_durn(BME280_STANDBY_TIME_1_MS);
bme1_rslt += bme280_set_filter(BME280_FILTER_COEFF_16);
bme2_rslt += bme280_set_filter(BME280_FILTER_COEFF_16);
bme1_rslt += bme280_set_power_mode(BME280_NORMAL_MODE);
bme2_rslt += bme280_set_power_mode(BME280_NORMAL_MODE);
if (com_rslt == SUCCESS)
{
bme1_rslt = bme280_read_uncomp_pressure_temperature_humidity(
&v_uncomp_pressure_s32, &v_uncomp_temperature_s32, &v_uncomp_humidity_s32);
bme2_rslt = bme280_read_uncomp_pressure_temperature_humidity(
&v_uncomp_pressure_s32, &v_uncomp_temperature_s32, &v_uncomp_humidity_s32);
}
}