Got a trouble of reading a temperature sensor using I2C on the ESP32
jeweeel
Posts: 1
I am trying to read a temperature and humidity sensor (SI7020) using I2C on the ESP32.
I modified their example code to read just from one slave device (0x40) but some commands do not work. I tried resetting the device with 0xFE as well.
I can read the device ID (0xFA):
However if I try and read the temperature (0xE3), I get:
If I use 0xE0 I always get:
Why am I not able to read the temperature from SI7020?
The code I'm using:
Can anyone help me out?Thanks!
I modified their example code to read just from one slave device (0x40) but some commands do not work. I tried resetting the device with 0xFE as well.
I can read the device ID (0xFA):
******************* TASK[0] MASTER READ SENSOR( SI7020 ) ******************* data_h: 48 data_l: 52 sensor val: 15428.333333
However if I try and read the temperature (0xE3), I get:
data_h: 00 data_l: 00
If I use 0xE0 I always get:
data_h: 39 data_l: 9f
Why am I not able to read the temperature from SI7020?
The code I'm using:
#include <stdio.h> #include "driver/i2c.h" #define DATA_LENGTH 512 /*!<Data buffer length for test buffer*/ #define RW_TEST_LENGTH 127 /*!<Data length for r/w test, any value from 0-DATA_LENGTH*/ #define DELAY_TIME_BETWEEN_ITEMS_MS 2000 /*!< delay time between different test items */ #define I2C_EXAMPLE_MASTER_SCL_IO 19 /*!< gpio number for I2C master clock */ #define I2C_EXAMPLE_MASTER_SDA_IO 18 /*!< gpio number for I2C master data */ #define I2C_EXAMPLE_MASTER_NUM I2C_NUM_1 /*!< I2C port number for master dev */ #define I2C_EXAMPLE_MASTER_TX_BUF_DISABLE 0 /*!< I2C master do not need buffer */ #define I2C_EXAMPLE_MASTER_RX_BUF_DISABLE 0 /*!< I2C master do not need buffer */ #define I2C_EXAMPLE_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */ #define SI7020_SENSOR_ADDR 0x40 /*!< slave address for SI7020 sensor */ #define SI7020_CMD_READ 0xE0 /*!< Command to set measure mode */ //#define ESP_SLAVE_ADDR 0x28 /*!< ESP32 slave address, you can set any 7bit value */ #define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ #define READ_BIT I2C_MASTER_READ /*!< I2C master read */ #define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ #define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ #define ACK_VAL 0x0 /*!< I2C ack value */ #define NACK_VAL 0x1 /*!< I2C nack value */ xSemaphoreHandle print_mux; /** * @brief test code to write esp-i2c-slave * * 1. set mode * _________________________________________________________________ * | start | slave_addr + wr_bit + ack | write 1 byte + ack | stop | * --------|---------------------------|---------------------|------| * 2. wait more than 24 ms * 3. read data * ______________________________________________________________________________________ * | start | slave_addr + rd_bit + ack | read 1 byte + ack | read 1 byte + nack | stop | * --------|---------------------------|--------------------|--------------------|------| */ static esp_err_t i2c_example_master_sensor_test(i2c_port_t i2c_num, uint8_t* data_h, uint8_t* data_l) { i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, SI7020_SENSOR_ADDR << 1 | WRITE_BIT, ACK_CHECK_DIS); i2c_master_write_byte(cmd, SI7020_CMD_READ, ACK_CHECK_EN); i2c_master_stop(cmd); int ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); if (ret == ESP_FAIL) { return ret; } vTaskDelay(1000 / portTICK_RATE_MS); cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, SI7020_SENSOR_ADDR << 1 | READ_BIT, ACK_CHECK_DIS); i2c_master_read_byte(cmd, data_h, ACK_VAL); i2c_master_read_byte(cmd, data_l, NACK_VAL); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); if (ret == ESP_FAIL) { return ESP_FAIL; } return ESP_OK; } /** * @brief i2c master initialization */ static void i2c_example_master_init() { int i2c_master_port = I2C_EXAMPLE_MASTER_NUM; i2c_config_t conf; conf.mode = I2C_MODE_MASTER; conf.sda_io_num = I2C_EXAMPLE_MASTER_SDA_IO; conf.sda_pullup_en = GPIO_PULLUP_ENABLE; conf.scl_io_num = I2C_EXAMPLE_MASTER_SCL_IO; conf.scl_pullup_en = GPIO_PULLUP_ENABLE; conf.master.clk_speed = I2C_EXAMPLE_MASTER_FREQ_HZ; i2c_param_config(i2c_master_port, &conf); i2c_driver_install(i2c_master_port, conf.mode, I2C_EXAMPLE_MASTER_RX_BUF_DISABLE, I2C_EXAMPLE_MASTER_TX_BUF_DISABLE, 0); } static void i2c_test_task(void* arg) { int i = 0; int ret; uint32_t task_idx = (uint32_t) arg; uint8_t* data = (uint8_t*) malloc(DATA_LENGTH); uint8_t sensor_data_h, sensor_data_l; while (1) { ret = i2c_example_master_sensor_test( I2C_EXAMPLE_MASTER_NUM, &sensor_data_h, &sensor_data_l); xSemaphoreTake(print_mux, portMAX_DELAY); printf("*******************\n"); printf("TASK[%d] MASTER READ SENSOR( SI7020 )\n", task_idx); printf("*******************\n"); if (ret == ESP_OK) { printf("data_h: %02x\n", sensor_data_h); printf("data_l: %02x\n", sensor_data_l); printf("sensor val: %f\n", ( sensor_data_h << 8 | sensor_data_l ) / 1.2); } else { printf("No ack, sensor not connected...skip...\n"); } xSemaphoreGive(print_mux); vTaskDelay(( DELAY_TIME_BETWEEN_ITEMS_MS * ( task_idx + 1 ) ) / portTICK_RATE_MS); //--------------------------------------------------- for (i = 0; i < DATA_LENGTH; i++) { data[i] = i; } } } void app_main() { print_mux = xSemaphoreCreateMutex(); //i2c_example_slave_init(); i2c_example_master_init(); xTaskCreate(i2c_test_task, "i2c_test_task_0", 1024 * 2, (void* ) 0, 10, NULL); //xTaskCreate(i2c_test_task, "i2c_test_task_1", 1024 * 2, (void* ) 1, 10, NULL); }
Can anyone help me out?Thanks!
Comments
https://electronics.stackexchange.com/questions/333085/trouble-using-i2c-on-esp32-to-read-temperature-humidity-sensor-si7020
Looks like the simple solution there could work.