This tutorial shows how to use the DS18B20 temperature sensor with the ESP32 and ESP8266 using MicroPython firmware. You’ll learn how to read temperature from one DS18B20 sensor and multiple sensors at the same time. You’ll also build a web server to display your sensor readings.
You might also like reading other DS18B20 guides:
- ESP32 DS18B20 Temperature Sensor with Arduino IDE
- ESP8266 DS18B20 Temperature Sensor with Arduino IDE
- ESP32 with Multiple DS18B20 Temperature Sensors
- DS18B20 Temperature Sensor with Arduino
Prerequisites
To follow this tutorial you need MicroPython firmware installed in your ESP32 or ESP8266 boards. You also need an IDE to write and upload the code to your board. We suggest using Thonny IDE or uPyCraft IDE:
- Thonny IDE:
- uPyCraft IDE:
- Getting Started with uPyCraft IDE
- Install uPyCraft IDE (Windows, Mac OS X, Linux)
- Flash/Upload MicroPython Firmware to ESP32 and ESP8266
Learn more about MicroPython: MicroPython Programming with ESP32 and ESP8266 eBook
Introducing DS18B20 Temperature Sensor
The DS18B20 temperature sensor is a one-wire digital temperature sensor. This means that it just requires one data line (and GND) to communicate with your ESP32 or ESP8266.
It can be powered by an external power supply or it can derive power from the data line (called “parasite mode”), which eliminates the need for an external power supply.
Each DS18B20 temperature sensor has a unique 64-bit serial code. This allows you to wire multiple sensors to the same data wire. So, you can get temperature from multiple sensors using just one GPIO.
The DS18B20 temperature sensor is also available in waterproof version.
Here’s a summary of the most relevant specs of the DS18B20 temperature sensor:
- Communicates over one-wire bus
- Power supply range: 3.0V to 5.5V
- Operating temperature range: -55ºC to +125ºC
- Accuracy +/-0.5 ºC (between the range -10ºC to 85ºC)
For more information consult the DS18B20 datasheet.
Parts Required
To follow this tutorial you need the following parts:
- ESP32 or ESP8266 (read ESP32 vs ESP8266)
- DS18B20 temperature sensor (one or multiple sensors) – waterproof version
- 4.7k Ohm resistor
- Jumper wires
- Breadboard
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Schematic – ESP32
As mentioned previously, the DS18B20 temperature sensor can be powered through the VDD pin (normal mode), or it can derive its power from the data line (parasite mode). You can chose either modes.
If you’re using an ESP32, follow one of these two schematic diagrams.
Parasite Mode
Normal Mode
Schematic – ESP8266
If you’re using an ESP8266, follow one of these two schematic diagrams.
Parasite mode
Normal mode
Note: in this tutorial we’re connecting the DS18B20 data line to GPIO 4, but you can use any other suitable GPIO.
Code (Single DS18B20)
Copy the following code to the main.py file and upload it to your board. This code simply gets temperature from the DS18B20 temperature sensor and displays the readings on the shell.
# Complete project details at https://RandomNerdTutorials.com
import machine, onewire, ds18x20, time
ds_pin = machine.Pin(4)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
roms = ds_sensor.scan()
print('Found DS devices: ', roms)
while True:
ds_sensor.convert_temp()
time.sleep_ms(750)
for rom in roms:
print(rom)
print(ds_sensor.read_temp(rom))
time.sleep(5)
This code works both with the EPS32 and ESP8266 and works whether you’re using one or multiple DS18B20 temperature sensors.
How the code works
Import the machine module to interact with the GPIOs, the onewire and the ds18x20 modules to interact with the DS18B20 temperature sensor and the time module to add delays.
import machine, onewire, ds18x20, time
Create a variable called ds_pin that refers to GPIO 4, the pin the data wire of the DS18B20 temperature sensor is connected to.
ds_pin = machine.Pin(4)
Here, we’re reading the temperature from GPIO 4, but you can use any other suitable GPIO. You can check the best GPIOs to use on the following articles:
- ESP32 Pinout Reference: Which GPIO pins should you use?
- ESP8266 Pinout Reference: Which GPIO pins should you use?
Then, create a ds18x20 object called ds_sensor on the ds_pin defined earlier. If you want to read the sensor using a different pin, you need to modify the previous line.
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
The DS18B20 communicates via one-wire communication protocol and each sensor has a unique 64-bit serial code. This means you can read several temperature sensors wired on the same GPIO.
The following line uses the scan() function to scan for DS18B20 sensors. The addresses found are saved on the roms variable (the roms variable is of type list).
roms = ds_sensor.scan()
Print the address of each sensor to the shell:
print('Found DS devices: ', roms)
Then, there’s a while loop that gets the temperature from the DS18B20 sensor(s) every 5 seconds.
You need to call the convert_temp() function on the ds_sensor object each time you want to sample temperature.
ds_sensor.convert_temp()
Add a delay of 750 ms to give enough time to convert the temperature:
time.sleep_ms(750)
After that, we can read the temperature on the addresses found earlier by using the read_temp() method and passing the address as argument as shown in the following line of code.
print(ds_sensor.read_temp(rom))
Because you can add multiple sensors to the same data line, we have a for loop that goes through all the addresses and prints the temperature for each of them:
for rom in roms:
print(rom)
print(ds_sensor.read_temp(rom))
Demonstration
After uploading the code to your board, you should get new temperature readings every 5 seconds.
Getting Temperature from Multiple DS18B20 Temperature Sensors
To get temperature from multiple DS18B20 temperature sensors, you can use the same previous script. You just need to wire more DS18B20 sensors. These sensors share the same data line – in this case, all sensors are wired to GPIO 4.
If you’re using an ESP32, you can follow the next schematic diagram.
If you’re using an ESP8266, follow the next schematic diagram instead.
Code (Multiple DS18B20s)
After uploading the code, you should get all temperature readings displayed in the Shell.
# Complete project details at https://RandomNerdTutorials.com
import machine, onewire, ds18x20, time
ds_pin = machine.Pin(4)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
roms = ds_sensor.scan()
print('Found DS devices: ', roms)
while True:
ds_sensor.convert_temp()
time.sleep_ms(750)
for rom in roms:
print(rom)
print(ds_sensor.read_temp(rom))
time.sleep(5)
Display DS18B20 Temperature Readings on Web Server
Now that you know how to get temperature and humidity from DS18B20 sensors, we’ll display the readings on a web server that you can access on your local network.
For this example, you need two files:
- boot.py: runs when the device starts and sets up several configuration options like your network credentials, importing libraries, setting the pins, etc.
- main.py: this is the main script where we’ll handle the web server. It executes immediately after the boot.py.
Note: it is a good practice to include the boot.py and main.py files. However, if you prefer, you can include all the code in the main.py file.
boot.py (DS18B20 web server)
Create a new file in your IDE called boot.py and copy the following code.
# Complete project details at https://RandomNerdTutorials.com
try:
import usocket as socket
except:
import socket
from time import sleep
from machine import Pin
import onewire, ds18x20
import network
import esp
esp.osdebug(None)
import gc
gc.collect()
ds_pin = Pin(4)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect(ssid, password)
while station.isconnected() == False:
pass
print('Connection successful')
print(station.ifconfig())
This file imports the required libraries, sets up the DS18B20 sensor and connects to your network.
Here, we’re setting the DS18B20 data pin on GPIO 4 but you can use any other suitable pin:
ds_pin = Pin(4)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
You should insert your network credentials in the following variables so that the ESP is able to connect to your network.
ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'
main.py (DS18B20 web server)
In the main.py file is where we’ll create the web server and handle the requests. Copy the following code to your main.py file.
# Complete project details at https://RandomNerdTutorials.com
def read_ds_sensor():
roms = ds_sensor.scan()
print('Found DS devices: ', roms)
print('Temperatures: ')
ds_sensor.convert_temp()
for rom in roms:
temp = ds_sensor.read_temp(rom)
if isinstance(temp, float):
msg = round(temp, 2)
print(temp, end=' ')
print('Valid temperature')
return msg
return b'0.0'
def web_page():
temp = read_ds_sensor()
html = """<!DOCTYPE HTML><html><head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<style> html { font-family: Arial; display: inline-block; margin: 0px auto; text-align: center; }
h2 { font-size: 3.0rem; } p { font-size: 3.0rem; } .units { font-size: 1.2rem; }
.ds-labels{ font-size: 1.5rem; vertical-align:middle; padding-bottom: 15px; }
</style></head><body><h2>ESP with DS18B20</h2>
<p><i class="fas fa-thermometer-half" style="color:#059e8a;"></i>
<span class="ds-labels">Temperature</span>
<span id="temperature">""" + str(temp) + """</span>
<sup class="units">°C</sup>
</p>
<p><i class="fas fa-thermometer-half" style="color:#059e8a;"></i>
<span class="ds-labels">Temperature</span>
<span id="temperature">""" + str(round(temp * (9/5) + 32.0, 2)) + """</span>
<sup class="units">°F</sup>
</p></body></html>"""
return html
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
while True:
try:
if gc.mem_free() < 102000:
gc.collect()
conn, addr = s.accept()
conn.settimeout(3.0)
print('Got a connection from %s' % str(addr))
request = conn.recv(1024)
conn.settimeout(None)
request = str(request)
print('Content = %s' % request)
response = web_page()
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.sendall(response)
conn.close()
except OSError as e:
conn.close()
print('Connection closed')
Reading the DS18B20 Sensor
The code starts by creating a function called read_ds_sensor() that gets the temperature from the DS18B20 temperature sensor. If you’ve followed the previous section, you should be familiar with the methods used here.
def read_ds_sensor():
roms = ds_sensor.scan()
print('Found DS devices: ', roms)
ds_sensor.convert_temp()
for rom in roms:
temp = ds_sensor.read_temp(rom)
if isinstance(temp, float):
temp = round(temp, 2)
print('Valid temperature')
return temp
return '0'
Web Page
The web_page() function returns the HTML page with the latest temperature readings.
We’ve built a similar web page on a previous tutorial. So, if you want to learn how this HTML works, you can read this article: MicroPython: ESP32/ESP8266 with DHT11/DHT22 Web Server.
Creating the web server
After that, make the usual procedures to create a socket server.
while True:
try:
if gc.mem_free() < 102000:
gc.collect()
conn, addr = s.accept()
conn.settimeout(3.0)
print('Got a connection from %s' % str(addr))
request = conn.recv(1024)
conn.settimeout(None)
request = str(request)
print('Content = %s' % request)
response = web_page()
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.sendall(response)
conn.close()
except OSError as e:
conn.close()
print('Connection closed')
For an in-depth explanation of this procedure, refer to this tutorial.
Basically, when the ESP receives a request, we send the web page with the latest readings as a response:
response = web_page()
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.sendall(response)
Web Server Demonstration
After uploading the boot.py and main.py files to your board. Click the ESP RST button to run the code.
Then, open your browser and type the ESP IP address. You should access the web page with the latest sensor readings in Celsius and Fahrenheit degrees:
Wrapping Up
We hope you’ve found this MicroPython guide about the DS18B20 temperature sensor with the ESP32 and ESP8266 useful. We have other projects with the ESP and MicroPython that you may like:
- MicroPython: BME280 with ESP32 and ESP8266 (Pressure, Temperature, Humidity)
MicroPython: ESP32/ESP8266 with DHT11/DHT22 Web Server - MicroPython: Getting Started with MQTT on ESP32/ESP8266
- Low Power Weather Station Datalogger using ESP8266 and BME280 with MicroPython
- MicroPython: OLED Display with ESP32 and ESP8266
Learn more about MicroPython with ESP32 and ESP8266 with our eBook: MicroPython Programming with ESP32 and ESP8266
Thanks for reading.
A circuit diagram would be useful also, as your schematic is a component diagram.
Dear Friend,
when I write the code in esp32 then everything worked perfectly. But when I use the same code in esp8266 node mcu then i got no data. it shows “Found DS devices: []”.
No data in the list.
Hi. Thank you very much for your tutorials, they are amazing!
Your circuit and code works very well for me with three sensors but when I add a fourth sensor, the scan returns “Found DS devices: [ ]”
I have tried removing the first sensor and the system works fine againt, so this means that it is not a failure of the fourth sensor.
Does the library have any limitations regarding the number of sensors?
I’m using ds18b20 waterproof (5 meters) and ESP32 Lolin32
Hi.
It doesn’t have a limit for the number of sensors.
However, as you add more sensors, the ESP32 might not be able to supply enough power to all sensors on the same GPIO.
Regards,
Sara
How can I use more than onewire instance as I want each sensor on individual pins. The reason is if one sensor fails or is replaced then the address will be different and could mean the sensor readings my no longer match the sensors physical location.
Hi.
Yes. I think that is possible. You just need to creare multiple onewire instances with different names.
Regards,
Sara
Hi.
If i want 14 ds18b20 on 14 pins, is that possible?
The reason is, that the controller is not accessible, and this would simplify changing sensors, when they brake.
Hi.
I’m new in this topic. Can you help me?
Is it possible to connect this temperature sensor to device like this
aliexpress.com/item/32883116057.html?spm=a2g0o.order_list.0.0.26cf1802DLIjbV
LOLIN D32 Pro V2.0.0 – wifi & bluetooth board based ESP-32 esp32 Rev1 ESP32-WROVER 16MB 8MB 4MB FLASH PSRAM MicroPython
I can’t find any GPIO connector on this board 🙁
Hi.
Yes, you can use that board.
You need to solder the stack of pins that come with the board.
Then, you can use the GPIOs as in any regular board.
Regards,
Sara