If you want to create a temperature measurement network using an Arduino or ESP8266, the OneWire DS18B20 probes are ideal. The OneWire is a digital data bus that requires only one wire. The OneWire bus can address up to 100 devices with a single wire. There are many tutorials on the Internet that explain how to implement DS18B20 probes with Arduino code. We will not reinvent the wheel here.
Post updated may 28, 2020
You have been several to contact me to ask me an example using several DS18B20 sensors and how to publish the measurements on a home automation server. That’s what we’re going to do here. I propose instead a methodology to identify the sensors, read the measurements and send them to a home automation server using an HTTP request. In the next tutorial, we will see how to do with MicroPython code. If you have other needs, do not hesitate to ask me in the comments.
Necessary material
For this tutorial, I adapted the Arduino code that came with the Arduino OneWire and DallasTemperature libraries. I tested the code on an ESP32 and more particularly on the Wemos LoLin32 Lite and the Wemos d1 mini based ESP8266. The libraries are therefore compatible with ESP8266 and ESP32 WiFi modules last generation which is much more convenient to send measurements to a home automation server.

Multiple connection of Dallas DS18B20 probes
The connection is very simple. The One-Wire bus is usually located on a yellow wire. Red is used for power, black for GND as usual. For the bus to work, it must be “de-wormed”. For this, a resistor (4K7 in general) is placed between the +5V and the data bus. I also tried other resistors (5K7) and a power supply +3V3 successfully. Obviously, everything will depend on the cable length. The longer the cabling, the more rigorous it will be to supply the power and the de-interference of the signal.
For this tutorial, the DS18B20 is plugged into pin 4 of the ESP8266. You can also use all the codes in this tutorial on an Arduino Uno or ESP32.
Scan DS18B20 probe addresses, Arduino code (compatible ESP8266 and ESP32)
The first thing to do is to identify the probes. Each probe has a unique 8-bit identifier. Unfortunately, it is never indicated on the packaging. It’s up to us to do it manually. Here is a small scanner that retrieves the addresses of DS18B20 probes. It scans the OneWire bus every 2 seconds for connected probes. It is possible to add “hot” sensors without having to restart the program.
/* * One Wire scanner * Testé sur la carte ESP32 Wemos LoLin32 Lite | Checked on Wemos LoLin32 Lite development board * Code inspiré de l'exemple livré avec la librairie Arduino DallasTemperature * Code inspired by DallasTemperature Aduino library from * http://milesburton.com/Dallas_Temperature_Control_Library */ #include <OneWire.h> // Bus OneWie connecté sur la broche 4 | OneWire bus connected on Pin 4 // Installer une résistance de 4.7K entre le +5V et le cable de données // A 4.7K resistor is necessary between +5V and Data wire OneWire ds(4); byte i; byte type_s; byte data[12]; byte addr[8]; void OneWireScanner(){ if ( !ds.search(addr)) { Serial.println("No more addresses."); Serial.println(); ds.reset_search(); return; } Serial.print("ROM = "); for( i = 0; i < 8; i++) { Serial.write(' '); Serial.print("0x"); Serial.print(addr[i], HEX); if ( i != 7 ) { Serial.print(", "); } } if (OneWire::crc8(addr, 7) != addr[7]) { Serial.println("CRC is not valid!"); return; } Serial.println(); // the first ROM byte indicates which chip switch (addr[0]) { case 0x10: Serial.println(" Chip = DS18S20"); // or old DS1820 type_s = 1; break; case 0x28: Serial.println(" Chip = DS18B20"); type_s = 0; break; case 0x22: Serial.println(" Chip = DS1822"); type_s = 0; break; default: Serial.println("Device is not a DS18x20 family device."); return; } } void setup() { Serial.begin(115200); } void loop() { // put your main code here, to run repeatedly: OneWireScanner(); delay(5000); }
Open the Arduino IDE, create a new sketch and paste the code above. Modify the pin to which the DS18B20 sensor will be connected. Then open the Library Manager, Sketch -> Include Library -> Manage Libraries. Do a search on the OneWire keyword and then install the OneWire library
Upload the program and open the serial monitor. Here is the execution log with two DS18B20 probes. Uncheck the “Auto Scroll” option. You can easily copy the address of each probe to include it in your project. In practice, I advise you to successively connect the probes to identify and stick a label bearing its address, for example (28-D4-B0-26-00-00-80-BC)
ROM = 0x28, 0xD4, 0xB0, 0x26, 0x0, 0x0, 0x80, 0xBC Chip = DS18B20 ROM = 0x28, 0xF4, 0xBC, 0x26, 0x0, 0x0, 0x80, 0x2B Chip = DS18B20 No more addresses.
Individual reading of the temperature of several DS18B20 probes, compatible Arduino code ESP8266 and ESP32
Now that each temperature sensor is identified, we will use the DallasTemperature library that adds some very useful methods for managing DS18B20 sensors. Return to the library manager to install the DallasTemperature library.
Create a new sketch and paste the code below. Specify the pin to which the One-Wire data bus is attached using the ONE_WIRE_BUS constant. You can change the accuracy of the measurement with the TEMPERATURE_PRECISION constant. By default, it is returned on 10 bits. Finally, replace the addresses of your probes for insideThermometer and outsideThermometer.
#include <OneWire.h> #include <DallasTemperature.h> // Data wire is plugged into port 4 on the Arduino or ESP32 #define ONE_WIRE_BUS 4 #define TEMPERATURE_PRECISION 10 // 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); // Tableaux contenant l'adresse de chaque sonde OneWire | arrays to hold device addresses DeviceAddress insideThermometer = { 0x28, 0xD4, 0xB0, 0x26, 0x0, 0x0, 0x80, 0xBC }; DeviceAddress outsideThermometer = { 0x28, 0xF4, 0xBC, 0x26, 0x0, 0x0, 0x80, 0x2B }; void setup() { Serial.begin(115200); // Start up the library sensors.begin(); // locate devices on the bus Serial.print("Locating devices..."); Serial.print("Found "); Serial.print(sensors.getDeviceCount(), DEC); Serial.println(" devices."); // report parasite power requirements Serial.print("Parasite power is: "); if (sensors.isParasitePowerMode()) Serial.println("ON"); else Serial.println("OFF"); // Vérifie sir les capteurs sont connectés | check and report if sensors are conneted if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); // set the resolution to 9 bit per device sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION); sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION); // On vérifie que le capteur st correctement configuré | Check that ensor is correctly configured Serial.print("Device 0 Resolution: "); Serial.print(sensors.getResolution(insideThermometer), DEC); Serial.println(); Serial.print("Device 1 Resolution: "); Serial.print(sensors.getResolution(outsideThermometer), DEC); Serial.println(); } void printTemperature(String label, DeviceAddress deviceAddress){ float tempC = sensors.getTempC(deviceAddress); Serial.print(label); if (tempC == -127.00) { Serial.print("Error getting temperature"); } else { Serial.print(" Temp C: "); Serial.print(tempC); Serial.print(" Temp F: "); Serial.println(DallasTemperature::toFahrenheit(tempC)); } } void loop() { // put your main code here, to run repeatedly: Serial.print("Requesting temperatures..."); sensors.requestTemperatures(); Serial.println("DONE"); // print the device information printTemperature("Inside : ", insideThermometer); printTemperature("Outside : ", outsideThermometer); delay(5000); }
How does the code work?
The DallasTemperature library is expecting a OneWire object that is attached to the ESP32 (or Arduino) pin. Here is the pin n ° 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);
The DallasTemperature library allows to define an address for each probe (which we did previously). Here, we will define an inner (Inside) and outer (Outside) probe. It is a DeviceAdress variable that expects an array of hexadecimal values
DeviceAddress insideThermometer = {0x28, 0xD4, 0xB0, 0x26, 0x0, 0x0, 0x80, 0xBC}; DeviceAddress outsideThermometer = {0x28, 0xF4, 0xBC, 0x26, 0x0, 0x0, 0x80, 0x2B};
In the setup loop, the sensors.begin () method is used to start the communication with the probes. Now, we can read the temperature on a particular probe at any time, for the outside temperature, this will give for example
sensors.requestTemperatures(); // Demande la lecture de toutes les sondes | Request all temperatures from probes float tempC = sensors.getTempC(outsideThermometer); // Récupère la température de la sonde extérieure | Get temperature from outside probe Serial.print(" Temp C: "); // Imprime la temperature (par défaut en °C | Print outside temp. By default in Celcius Serial.print(tempC);
The DallasTemperature bookseller offers other useful methods here. Everything is available in the source code on GitHub
// returns the number of devices found on the bus uint8_t getDeviceCount(void); // returns true if address is valid bool validAddress(const uint8_t*); // returns true if address is of the family of sensors the lib supports. bool validFamily(const uint8_t* deviceAddress); // finds an address at a given index on the bus bool getAddress(uint8_t*, uint8_t); // attempt to determine if the device at the given address is connected to the bus bool isConnected(const uint8_t*); // attempt to determine if the device at the given address is connected to the bus // also allows for updating the read scratchpad bool isConnected(const uint8_t*, uint8_t*); // read device's scratchpad bool readScratchPad(const uint8_t*, uint8_t*); // write device's scratchpad void writeScratchPad(const uint8_t*, const uint8_t*); // read device's power requirements bool readPowerSupply(const uint8_t*); // get global resolution uint8_t getResolution(); // set global resolution to 9, 10, 11, or 12 bits void setResolution(uint8_t); // returns the device resolution: 9, 10, 11, or 12 bits uint8_t getResolution(const uint8_t*); // set resolution of a device to 9, 10, 11, or 12 bits bool setResolution(const uint8_t*, uint8_t, bool skipGlobalBitResolutionCalculation = false); // sets/gets the waitForConversion flag void setWaitForConversion(bool); bool getWaitForConversion(void); // sets/gets the checkForConversion flag void setCheckForConversion(bool); bool getCheckForConversion(void); // sends command for all devices on the bus to perform a temperature conversion void requestTemperatures(void); // sends command for one device to perform a temperature conversion by address bool requestTemperaturesByAddress(const uint8_t*); // sends command for one device to perform a temperature conversion by index bool requestTemperaturesByIndex(uint8_t); // returns temperature raw value (12 bit integer of 1/128 degrees C) int16_t getTemp(const uint8_t*); // returns temperature in degrees C float getTempC(const uint8_t*); // returns temperature in degrees F float getTempF(const uint8_t*); // Get temperature for device index (slow) float getTempCByIndex(uint8_t); // Get temperature for device index (slow) float getTempFByIndex(uint8_t); // returns true if the bus requires parasite power bool isParasitePowerMode(void); // Is a conversion complete on the wire? bool isConversionComplete(void); int16_t millisToWaitForConversion(uint8_t);
Program test with two DS18B20 probes
Upload the program and open the serial monitor. The individual reading of each probe is immediate.
Inside: Temp C: 18.00 F Temp: 64.40 Outside: Temp C: 18.25 Temp F: 64.85 Requesting temperatures ... DONE
If you disconnect one of the probes, an error message is displayed next to the faulty probe. It is very easy to send an email to indicate that a probe is defective. To test the probes, one also has the method isConnected (probe_address) of the DallasTemperature library. The One-Wire bus runs hot. As soon as you reconnect the probe, it is automatically detected and the temperature reading is immediate. It’s really very practical. We could imagine a small web interface to manage the probes without having to recompile the program as soon as we add a new probe. By going further, you can read this series of articles on the creation of an WEB interface for DIY projects based on ESP8266
Inside : Temp C: 18.00 Temp F: 64.40 Outside : Error getting temperature
Publishing temperatures on a Domoticz server by HTTP request
All that remains is to send the data to a home automation server. Here we will take the example of Domoticz which has a JSON interface (API). The format of the HTTP request is the following for a temperature type measurement (the documentation of the API is detailed here). For more details, read this previous article or this one to do the same thing with Jeedom.
Start by going to the Domoticz server to create two virtual devices of the temperature type and get the Idx of each probe. Follow this tutorial to learn how to do it.
The following code is compatible with Arduino, ESP8266 and ESP32. Several parameters must be modified in the code before uploading it:
- Specify the One Wire bus pin on the constant ONE_WIRE_BUS
- Replace probe addresses, insideThermometer and outsideThermometer
- The WiFi network on which to connect with the constant wifi_ssid, as well as the password
- Domoticz server IP address, host variable, connection port (default 8080)
- The Domoticz Idx for each IDX_insideTemp and IDX_outsideTemp probe
/* * Read multiple One-Wire DS18B20 probes and publish value on Domoticz with HTTP request * Lecture multiple de sonde OneWire DS18B20 et plublication des mesures sur un serveur Domoticz requete HTTP * Code adapté - Code adaptated * */ #include <OneWire.h> #include <DallasTemperature.h> // Pour un Arduino ou ESP32 (le SDK Espressif doit être installé) | For Arduino or ESP32 (Espressif SDK must be installed) #include <WiFi.h> #include <HTTPClient.h> // Pour une carte ESP8266 | For ESP8266 development board //#include <ESP8266WiFi.h> //#include <ESP8266HTTPClient.h> #include <PubSubClient.h> // Data wire is plugged into port 4 on the Arduino or ESP32 #define ONE_WIRE_BUS 4 #define TEMPERATURE_PRECISION 10 // 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); // Tableaux contenant l'adresse de chaque sonde OneWire | arrays to hold device addresses DeviceAddress insideThermometer = { 0x28, 0xD4, 0xB0, 0x26, 0x0, 0x0, 0x80, 0xBC }; DeviceAddress outsideThermometer = { 0x28, 0xF4, 0xBC, 0x26, 0x0, 0x0, 0x80, 0x2B }; // Parametres WIFI - WiFi settings #define wifi_ssid "xxxxxxxx" #define wifi_password "xxxxxxxx" // Paramètres HTTP Domoticz - HTTP Domoticz settings const char* host = "xxx.xxx.xxx.xxx"; const int port = 8080; #define IDX_insideTemp 24 #define IDX_outsideTemp 25 HTTPClient http; void setup() { Serial.begin(115200); // Connexion au réseau WiFi, connexion aux sondes // Start WiFi connexion and probes setup_wifi(); sensors.begin(); // locate devices on the bus Serial.print("Locating devices..."); Serial.print("Found "); Serial.print(sensors.getDeviceCount(), DEC); Serial.println(" devices."); // report parasite power requirements Serial.print("Parasite power is: "); if (sensors.isParasitePowerMode()) Serial.println("ON"); else Serial.println("OFF"); // Vérifie sir les capteurs sont connectés | check and report if sensors are conneted if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); // set the resolution to 9 bit per device sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION); sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION); // On vérifie que le capteur st correctement configuré | Check that ensor is correctly configured Serial.print("Device 0 Resolution: "); Serial.print(sensors.getResolution(insideThermometer), DEC); Serial.println(); Serial.print("Device 1 Resolution: "); Serial.print(sensors.getResolution(outsideThermometer), DEC); Serial.println(); } void printTemperature(String label, DeviceAddress deviceAddress){ float tempC = sensors.getTempC(deviceAddress); Serial.print(label); if (tempC == -127.00) { Serial.print("Error getting temperature"); } else { // Format JSON à respecter pour l'API Domoticz - Domoticz JSON API // /json.htm?type=command¶m=udevice&idx=IDX&nvalue=0&svalue=TEMP // https://www.domoticz.com/wiki/Domoticz_API/JSON_URL%27s#Temperature if ( label == "Inside : " ) { String url = "/json.htm?type=command¶m=udevice&idx="; url += String(IDX_insideTemp); url += "&nvalue=0&svalue="; url += String(tempC); sendToDomoticz(url); } else { String url = "/json.htm?type=command¶m=udevice&idx="; url += String(IDX_outsideTemp); url += "&nvalue=0&svalue="; url += String(tempC); sendToDomoticz(url); } } } void loop() { Serial.print("Requesting temperatures..."); sensors.requestTemperatures(); Serial.println("DONE"); // print the device information printTemperature("Inside : ", insideThermometer); printTemperature("Outside : ", outsideThermometer); delay(5000); } //Connexion au réseau WiFi void setup_wifi() { delay(10); Serial.println(); Serial.print("Connecting to "); Serial.println(wifi_ssid); WiFi.begin(wifi_ssid, wifi_password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connexion OK "); Serial.print("=> Addresse IP : "); Serial.print(WiFi.localIP()); } void sendToDomoticz(String url){ Serial.print("Connecting to "); Serial.println(host); Serial.print("Requesting URL: "); Serial.println(url); http.begin(host,port,url); int httpCode = http.GET(); if (httpCode) { if (httpCode == 200) { String payload = http.getString(); Serial.println("Domoticz response "); Serial.println(payload); } } Serial.println("closing connection"); http.end(); }
Now, you can now add DS18B20 probes to your Arduino, ESP8266 or ESP32 connected object projects quite quickly. We find the DS18B20 in the form of a 3-pin housing or most often pre-wired in a waterproof stainless steel case. It can for example be used to regulate a heating with an indoor temperature sensor and an outdoor sensor. The stainless steel case is very suitable for monitoring the temperature in humid or dusty environments (fridge, freezer, swimming pool, aquarium …), environments inaccessible to the usual sensors (DHT22, DHT12 on I2C bus …). If you have no notion of programming, the DS18B20 is also supported by the ESP Easy firmware on ESP8266 and now on ESP32.






- ESP32, GPIO pins and associated functions. I/O, PWM, RTC, I2C, SPI, ADC, DAC
- M5Stack Atomic GPS. ESP32 TinyGPS++ tracker, GPX export on SD card, visualization on Google Maps or VSCode
- How to store data on a micro SD card. Arduino code compatible ESP32, ESP8266
- Getting started Arduino. Receive commands from the serial port (ESP32 ESP8266 compatible)
- C++ functions print•println•printf•sprintf for Arduino ESP32 ESP8266. Combine•format → serial port
- C++ String functions. concat•c_srt•indexOf•replace•subString… for Arduino, ESP32, ESP8266
Are You sure the wiring is fine? Please take a look at: http://www.instructables.com/id/Simple-Example-ArduinoESP8266DS18B20/
I’ve tried Your way and DS18B20 got very hot :/
Hello Misui. I think yes. Now I have a doubt :O. In any case, I did not observe any heating of my sensors. I power the sensors in 3V3. You too ?
Hi there, I’very used 5V. In my case when I used Your schema I was unable to find sensor using 1wire sensor. I had to switch GND and power and then it worked fine. Have You looked at attached pinout?
Hello Misiu and happy new year ! Yes I looked but as you can see on the technical documentation https://cdn.sparkfun.com/datasheets/Sensors/Temp/DS18B20.pdf, we can power the ds18b20 between 3V and 5V. So it is not necessary to put a resistor to decrease the voltage. By cons you may have bought a clone or your sensor may be defective. Do you have other sensors to test?
In datasheet You attached GND is far left pin, but in Your schema GND is far right pin. (please look at my attached image from previous comment, datasheet You linked and compare it with first schema in this post)
I switched VDD and GND and everything worked fine.
Please correct that schema. Voltage isn’t the problem and Yes, looking at datasheet I can confirm that it should work with 3.3V.
Oh yes, excuse me Misui. I used ds18b20 waterproof and I was wrong when I did the wiring scheme. It’s corrected. See you soon
That looks much better 🙂 Thanks for fix and for article. It really helped me getting started with DS18B20.
I’ve bookmarked Your site so I’ll definitively come back! 🙂
Thank you very much Misiu 😀
Is it possible to do this:
1. PRIVATE server using ESP8288 AND ESP-NOW by ExpressIF
2- Several Temperature sensors using ESP8266 (model 01) OR Arduino nano scattered allover the house and may be outside too.
3. Send data to the local server (ESP-NOW)
4. Display on a web page ALL temperature,s readings collected i.e mapping temperature across the whole house
In my view this is a project that is worth considering………Your comments will be greatly appreciated
So far you are doing a great work..thank you for sharing it
Hello Samir, Thank you very much !
At the moment, i don’t know ESP-NOW but i’ll try to answer
1 and 4. I need to test to be sure before answer you. I propose you to test and write tutorials this week or the week after
2. Yes, you can have up to 100 DS18B20 probes. 1-wire protocol is very reliable so you can have up to 15m (maybe more) between arduino and sensor
3. Sure you can
Great to hear from you….
I believe the crucial part of such proposed project is being WIRELESS.
This due to the fact that the sensors are way apart and may be in Two floors ( or a basement and ground floor)
Sure, i hope you can wait few days, just the time i make enough tests. I’ll reply you directly in this comment. Have a good week-end Aridhy.
This is a good intro to ESP-NOW
But remember, there is more than one way to do it. Your way of using Domoticz is a viable approach.
Yes of course, so many solutions. MQTT, HTTP… Thank you for the link 🙂