UncleRus / esp-idf-lib

Component library for ESP32-xx and ESP8266
https://esp-idf-lib.readthedocs.io/en/latest/
1.33k stars 414 forks source link

Strange behavior with BME280 + MAX17048 #607

Closed r3v1 closed 5 months ago

r3v1 commented 5 months ago

The issue

Hello,

I have used the examples/bmp280 and examples/max17014x examples to program a BME280 and MAX17048 sensor. The thing is that there is something that I am not understanding about the library, because a strange thing happens to me.

When the battery is physically connected to my PCB (ESP32-S2 based), both the BME280 and MAX17048 report readings perfectly. However, if I physically disconnect the BME280 and keep the battery connected, the code is not able to detect the MAX17048 chip.

I have followed both the individual examples and simple_barometer, but I can't figure out why it doesn't work. On Arduino it works perfectly.

Attached is an excerpt of the code used:

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_mac.h"
#include "driver/gpio.h"

#include "string.h"
#include "nvs.h"
#include "nvs_flash.h"
#include <sys/socket.h>

#include "bmp280.h"
#include "max1704x.h"

static const char *BME280_TAG = "BME280";
static const char *MAX17048_TAG = "MAX17048";

#define SDA_GPIO 36
#define SCL_GPIO 35

void sensor_reading(void *pvParameters)
{
    /* --------------------------------------- INIT BME280 -------------------------------------- */
    float pressure, temperature, humidity;

    bmp280_params_t params;
    bmp280_init_default_params(&params);

    // Configuración para Weather Station
    params.mode = BMP280_MODE_FORCED;
    params.filter = BMP280_FILTER_OFF;
    params.oversampling_pressure = BMP280_ULTRA_LOW_POWER;
    params.oversampling_temperature = BMP280_ULTRA_LOW_POWER;
    params.oversampling_humidity = BMP280_ULTRA_LOW_POWER;

    bmp280_t bmp280_dev;
    memset(&bmp280_dev, 0, sizeof(bmp280_t));

    ESP_ERROR_CHECK(bmp280_init_desc(&bmp280_dev, BMP280_I2C_ADDRESS_0, I2C_NUM_0, SDA_GPIO, SCL_GPIO));

    if (bmp280_init(&bmp280_dev, &params) != ESP_OK)
    {
        ESP_LOGE(BME280_TAG, "Failed to initialize BME280");
    }
    else
    {
        // Force reading
        bmp280_force_measurement(&bmp280_dev);
        bool busy;
        do
        {
            bmp280_is_measuring(&bmp280_dev, &busy);
        } while (busy);

        // Lectura de datos
        if (bmp280_read_float(&bmp280_dev, &temperature, &pressure, &humidity) == ESP_OK)
        {
            ESP_LOGI(BME280_TAG, "Temperature: %.2f °C, Pressure: %.2f hPa, Humidity: %.2f %%", temperature, pressure, humidity);
        }
    }

    /* -------------------------------------- INIT MAX17048 ------------------------------------- */
    float voltage = 0;
    float soc_percent = 0;
    float rate_change = 0;
    max1704x_t max17048_dev = {0};

    // Set up I2C bus to communicate with MAX17048
    max17048_dev.model = MAX17048_9;

    if (max1704x_init_desc(&max17048_dev, I2C_NUM_0, SDA_GPIO, SCL_GPIO) != ESP_OK)
    {
        ESP_LOGE(MAX17048_TAG, "No se ha encontrado el sensor MAX17048. Verifique las conexiones.");
    }
    else
    {
        max1704x_get_voltage(&max17048_dev, &voltage);
        max1704x_get_soc(&max17048_dev, &soc_percent);
        max1704x_get_crate(&max17048_dev, &rate_change);

        if (voltage != 0 && soc_percent != 0 && rate_change != 0)
        {
            ESP_LOGI(MAX17048_TAG, "Voltage: %.2fV, SOC: %.2f%%, SOC rate of change: %.2f%%", voltage, soc_percent, rate_change);
        }
    }

    vTaskDelete(NULL);
}

void app_main(void)
{
    /* ------------------------------------- INITIALIZE NVS ------------------------------------- */
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    ESP_ERROR_CHECK(err);
    /* ---------------------------------- SENSOR MEASUREMENTS ----------------------------------- */
    ESP_ERROR_CHECK(i2cdev_init());
    xTaskCreate(sensor_reading, "sensor_reading", 4096, NULL, 5, NULL);
}

Any help is welcome, thanks

Which SDK are you using?

esp-idf

Which version of SDK are you using?

0.9.4

Which build target have you used?

Component causing the issue

MAX1704x, BMP280

Anything in the logs that might be useful for us?

No response

Additional information or context

No response

Confirmation

trombik commented 5 months ago

Please provide the log.

r3v1 commented 5 months ago

Here are the logs with both battery and BME280 connected:

I (120) main_task: Started on CPU0
I (120) main_task: Calling app_main()
V (120) partition: Loading the partition table
V (120) calculated md5: 0x3ffc5e98   bf 25 82 2c 0f a6 d8 64  1b d9 30 25 1e 06 b4 c4  |.%.,...d..0%....|
V (130) stored md5: 0x3f0180d0   bf 25 82 2c 0f a6 d8 64  1b d9 30 25 1e 06 b4 c4  |.%.,...d..0%....|
V (140) partition: Partition table MD5 verified
V (140) i2cdev: [0x76 at 0] creating mutex
V (140) i2cdev: [0x76 at 0] taking mutex
D (140) i2cdev: Reconfiguring I2C driver on port 0
D (140) i2cdev: I2C driver successfully reconfigured on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
I (140) main_task: Returned from app_main()
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (160) bmp280: Calibration data received:
D (160) bmp280: dig_T1=28295
D (160) bmp280: dig_T2=26483
D (160) bmp280: dig_T3=50
D (160) bmp280: dig_P1=36644
D (160) bmp280: dig_P2=-10651
D (160) bmp280: dig_P3=3024
D (160) bmp280: dig_P4=7119
D (160) bmp280: dig_P5=17
D (160) bmp280: dig_P6=-7
D (160) bmp280: dig_P7=9900
D (160) bmp280: dig_P8=-10230
D (160) bmp280: dig_P9=4285
D (160) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (160) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (160) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (160) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (160) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (160) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (160) bmp280: Calibration data received:
D (160) bmp280: dig_H1=75
D (160) bmp280: dig_H2=366
D (160) bmp280: dig_H3=0
D (160) bmp280: dig_H4=310
D (160) bmp280: dig_H5=50
D (160) bmp280: dig_H6=30
D (160) bmp280: Writing config reg=60
D (160) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (160) bmp280: Writing ctrl hum reg=1
D (160) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (160) bmp280: Writing ctrl reg=24
D (160) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
V (160) i2cdev: [0x76 at 0] giving mutex
V (160) i2cdev: [0x76 at 0] taking mutex
D (160) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (170) bmp280: Writing ctrl reg=25
D (170) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
V (170) i2cdev: [0x76 at 0] giving mutex
V (170) i2cdev: [0x76 at 0] taking mutex
D (170) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
V (170) i2cdev: [0x76 at 0] giving mutex
V (170) i2cdev: [0x76 at 0] taking mutex
D (170) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
V (170) i2cdev: [0x76 at 0] giving mutex
V (170) i2cdev: [0x76 at 0] taking mutex
D (170) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
V (170) i2cdev: [0x76 at 0] giving mutex
V (170) i2cdev: [0x76 at 0] taking mutex
D (170) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
V (170) i2cdev: [0x76 at 0] giving mutex
V (170) i2cdev: [0x76 at 0] taking mutex
D (170) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
V (170) i2cdev: [0x76 at 0] giving mutex
V (170) i2cdev: [0x76 at 0] taking mutex
D (170) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
V (170) i2cdev: [0x76 at 0] giving mutex
V (170) i2cdev: [0x76 at 0] taking mutex
D (170) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
V (170) i2cdev: [0x76 at 0] giving mutex
V (180) i2cdev: [0x76 at 0] taking mutex
D (180) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
D (180) bmp280: ADC temperature: 507904
D (180) bmp280: ADC pressure: 326736
D (180) bmp280: ADC humidity: 31391
V (180) i2cdev: [0x76 at 0] giving mutex
I (180) BME280: Temperature: 17.42 °C, Pressure: 102381.00 hPa, Humidity: 64.06 %
V (190) i2cdev: [0x36 at 0] creating mutex
V (190) i2cdev: [0x36 at 0] taking mutex
D (190) i2cdev: Reconfiguring I2C driver on port 0
D (190) i2cdev: I2C driver successfully reconfigured on port 0
D (200) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
V (200) i2cdev: [0x36 at 0] giving mutex
V (200) i2cdev: [0x36 at 0] taking mutex
D (200) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
V (200) i2cdev: [0x36 at 0] giving mutex
V (200) i2cdev: [0x36 at 0] taking mutex
D (200) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
V (200) i2cdev: [0x36 at 0] giving mutex
D (200) max1704x: crateValue: -13
I (200) MAX17048: Voltage: 3.88V, SOC: 61.95%, SOC rate of change: -2.70%

And now BME280 is disconnected:

I (120) main_task: Started on CPU0
I (120) main_task: Calling app_main()
V (120) partition: Loading the partition table
V (120) calculated md5: 0x3ffc5e98   bf 25 82 2c 0f a6 d8 64  1b d9 30 25 1e 06 b4 c4  |.%.,...d..0%....|
V (130) stored md5: 0x3f0180d0   bf 25 82 2c 0f a6 d8 64  1b d9 30 25 1e 06 b4 c4  |.%.,...d..0%....|
V (140) partition: Partition table MD5 verified
V (140) i2cdev: [0x76 at 0] creating mutex
V (140) i2cdev: [0x76 at 0] taking mutex
D (140) i2cdev: Reconfiguring I2C driver on port 0
D (140) i2cdev: I2C driver successfully reconfigured on port 0
D (150) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
I (140) main_task: Returned from app_main()
E (1150) i2cdev: Could not read from device [0x76 at 0]: 263 (ESP_ERR_TIMEOUT)
V (1160) i2cdev: [0x76 at 0] giving mutex
E (1160) bmp280: Sensor not found
E (1160) BME280: Failed to initialize BME280
V (1160) i2cdev: [0x36 at 0] creating mutex
V (1160) i2cdev: [0x36 at 0] taking mutex
D (1160) i2cdev: Reconfiguring I2C driver on port 0
D (1160) i2cdev: I2C driver successfully reconfigured on port 0
D (1170) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
E (2170) i2cdev: Could not read from device [0x36 at 0]: 263 (ESP_ERR_TIMEOUT)
V (2180) i2cdev: [0x36 at 0] giving mutex
V (2180) i2cdev: [0x36 at 0] taking mutex
D (2180) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
E (3180) i2cdev: Could not read from device [0x36 at 0]: 263 (ESP_ERR_TIMEOUT)
V (3190) i2cdev: [0x36 at 0] giving mutex
V (3190) i2cdev: [0x36 at 0] taking mutex
D (3190) i2cdev: Timeout: ticks = 0 (0 usec) on port 0
E (4190) i2cdev: Could not read from device [0x36 at 0]: 263 (ESP_ERR_TIMEOUT)
V (4200) i2cdev: [0x36 at 0] giving mutex
UncleRus commented 5 months ago

Looks like a hardware problem. Check that the remaining device (max17048) has SDA and SCL lines pulled up properly.

r3v1 commented 5 months ago

Unfortunately for me, I forgot adding pullup resistors... The code is right.