i2c_master_probe doesn't send any data, it just timeous out

ivan.gerber
Posts: 11
Joined: Wed Apr 16, 2025 7:22 pm

i2c_master_probe doesn't send any data, it just timeous out

Postby ivan.gerber » Fri Jun 27, 2025 7:55 pm

Hello, I'm having issues when connecting an I2C device to the ESP32S3 module.
First, a bit of context:
- Using ESP32S3-WROOM module, programming in VSCode using Platformio with ESP-IDF last stable version 5.4.
- The I2C bus has 3 different sensors attach to it: LIS3DH accelerometer (0x19), OPT3004 ambient light sensor (0x44) and GP8211S 0-10v digital to analog converter (0x58).
- It's a custom pcb design, with a 12VDC power supply, a lithium-polymer battery charger, and a LDO that regulates battery voltage to 3,3V.

My issue is that the GP8211S DAC IC is not responding to I2C commands, so I tried to use the i2c_master_probe() function to scan, in case I mistaken the address of the device. However when I call this function, nothing comes out via the SDA pin nor the SCL pin.
Here is the code I made for this:

Code: Select all

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

#define TAG "GP8211S"

gp8211s_t *GP8211S_PARAMS = nullptr;

static const uint8_t GP8211S_I2C_ADDR = 0x58; // I2C Address GP8211S
i2c_master_dev_handle_t gp8211s_i2c_dev_handle;

#define GP8211S_REG_CONFIG 0x01
#define GP8211S_REG_DAC 0x02

/**
 * @brief Initialize the DAC GP8211S I2C device
 *
 */
gp8211s_status_t gp8211s_i2c_init_device(void);
/**
 * @brief Converts a percentage (0-100) to a 16-bit register value for the GP8211S DAC
 *
 * @param percentage percentage value to convert (0-100)
 * @return uint16_t 16-bit register value corresponding to the percentage
 */
uint16_t gp8211s_convert_percentage(uint8_t percentage);

gp8211s_status_t gp8211s_init(gp8211s_t *gp8211s_params)
{
  //ESP_LOGI(TAG, "%s - Initializing DAC GP8211S", __func__);
  if (gp8211s_params == NULL)
  {
    ESP_LOGE(TAG, "%s - Null parameters", __func__);
    return GP8211S_ERR;
  }
  GP8211S_PARAMS = gp8211s_params;
  //Initialize I2C
  if (gp8211s_i2c_init_device() != GP8211S_OK)
  {
    ESP_LOGE(TAG, "%s - Error initializing I2C device", __func__);
    return GP8211S_ERR;
  }
  // write config register for 0-10v output
  uint8_t config[2];
  config[0] = GP8211S_REG_CONFIG; // config register address
  config[1] = 0x77; // 0-10v output mode
  esp_err_t err = i2c_master_transmit(gp8211s_i2c_dev_handle, config, sizeof(config), 1000);
  if (err != ESP_OK)
  {
    ESP_LOGE(TAG, "%s - Error writing to device: %s", __func__, esp_err_to_name(err));
    return GP8211S_ERR;
  }
  ESP_LOGI(TAG, "%s - DAC GP8211S initialized", __func__);
  return GP8211S_OK;
}

gp8211s_status_t gp8211s_change_percentage(uint8_t percentage)
{
    if (GP8211S_PARAMS == NULL)
  {
    ESP_LOGE(TAG, "%s - Null parameters", __func__);
    return GP8211S_ERR;
  }
  // write config register for 0-10v output
  uint8_t config[2];
  config[0] = GP8211S_REG_CONFIG; // config register address
  config[1] = 0x77; // 0-10v output mode
  esp_err_t err = i2c_master_transmit(gp8211s_i2c_dev_handle, config, sizeof(config), 1000);
  if (err != ESP_OK)
  {
    ESP_LOGE(TAG, "%s - Error writing to device: %s", __func__, esp_err_to_name(err));
    return GP8211S_ERR;
  }
  // calculate register value from percentage
  uint16_t reg_val = gp8211s_convert_percentage(percentage);
  ESP_LOGI(TAG, "%s - Percentage: %d - Register value: %04X", __func__, percentage, reg_val);
  // write register value to DAC
  if (reg_val > 0x7FFF) reg_val = 0x7FFF;
  uint8_t data[3];
  data[0] = GP8211S_REG_DAC; // DAC value register address
  data[1] = reg_val & 0xFF; // LSB
  data[2] = (reg_val >> 8) & 0x7F; // MSB (only 7 bits used)
  err = i2c_master_transmit(gp8211s_i2c_dev_handle, data, sizeof(data), 1000);
  if (err != ESP_OK)
  {
    ESP_LOGE(TAG, "%s - Error writing to device: %s", __func__, esp_err_to_name(err));
    return GP8211S_ERR;
  }
  return GP8211S_OK;
}

gp8211s_status_t gp8211s_i2c_init_device(void)
{
  if (GP8211S_PARAMS == NULL)
  {
    ESP_LOGE(TAG, "%s - Null parameters", __func__);
    return GP8211S_ERR;
  }
  i2c_device_config_t dev_cfg = {
    .dev_addr_length = I2C_ADDR_BIT_LEN_7,
    .device_address = GP8211S_I2C_ADDR,
    .scl_speed_hz = 100000,
    .scl_wait_us = 0,
    .flags = 0,
  };
  // Test - probe I2C addresses
  ESP_LOGI(TAG, "%s - Probing I2C addresses...", __func__);
  uint8_t addr_check = 0;
  esp_err_t err;
  while (addr_check < 0xff)
  {
    err = i2c_master_probe((i2c_master_bus_handle_t)GP8211S_PARAMS->i2c_master_bus_handle, addr_check, 1000);
    if (err != ESP_OK)
    {
      ESP_LOGE(TAG, "%s - Error probing I2C address 0x%02X: %s", __func__, addr_check, esp_err_to_name(err));
    }
    else
    {
      ESP_LOGI(TAG, "%s - I2C device found in address: 0x%02X", __func__, addr_check);
    }
    addr_check++;
  }
  err = i2c_master_bus_add_device((i2c_master_bus_handle_t)GP8211S_PARAMS->i2c_master_bus_handle, &dev_cfg, &gp8211s_i2c_dev_handle);
  if (err != ESP_OK)
  {
    ESP_LOGE(TAG, "%s - Error adding I2C device to the bus: %s", __func__, esp_err_to_name(err));
    return GP8211S_ERR;
  }
  return GP8211S_OK;
}

uint16_t gp8211s_convert_percentage(uint8_t percentage)
{
  // scale 0-100 is 0x0000-0x7ffff
  if (percentage > 100) percentage = 100; // limit to 100%
  uint16_t reg_val = (uint16_t)((percentage * 0x7FFF) / 100); // convert value to register value
  return reg_val;
}
In the main.cpp I have this bit of code to intialize the i2c bus, then I give the bus_handle to each library (accelerometer, als and dac):

Code: Select all

void main_crear_handle_i2c_master(void)
{
	// Create I2C master handle
	i2c_master_bus_config_t i2c_master_config = {
			.i2c_port = 1,
			.sda_io_num = (gpio_num_t)PIN_I2C_SDA,
			.scl_io_num = (gpio_num_t)PIN_I2C_SCL,
			.clk_source = I2C_CLK_SRC_DEFAULT,
			.glitch_ignore_cnt = 7,
			.intr_priority = 1,
			.trans_queue_depth = 10,
			.flags = {
					.enable_internal_pullup = 1,
					.allow_pd = 0}};
	ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_master_config, &i2c_master_handle));
	if (i2c_master_handle == NULL)
	{
		ESP_LOGE(TAG, "Error creating I2C master handle");
	}
}
The OPT3004 and the LIS3DH are close to eachother so they share the 4.7k pull-up resistors for the SCL and SDA lines. The problematic GP8211S IC has it's own 4.7k pull-up resistors.

Here is an image of the schematic of these ICs connections:
Image
The voltage in the SDA and SCL pins is ok in standby, measured with multimeter.

I have a logic analyzer to debug the I2C lines, here is the attempt to communicate with the GP8211S IC (address 0x58) before adding the i2c_master_probe code:
Image

After this unsuccessful attempsts to communicate with the GP8211S IC, I added the i2c_master_probe function in order to test the I2C bus, the result was that no data came out from the I2C lines in the logic analyzer, and this data shows in the firmware logs:

Code: Select all

I (7908) GP8211S: gp8211s_i2c_init_device - Probing I2C addresses...
E (8918) i2c.master: I2C software timeout
E (8918) i2c.master: probe device timeout. Please check if xfer_timeout_ms and pull-ups are correctly set up
E (8918) GP8211S: gp8211s_i2c_init_device - Error probing I2C address 0x00: ESP_ERR_TIMEOUT
E (9928) i2c.master: I2C software timeout
E (9928) i2c.master: probe device timeout. Please check if xfer_timeout_ms and pull-ups are correctly set up
E (9928) GP8211S: gp8211s_i2c_init_device - Error probing I2C address 0x01: ESP_ERR_TIMEOUT
E (10938) i2c.master: I2C software timeout
E (10938) i2c.master: probe device timeout. Please check if xfer_timeout_ms and pull-ups are correctly set up
E (10938) GP8211S: gp8211s_i2c_init_device - Error probing I2C address 0x02: ESP_ERR_TIMEOUT
E (11948) i2c.master: I2C software timeout
E (11948) i2c.master: probe device timeout. Please check if xfer_timeout_ms and pull-ups are correctly set up
E (11948) GP8211S: gp8211s_i2c_init_device - Error probing I2C address 0x03: ESP_ERR_TIMEOUT
It goes on and on until the end (reaching 0xfe), even when probing the 0x19 and 0x44 addresses (lis3dh and opt3004).

I know I must miss something, I've search the forum and the documentation, but I can't seem to find answer to these issues. I'll appreciate any input that could help me solved this.

dmitrij999
Posts: 100
Joined: Sat Mar 02, 2019 8:06 pm

Re: i2c_master_probe doesn't send any data, it just timeous out

Postby dmitrij999 » Fri Jun 27, 2025 8:09 pm

Could you please check the I2C bus with I2C-tools?
I mean, take an i2c-tools from example of your esp-idf, and perform an I2C scan

ivan.gerber
Posts: 11
Joined: Wed Apr 16, 2025 7:22 pm

Re: i2c_master_probe doesn't send any data, it just timeous out

Postby ivan.gerber » Thu Jul 03, 2025 8:57 pm

Hello @dmitrij999 , thank you for your response.
It took me some time to familiarize with it, but here is the result.
Image

It seems to detect a device in the 0x58 I2C address, I need to keep investigating.

Thank you for pointing me to something useful, I'll share any development

ivan.gerber
Posts: 11
Joined: Wed Apr 16, 2025 7:22 pm

Re: i2c_master_probe doesn't send any data, it just timeous out

Postby ivan.gerber » Fri Jul 04, 2025 1:17 pm

Finally, I discovered that the actual address of the device is not 0x58 (its 0x59) and my real problem with the communication was due to bad pin connection between the ESP and the DAC IC.
Although I never found out what was the problem with the i2c_master_probe function, my real issue was fixed.
Thanks again @dmitrij999 for showing me the i2ctool, it's really powerful.

Who is online

Users browsing this forum: ChatGPT-User, Semrush [Bot] and 8 guests