Need Help with I2C Master Code on ESP32

harith
Posts: 7
Joined: Tue Jun 04, 2024 6:12 pm

Need Help with I2C Master Code on ESP32

Postby harith » Tue Jun 04, 2024 6:23 pm

Subject:

Hi everyone,

I'm new to ESP32 and esp idf programming and trying to get an I2C master working using the code example from the [ESP-IDF documentation](https://docs.espressif.com/projects/esp ... s/i2c.html). Despite following the example, my code doesn't seem to work.

Here's the code I'm using:

Code: Select all

#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2c_master.h"
#include "driver/i2c.h"

static const char *TAG = "MONIDAT";

void app_main(void)
{
    i2c_master_bus_config_t i2c_mst_config = {
        .clk_source = I2C_CLK_SRC_DEFAULT,
        .i2c_port = -1,
        .scl_io_num = 22,
        .sda_io_num = 21,
        .glitch_ignore_cnt = 7,
    };
    i2c_master_bus_handle_t bus_handle;

    i2c_device_config_t dev_cfg = {
        .dev_addr_length = I2C_ADDR_BIT_LEN_7,
        .device_address = 0x54,
        .scl_speed_hz = 400000,
    };
    i2c_master_dev_handle_t dev_handle;

    uint8_t buffer[6] = {};

    ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
    ESP_ERROR_CHECK(i2c_master_probe(bus_handle, 0x54, -1)); 
    ESP_ERROR_CHECK(i2c_del_master_bus(bus_handle));

    ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
    ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));

    i2c_master_receive(dev_handle, buffer, sizeof(buffer), -1);
    for (size_t i = 0; i < sizeof(buffer); i++) {
        ESP_LOGI(TAG, "bytes %d is %d/n", i, buffer[i]);
    }
    ESP_ERROR_CHECK(i2c_del_master_bus(bus_handle));
}

I have tons of error message but i don't understand them

the building step is going fine but once i flash the esp32 it goes completely crazy

Am I missing something? Any help or suggestions would be greatly appreciated!

Thanks!
Attachments
Capture.PNG
Capture.PNG (90.8 KiB) Viewed 2473 times

chegewara
Posts: 2378
Joined: Wed Jun 14, 2017 9:00 pm

Re: Need Help with I2C Master Code on ESP32

Postby chegewara » Wed Jun 05, 2024 2:08 am

I know what documentation says, but did you try to set this value to 0:

Code: Select all

    i2c_master_bus_config_t i2c_mst_config = {
        .clk_source = I2C_CLK_SRC_DEFAULT,
        .i2c_port = -1, <----------- SET it to 0
        
        

harith
Posts: 7
Joined: Tue Jun 04, 2024 6:12 pm

Re: Need Help with I2C Master Code on ESP32

Postby harith » Wed Jun 05, 2024 2:47 pm

chegewara wrote:
Wed Jun 05, 2024 2:08 am
I know what documentation says, but did you try to set this value to 0:

Code: Select all

    i2c_master_bus_config_t i2c_mst_config = {
        .clk_source = I2C_CLK_SRC_DEFAULT,
        .i2c_port = -1, <----------- SET it to 0
        
       
Yup I have tested and the output is still the same,

I don't know what I am missing

ESP_Sprite
Posts: 9773
Joined: Thu Nov 26, 2015 4:08 am

Re: Need Help with I2C Master Code on ESP32

Postby ESP_Sprite » Fri Jun 07, 2024 1:11 am

Can you try removing the i2c_del_master and i2c_new_master_bus between your probe and i2c_master_receive?

harith
Posts: 7
Joined: Tue Jun 04, 2024 6:12 pm

Re: Need Help with I2C Master Code on ESP32

Postby harith » Sat Jun 08, 2024 3:23 pm

Hello it is still the same output
that is really confusing

ESP_Sprite
Posts: 9773
Joined: Thu Nov 26, 2015 4:08 am

Re: Need Help with I2C Master Code on ESP32

Postby ESP_Sprite » Sun Jun 09, 2024 1:36 am

Strange. What ESP32 is this on and what version of ESP-IDF are you running? Also, what sensor are you talking to?

harith
Posts: 7
Joined: Tue Jun 04, 2024 6:12 pm

Re: Need Help with I2C Master Code on ESP32

Postby harith » Sun Jun 09, 2024 5:06 pm

I'm working with an ESP32 WROOM-32 module from Az-Delivery, which is a bit on the older side, the module is 3 years old without updating the firmware. The IDF version I'm using is 5.2, and the sensor in question is a TSL2591.

after several tests , I've encountered a peculiar issue. The setup works perfectly when I power on the ESP32 and monitor the output via PuTTY. However, the system crashes every time I hit the reset button. It seems like the system only works once, and any attempt to reset results in a crash.

Here's the latest code snippet I’ve been using (please note, it did work once):

Code: Select all

#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2c_master.h"
#include "esp_timer.h"

static const char *TAG = "MONIDAT";

// TSL2591 I2C address
#define TSL2591_ADDR         0x29
#define TSL2591_COMMAND_BIT  0xA0
#define TSL2591_REGISTER_ENABLE  0x00
#define TSL2591_REGISTER_CONTROL 0x01
#define TSL2591_REGISTER_CHAN0_LOW 0x14

// TSL2591 configurations
#define TSL2591_ENABLE_POWERON   0x01
#define TSL2591_ENABLE_AEN       0x02
#define TSL2591_GAIN_MED         0x10

esp_err_t tsl2591_write_register(uint8_t reg, uint8_t value,i2c_master_dev_handle_t dev_handle)
{
    uint8_t buffer[2] = { TSL2591_COMMAND_BIT | reg, value };
    return i2c_master_transmit(dev_handle,buffer,sizeof(buffer),-1);
}

esp_err_t tsl2591_read_register(uint8_t reg, uint8_t *data, size_t len,i2c_master_dev_handle_t dev_handle)
{
    reg = TSL2591_COMMAND_BIT | reg;
    
    return i2c_master_transmit_receive(dev_handle,&reg,1,data,len,-1);

}

void tsl2591_init(i2c_master_dev_handle_t dev_handle)
{
    // Power on and enable the TSL2591
    ESP_ERROR_CHECK(tsl2591_write_register(TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWERON | TSL2591_ENABLE_AEN,dev_handle));
    // Set medium gain
    ESP_ERROR_CHECK(tsl2591_write_register(TSL2591_REGISTER_CONTROL, TSL2591_GAIN_MED,dev_handle));
}

void measure_task(i2c_master_dev_handle_t dev_handle)
{
    uint8_t data[2];
    int num_measurements = 100000;
    int64_t start_time = esp_timer_get_time();

    for (int i = 0; i < num_measurements; i++)
    {
        ESP_ERROR_CHECK(tsl2591_read_register(TSL2591_REGISTER_CHAN0_LOW, data, 2,dev_handle));
        uint16_t luminosity = (data[1] << 8) | data[0];
        // Optionally log every 1000th measurement to avoid overwhelming the log
        if (i % 100 == 0) {
            ESP_LOGI(TAG, "Measurement %d: Luminosity: %d", i, luminosity);
        }
    }

    int64_t end_time = esp_timer_get_time();
    float elapsed_time_sec = (end_time - start_time) / 1000000.0;
    ESP_LOGI(TAG, "Completed %d measurements in %.2f seconds good job", num_measurements, elapsed_time_sec);

}

void app_main(void)
{
    i2c_master_bus_config_t i2c_mst_config = {
        .clk_source = I2C_CLK_SRC_DEFAULT,
        .i2c_port = -1,
        .scl_io_num = 22,
        .sda_io_num = 21,
        .glitch_ignore_cnt = 7,
        
    };
    i2c_master_bus_handle_t bus_handle;

    i2c_device_config_t dev_cfg = {
    .dev_addr_length = I2C_ADDR_BIT_LEN_7,
    .device_address = 0x29,
    .scl_speed_hz = 400000,
    };
    i2c_master_dev_handle_t dev_handle;

        ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
        ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
        ESP_LOGI(TAG,"the bus has been activated");

        tsl2591_init(dev_handle);
        measure_task(dev_handle);
        ESP_ERROR_CHECK(i2c_del_master_bus(bus_handle));
}

To isolate the problem, I've also purchased an ESP32-S3 to test whether the issue might be with the hardware itself.
Has anyone experienced something similar or have any insights on what might be causing this behavior?

MicroController
Posts: 1759
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Need Help with I2C Master Code on ESP32

Postby MicroController » Sun Jun 09, 2024 6:10 pm

harith wrote:
Sun Jun 09, 2024 5:06 pm
The setup works perfectly when I power on the ESP32 and monitor the output via PuTTY. However, the system crashes every time I hit the reset button. It seems like the system only works once, and any attempt to reset results in a crash.
Try calling i2c_master_bus_reset() after creating the new bus handle but before starting the first transaction on the bus. This implicitly "clears" the bus which may be in an inconsistent state after a reset of only the MCU but not the sensor.

harith
Posts: 7
Joined: Tue Jun 04, 2024 6:12 pm

Re: Need Help with I2C Master Code on ESP32

Postby harith » Mon Jun 10, 2024 10:52 am

Nope it does not work.
I’ve noticed something interesting that might shed more light on the issue. When I press the reset button while the program is running, it causes an error that requires me to power cycle the module of to recover. However, if I let the program run to completion and then press the reset button, the program restarts normally.

It seems that I need to allow the program to finish before resetting.

Edit : I tested on a ESP32-S3 N16R8 and now it works, I can press reset without having the program to go completely crazy

but during the execution of the program I have this "error" :

Code: Select all

I (15255) MONIDAT: Measurement 86800: Luminosity: 3
I (15265) MONIDAT: Measurement 86900: Luminosity: 3
I (15285) MONIDAT: Measurement 87000: Luminosity: 3
I (15305) MONIDAT: Measurement 87100: Luminosity: 3
E (15305) task_wdt: Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:
E (15305) task_wdt:  - IDLE0 (CPU 0)
E (15305) task_wdt: Tasks currently running:
E (15305) task_wdt: CPU 0: main
E (15305) task_wdt: CPU 1: IDLE1
E (15305) task_wdt: Print CPU 0 (current core) backtrace


Backtrace: 0x4200D673:0x3FC93300 0x4200DA90:0x3FC93320 0x40377175:0x3FC93350 0x4200AF31:0x3FC99090 0x4200B10C:0x3FC990C0 0x4200B1D3:0x3FC99100 0x4200BE12:0x3FC99130 0x42008436:0x3FC991D0 0x4200849B:0x3FC99200 0x420085E9:0x3FC99240 0x4201B877:0x3FC992A0 0x4037A9E1:0x3FC992D0
0x4200d673: task_wdt_timeout_handling at C:/ESP/components/esp_system/task_wdt/task_wdt.c:441
0x4200da90: task_wdt_isr at C:/ESP/components/esp_system/task_wdt/task_wdt.c:515
0x40377175: _xt_lowint1 at C:/ESP/components/xtensa/xtensa_vectors.S:1240
0x4200af31: s_i2c_send_commands at C:/ESP/components/driver/i2c/i2c_master.c:433 (discriminator 1)
0x4200b10c: s_i2c_transaction_start at C:/ESP/components/driver/i2c/i2c_master.c:509
0x4200b1d3: s_i2c_synchronous_transaction at C:/ESP/components/driver/i2c/i2c_master.c:780
0x4200be12: i2c_master_transmit_receive at C:/ESP/components/driver/i2c/i2c_master.c:995
0x42008436: tsl2591_read_register at C:/ESP/examples/get-started/lisi_monidat/main/lisi_monidat.c:34
0x4200849b: measure_task at C:/ESP/examples/get-started/lisi_monidat/main/lisi_monidat.c:55
0x420085e9: app_main at C:/ESP/examples/get-started/lisi_monidat/main/lisi_monidat.c:98
0x4201b877: main_task at C:/ESP/components/freertos/app_startup.c:208
0x4037a9e1: vPortTaskWrapper at C:/ESP/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:134        


I (15375) MONIDAT: Measurement 87200: Luminosity: 3
I (15385) MONIDAT: Measurement 87300: Luminosity: 3
I (15405) MONIDAT: Measurement 87400: Luminosity: 3
I (15425) MONIDAT: Measurement 87500: Luminosity: 3
but then the program continue and execute well
one issue fixed, another one is comming ! :D

Edit : maybe du to "no delay" default the tick period is 10ms, so any delay of less than 10ms results in a 0 delay right ? https://esp32.com/viewtopic.php?t=32384

MicroController
Posts: 1759
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Need Help with I2C Master Code on ESP32

Postby MicroController » Mon Jun 10, 2024 7:08 pm

harith wrote:
Mon Jun 10, 2024 10:52 am
When I press the reset button while the program is running, it causes an error that requires me to power cycle the module of to recover. However, if I let the program run to completion and then press the reset button, the program restarts normally.
That's because of the 'inconsistency' emerging between the bus participants when the master is reset mid-transaction, which i2c_master_bus_reset() attempts to rectify. At a glance, the software-based implementation for the older ESPs may be a bit too 'optimistic' in assuming that every slave will correctly handle a STOP condition at any bit position, not only after each full byte.
It seems that I need to allow the program to finish before resetting.
Yes, or more specifically, don't reset the MCU while an I2Ç transaction is ongoing. Or, check if you can make the MCU reset/power cycle the I2C slaves when it boots.

Who is online

Users browsing this forum: No registered users and 62 guests