Having trouble getting i2c slave to ACK
Posted: Fri Jun 05, 2020 1:53 am
Been having issues trying to get the SHT31 Slave to ACK after initiating a Read. I am able to Initialize, Soft Reset, and Start a Measurement, but once I try to Read the Measurement I get a NACK from the Slave.
ESP-IDF returns a ESP_ERR_TIMEOUT or ESP_FAIL.
Here's sample code of the Soft-Reset, Init, Status Register, Heater, Start Measurement (Single Shot) and Reading after the Measurement.
It's worth noting that I'm able to get everything working using Arduino Code (using Adafruits SHT Library). But am migrating everything to ESP-IDF and am running into this issue .
esp_err_t reset() {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SHT31_ADDRESS << 1) | I2C_MASTER_WRITE, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x30, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0xA2, SHT31_ACK_CHECK_EN);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(SHT31_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
ESP_LOGI(tag, "SHT31 Soft-Reset");
if (ret == ESP_OK) {
ESP_LOGI(tag, "Success");
} else if (ret == ESP_ERR_INVALID_ARG) {
ESP_LOGI(tag, "Parameter error");
} else if (ret == ESP_FAIL) {
ESP_LOGI(tag, "Sending command error, slave doesn’t ACK the transfer.");
} else if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGI(tag, "I2C driver not installed or not in master mode.");
} else if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(tag, "Operation timeout because the bus is busy.");
}
return ESP_OK;
}
void init() {
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = SHT31_SDA_IO;
conf.scl_io_num = SHT31_SCL_IO;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = SHT31_FREQ_HZ;
ESP_ERROR_CHECK(i2c_param_config(SHT31_NUM, &conf));
ESP_ERROR_CHECK(i2c_set_timeout(SHT31_NUM, 100000));
ESP_ERROR_CHECK(i2c_driver_install(SHT31_NUM, conf.mode, SHT31_RX_BUF_DISABLE, SHT31_TX_BUF_DISABLE, 0));
vTaskDelay(200 / portTICK_PERIOD_MS);
reset();
vTaskDelay(10 / portTICK_PERIOD_MS);
}
void status_register_read() {
uint8_t readBuffer;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SHT31_ADDRESS << 1) | I2C_MASTER_READ, SHT31_ACK_CHECK_EN);
i2c_master_read_byte(cmd, &readBuffer, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 1, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 2, SHT31_NACK_VAL);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(SHT31_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
ESP_LOGI(tag, "Status Register Read");
if (ret == ESP_OK) {
ESP_LOGI(tag, "Success");
} else if (ret == ESP_ERR_INVALID_ARG) {
ESP_LOGI(tag, "Parameter error");
} else if (ret == ESP_FAIL) {
ESP_LOGI(tag, "Sending command error, slave doesn’t ACK the transfer.");
} else if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGI(tag, "I2C driver not installed or not in master mode.");
} else if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(tag, "Operation timeout because the bus is busy.");
}
}
void status_register() {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SHT31_ADDRESS << 1) | I2C_MASTER_WRITE, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0xF3, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x2D, SHT31_ACK_CHECK_EN);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(SHT31_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
ESP_LOGI(tag, "Status Register Write");
if (ret == ESP_OK) {
ESP_LOGI(tag, "Success");
} else if (ret == ESP_ERR_INVALID_ARG) {
ESP_LOGI(tag, "Parameter error");
} else if (ret == ESP_FAIL) {
ESP_LOGI(tag, "Sending command error, slave doesn’t ACK the transfer.");
} else if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGI(tag, "I2C driver not installed or not in master mode.");
} else if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(tag, "Operation timeout because the bus is busy.");
}
status_register_read();
}
void heater_on() {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SHT31_ADDRESS << 1) | I2C_MASTER_WRITE, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x30, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x6D, SHT31_ACK_CHECK_EN);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(SHT31_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
ESP_LOGI(tag, "Heater On");
if (ret == ESP_OK) {
ESP_LOGI(tag, "Success");
} else if (ret == ESP_ERR_INVALID_ARG) {
ESP_LOGI(tag, "Parameter error");
} else if (ret == ESP_FAIL) {
ESP_LOGI(tag, "Sending command error, slave doesn’t ACK the transfer.");
} else if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGI(tag, "I2C driver not installed or not in master mode.");
} else if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(tag, "Operation timeout because the bus is busy.");
}
}
void single_shot() {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SHT31_ADDRESS << 1) | I2C_MASTER_WRITE, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x24, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x00, SHT31_ACK_CHECK_EN);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(SHT31_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
ESP_LOGI(tag, "Single Shot");
if (ret == ESP_OK) {
ESP_LOGI(tag, "Success");
} else if (ret == ESP_ERR_INVALID_ARG) {
ESP_LOGI(tag, "Parameter error");
} else if (ret == ESP_FAIL) {
ESP_LOGI(tag, "Sending command error, slave doesn’t ACK the transfer.");
} else if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGI(tag, "I2C driver not installed or not in master mode.");
} else if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(tag, "Operation timeout because the bus is busy.");
}
}
void read_temperature_humidity() {
uint8_t readBuffer;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SHT31_ADDRESS << 1) | I2C_MASTER_READ, SHT31_ACK_CHECK_EN);
i2c_master_read_byte(cmd, &readBuffer, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 1, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 2, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 3, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 4, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 5, SHT31_NACK_VAL);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(SHT31_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
ESP_LOGI(tag, "Read Measurement");
if (ret == ESP_OK) {
ESP_LOGI(tag, "Success");
} else if (ret == ESP_ERR_INVALID_ARG) {
ESP_LOGI(tag, "Parameter error");
} else if (ret == ESP_FAIL) {
ESP_LOGI(tag, "Sending command error, slave doesn’t ACK the transfer.");
} else if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGI(tag, "I2C driver not installed or not in master mode.");
} else if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(tag, "Operation timeout because the bus is busy.");
}
All the Setup Stuff
https://preview.redd.it/yl5o974uhy251.p ... 3122f70dfa
When trying to Read
Also here is a link to the datasheet (Goto Section 4): https://www.sensirion.com/fileadmin/use ... igital.pdf
ESP-IDF returns a ESP_ERR_TIMEOUT or ESP_FAIL.
Here's sample code of the Soft-Reset, Init, Status Register, Heater, Start Measurement (Single Shot) and Reading after the Measurement.
It's worth noting that I'm able to get everything working using Arduino Code (using Adafruits SHT Library). But am migrating everything to ESP-IDF and am running into this issue .
esp_err_t reset() {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SHT31_ADDRESS << 1) | I2C_MASTER_WRITE, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x30, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0xA2, SHT31_ACK_CHECK_EN);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(SHT31_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
ESP_LOGI(tag, "SHT31 Soft-Reset");
if (ret == ESP_OK) {
ESP_LOGI(tag, "Success");
} else if (ret == ESP_ERR_INVALID_ARG) {
ESP_LOGI(tag, "Parameter error");
} else if (ret == ESP_FAIL) {
ESP_LOGI(tag, "Sending command error, slave doesn’t ACK the transfer.");
} else if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGI(tag, "I2C driver not installed or not in master mode.");
} else if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(tag, "Operation timeout because the bus is busy.");
}
return ESP_OK;
}
void init() {
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = SHT31_SDA_IO;
conf.scl_io_num = SHT31_SCL_IO;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = SHT31_FREQ_HZ;
ESP_ERROR_CHECK(i2c_param_config(SHT31_NUM, &conf));
ESP_ERROR_CHECK(i2c_set_timeout(SHT31_NUM, 100000));
ESP_ERROR_CHECK(i2c_driver_install(SHT31_NUM, conf.mode, SHT31_RX_BUF_DISABLE, SHT31_TX_BUF_DISABLE, 0));
vTaskDelay(200 / portTICK_PERIOD_MS);
reset();
vTaskDelay(10 / portTICK_PERIOD_MS);
}
void status_register_read() {
uint8_t readBuffer;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SHT31_ADDRESS << 1) | I2C_MASTER_READ, SHT31_ACK_CHECK_EN);
i2c_master_read_byte(cmd, &readBuffer, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 1, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 2, SHT31_NACK_VAL);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(SHT31_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
ESP_LOGI(tag, "Status Register Read");
if (ret == ESP_OK) {
ESP_LOGI(tag, "Success");
} else if (ret == ESP_ERR_INVALID_ARG) {
ESP_LOGI(tag, "Parameter error");
} else if (ret == ESP_FAIL) {
ESP_LOGI(tag, "Sending command error, slave doesn’t ACK the transfer.");
} else if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGI(tag, "I2C driver not installed or not in master mode.");
} else if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(tag, "Operation timeout because the bus is busy.");
}
}
void status_register() {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SHT31_ADDRESS << 1) | I2C_MASTER_WRITE, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0xF3, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x2D, SHT31_ACK_CHECK_EN);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(SHT31_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
ESP_LOGI(tag, "Status Register Write");
if (ret == ESP_OK) {
ESP_LOGI(tag, "Success");
} else if (ret == ESP_ERR_INVALID_ARG) {
ESP_LOGI(tag, "Parameter error");
} else if (ret == ESP_FAIL) {
ESP_LOGI(tag, "Sending command error, slave doesn’t ACK the transfer.");
} else if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGI(tag, "I2C driver not installed or not in master mode.");
} else if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(tag, "Operation timeout because the bus is busy.");
}
status_register_read();
}
void heater_on() {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SHT31_ADDRESS << 1) | I2C_MASTER_WRITE, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x30, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x6D, SHT31_ACK_CHECK_EN);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(SHT31_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
ESP_LOGI(tag, "Heater On");
if (ret == ESP_OK) {
ESP_LOGI(tag, "Success");
} else if (ret == ESP_ERR_INVALID_ARG) {
ESP_LOGI(tag, "Parameter error");
} else if (ret == ESP_FAIL) {
ESP_LOGI(tag, "Sending command error, slave doesn’t ACK the transfer.");
} else if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGI(tag, "I2C driver not installed or not in master mode.");
} else if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(tag, "Operation timeout because the bus is busy.");
}
}
void single_shot() {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SHT31_ADDRESS << 1) | I2C_MASTER_WRITE, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x24, SHT31_ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x00, SHT31_ACK_CHECK_EN);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(SHT31_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
ESP_LOGI(tag, "Single Shot");
if (ret == ESP_OK) {
ESP_LOGI(tag, "Success");
} else if (ret == ESP_ERR_INVALID_ARG) {
ESP_LOGI(tag, "Parameter error");
} else if (ret == ESP_FAIL) {
ESP_LOGI(tag, "Sending command error, slave doesn’t ACK the transfer.");
} else if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGI(tag, "I2C driver not installed or not in master mode.");
} else if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(tag, "Operation timeout because the bus is busy.");
}
}
void read_temperature_humidity() {
uint8_t readBuffer;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SHT31_ADDRESS << 1) | I2C_MASTER_READ, SHT31_ACK_CHECK_EN);
i2c_master_read_byte(cmd, &readBuffer, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 1, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 2, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 3, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 4, SHT31_ACK_VAL);
i2c_master_read_byte(cmd, &readBuffer + 5, SHT31_NACK_VAL);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(SHT31_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
ESP_LOGI(tag, "Read Measurement");
if (ret == ESP_OK) {
ESP_LOGI(tag, "Success");
} else if (ret == ESP_ERR_INVALID_ARG) {
ESP_LOGI(tag, "Parameter error");
} else if (ret == ESP_FAIL) {
ESP_LOGI(tag, "Sending command error, slave doesn’t ACK the transfer.");
} else if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGI(tag, "I2C driver not installed or not in master mode.");
} else if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(tag, "Operation timeout because the bus is busy.");
}
All the Setup Stuff
https://preview.redd.it/yl5o974uhy251.p ... 3122f70dfa
When trying to Read
Also here is a link to the datasheet (Goto Section 4): https://www.sensirion.com/fileadmin/use ... igital.pdf