SHT20 Temperature and Humidity Sensor
The SHT20 digital temperature and humidity sensor, launched by Sensirion (Switzerland), is based on the world-leading CMOSens ® digital sensing technology, featuring extremely high reliability and outstanding long-term stability. With full-range calibration and a two-wire digital interface, it can be connected directly to a microcontroller, greatly shortening development time, simplifying the peripheral circuit, and reducing costs. In addition, its small size, fast response, low power consumption, submersibility, strong anti-interference ability, integrated temperature and humidity measurement, dew point measurement, and high cost-effectiveness make this product suitable for a wide variety of applications.
Module Source
Purchase link: https://item.taobao.com/item.htm?spm=a21n57.1.0.0.700a523chCfvAP&id=615550651141&ns=1&abbucket=0#detail Materials download link: https://pan.baidu.com/s/1HrQkwECvGgQSHvt_RNdLdA
Specifications
Operating voltage: 2.1~3.6V Operating current: 0.1~1000uA Temperature accuracy: ±0.3℃ Temperature range: -40~125℃ Humidity range: 0~100 %RH Humidity accuracy: ±3%RH Output method: IIC Number of pins: 4 Pin
View Materials
After the transmission starts, the first byte sent includes the I2C device address (7bit) and an SDA direction bit (R:1, W:0).
One bit is sent per clock cycle. After the 8th falling edge, the SDA pin is pulled low (ACK bit = 0) to indicate that the sensor data was received correctly. After issuing a measurement command ('1110' '0011' for temperature measurement, '1110' '0101' for relative humidity measurement; this is master mode), the MCU must wait for the measurement to complete.
WARNING
📌 Master mode and non-master mode: ① Master mode: During measurement, the SCL line is blocked (controlled by the sensor). While measuring, the SHT2x pulls SCL low to force the master into a wait state. Releasing the SCL line indicates that the sensor's internal operation is complete and data transmission can continue.
The gray parts are controlled by the sensor. When the sensor returns data to the MCU, the MCU must return an ACK signal for each byte received. After all data has been received, the MCU returns a NACK followed by the stop sequence (P).
Note: The checksum is optional. If not needed, return NACK after data reception is complete.
② Non-master mode: During measurement, the SCL line is open and can be used for other communication tasks on the I2C bus. When the MCU wants to query the sensor status, it first initiates a start signal, then sends the slave address and SDA direction bit (write). If the slave address matches successfully, the sensor sends an ACK signal and starts the measurement. If the sensor has completed the measurement and sends an ACK signal, the MCU can read the relevant data. If the measurement has not completed, the sensor sends a NACK signal, and the MCU must resend the start transmission sequence until the measurement is complete, at which point the MCU reads the data.
Note: The measurement data for both temperature and humidity is two bytes. Regardless of the transmission mode, the maximum measurement resolution is 14 bits. The last two bits of the second byte on SDA are used to indicate relevant status information. Bit1 indicates the measurement type (0 = temperature, 1 = humidity).
The gray area is controlled by the sensor. If the checksum is not needed, after receiving two bytes of data, the MCU directly sends a NACK followed by the stop sequence (P) to end the communication.
The maximum measurement time typically depends on the measurement type and resolution.
When calculating the MCU communication time, the maximum measurement time for temperature is 85ms, while for relative humidity it is 29ms.
The default resolution set inside the sensor is 12 bits for relative humidity and 14 bits for temperature. The SDA output data is converted into a two-byte data packet with the high byte (MSB) first (left-aligned). Each byte is followed by an acknowledge bit. The two status bits, i.e., the last two bits of the LSB, must be set to 0 before performing physical calculations. Calculate humidity: where SRH is the raw humidity data we read.
Calculate temperature: where ST is the raw temperature data we read.
Porting Process
Pin Selection
Port to Project
Our goal is to port the example to the ESP32-S3 dev board. Complete driver code has been provided for you. Follow the steps below to complete the porting. For detailed instructions on creating folders and new .c and .h files, refer to section 1.4.2 in the [DHT11 Temperature and Humidity Sensor] chapter; we will not repeat it here. The only difference is that we replace the file names bsp_dht11.c and bsp_dht11.h with bsp_sht20.c and bsp_sht20.h, and rename the folder to SHT20.
Write Code
In the file bsp_sht20.c, write the following code.
/*
* LCSC-Openkits (LCKFB) software and hardware materials and related expansion board software and hardware materials are all open source on the official website.
* Dev board official website: www.lckfb.com
* Technical support resides on the forum; any technical questions are welcome for exchange and learning at any time.
* LCKFB Forum: club.szlcsc.com
* Follow our Bilibili account: [LCSC-Openkits (LCKFB)] to keep up with our latest updates!
* We do not make money by selling boards; we take cultivating engineers as our mission.
* Change Logs:
* Date Author Notes
* 2024-01-04 LCKFB-lp first version
*/
#include "bsp_sht20.h"
#include "stdio.h"
void delay_ms(unsigned int ms)
{
vTaskDelay(ms / portTICK_PERIOD_MS);
}
void delay_us(unsigned int us)
{
ets_delay_us(us);
}
/******************************************************************
* Function Name: SHT20_GPIO_Init
* Function Description: Initialize IIC pins
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes:
******************************************************************/
void SHT20_GPIO_Init(void)
{
gpio_config_t lll_config = {
.pin_bit_mask = (1ULL<<SHT20_SCL_PIN)|(1ULL<<SHT20_SDA_PIN), // Configure pins
.mode =GPIO_MODE_OUTPUT, // Output mode
.pull_up_en = GPIO_PULLUP_ENABLE, // Enable pull-up
.pull_down_en = GPIO_PULLDOWN_DISABLE, // Disable pull-down
.intr_type = GPIO_INTR_DISABLE // Disable pin interrupt
};
gpio_config(&lll_config);
}
/******************************************************************
* Function Name: IIC_Start
* Function Description: IIC start signal
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void IIC_Start(void)
{
SDA_OUT();
SDA(1);
delay_us(5);
SCL(1);
delay_us(5);
SDA(0);
delay_us(5);
SCL(0);
delay_us(5);
}
/******************************************************************
* Function Name: IIC_Stop
* Function Description: IIC stop signal
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void IIC_Stop(void)
{
SDA_OUT();
SCL(0);
SDA(0);
SCL(1);
delay_us(5);
SDA(1);
delay_us(5);
}
/******************************************************************
* Function Name: IIC_Send_Ack
* Function Description: Master sends acknowledge
* Function Parameters: 0=ACK 1=NACK
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void IIC_Send_Ack(unsigned char ack)
{
SDA_OUT();
SCL(0);
SDA(0);
delay_us(5);
if(!ack) SDA(0);
else SDA(1);
SCL(1);
delay_us(5);
SCL(0);
SDA(1);
}
/******************************************************************
* Function Name: IIC_Wait_Ack
* Function Description: Wait for slave acknowledge
* Function Parameters: None
* Function Return: 1=NACK 0=ACK
* Author: LC
* Notes: None
******************************************************************/
unsigned char IIC_Wait_Ack(void)
{
char ack = 0;
unsigned char ack_flag = 10;
SDA_IN();
SDA(1);
delay_us(5);
SCL(1);
delay_us(5);
while( (GETSDA()==1) && ( ack_flag ) )
{
ack_flag--;
delay_us(5);
}
if( ack_flag <= 0 )
{
IIC_Stop();
return 1;
}
else
{
SCL(0);
SDA_OUT();
}
return ack;
}
/******************************************************************
* Function Name: IIC_Write
* Function Description: IIC write one byte
* Function Parameters: dat=data to write
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void IIC_Write(unsigned char dat)
{
int i = 0;
SDA_OUT();
SCL(0);//Pull clock low to start data transfer
for( i = 0; i < 8; i++ )
{
SDA( (dat & 0x80) >> 7 );
delay_us(2);
dat<<=1;
delay_us(6);
SCL(1);
delay_us(4);
SCL(0);
delay_us(4);
}
}
/******************************************************************
* Function Name: IIC_Read
* Function Description: IIC read one byte
* Function Parameters: None
* Function Return: One byte of data read
* Author: LC
* Notes: None
******************************************************************/
unsigned char IIC_Read(void)
{
unsigned char i,receive=0;
SDA_IN();//Set SDA as input
for(i=0;i<8;i++ )
{
SCL(0);
delay_us(5);
SCL(1);
delay_us(5);
receive<<=1;
if( GETSDA() )
{
receive|=1;
}
delay_us(5);
}
return receive;
}
/******************************************************************
* Function Name: SHT20_Read
* Function Description: Measure temperature and humidity
* Function Parameters: regaddr=register address, regaddr=0xf3 for temperature, 0xf5 for humidity
* Function Return: Returns temperature when regaddr=0xf3, humidity when regaddr=0xf5
* Author: LC
* Notes: None
******************************************************************/
float SHT20_Read(unsigned char regaddr)
{
unsigned char data_H = 0;
unsigned char data_L = 0;
float temp = 0;
IIC_Start();
IIC_Write(0x80|0);
if( IIC_Wait_Ack() == 1 ) printf("error -1\r\n");
IIC_Write(regaddr);
if( IIC_Wait_Ack() == 1 ) printf("error -2\r\n");
do{
delay_us(10);
IIC_Start();
IIC_Write(0x80|1);
}while( IIC_Wait_Ack() == 1 );
delay_us(20);
data_H = IIC_Read();
IIC_Send_Ack(0);
data_L = IIC_Read();
IIC_Send_Ack(1);
IIC_Stop();
if( regaddr == 0xf3 )
{
temp = ((data_H<<8)|data_L) / 65536.0 * 175.72 - 46.85;
}
if( regaddr == 0xf5 )
{
temp = ((data_H<<8)|data_L) / 65536.0 * 125.0 - 6;
}
return temp;
}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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
In the file bsp_sht20.h, write the following code.
/*
* LCSC-Openkits (LCKFB) software and hardware materials and related expansion board software and hardware materials are all open source on the official website.
* Dev board official website: www.lckfb.com
* Technical support resides on the forum; any technical questions are welcome for exchange and learning at any time.
* LCKFB Forum: club.szlcsc.com
* Follow our Bilibili account: [LCSC-Openkits (LCKFB)] to keep up with our latest updates!
* We do not make money by selling boards; we take cultivating engineers as our mission.
* Change Logs:
* Date Author Notes
* 2024-01-04 LCKFB-lp first version
*/
#ifndef _BSP_SHT20_H_
#define _BSP_SHT20_H_
#include "driver/i2c.h"
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "freertos/queue.h"
#include <inttypes.h>
#include "sdkconfig.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "rom/ets_sys.h"
#include "esp_system.h"
#include "driver/gpio.h"
#define SHT20_SCL_PIN 1
#define SHT20_SDA_PIN 2
#define SDA_IN() {gpio_set_direction(SHT20_SDA_PIN, GPIO_MODE_INPUT);} // SDA input mode
#define SDA_OUT() {gpio_set_direction(SHT20_SDA_PIN, GPIO_MODE_OUTPUT);} // SDA output mode
#define SCL(BIT) gpio_set_level( SHT20_SCL_PIN, BIT?1:0 )
#define SDA(BIT) gpio_set_level( SHT20_SDA_PIN, BIT?1:0 )
#define GETSDA() gpio_get_level( SHT20_SDA_PIN )
void delay_us(unsigned int us);
void delay_ms(unsigned int ms);
void SHT20_GPIO_Init(void);
float SHT20_Read(unsigned char regaddr);
#endif2
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Porting Verification
In the main function of your own project, write the following code.
/*
* LCSC-Openkits (LCKFB) software and hardware materials and related expansion board software and hardware materials are all open source on the official website.
* Dev board official website: www.lckfb.com
* Technical support resides on the forum; any technical questions are welcome for exchange and learning at any time.
* LCKFB Forum: club.szlcsc.com
* Follow our Bilibili account: [LCSC-Openkits (LCKFB)] to keep up with our latest updates!
* We do not make money by selling boards; we take cultivating engineers as our mission.
* Change Logs:
* Date Author Notes
* 2024-01-04 LCKFB-lp first version
*/
#include <stdio.h>
#include "bsp_sht20.h"
void app_main(void)
{
SHT20_GPIO_Init();
delay_ms(1000);
printf("demo start\r\n");
while(1)
{
printf("temperature = %.2f ℃\r\n",SHT20_Read(0xf3));
printf("humidity = %.2f %%RH\r\n",SHT20_Read(0xf5));
delay_ms(1000);
}
}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
Power-on effect:
Driver code:
File Download
📌 Materials Download Center (click to jump)
📌 In the Materials Download Center -> Module Porting Materials Download, inside the compressed package of this chapter.