Chapter 12 ESP32 reads the temperature and humidity of SHT30 (IIC)

Pay attention to the public account of Jiayouchuang Technology

Learning goals and objectives

  1. The principle of I2C communication
  2. Learn to configure the I2C function of ESP32
  3. Master I2C reading the temperature and humidity program of SHT30

Introduction to I2C Communication Protocol

The I2C communication protocol (Inter-Integrated Circuit) was developed by Philips. Because of its few pins, simple hardware implementation and strong scalability, it does not require external transceiver equipment such as USART, CAN and other communication protocols. It is now widely used in Communication between multiple integrated circuits (ICs) within a system. Below we explain the physical layer and protocol layer of the I2C protocol respectively.

physical layer

The common connection method between 2C communication devices The communication structure is as follows.

Its physical layer has the following main characteristics:

  • A bus that supports multiple devices. "Bus" refers to a signal line shared by multiple devices. In one I2C communication bus, multiple I2C communication devices can be connected to support multiple communication masters and multiple communication slaves.
  • An I2C bus uses only two bus lines, a bidirectional serial data line (SDA) and a serial clock line (SCL). The data line is used to represent data, and the clock line is used to synchronize data transmission and reception.
  • Each device connected to the bus has a unique address, and the host uses this address for access between different devices.
  • The bus is connected to the power supply through a pull-up resistor. When the I2C device is idle, it will output a high-impedance state, and when all devices are idle and output a high-impedance state, the pull-up resistor will pull the bus to a high level. When multiple hosts use the bus at the same time, in order to prevent data conflict, an arbitration method is used to determine which device occupies the bus.
  • Commonly used rates: The standard mode transmission rate is 100kbit/s, and the fast mode is 400kbit/s.
  • I3C came out recently, and the performance has been greatly improved.

Protocol layer

The I2C protocol defines the communication start and stop signals, data validity, response, arbitration, clock synchronization and address broadcast.

 The basic structure of the I2C communication process is as follows:

  • I2C write format

 

  • I2C read format

  • I2C read and write format

A few details of I2C are as follows:

  • I2C start and stop signals

The start (S) and stop (P) signals mentioned above are two special states, see Figure 23-5. When the SCL line is high

Usually, the SDA line switches from high level to low level, which indicates the beginning of communication. When SCL is high, the SDA line switches from low to high, indicating the stop of communication. Start and stop signals are generally generated by the host.

  • data validity

I2C uses the SDA signal line for data transmission and the SCL signal line for data synchronization. The SDA data line transfers one bit of data every clock cycle of SCL. During transmission, the data represented by SDA is valid when SCL is at high level, that is, when SDA is at high level at this time, it means data "1", and when it is at low level, it means data "0". When SCL is low, the data of SDA is invalid. Generally, SDA switches the level at this time to prepare for the next data representation.

Each data transfer is in bytes, and there is no limit to the number of bytes per transfer.

  • Address and Data Direction

Each device on the I2C bus has its own independent address. When the host initiates communication, it sends the device address (SLAVE_ADDRESS) through the SDA signal line to find the slave. The I2C protocol stipulates that the device address can be 7-bit or 10-bit. In practice, the 7-bit address is widely used. A data bit following the device address is used to indicate the direction of data transfer, which is the data direction bit (R/W), bit 8 or bit 11. When the data direction bit is "1", it indicates that the master reads data from the slave, and when the bit is "0", it indicates that the master writes data to the slave.

When reading the data direction, the host will release the control of the SDA signal line, the slave will control the SDA signal line, and the host will receive the signal. When writing the data direction, the SDA will be controlled by the host and the slave will receive the signal.

 

  • response

Both data and address transfers of I2C are responsive. The response includes two signals, "acknowledgement (ACK)" and "non-acknowledgement (NACK)". As a data receiving end, when the device (regardless of master and slave) receives a byte of data or address transmitted by I2C, if you want the other party to continue to send data, you need to send an "acknowledgment (ACK)" signal to the other party, the sender will Continue to send the next data; if the receiver wants to end the data transmission, it will send a "NACK" signal to the other party. After the sender receives the signal, it will generate a stop signal to end the signal transmission.

The host generates a clock during transmission. At the ninth clock, the data sender will release the control of SDA, and the data receiver will control SDA. If SDA is high, it means a non-acknowledgement signal (NACK), and a low level means a response signal (ACK).

It is useless to copy so many theories, because ESP32 has hardware I2C, as long as you call the relevant API, it is very simple to use.

 

SHT30 temperature and humidity sensor parameters introduction

  • SHT30 temperature and humidity test range

temperature

humidity

-40~125℃ Error ±0.3℃

0~100% error conquer 3%RH

  • SHT30 has two communication formats. Only I2C communication is explained here. The schematic diagram is as follows:

  • SHT30 write timing

  • SHT30 read temperature sequence

  • The timings of other commands of SHT30 are similar, please refer to the English manual of SHT30.

Hardware Design and Principle

This experimental board uses I2C_1 of ESP32 . The following table is the mapping of our program IO.

I2C_1

Features

Map the pins of the ESP32

SCL

clock

IO33

SDA

data

IO32

 

If the I2C connection method or pins of the experimental board you are using are different, you only need to modify the pins according to our project, and the control principle of the program is the same.

 

software design

code logic

Introduction to I2C master interface of ESP32

The interface here can correspond to the noun in the I2C communication principle.

  • I2C configuration function: i2c_param_config();

function prototype

esp_err_t i2c_param_config

(

i2c_port_t i2c_num,

const i2c_config_t* i2c_conf

)

function

I2C configuration function

parameter

[in] i2c_num: I2C number, value

  1. I2C_NUM_0 = 0, /*I2C_0 */
  2. I2C_NUM_1 , /*I2C_1*/

[in] i2c_conf: I2C parameter configuration

typedef struct{undefined

i2c_mode_t mode; /*I2C mode*/

gpio_num_t sda_io_num; /*SDA pin*/

gpio_pullup_t sda_pullup_en; /*SDA pullup enable*/

gpio_num_t scl_io_num; /*SCL pin*/

gpio_pullup_t scl_pullup_en; /*SCL pullup enable*/

union {undefined

struct {undefined

uint32_t clk_speed; /*Clock speed*/

} master;

struct {undefined

uint8_t addr_10bit_en; /*10-bit address enable*/

uint16_t slave_addr; /*Address when used as a slave*/

} slave;

};

}i2c_config_t;

return value

ESP_OK: success

ESP_ERR_INVALID_ARG : parameter error

 

  • I2C function installation enable function: i2c_driver_install();

function prototype

esp_err_t i2c_driver_install

(

i2c_port_t i2c_num,

i2c_mode_t mode,

size_t slv_rx_buf_len,

size_t slv_tx_buf_len,

int_alloc_flags

)

function

I2C function installation enable function

parameter

[in] i2c_num: I2C number

[in] mode: I2C mode

[in] slv_rx_buf_len: Receive buffer size

[in] slv_tx_buf_len: Send buffer size

[in] intr_alloc_flags: allocation interrupt flags

return value

ESP_OK: success

ESP_ERR_INVALID_ARG : parameter error

  • Create I2C connection function: i2c_cmd_link_create();

function prototype

int i2c_cmd_link_create()

function

Create I2C connection function

parameter

[in] No

return value

i2c_cmd_handle_t: handle of the I2C connection

  • Write the start signal to the cache function: i2c_master_start();

function prototype

esp_err_t i2c_master_start

(

i2c_cmd_handle_t cmd_handle

)

function

I2C write start signal to buffer function

parameter

[in] cmd_handle: The handle of the I2C connection, the return value of the i2c_cmd_link_create() function

return value

ESP_OK: success

ESP_ERR_INVALID_ARG : parameter error

  • The command to write a byte is put into the cache function: i2c_master_write_byte();

function prototype

esp_err_t i2c_master_write_byte

(

i2c_cmd_handle_t cmd_handle,

uint8_t data,

bool ack_en

)

function

I2C write a byte command to the cache function

parameter

[in] cmd_handle: The handle of the I2C connection, the return value of the i2c_cmd_link_create() function

[in] data: sent data

[in] ack_en: Whether to wait for ack to be enabled

return value

ESP_OK: success

ESP_ERR_INVALID_ARG : parameter error

  • Write stop signal to cache function: i2c_master_stop();

function prototype

esp_err_t i2c_master_stop

(

i2c_cmd_handle_t cmd_handle

)

function

I2C write stop signal to buffer function

parameter

[in] cmd_handle: The handle of the I2C connection, the return value of the i2c_cmd_link_create() function

return value

ESP_OK: success

ESP_ERR_INVALID_ARG : parameter error

  • I2C send function: i2c_master_cmd_begin();

function prototype

esp_err_t i2c_master_cmd_begin

(

i2c_port_t i2c_num,

i2c_cmd_handle_t cmd_handle,

TickType_t ticks_to_wait

)

function

I2C send function

parameter

[in] i2c_num: I2C number

[in] cmd_handle: The handle of the I2C connection, the return value of the i2c_cmd_link_create() function

[in] ticks_to_wait: wait time

return value

ESP_OK: success

ESP_ERR_INVALID_ARG : parameter error

ESP_FAIL: send error

ESP_ERR_INVALID_STATE: I2C device not initialized

ESP_ERR_TIMEOUT: Timeout

  • Delete I2C connection function: i2c_cmd_link_delete();

function prototype

void i2c_cmd_link_delete

(

i2c_cmd_handle_t cmd_handle

)

function

I2C send start signal function

parameter

[in] cmd_handle: The handle of the I2C connection, the return value of the i2c_cmd_link_create() function

return value

none

The above is the API of the whole process of I2C sending data. The process is as follows

  • The command to read a byte is put into the cache function: i2c_master_read_byte();

function prototype

esp_err_t i2c_master_read_byte

(

i2c_cmd_handle_t cmd_handle,

uint8_t* data,

i2c_ack_type_t ack

)

function

I2C read a byte command into the cache function

parameter

[in] cmd_handle: The handle of the I2C connection, the return value of the i2c_cmd_link_create() function

[in] data: sent data

[in] ack: value of acknowledgment

return value

ESP_OK: success

ESP_ERR_INVALID_ARG : parameter error

The above is the API of the whole process of I2C reading data, the process is as follows

For more detailed interfaces, please refer to the official guide .

 

SHT30 temperature acquisition code writing

Load I2C related header files, define I2C IO mapping pins, define related variables, etc.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

#include <stdio.h>

#include "string.h"

#include "esp_system.h"

#include "esp_spi_flash.h"

#include "esp_wifi.h"

#include "esp_event_loop.h"

#include "esp_log.h"

#include "esp_err.h"

#include "nvs_flash.h"

#include "freertos / FreeRTOS.h"

#include "freertos/task.h"

#include "freertos / FreeRTOS.h"

#include "freertos/task.h"

#include "driver/gpio.h"

#include "driver/i2c.h"

//I2C

#define I2C_SCL_IO 33 //SCL->IO33

#define I2C_SDA_IO 32 //SDA->IO32

#define I2C_MASTER_NUM I2C_NUM_1 //I2C_1

#define WRITE_BIT I2C_MASTER_WRITE //写:0

#define READ_BIT I2C_MASTER_READ //读:1

#define ACK_CHECK_EN 0x1 //The master checks the ACK of the slave

#define ACK_CHECK_DIS 0x0 //The master does not check the ACK of the slave

#define ACK_VAL 0x0 //Acknowledge

#define NACK_VAL 0x1 //No response

// SHT30

#define SHT30_WRITE_ADDR 0x44 //Address

#define CMD_FETCH_DATA_H 0x22 //cycle sampling, refer to sht30 datasheet

#define CMD_FETCH_DATA_L 0x36

  • I2C configuration function

1

2

3

4

5

6

7

8

9

10

11

12

13

14

void i2c_init(void)

{undefined

//i2c configuration structure

    i2c_config_t conf;

    conf.mode = I2C_MODE_MASTER; //I2C mode

    conf.sda_io_num = I2C_SDA_IO; // SDA IO projection

    conf.sda_pullup_en = GPIO_PULLUP_ENABLE; //SDA IO mode

    conf.scl_io_num = I2C_SCL_IO; // SCL IO 映射

    conf.scl_pullup_en = GPIO_PULLUP_ENABLE; //SCL IO mode

    conf.master.clk_speed = 100000; //I2C CLK frequency

    i2c_param_config(I2C_MASTER_NUM, &conf); //Set I2C

    //Register the I2C service even if it is enabled

    i2c_driver_install(I2C_MASTER_NUM, conf.mode,0,0,0);

}

  • SHT30 configuration function

1

2

3

4

5

6

7

8

9

10

11

12

13

14

int sht30_init(void)

{undefined

    int ret;

    //Configure the register of SHT30

    i2c_cmd_handle_t cmd = i2c_cmd_link_create(); //New operation I2C handle

    i2c_master_start(cmd); //Start I2C

    i2c_master_write_byte(cmd, SHT30_WRITE_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN); //send address + write + check ack

    i2c_master_write_byte(cmd, CMD_FETCH_DATA_H, ACK_CHECK_EN); //Send high 8 bits of data + check ack

    i2c_master_write_byte(cmd, CMD_FETCH_DATA_L, ACK_CHECK_EN); //Send the lower 8 bits of data + check ack

    i2c_master_stop(cmd); //Stop I2C

    ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 100 / portTICK_RATE_MS); //I2C send

    i2c_cmd_link_delete(cmd); //Delete the I2C handle

    return ret;

}

 

  • Main functions: I2C initialization, SHT30 initialization, timing reading of temperature and humidity values, printing, etc.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

void app_main()

{undefined

    i2c_init(); //I2C initialization

    sht30_init(); //sht30 initialization

    vTaskDelay(100/portTICK_RATE_MS); //Delay 100ms

    while(1)

    {undefined

        if(sht30_get_value()==ESP_OK) //Get temperature and humidity

        {undefined

            //Algorithm reference sht30 datasheet

            g_temp    =( ( (  (sht30_buf[0]*256) +sht30_buf[1]) *175   )/65535.0  -45  );

            g_rh  =  ( ( (sht30_buf[3]*256) + (sht30_buf[4]) )*100/65535.0) ;

            ESP_LOGI("SHT30", "temp:%4.2f C \r\n", g_temp); // ℃ prints out garbled characters, so use C

            ESP_LOGI("SHT30", "hum:%4.2f %%RH \r\n", g_rh);

 

        }            

        vTaskDelay(2000/portTICK_RATE_MS);

    }

}

hardware connection

The SHT30 module and ESP32 development board can be connected according to the IO mapping table.

Show results

 

Summary of temperature and humidity sensors

  • Espressif has packaged the API of the I2C part very well, so the process is very important. No matter what I2C device is, you must know the process of I2C reading and writing of the device.
  • If the temperature and humidity sensor wants to ensure the accuracy in the product, the sensor must be placed on the edge of the product, the product shell should be drilled, and the sensor should be hollowed out.
  • Source address: https://github.com/xiaolongba/wireless-tech

 

 

Related: Chapter 12 ESP32 reads the temperature and humidity of SHT30 (IIC)