DS18B20 Temperature Sensor
The DS18B20 digital temperature sensor provides temperature measurements with 9-bit to 12-bit precision and features non-volatile user-programmable upper and lower trigger point alarms. The DS18B20 communicates via a single bus, and by definition only requires one data line (and ground) to communicate with a microcontroller. In addition, the DS18B20 can be powered directly from the data line ("parasitic power"). Each DS18B20 has a unique 64-bit serial code, which allows multiple DS18B20s to work on the same bus. Therefore, it is simple to implement with a single microprocessor. Control many DS18B20s distributed over a large area. Applications that can benefit from this feature include HVAC environmental control, temperature monitoring systems inside buildings, equipment, or machinery, as well as process monitoring and control systems.
Module Source
Purchase link: https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-19589090137.12.179936b41D2Vd1&id=610859288168 Materials download link: https://pan.baidu.com/s/1L83uG8So6k1NG_QznraoFQ
Figure 14.1-1 Product physical display
Specifications
Operating voltage: 3-5.5V Operating current: 750nA~1.5mA Measurement resolution: 9-bit to 12-bit programmable resolution Temperature range: -55 ~ +125 ℃ Measurement accuracy: ±0.5 ℃ Communication protocol: Single bus Number of pins: 3 Pin (2.54mm pitch pin header)
Principle Analysis
Timing Description
Initialization:
- Pull the bus low and keep it low for at least 480us.
- Switch to input mode; the bus is pulled high by the pull-up resistor for approximately 15~60us.
- If the initialization is successful, a low level "0" returned by the DS18B20 will be generated, lasting approximately 60~240us.
- The DS18B20 releases the bus, pulling the bus high.
Read Sequence: 5. Pull the data line low for at least 1us. 6. Switch the data line to input mode; the DS18B20 starts acquiring data for approximately 15us. 7. If the DS18B20 wants to send out 0, it pulls the bus low until the end of the read cycle. If it wants to send out 1, it releases the bus to high level. Note: All read slots must be at least 60us, and at least 1us of recovery time is required between two independent slots.
Write Sequence: 8. First set the data line to low level "0", delay 15us. 9. Send data in order from the least significant bit to the most significant bit (only one bit at a time). 10. Delay 60us. 11. Pull the data line high to "1". 12. Repeat steps 1~4 until a complete byte is sent. 13. Pull the data line high to release the bus.
Register Description
0XCC
The master can use this command to simultaneously address all devices on the bus without sending any other address. The DS18B20 performs a synchronized temperature conversion by issuing the 0XCC command followed by the temperature conversion command [44h]. Note that the Read Scratchpad [BEh] command can only follow the Skip ROM command when there is only one slave device on the bus. In this case, time can be saved by allowing the master to read from the slave without sending the device's 64-bit ROM code. If there are multiple slave devices on the bus, the Skip ROM command followed by the Read Scratchpad command will cause data collisions because multiple devices will try to transmit data simultaneously.
0X44 This command starts a single temperature conversion. After conversion, the resulting temperature data is stored in the 2-byte temperature register at address [BEh].
0XBE This command allows the master to read the contents of the temperature register. Data transfer starts from the least significant bit until the 9th byte is read (bit8=CRC). If only temperature data is needed, the master can issue a reset at any time to terminate the read.
Temperature Conversion
The resolution of the temperature sensor can be configured to 9, 10, 11, or 12 bits, corresponding to increments of 0.5°C, 0.25°C, 0.125°C, and 0.0625°C, respectively. The default resolution at power-up is 12 bits. We do not modify it because higher resolution means higher accuracy.
For example, as in the example from the data sheet, if the current temperature is +25.0625℃, the upper 8 bits read from the register are 0000 0001, and the lower 8 bits are 1001 0001. Combine them to get the 16-bit data: 0000 0001 1001 0001. Convert this to decimal to get 401. Multiply the read data by the resolution to obtain the actual temperature.
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_ds18b20.c and bsp_ds18b20.h, and rename the folder to ds18b20.
Write Code
In the file bsp_ds18b20.c, write the following:
#include "bsp_ds18b20.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: bsp_ds18b20_GPIO_Init
* Function Description: MLX90614 pin initialization
* Function Parameters: None
* Function Return: 1=device not detected 0=device detected
* Author: LC
* Notes: None
******************************************************************/
char DS18B20_GPIO_Init(void)
{
unsigned char ret = 255;
gpio_config_t lll_config = {
.pin_bit_mask = (1ULL<<GPIO_DQ), // 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);
ret = DS18B20_Check();//Check if the device exists
return ret;
}
/******************************************************************
* Function Name: DS18B20_Read_Byte
* Function Description: Read one byte from DS18B20
* Function Parameters: None
* Function Return: Byte data read
* Author: LC
* Notes: None
******************************************************************/
uint8_t DS18B20_Read_Byte(void)
{
uint8_t i=0,dat=0;
for (i=0;i<8;i++)
{
DQ_OUT();//Set as input mode
DQ(0); //Pull low
delay_us(2);
DQ(1); //Release the bus
DQ_IN();//Set as input mode
delay_us(12);
dat>>=1;
if( DQ_GET() )
{
dat=dat|0x80;
}
delay_us(50);
}
return dat;
}
/******************************************************************
* Function Name: DS18B20_Write_Byte
* Function Description: Write one byte to DS18B20
* Function Parameters: dat: byte to write
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void DS18B20_Write_Byte(uint8_t dat)
{
uint8_t i;
uint8_t testb;
DQ_OUT();//Set output mode
for (i=0;i<8;i++)
{
if ( (dat&0x01) ) //Write 1
{
DQ(0);
delay_us(2);
DQ(1);
delay_us(60);
}
else //Write 0
{
DQ(0);//Pull low for 60us
delay_us(60);
DQ(1);//Release the bus
delay_us(2);
}
dat=dat>>1;//Transmit next bit
}
}
/******************************************************************
* Function Name: DS18B20_Check
* Function Description: Detect whether DS18B20 exists
* Function Parameters: None
* Function Return: 1: DS18B20 not detected 0: exists
* Author: LC
* Notes: None
******************************************************************/
uint8_t DS18B20_Check(void)
{
uint8_t timeout=0;
//Reset DS18B20
DQ_OUT(); //Set as output mode
DQ(0); //Pull DQ low
delay_us(750); //Pull low for 750us
DQ(1); //Pull DQ high
delay_us(15); //15us
//Set as input mode
DQ_IN();
//Wait for pull low; pulled low indicates an acknowledge
while ( DQ_GET() &&timeout<200)
{
timeout++;//Timeout check
delay_us(1);
};
//Device did not acknowledge
if(timeout>=200)
return 1;
else
timeout=0;
//Wait for 18B20 to release the bus
while ( !DQ_GET() &&timeout<240)
{
timeout++;//Timeout check
delay_us(1);
};
//Bus release failed
if(timeout>=240)
return 1;
return 0;
}
/******************************************************************
* Function Name: DS18B20_Start
* Function Description: DS18B20 starts temperature conversion
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void DS18B20_Start(void)
{
DS18B20_Check(); //Query whether any device acknowledged
DS18B20_Write_Byte(0xcc); //Address all devices on the bus
DS18B20_Write_Byte(0x44); //Start temperature conversion
}
/******************************************************************
* Function Name: DS18B20_GetTemperture
* Function Description: Get temperature value from ds18b20
* Function Parameters: None
* Function Return: Temperature data
* Author: LC
* Notes: None
******************************************************************/
float DS18B20_GetTemperture(void)
{
uint16_t temp;
uint8_t dataL=0,dataH=0;
float value;
DS18B20_Start();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);//Address all devices on the bus
DS18B20_Write_Byte(0xbe);//Read data command
dataL=DS18B20_Read_Byte(); //LSB
dataH=DS18B20_Read_Byte(); //MSB
temp=(dataH<<8)+dataL;//Combine data
if(dataH&0X80)//High bit is 1, indicating negative temperature
{
temp=(~temp)+1;
value=temp*(-0.0625);
}
else
{
value=temp*0.0625;
}
return value;
}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
In the file bsp_ds18b20.h, write the following:
#ifndef _BSP_DS18B20_H_
#define _BSP_DS18B20_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"
//Port porting
#define GPIO_DQ 1
//Set DQ output mode
#define DQ_OUT() gpio_set_direction(GPIO_DQ,GPIO_MODE_OUTPUT)
//Set DQ input mode
#define DQ_IN() gpio_set_direction(GPIO_DQ,GPIO_MODE_INPUT)
//Get DQ pin level change
#define DQ_GET() gpio_get_level(GPIO_DQ)
//DQ output
#define DQ(x) gpio_set_level(GPIO_DQ, x?1:0)
void delay_us(unsigned int us);
void delay_ms(unsigned int ms);
void DS18B20_Reset(void);
uint8_t DS18B20_Check(void);
char DS18B20_GPIO_Init(void);
void DS18B20_Start(void);
float DS18B20_GetTemperture(void);
#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
Porting Verification
In main.c, input 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-02 LCKFB-lp first version
*/
#include <stdio.h>
#include "bsp_ds18b20.h"
void app_main(void)
{
DS18B20_GPIO_Init();
while(1)
{
printf("temperature = %.2f\r\n", DS18B20_GetTemperture() );
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
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.