This is a in-depth guide for the DS18B20 temperature sensor with ESP32 using Arduino IDE. We’ll show you how to wire the sensor, install the required libraries, and write the code to get the sensor readings from one and multiple sensors. Finally, we’ll build a simple web server to display the sensor readings.
You might also like reading other DS18B20 guides:
- ESP8266 DS18B20 Temperature Sensor with Arduino IDE
- ESP32/ESP8266 DS18B20 Temperature Sensor with MicroPython
- ESP32 with Multiple DS18B20 Temperature Sensors
- DS18B20 Temperature Sensor with Arduino
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.
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 communication
- 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 (read Best ESP32 development boards)
- 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 folllow one of these two schematic diagrams.
Parasite Mode
Normal Mode
Preparing Your Arduino IDE
Weâll program the ESP32 using Arduino IDE, so make sure you have the ESP32 add-on installed before proceeding:
Installing Libraries
To interface with the DS18B20 temperature sensor, you need to install the One Wire library by Paul Stoffregen and the Dallas Temperature library. Follow the next steps to install those libraries.
1. Open your Arduino IDE and go to Sketch > Include Library > Manage Libraries. The Library Manager should open.
2. Type âonewireâ in the search box and install OneWire library by Paul Stoffregen.
3. Then, search for “Dallas” and install DallasTemperature library by Miles Burton.
After installing the libraries, restart your Arduino IDE.
Code (Single DS18B20)
After installing the required libraries, you can upload the code to the ESP32. The following code reads temperature from the DS18B20 temperature sensor and displays the readings on the Arduino IDE Serial Monitor.
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com
*********/
#include <OneWire.h>
#include <DallasTemperature.h>
// GPIO where the DS18B20 is connected to
const int oneWireBus = 4;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
void setup() {
// Start the Serial Monitor
Serial.begin(115200);
// Start the DS18B20 sensor
sensors.begin();
}
void loop() {
sensors.requestTemperatures();
float temperatureC = sensors.getTempCByIndex(0);
float temperatureF = sensors.getTempFByIndex(0);
Serial.print(temperatureC);
Serial.println("ÂșC");
Serial.print(temperatureF);
Serial.println("ÂșF");
delay(5000);
}
There are many different ways to get the temperature from DS18B20 temperature sensors. However, if you’re using just one single sensor, this is one of the easiest and simplest ways.
How the Code Works
Start by including the OneWire and the DallasTemperature libraries.
#include <OneWire.h>
#include <DallasTemperature.h>
Create the instances needed for the temperature sensor. The temperature sensor is connected to GPIO 4.
// GPIO where the DS18B20 is connected to
const int oneWireBus = 4;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
In the setup(), initialize the Serial Monitor at a baud rate of 115200.
Serial.begin(115200);
Initialize the DS18B20 temperature sensor:
sensors.begin();
Before actually getting the temperature, you need to call the requestTemperatures() method.
sensors.requestTemperatures();
Then, get the temperature in Celsius by using the getTempCByIndex() method as shown below:
float temperatureC = sensors.getTempCByIndex(0);
Or use the getTempFByIndex() to get the temperature in Fahrenheit.
float temperatureF = sensors.getTempFByIndex(0);
The getTempCByIndex() and the getTempFByIndex() methods accept the index of the temperature sensor. Because we’re using just one sensor its index is 0. If you want to read more than one sensor, you use index 0 for one sensor, index 1 for other sensor and so on.
Finally, print the results in the Serial Monitor.
Serial.print(temperatureC);
Serial.println("ÂșC");
Serial.print(temperatureF);
Serial.println("ÂșF");
New temperature readings are requested every 5 seconds.
delay(5000);
Demonstration
After uploading the code, you should get your sensor readings displayed in the Serial Monitor:
Getting Temperature from Multiple DS18B20 Temperature Sensors
The DS18B20 temperature sensor communicates using one-wire protocol and each sensor has a unique 64-bit serial code, so you can read the temperature from multiple sensors using just one single GPIO. You just need to wire all data lines together as shown in the following schematic diagram:
Code (Multiple DS18B20s)
Then, upload the following code. It scans for all devices on GPIO 4 and prints the temperature for each one. (This sketch is based on an example provided by the DallasTemperature library).
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com
*********/
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged TO GPIO 4
#define ONE_WIRE_BUS 4
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// Number of temperature devices found
int numberOfDevices;
// We'll use this variable to store a found device address
DeviceAddress tempDeviceAddress;
void setup(){
// start serial port
Serial.begin(115200);
// Start up the library
sensors.begin();
// Grab a count of devices on the wire
numberOfDevices = sensors.getDeviceCount();
// locate devices on the bus
Serial.print("Locating devices...");
Serial.print("Found ");
Serial.print(numberOfDevices, DEC);
Serial.println(" devices.");
// Loop through each device, print out address
for(int i=0;i<numberOfDevices; i++){
// Search the wire for address
if(sensors.getAddress(tempDeviceAddress, i)){
Serial.print("Found device ");
Serial.print(i, DEC);
Serial.print(" with address: ");
printAddress(tempDeviceAddress);
Serial.println();
} else {
Serial.print("Found ghost device at ");
Serial.print(i, DEC);
Serial.print(" but could not detect address. Check power and cabling");
}
}
}
void loop(){
sensors.requestTemperatures(); // Send the command to get temperatures
// Loop through each device, print out temperature data
for(int i=0;i<numberOfDevices; i++){
// Search the wire for address
if(sensors.getAddress(tempDeviceAddress, i)){
// Output the device ID
Serial.print("Temperature for device: ");
Serial.println(i,DEC);
// Print the data
float tempC = sensors.getTempC(tempDeviceAddress);
Serial.print("Temp C: ");
Serial.print(tempC);
Serial.print(" Temp F: ");
Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
}
}
delay(5000);
}
// function to print a device address
void printAddress(DeviceAddress deviceAddress) {
for (uint8_t i = 0; i < 8; i++){
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}
Demonstration
In this example, we’re using three DS18B20 temperature sensors. This is what we get on the Arduino IDE Serial Monitor.
We have a dedicated article on how to interface multiple DS18B20 temperature sensors with the EPS32. Just follow the next tutorial:
Display DS18B20 Temperature Readings in a Web Server
To build the web server weâll use the ESPAsyncWebServer library that provides an easy way to build an asynchronous web server. Building an asynchronous web server has several advantages. We recommend taking a quick look at the library documentation on its GitHub page.
Installing the ESPAsyncWebServer and AsyncTCP libraries
You need to install the following libraries in your Arduino IDE to build the web server for this project.
- ESPAsyncWebServer (.zip folder)
- AsyncTCPÂ (.zip folder)
The ESPAsyncWebServer, AsynTCP, and ESPAsyncTCP libraries arenât available to install through the Arduino Library Manager, so you need to copy the library files to the Arduino installation Libraries folder. Alternatively, in your Arduino IDE, you can go to Sketch > Include Library > Add .zip Library and select the libraries youâve just downloaded.
Code (DS18B20 Async Web Server)
Open your Arduino IDE and copy the following code.
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com
*********/
// Import required libraries
#ifdef ESP32
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#else
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Hash.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#endif
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is connected to GPIO 4
#define ONE_WIRE_BUS 4
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
// Variables to store temperature values
String temperatureF = "";
String temperatureC = "";
// Timer variables
unsigned long lastTime = 0;
unsigned long timerDelay = 30000;
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
String readDSTemperatureC() {
// Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus
sensors.requestTemperatures();
float tempC = sensors.getTempCByIndex(0);
if(tempC == -127.00) {
Serial.println("Failed to read from DS18B20 sensor");
return "--";
} else {
Serial.print("Temperature Celsius: ");
Serial.println(tempC);
}
return String(tempC);
}
String readDSTemperatureF() {
// Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus
sensors.requestTemperatures();
float tempF = sensors.getTempFByIndex(0);
if(int(tempF) == -196){
Serial.println("Failed to read from DS18B20 sensor");
return "--";
} else {
Serial.print("Temperature Fahrenheit: ");
Serial.println(tempF);
}
return String(tempF);
}
const char index_html[] PROGMEM = R"rawliteral(
<!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 DS18B20 Server</h2>
<p>
<i class="fas fa-thermometer-half" style="color:#059e8a;"></i>
<span class="ds-labels">Temperature Celsius</span>
<span id="temperaturec">%TEMPERATUREC%</span>
<sup class="units">°C</sup>
</p>
<p>
<i class="fas fa-thermometer-half" style="color:#059e8a;"></i>
<span class="ds-labels">Temperature Fahrenheit</span>
<span id="temperaturef">%TEMPERATUREF%</span>
<sup class="units">°F</sup>
</p>
</body>
<script>
setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("temperaturec").innerHTML = this.responseText;
}
};
xhttp.open("GET", "/temperaturec", true);
xhttp.send();
}, 10000) ;
setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("temperaturef").innerHTML = this.responseText;
}
};
xhttp.open("GET", "/temperaturef", true);
xhttp.send();
}, 10000) ;
</script>
</html>)rawliteral";
// Replaces placeholder with DS18B20 values
String processor(const String& var){
//Serial.println(var);
if(var == "TEMPERATUREC"){
return temperatureC;
}
else if(var == "TEMPERATUREF"){
return temperatureF;
}
return String();
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
Serial.println();
// Start up the DS18B20 library
sensors.begin();
temperatureC = readDSTemperatureC();
temperatureF = readDSTemperatureF();
// Connect to Wi-Fi
WiFi.begin(ssid, password);
Serial.println("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
server.on("/temperaturec", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", temperatureC.c_str());
});
server.on("/temperaturef", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", temperatureF.c_str());
});
// Start server
server.begin();
}
void loop(){
if ((millis() - lastTime) > timerDelay) {
temperatureC = readDSTemperatureC();
temperatureF = readDSTemperatureF();
lastTime = millis();
}
}
Insert your network credentials in the following variables and the code will work straight away.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
How the Code Works
In the following paragraphs weâll explain how the code works. Keep reading if you want to learn more or jump to the “Demonstration” section to see the final result.
Importing libraries
First, import the required libraries for the ESP32 board:
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <OneWire.h>
#include <DallasTemperature.h>
Instantiate DS18B20 Sensor
Define the GPIO that the DS18B20 data pin is connected to. In this case, itâs connected to GPIO 4.
#define ONE_WIRE_BUS 4
Instantiate the instances needed to initialize the sensor:
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
Setting your network credentials
Insert your network credentials in the following variables, so that the ESP8266 can connect to your local network.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Create an AsyncWebServer object on port 80.
AsyncWebServer server(80);
Read Temperature Functions
Then, we create two functions to read the temperature.
The readDSTemperatureC() function returns the readings in Celsius degrees.
String readDSTemperatureC() {
// Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus
sensors.requestTemperatures();
float tempC = sensors.getTempCByIndex(0);
if(tempC == -127.00){
Serial.println("Failed to read from DS18B20 sensor");
return "--";
} else {
Serial.print("Temperature Celsius: ");
Serial.println(tempC);
}
return String(tempC);
}
In case the sensor is not able to get a valid reading, it returns -127. So, we have an if statement that returns two dashes (â-) in case the sensor fails to get the readings.
if(tempC == -127.00){
Serial.println("Failed to read from DS18B20 sensor");
return "--";
The reaDSTemperatureF() function works in a similar way but returns the readings in Fahrenheit degrees.
The readings are returned as string type. To convert a float to a string, use the String() function.
return String(tempC);
Building the Web Page
The next step is building the web page. The HTML and CSS needed to build the web page are saved on the index_html variable.
In the HTML text we have TEMPERATUREC and TEMPERATUREF between % signs. This is a placeholder for the temperature values.
This means that this %TEMPERATUREC% text is like a variable that will be replaced by the actual temperature value from the sensor. The placeholders on the HTML text should go between % signs.
We’ve explained in great detail how the HTML and CSS used in this web server works in a previous tutorial. So, if you want to learn more, refer to the next project:
Processor
Now, we need to create the processor() function, that will replace the placeholders in our HTML text with the actual temperature values.
String processor(const String& var){
//Serial.println(var);
if(var == "TEMPERATUREC"){
return readDSTemperatureC();
}
else if(var == "TEMPERATUREF"){
return readDSTemperatureF();
}
return String();
}
When the web page is requested, we check if the HTML has any placeholders. If it finds the %TEMPERATUREC% placeholder, we return the temperature in Celsius by calling the readDSTemperatureC() function created previously.
if(var == "TEMPERATUREC"){
return readDSTemperatureC();
}
If the placeholder is %TEMPERATUREF%, we return the temperature in Fahrenheit.
else if(var == "TEMPERATUREF"){
return readDSTemperatureF();
}
setup()
In the setup(), initialize the Serial Monitor for debugging purposes.
Serial.begin(115200);
Initialize the DS18B20 temperature sensor.
sensors.begin();
Connect to your local network and print the ESP32 IP address.
WiFi.begin(ssid, password);
Serial.println("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
// Print ESP8266 Local IP Address
Serial.println(WiFi.localIP());
Finally, add the next lines of code to handle the web server.
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
server.on("/temperaturec", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", readDSTemperatureC().c_str());
});
server.on("/temperaturef", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", readDSTemperatureF().c_str());
});
When we make a request on the root URL, we send the HTML text that is stored in the index_html variable. We also need to pass the processor function, that will replace all the placeholders with the right values.
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
We need to add two additional handlers to update the temperature readings. When we receive a request on the /temperaturec URL, we simply need to send the updated temperature value. It is plain text, and it should be sent as a char, so, we use the c_str() method.
server.on("/temperaturec", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", readDSTemperatureC().c_str());
});
The same process is repeated for the temperature in Fahrenheit.
server.on("/temperaturef", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", readDSTemperatureF().c_str());
});
Lastly, we can start the server.
server.begin();
Because this is an asynchronous web server, we donât need to write anything in the loop().
void loop(){
}
Thatâs pretty much how the code works.
Demonstration
After uploading the code, open the Arduino IDE Serial Monitor at a baud rate of 115200. Press the ESP32 on-board RST button and after a few seconds your IP address should show up.
In your local network, open a browser and type the ESP32 IP address.
Now you can see temperature in Celsius and Fahrenheit in your web server. The sensor readings update automatically without the need to refresh the web page.
Wrapping Up
We hope you’ve found this tutorial useful. We have guides for other sensors and modules with the ESP32 that you may like:
- ESP32 with BME280 (Pressure, Temperature and Humidity)
- ESP32 Built-In Hall Effect Sensor
- ESP32 OLED Display with Arduino IDE
- ESP32 DHT Temperature and Humidity Sensor with Arduino IDE
If you want to learn more about the ESP32 take a look at our course, or check or ESP32 free resources:
Thanks for reading.
Make sense!
The above code works really well on my Heltec Lora ESP32 board at 240MHz, but the onewire library breaks down if you reduce the speed of the processor to save energy or for compatibility with other interfaces. Current thinking seems to be this is because the onewire interface is bitbashed and processor interrupts smooth operation.
I’ve used the one sensor example and it works fine.
When I add a second sensor as depicted and run the multiple sensor code it can’t find any sensors (“Location devices…Found 0devices”).
Any Idea what might be happening?
Hi Peter.
I don’t know what can be the problem.
Please double-check your wiring and that each sensor works fine individually before hooking up the two sensors at the same time.
Regards,
Sara
Sara;
Got both sensors working with one of the Dallas examples but they still refuse to work with the multiple sensor code above???
I’ll do some more analysis tomorrow to try to determine what may be happening.
Sara;
I’ve checked the sensor waveform with an oscilloscope and data looks good (clean transitions between 3.3 and 0 V).
I’ve noticed that the Dallas example also returns 0 devices found using the “sensors.getDeviceCount()” command but the example then does an address assignment by index and finds both devices and then continues by reading the temperatures.
In the multiple sensor code above it looks like the code extracts the address for each device found in a loop but since no devices are found….
Seems like either the DS18B20 sensors I have are defective (in not correctly responding to the .getdevicecount command or the library has an issue with the same command.
Anyway I’m moving forward as I can now read the sensor temperatures.
I had the same experience and I can say for sure the sensors work fine as I used them together with an Arduino Nano just before.
The lib apparently has an issue.
Peter, this is a comon problem.
try
sensors.begin();
delay (10);
sensors.begin();
well good explanation
i just uploaded the code and using DHT11 temprature sensor it gives error A fatal error occurred: Failed to connect to ESP32: Invalid head of packet (0x46)
how to remove the error
Hi.
Can you follow this and see if it solves your problem? https://rntlab.com/question/failed-to-connect-to-esp32-invalid-head-of-packet-0x2e/
Regards,
Sara
Great tutorial, thanks for sharing. I incorporated for demo purposes most of your code into a larger RTOS-based project and it works well. Running on a nodeMCU ESP32-S on my local LAN wifi.
Great đ
Hi Sara,
I build that and i had for one DS180B20, the temperature -127C
Hi.
That usually means that there’s some issue with the wiring or power.
Regards,
Sara
Hi, i double check the wire (polarity PSU) and it is ok. I am using 5V (~4.6V).
Are you using the same GPIO we use in this project?
Hi Sara,
I am using NodeMCU-32, I changed to GPIO4 and still not working.
I was using GPIO34 before.
Thanks for the hint about the wiring. In my case, it was indeed a wiring error. Same symptom (T=-127C) and sure enough, after I corrected a wiring error it was fixed. Thanks.
Is 4.7kOhm resistor is required for DS18B20 temperature sensor waterproof version too?
For reliable operation, yes, use the 4.7k resistor on the waterproof sensor also. I do.
I could not get it to run properly (kept getting -127) until I added the resistor.
Hello, i’d like to know if its possible and how to add a chart/graph of how the temperatures increases/decreases in real time.
Hi.
Take a look at this tutorial: https://randomnerdtutorials.com/esp32-esp8266-plot-chart-web-server/
Regards,
Sara
Hello, I would like to know wath can be the maximum cable length by 3,3v supply from the esp32, and secondly if the use of 5v supply on the sensor would be an issue for the esp32 input (witch is a 3,3v per datasheet). Thank you
Dear Paul,
I have use 12 meters cable with 3.3V without any difference using 1m cable (sensors in same area gives same measurements +- sensor error).
I have use UTP cat6 cable, using 3 non twisted wires. Orange, green , blue.
Thank you for your reply Elias. My sensors are ordered, I will try it soon.
Hello!
Great tutorials for a learner!
I used your ESP32 tutorial and the serial output (https://randomnerdtutorials.com/esp32-multiple-ds18b20-temperature-sensors/) which worked great! My five sensors are reporting back IDs and I can see the measurements!
However, it seems that the webserver code above does only show one temperature value although in the code, the ReadTemperature issue a global temperature and Requests to all devices on the bus.
I am guessing that “float tempC = sensors.getTempCByIndex(0);” is causing this, I’m imagining I could but a while loop around this, however the imprints into the html is not in a while loop either.
Thanks for your advice!
Hi.
You would need to create multiple variables to get the temperature from the multiple sensors.
Then, modify the HTML to display multiple sensor readings.
Regards,
Sara
Hi Sara,
it has been more than 20 years that I looked into programming code, but indeed, I worked now with static variables and all my five sensors are now dumping their load into html.
As I’m already made the same project on a Raspberry pi (which had limitations in to quickly reading too many sensors at once, I’m curious to know whether the ESP32 suffers from the same symptoms.
Thank you and have a nice day!
Firstly a big thank you for these random nerd tutorials, my ‘smart pool’ project has temperature sensors, async web interface and email reporting based originally on your excellent examples. However a comment and a question:
The DS18B20 is terribly slow at converting temperatures (up to about 700mS) however you don’t have to wait for this process. If you call sensors.setWaitForConversion(false) at startup, you can do lots of useful other stuff between your sensors.requestTemperatures() and sensors.getTempC(tempDeviceAddress) you just need to make sure there is an adequate time delay (say 1S).
One of my DS18B20s sits on the roof and we had a bad electrical storm a couple of days ago. The webserver kept working, my email reports failed as did some temperature sensors. I rebooted, then all the temperature sensors failed – but the email reports came a back. I assumed the ESP was partially fried, but when I did a full power cycle and software upload,everything came back as usual – MIRACLE! All very strange, but this does raise the question: what is best practice when connecting to an external DS18B20s? This seems a good place to start https://www.eevblog.com/forum/beginners/protecting-pic-inputs-connected-to-ds18b20/msg182951/?PHPSESSID=j8beh30uf8qsfraitsui45n6t6#msg182951 Further comment appreciated.
Hi
I used two senors and when i uploaded the webserver codes i had readings from only one sensor displayed on the webserver.
Any information on how to get readings from both sensors ?
Thanks
Hi!
This code is to show only the first sensor reading in both °C and °F (see this line: float tempC = sensors.getTempCByIndex(0);)
So either loop through your sensors, or work with the “mac” addresses and launch those in the visualisation.
Good luck!
Solved !!!! By reading all comments and doing some minors modifications….
This is my code, with Wemos D1 mini (just Celsius) :
“// Import required libraries
#ifdef ESP32
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#define ONE_WIRE_BUS 15 // ESP32
#else
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Hash.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#define ONE_WIRE_BUS 4 // D2
#endif
#include <OneWire.h>
#include <DallasTemperature.h>
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
// Replace with your network credentials
const char* ssid = “Andy_2.4G”;
const char* password = “andy1603”;
String StrTempC;
String StrTempF;
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
String readDSTemperatureC() {
// Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus
sensors.requestTemperatures();
float tempC = sensors.getTempCByIndex(0);
if(tempC == -127.00) {
Serial.println(“Failed to read from DS18B20 sensor”);
return “–“;
} else {
Serial.print(“Temperature Celsius: “);
Serial.println(tempC);
}
return String(tempC);
}
String readDSTemperatureF() {
// Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus
sensors.requestTemperatures();
float tempF = sensors.getTempFByIndex(0);
if(int(tempF) == -196){
Serial.println(“Failed to read from DS18B20 sensor”);
return “–“;
} else {
Serial.print(“Temperature Fahrenheit: “);
Serial.println(tempF);
}
return String(tempF);
}
const char index_html[] PROGMEM = R”rawliteral(
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;
}
ESP DS18B20 Server
Temperature Celsius
%TEMPERATUREC%
°C
setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById(“temperaturec”).innerHTML = this.responseText;
}
};
xhttp.open(“GET”, “/temperaturec”, true);
xhttp.send();
}, 1000) ;
setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById(“temperaturef”).innerHTML = this.responseText;
}
};
xhttp.open(“GET”, “/temperaturef”, true);
xhttp.send();
}, 1000) ;
)rawliteral”;
// Replaces placeholder with DHT values
String processor(const String& var){
//Serial.println(var);
if(var == “TEMPERATUREC”){
//return String(sensors.getTempCByIndex(0));
return StrTempC;
}
else if(var == “TEMPERATUREF”){
//return String(sensors.getTempFByIndex(0));
return StrTempF;
}
return String();
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
Serial.println();
// Start up the DS18B20 library
sensors.begin();
// Connect to Wi-Fi
WiFi.begin(ssid, password);
Serial.println(“Connecting to WiFi”);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
}
Serial.println();
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
server.on(“/”, HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, “text/html”, index_html, processor);
});
server.on(“/temperaturec”, HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, “text/plain”, String(StrTempC).c_str());
});
// Start server
server.begin();
}
void loop(){
StrTempC = readDSTemperatureC();
Serial.print(StrTempC);
Serial.print(” “);
StrTempF = readDSTemperatureF();
Serial.println(StrTempF);
}”
THANKS FOR GREAT INFO !!!
Hi! thanks for the tutorial, it proved very helpful.
I have this application where I have two sensors, one for air temperature and one for water temperature. water temperature probe is used to switch a heater on or off with a PID of some kind.
If one of the sensors dies, I really don’t want the other sensor’s data to be falsely used ; and since I cannot predict which sensor will have the lowest ID, I recon it’s better to hardcode the device ID (I’d rather have to reprogram my ESP than suffer heavy burns).
So I tried something like
tempC = sensors.getTempC(0x28F7E9F60C000003);
but this gives me
invalid conversion from ‘long long int’ to ‘const uint8_t* {aka const unsigned char*}’
any help?
Hi.
See this tutorial to learn how to get temperature from a specific id: https://randomnerdtutorials.com/esp32-multiple-ds18b20-temperature-sensors/
I hope this helps.
Regards,
Sara
totally does! thanks!
Another great tutorial. I was getting the -127 error too, until I realized that I
hadn’t wired the pull up resistor into the circuit.
Single DS18B20
Obtain ” Error Compiling for ESP32 Dev Module.”
Lists various errors in OneWire.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
In file included from C:\Users\Paul Keenan\Documents\Arduino\libraries\OneWire\OneWire.cpp:144:
C:\Users\Paul Keenan\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h: In function ‘void directModeInput(uint32_t)’:
C:\Users\Paul Keenan\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h:161:26: error: ‘rtc_gpio_desc’ was not declared in this scope
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
^~~~~~~~~~~~~
C:\Users\Paul Keenan\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h:161:26: note: suggested alternative: ‘rtc_io_desc’
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
^~~~~~~~~~~~~
rtc_io_desc
C:\Users\Paul Keenan\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h: In function ‘void directModeOutput(uint32_t)’:
C:\Users\Paul Keenan\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h:189:26: error: ‘rtc_gpio_desc’ was not declared in this scope
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
^~~~~~~~~~~~~
C:\Users\Paul Keenan\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h:189:26: note: suggested alternative: ‘rtc_io_desc’
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
^~~~~~~~~~~~~
rtc_io_desc
exit status 1
Error compiling for board ESP32 Dev Module.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
OneWire v2.3.5 DallasTemperature v3.9.0
Used similar code that worked in summer but get now get same compile error.
Any fix ?
Hi.
It seems to be a problem with the library.
See this discussion: https://githubmemory.com/repo/PaulStoffregen/OneWire/issues/100
Regards,
Sara
Discussion involves problem with esp32 v 2.0.0
Using esp32 1.0.6 which is supposed to be ok.
However decided to replace all instances of rtc_gpio_desc with rtc_io_desc in file OneWire _direct_gpio.h & compile failed but with different errors…
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
In file included from C:\Users\Paul Keenan\Documents\Arduino\libraries\OneWire\OneWire.cpp:144:0:
C:\Users\Paul Keenan\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h: In function ‘void directModeInput(uint32_t)’:
C:\Users\Paul Keenan\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h:161:26: error: ‘rtc_gpio_desc’ was not declared in this scope
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
^
C:\Users\Paul Keenan\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h: In function ‘void directModeOutput(uint32_t)’:
C:\Users\Paul Keenan\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h:189:26: error: ‘rtc_gpio_desc’ was not declared in this scope
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
^
At global scope:
cc1plus.exe: warning: unrecognized command line option ‘-Wno-frame-address’
exit status 1
Error compiling for board ESP32 Dev Module.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Any furthet ideas
Please ignore past messages. Can no longer compile any programs, going to reload Arduino.
Reload of Arduino Worked ! Now compiling.
Thanks for your Help.
Great tutorial!
What if I want to run a server without connecting to my local network? Have the ESP32 ran as a webserver and access point at the same time.
Hi.
You can set the ESP32 as a station, access point or both.
Check the following resources:
– https://randomnerdtutorials.com/esp32-access-point-ap-web-server/
– https://randomnerdtutorials.com/esp32-useful-wi-fi-functions-arduino/
Regards,
Sara
Hello,
great tutorial, thank you!
But it would be nice to have a hint how to modify the HTML to display two sensor readings. I’ve seen your tutorial with multiple sensors and found out the adresses of both sensors. Now I can see the temperatures in the serial monitor but I don’t know how to display them in my webserver depending on the code above. Where do i have to place my adresses and do I need another placeholder for each sensor?
Sara,
You ask us to “Rename your folder from AsyncTCP-master to AsyncTCP” but the code uses the name #include <ESPAsyncTCP.h>
There’s no ESPAsyncTCP.h in the src folder.
What should I use?
Hi.
I updated the tutorial with easier to follow instructions to install the library:
Click the links to download the libraries’ files:
ESPAsyncWebServer (.zip folder): https://github.com/me-no-dev/ESPAsyncWebServer/archive/refs/heads/master.zip
AsyncTCP (.zip folder): https://github.com/me-no-dev/AsyncTCP/archive/refs/heads/master.zip
Then, in your Arduino IDE, you can go to Sketch > Include Library > Add .zip Library and select the libraries youâve just downloaded.
I hope this helps.
Regards,
Sara
Hi I wanna set the delay for data collection to 30 mins without an rtc is it possible?
I now have a classic car instrumentation application using an ESP32 as an Access Point and webserver. It publishes a web page with an update of 4 Dallas Temperature DS18B20 sensors informing the temperatures of my EV conversion. I can access the data via browser on my phone or tablet while in or near the vehicle. My next step is to integrate another ESP32 as a backup camera on the same network.
when I went to serial monitor to get the IP address all I got was dots. I hit the reset button and it displayed proper temp etc but why does it not give IP? Thanks
I fixed it non issue LOL
Hi Sara,
Thanks for the wonderful ESP32 Web Server tutorials. I am learning a lot from here.
I have duplicated your sketch code for “ESP32 DS18b20 temperature sensor Web Server” on my “ESP32 Dev Kit C V4”.
The Web Server It works well if the WiFi Connection can be established.
Unfortunately though, getting WiFi connection is like playing lottery.
The connection fails practically 70% of time. Sometimes one has to wait up to 10-15 minutes.
I have read in Internet that I am not alone with problem. People have proposed various workarounds but none is really a solution.
I assume that you are well aware of this problem.
Is this an ESP32 board design timing issue or something else?
Could you kindly propose a solution, please?
I am sure you would be helping not only me but also thousands of randomnerds fans out there.
Looking forward to an early reply.
Thanks and best regards
Hi.
I usually don’t have problems with Wi.Fi on my ESP32 boards.
Is your Wi-Fi network good? Is the ESP32 close to your router?
It may be an issue with your network.
You may also consider adding some code that tries to reconnect to the network when the connection is lost. See the following tutorials:
– https://randomnerdtutorials.com/solved-reconnect-esp32-to-wifi/
Regards,
Sara
Hi Sara,
Many thanks for your fast reply.
Yes, it seems that there was some problem with my WiFi network. My Fritzbox WLAN repeater (1750E) was connected to the Router via WLAN and NOT via LAN cable. Thus the WLAN signal from the repeater was probably too weak.
I have now changed the WLAN connection between the router and the WLAN repeater to “bridged LAN” connection. Instructions hereto are available on the AVM Web site. Now the WLAN signal emitted by the repeater is strong enough so that I have no ESP32 network connection issue anymore.
Thanks again also for the link to “reconnection sketch”. I might implement this in my sketch just in case ….
Best regards
Easy to follow instructions and this works great.
I made it to monitor the temp in my HotTub.
If I had one wish. That would be to add the âTimeâ to the display page.
When the Temperature is updated.
( I tried but couldnât figure it out)
I will be adding a battery and solar charging.
Why is it reading only -127 C?
How can I fix it?
Double-check the wiring and that the sensor is connected to the right GPIO.
Also, very long cables might cause this issue.
Regards,
Sara
Anyone have any experience of the heltec wifi 8 (esp8266 not esp32 version)?
Iâm using the adafruit ssd1306 oled and it works ok OR I can use the ds18 one wire works ok
BUT can I get them to work together, nope Iâm either missing something or the dambed thing is broken?
Iâm not asking for code as Iâm enjoying the task but just wondering if itâs just not possible and I will never get it to work because of io conflicts
Cheers Clive
Hi.
It’s possible to use both together.
What’s the issue that you have?
Do you get any compilation errors?
Regards,
Sara
Hi Sara
Than you for coming back to me
The more I investigate I think the heltec board just dosnt like to play as it may have lots on board but try as i might it wont play.
If the ds18 prints to the ide serial monitor and the onboard oled stays completely blank. the oled only outputs with no ds18 connected
The adafruit demo for the ssd1306 works as does your multi ds18 but alas I have tried all the io pins that are presented knowing that some are NOT to be used and yes some spectacular non responsive results
Maybe I need to go back to heltec.h but was hoping to use the nodemcu 1.0 so as to keep my code similar to other boards i have
This is a daft question you may know of or maybe Iâm complicating it but do driver declarations get effected by the order they are in a sketch?
Iâm enjoying your home automation ebook by the way hence i dragged out of the back of a drawer the heltec, maybe I should perfect my sketch on one of the nodemcu I have first to ensure its not just poor programming?
Cheers Clive
Hi again.
Yes, I recommend trying your code on a “regular” ESP8266 first to make sure your code is proper implemented.
The thing with the heltec board is the conflicts between the GPIOs.
On the pinout, it says that it supports onewire on all pins, except D0. So, in theory, you should be fine with any GPIO for the temperature sensor, except D0 and the OLED pins.
I don’t think I understood your question very well…. but the last declaration is the one that will be used.
Regards.
Sara
Hi Sara,
Why are the simple things so difficult to sort?
Sorted it , in defining the one wire bus I had tried D0 through D8 (amongst many other bit relating to the sad1306 !)
As the Heltec wifi 8 is a esp8266 using D instead of GPIO should have worked or so I thought but alas no
A simple swap from D2 to 0 and all the odd behaviour disappeared and it works
But I have learnt so much including remembering that I can read a little german having found http://www.az-delivery.de which pointed out my error and if I had disregarded the german website âŠ.
So just remember programming is a universal language that can override the language barrier (at least a little?)
I will have to clean up my code (actually yours) and post it here so others may learn not to give up and to learn just by doing and fiddling
Cheers Clive
Ps its 5 to midnight and time for bed
Hi.
Thanks for sharing your findings.
I recommend always using the GPIO number and not the D0…D5 notation.
I didn’t know you were using that notation.
Using the GPIO number only has worked for me for many different boards. Never had an issue with that.
Regards,
Sara
Hi,
Onewire does not seem to work anymore.
Not only does this example not compile but the Example ‘DS18x20_Temperature’ fails as well.
It gives various errors like below …
/Users/Sandy/Documents/Arduino/libraries/OneWire/OneWire.cpp: In member function ‘uint8_t OneWire::reset()’:
/Users/Sandy/Documents/Arduino/libraries/OneWire/OneWire.cpp:167:24: error: unused variable ‘reg’ [-Werror=unused-variable]
volatile IO_REG_TYPE *reg IO_REG_BASE_ATTR = baseReg;
^~~
Any ideas?
Sandy
Hi.
Did you install OneWire library by Paul Stoffregen as mentioned in the tutorial?
Regards,
Sara
Hi,
Yes I did
I have spent some time Googling this and the best I can come up with is that the latest ESP32 support in Arduino breaks OneWire.
The problem I have is using Arduino v2 – it has the ESP32 Boards Mgr v2.09.
I still have the older version of Arduino (v1.8.15) and that has the Board Mgr v 2.09 also but it compiles the code with OneWire so I am using that.
Regards, Sandy
Hi folks! Some news about this issue?
I have been the same trouble.
My case:
<OneWire.h> //v.2.3.7 (by Paul Stoffregen)
<DallasTemperature.h> //v.3.9.0
Arduino IDE 1.8.19
Solved: Change “Prefferences -> Compiler Warnings -> All to None”, compile again – write to the board ok. And back original configs:> “Prefferences -> Compiler Warnings -> None to All”
This is an excellent tutorial especially the Web Server.
I would like to get more than one DS18B20 output displaying but not sure how much I need to modify here to achieve this.
Any further examples would be great.
Hi.
Check the following tutorial. It’s exactly what you’re looking for:
– https://randomnerdtutorials.com/esp32-plot-readings-charts-multiple/
Regards,
Sara
Hi,
I have built this project and it works like a charm!
Thank you very much for this great tutorial, you are a star! đ
Kind regards from BarsbĂŒttel/Germany
Matthias
That’s great.
Thank you.
Regards,
Sara
Thank you so much.
Regards,
Sara
Hi Sara, I have tried this example and it was working. Now my browser is locking me out with security warnings. I am not getting the option to ignore. This is happening an both Brave and Chrome. I have tried the security settings but nothing seems to alter the message. Any ideas there?
Many thanks.
Hi.
What are the security warnings?
Regards,
Sara
its the browser saying that the site (192.168.1.2 ) is not secure. in red.. “your connection to this site is not secure” Up until a week ago you could click through it but now, none of my browsers will allow the site to display. There for I wonder if it’s possible to modify the example of you tutorial to include HTTPS. I have gone through getting a certificate but don’t know how to integrate into your example(s) that use the ESPAsyncWebServer library? The example of SSL from RNT has a link but I can’t follow enough to use with you other tutorial. Also which exact ESPAsyncWebServer library do you use?
Thanks heaps.. Mal
Hello, If the wire between the sensor and esp is like 6 meters long Where should the resistor be placed, Near the sensor or near ESP?
Hello,
I am having an issue when running this project. I am only using one sensor in Normal Mode, but when ran, it only receives one successful reading of temperature. Each reading after is met with the error message “Failed to read from DS18B20 sensor”. Something to note is that I am currently using a resistor value of 5.1kΩ as I do not currently possess resistors of exact value of 4.7kΩ. Could this be the cause of the problem?
Also, what is the purpose of connecting the Data Line to the power supply in a Normal mode setup?
I am still learning how to use Arduino IDE and electronics such as these, so any help would be much appreciated!đ
DS18B20 measure the real temperature without any kind of calibration?
My tests shown the temperature 9 degrees lower than the real obtained with a thermometer.