Problems with I2C timeout
Posted: Sat Apr 01, 2023 10:11 pm
Hello,
I'm pretty new to the IDF and I'm currently writing a i2c library for the sensor HTE501: https://www.epluse.com/fileadmin/data/p ... HTE501.pdf
The normal readings work without problem, but I have problems with the single shot measurement.
The sensor support two types to read the single shot measurement data (S.14):
* Single Shot Clock Stretching: In case a command with clock stretching enabled has been issued, the slave holds SCL low until the
calculation has been finished, time depends on resolution, max. ~19ms.
* Single Shot: A single-shot measurement is started after the command has been received successfully. The readout of
the calculated values RH and T is started by sending the I2C address again in read mode
I didn't manage to get it to work with clock stretching, always getting timeout error.
I also tried both with "i2c_master_write_read_device", but it still doesn't work.
The only version I have found working is when using a 20ms delay:
But it's a pretty unclean solution.
Does someone have a better idea? Maybe how to get it working with clock stretching?
Thanks for your help,
Tropaion
I'm pretty new to the IDF and I'm currently writing a i2c library for the sensor HTE501: https://www.epluse.com/fileadmin/data/p ... HTE501.pdf
The normal readings work without problem, but I have problems with the single shot measurement.
The sensor support two types to read the single shot measurement data (S.14):
* Single Shot Clock Stretching: In case a command with clock stretching enabled has been issued, the slave holds SCL low until the
calculation has been finished, time depends on resolution, max. ~19ms.
* Single Shot: A single-shot measurement is started after the command has been received successfully. The readout of
the calculated values RH and T is started by sending the I2C address again in read mode
I didn't manage to get it to work with clock stretching, always getting timeout error.
I also tried both with "i2c_master_write_read_device", but it still doesn't work.
The only version I have found working is when using a 20ms delay:
Code: Select all
esp_err_t hte501_measure(hte501_handle_t hte501, float* temp, float* hum)
{
hte501_dev_t* pSensor = (hte501_dev_t*) hte501;
// Receive buffer
uint8_t buff[HTE501_SINGLE_SHOT_LENGTH];
// Create command to send
uint8_t cmd[] = {HTE501_SINGLE_SHOT_HIGH, HTE501_SINGLE_SHOT_LOW};
// Send command
esp_err_t err = i2c_master_write_to_device(pSensor->bus, pSensor->dev_addr, &cmd[0], 2, I2C_TIMEOUT);
// Check for error
ESP_LOGI(TAG, "%s", esp_err_to_name(err));
if(err != ESP_OK) { return err; }
vTaskDelay(20 / portTICK_PERIOD_MS);
// Receive values
err = i2c_master_read_from_device(pSensor->bus, pSensor->dev_addr, &buff[0], 6, I2C_TIMEOUT);
// Check for error
ESP_LOGI(TAG, "%s", esp_err_to_name(err));
if(err != ESP_OK) { return err; }
// Write serial number to log
ESP_LOGI(TAG, "HTE501 Temp/Hum:");
ESP_LOG_BUFFER_HEX(TAG, &buff[0], HTE501_SINGLE_SHOT_LENGTH);
// Calculate temperature
*temp = (float)(((uint16_t)buff[0] << 8) | buff[1]) / 100.0f;
// Calculate humidity
*hum = (float)(((uint16_t)buff[3] << 8) | buff[4]) / 100.0f;
return err;
}
Does someone have a better idea? Maybe how to get it working with clock stretching?
Thanks for your help,
Tropaion