Dallas ds18b20 with esp32 and esp8266: introduction and parasite mode

Spread the love

The Dallas DS18B20 is a digital temperature sensor that communicates over a 1-wire interface. It is a popular choice for temperature sensing due to its high accuracy and low cost.

The ESP32 and ESP8266 are both microcontrollers that can be used to interface with the DS18B20 sensor. Both microcontrollers have built-in support for the 1-wire protocol, which makes it easy to interface with the DS18B20.

The DS18B20 has two modes of operation: normal mode and parasite mode. In normal mode, the sensor requires an external power supply, which provides both power and communication over the 1-wire interface. In parasite mode, the sensor draws power from the data line of the 1-wire interface. This allows the sensor to be powered using only two wires: the data line and the ground.

Dallas ds18b20 with esp32: introduction and parasite mode
Dallas ds18b20 with esp32: introduction and parasite mode

I already show some temperature and humidity sensors in this series of articles: “Temperature and humidity sensors: how to and comparison“, but now I’d like to explain better Dallas ds28b20. This one-wire temperature sensor can be managed in series without a big limit.

In particular, It has good precision (±0.5°) and a considerable range (-55°C to +125°C or -67°F to +257°F), but you can add in a single wire a lot of devices, It also supports a parasite power mode that allows to you to use only two wire in connection.

But now I’m going to add the explanation from the datasheet for better comprehension.

The DS18B20 digital thermometer provides 9-bit to 12-bit Celsius temperature measurements and has an alarm function with nonvolatile user-programmable upper and lower trigger points. The DS18B20 communicates over a 1-Wire bus that requires only one data line (and ground) for communication with a central microprocessor. In addition, the DS18B20 can derive power directly from the data line (“parasite power”), eliminating the need for an external power supply.

Each DS18B20 has a unique 64-bit serial code, which allows multiple DS18B20s to function on the same 1-Wire bus. Thus, using one microprocessor to control many DS18B20s distributed over a large area is simple. Applications that can benefit from this feature include HVAC environmental controls, temperature monitoring systems inside buildings, equipment, or machinery, and process monitoring and control systems.

Datasheet

Features

  • Unique 1-Wire® Interface Requires Only One Port Pin for Communication
  • Reduce Component Count with Integrated Temperature Sensor and EEPROM
    • Measures Temperatures from -55°C to +125°C (-67°F to +257°F)
    • ±0.5°C Accuracy from -10°C to +85°C
    • Programmable Resolution from 9 Bits to 12 Bits
    • No External Components Required
  • Parasitic Power Mode Requires Only 2 Pins for Operation (DQ and GND)
  • Simplifies Distributed Temperature-Sensing Applications with Multidrop Capability
    • Each Device Has a Unique 64-Bit Serial Code Stored in On-Board ROM
  • Flexible User-Definable Nonvolatile (NV) Alarm Settings with Alarm Search Command Identifies Devices with Temperatures Outside Programmed Limits
  • Available in 8-Pin SO (150 mils), 8-Pin µSOP, and 3-Pin TO-92 Packages

Datasheet

No online PDF viewer installed. Download!

Pinout

Dallas ds18b20 pinout
Dallas ds18b20 pinout

The sensor has more variants, but the wiring remains the same.

GND: connect to GND.
DATA: One-Wire Data bus.
VCC: power supply (3,3 – 5 V), but in parasite mode, you can connect to GND.

Here the sensor AliExpress

Wiring

The One-Wire library Is a standard for all microcontrollers, so the device can be used with many microcontrollers.

esp32

Here is the pinout of one of the most common esp32 prototype boards.

ESP32 DOIT DEV KIT v1 pinout
ESP32 DOIT DEV KIT v1 pinout

Here my selection of esp32 ESP32 Dev Kit v1 - TTGO T-Display 1.14 ESP32 - NodeMCU V3 V2 ESP8266 Lolin32 - NodeMCU ESP-32S - WeMos Lolin32 - WeMos Lolin32 mini - ESP32-CAM programmer - ESP32-CAM bundle - ESP32-WROOM-32 - ESP32-S

Normal mode

In normal mode, we are going to use a power line at 3.3v, so the connection becomes like so.

esp32 with waterproof ds18b20: wiring in breadboard
esp32 with waterproof ds18b20: wiring in breadboard

The connection is very simple.

esp32ds18b20
GNDGND
3.3vVCC
D22 pulled-upDATA
Schema

Here is the simple schema.

esp32 with ds18b20: schema
esp32 with ds18b20: schema

Parasite mode

In the parasite mode, you are going to put GND also in the VCC line of the sensor, and It gets the power from the Data line.

esp32 with ds18b20 in parasite mode: wiring breadboard
esp32 with ds18b20 in parasite mode: wiring breadboard
esp32ds18b20
GNDGND
GNDVCC
D22 pulled-upDATA

Next, we will analyze this modality in-depth, but you don’t need more information now.

Schema

Here is the schema.

esp32 with ds18b20 in parasite mode: schema
esp32 with ds18b20 in parasite mode: schema

esp8266

Normal mode

WeMos d1 esp8266 and ds18b20 wiring
WeMos d1 esp8266 and ds18b20 wiring
esp8266ds18b20
GNDGND
3.3vVCC
D2 pulled-upDATA

Parasite mode

esp8266 and ds18b20 in parasite
esp8266 and ds18b20 in parasite
esp8266ds18b20
GNDGND
GNDVCC
D2 pulled-upDATA

Library

First of all, you must remember that this sensor uses the One-Wire protocol, so you must add the OneWire library.

Every platform has It; we are going to explain this protocol better next when we introduce the use of multiple sensors.

Arduino IDE: OneWire library on libraries manager
Arduino IDE: OneWire library on libraries manager

After that, you must install a library that implements the protocol and sensor features.

I chose the most widely used, the DallasTemperature (in the past Dallas, now Maxim).

Arduino IDE: libreria DallasTemperature per il ds18b20 dal libraries manager
Arduino IDE: libreria DallasTemperature per il ds18b20 dal libraries manager

Devices supported

As described in the repository, this library supports the following devices :

  • DS18B20
  • DS18S20 (some problems on this device)
  • DS1822
  • DS1820
  • MAX31820
  • MAX31850

You will need a pull-up resistor of about 4.7KOhm between the 1-Wire data line and your VCC. if you are using the DS18B20, you can use parasite mode, and you can put to GND the VCC as described.

esp8266 wemos d1 mini and ds18b20: wiring
esp8266 wemos d1 mini and ds18b20: wiring

Troubleshooting

In case of temperature conversion problems (the result is -85), a strong pull-up setup may be necessary. See section Powering the DS18B20 in DS18B20 datasheet (page 7) and use DallasTemperature(OneWire*, uint8_t) constructor.

Powering the DS18B20 (normal/parasite)

The DS18B20 can be powered by an external supply on the VDD pin, or it can operate in “parasite power” mode, which allows the DS18B20 to function without a local external supply (you connect the VDD to the GND). DS18B20 “steals” power from the 1-Wire bus via the DQ pin when the bus is high. The stolen charge powers the DS18B20 while the bus is high, and some of the charges are stored on the parasite power capacitor (CPP) to provide power when the bus is low.

esp32 with ds18b20 in parasite mode: schema
esp32 with ds18b20 in parasite mode: schema

But when the DS18B20 performs temperature conversions or copies data from the scratchpad memory to EEPROM, the operating current can be as high as 1.5mA. This current can cause an unacceptable voltage drop across the weak 1-Wire pullup resistor and is more current than CPP can supply.

Strong pull-up for parasite mode

To assure that the DS18B20 has sufficient current supply, it is necessary to provide a strong pullup on the 1-Wire bus whenever temperature conversions occur or data is being copied from the scratchpad to EEPROM.
This can be accomplished by using a MOSFET to pull the bus directly to the rail.

esp32: wiring schema ds18b20 in parasite mode with strong pull-up
esp32: wiring schema ds18b20 in parasite mode with strong pull-up

The 1-Wire bus must be switched to the strong pullup within 10µs (max) after temperature conversions, and the bus must be held high by the pullup for the duration of the conversion or data transfer. No other activity can take place on the 1-Wire bus while the pullup is enabled.

The DS18B20 can also be powered by the conventional method of connecting an external power supply to the VDD pin, as shown. The advantage of this method is that the MOSFET pull-up is not required, and the 1-Wire bus is free to carry other traffic during the temperature conversion time.

esp32: wiring ds18b20 in parasite mode with strong pull-up
esp32: wiring ds18b20 in parasite mode with strong pull-up

The use of parasite power is not recommended for temperatures above +100°C since the DS18B20 may not be able to sustain communications due to the higher leakage currents that can exist at these temperatures.

Reduce the size of the library

We have included a REQUIRESNEW and REQUIRESALARMS definition. If you want to slim down the code, feel free to use either of these by including

#define REQUIRESNEW 

or

#define REQUIRESALARMS

at the top of DallasTemperature.h

Code

And now, we can start with some examples.

For esp8266, you must only change pin to 22 to D2 or directly 4.

Get sensor temperature

First of all, the fastest way to put in work the sensor.

// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 22
#define ONE_WIRE_BUS 22

// 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 setup function. We only start the sensors here
 */
void setup(void)
{
  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");

  // Start up the library
  sensors.begin();
}

/*
 * Main function, get and show the temperature
 */
void loop(void)
{ 
  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");
  // After we got the temperatures, we can print them here.
  // We use the function ByIndex, and as an example get the temperature from the first sensor only.
  float tempC = sensors.getTempCByIndex(0);

  // Check if reading was successful
  if(tempC != DEVICE_DISCONNECTED_C) 
  {
    Serial.print("Temperature for the device 1 (index 0) is: ");
    Serial.println(tempC);
  } 
  else
  {
    Serial.println("Error: Could not read temperature data");
  }
  delay(2000);
}

The Serial output is very simple.

Dallas Temperature IC Control Library Demo
Requesting temperatures...DONE
Temperature for the device 1 (index 0) is: 21.12
Requesting temperatures...DONE
Temperature for the device 1 (index 0) is: 21.12
Requesting temperatures...DONE
Temperature for the device 1 (index 0) is: 21.12

Get sensor info and temperature (by index)

ESP32 DO IT Dev Kit v1 and ds18b20: wiring
ESP32 DO IT Dev Kit v1 and ds18b20: wiring

First of all, we are going to retrieve the address, the connection information (parasite or not), and the temperature.

/**
 * Retrieve information about a single sensor
 * minor change by Renzo Mischianti <www.mischianti.org>
 *
 * www.mischianti.org
 */

// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 22 
#define ONE_WIRE_BUS 22

// 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);

// arrays to hold device address
DeviceAddress insideThermometer;

/*
 * Setup function. Here we do the basics
 */
void setup(void)
{
  // start serial port
  Serial.begin(112500);
  Serial.println("Dallas Temperature IC Control Library Demo");

  // locate devices on the bus
  Serial.print("Locating devices...");
  sensors.begin();
  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");

  // Assign address manually. The addresses below will beed to be changed
  // to valid device addresses on your bus. Device address can be retrieved
  // by using either oneWire.search(deviceAddress) or individually via
  // sensors.getAddress(deviceAddress, index)
  // Note that you will need to use your specific address here
  // insideThermometer = { 0x28, 0xFF, 0x64, 0x0E, 0x79, 0x69, 0x3A, 0x1A };
  // we can check if the address is correct and if It's all ok
  // if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");

  // Search for devices on the bus and assign based on an index. Ideally,
  // you would do this to initially discover addresses on the bus and then
  // use those addresses and manually assign them (see above) once you know
  // the devices on your bus (and assuming they don't change).
  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");

  // show the addresses we found on the bus
  Serial.print("Device 0 Address: ");
  printAddress(insideThermometer);
  Serial.println();

  Serial.print("Device 0 HEX Address: ");
  printHEXAddress(insideThermometer);
  Serial.println();

  // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
  sensors.setResolution(insideThermometer, 9);

  Serial.print("Device 0 Resolution: ");
  Serial.print(sensors.getResolution(insideThermometer), DEC);
  Serial.println();
}

/*
 * Main function. It will request the tempC from the sensors and display on Serial.
 */
void loop(void)
{
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");

  // It responds almost immediately. Let's print out the data
  printTemperature(insideThermometer); // Use a simple function to print out the data

  delay(4000);
}

// 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);
  }
}

void printHEXAddress(DeviceAddress deviceAddress)
{
    Serial.print("  { ");
    for (uint8_t i = 0; i < 8; i++)
    {
      Serial.print("0x");
      if (deviceAddress[i] < 0x10) Serial.print("0");
      Serial.print(deviceAddress[i], HEX);
      if (i < 7) Serial.print(", ");
    }
    Serial.println(" }");
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  // method 1 - slower
  //Serial.print("Temp C: ");
  //Serial.print(sensors.getTempC(deviceAddress));
  //Serial.print(" Temp F: ");
  //Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit

  // method 2 - faster
  float tempC = sensors.getTempC(deviceAddress);
  if(tempC == DEVICE_DISCONNECTED_C)
  {
    Serial.println("Error: Could not read temperature data");
    return;
  }
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
}

We receive this on the output of the serial.

Dallas Temperature IC Control Library Demo
Locating devices...Found 1 devices.
Parasite power is: OFF 
Device 0 Address: 28FF640E79693A1A
Device 0 HEX Address:   { 0x28, 0xFF, 0x64, 0x0E, 0x79, 0x69, 0x3A, 0x1A }

Device 0 Resolution: 9
Requesting temperatures...DONE
Temp C: 22.50 Temp F: 72.50
Requesting temperatures...DONE
Temp C: 22.50 Temp F: 72.50

As you can see, I set the OneWire pin to 22:

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 22

// 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);

Check how many sensor we retrieve in the line:

  // locate devices on the bus
  Serial.print("Locating devices...");
  sensors.begin();
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");

Check If we do a parasite connection:

  // report parasite power requirements
  Serial.print("Parasite power is: ");
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");

Put a in insideThermometer the address of sensor 0:

  // Search for devices on the bus and assign based on an index. Ideally,
  // you would do this to initially discover addresses on the bus and then
  // use those addresses and manually assign them (see above) once you know
  // the devices on your bus (and assuming they don't change).
  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");

Now we can read the temperature (in celsius):

  float tempC = sensors.getTempC(deviceAddress);

Then convert in Fahrenheit:

  Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit

You can do a read of Fahrenheit directly, but inside do the same operations:

  Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit

Thanks

  1. ESP32: pinout, specs and Arduino IDE configuration
  2. ESP32: integrated SPIFFS Filesystem
  3. ESP32: manage multiple Serial and logging
  4. ESP32 practical power saving
    1. ESP32 practical power saving: manage WiFi and CPU
    2. ESP32 practical power saving: modem and light sleep
    3. ESP32 practical power saving: deep sleep and hibernation
    4. ESP32 practical power saving: preserve data, timer and touch wake up
    5. ESP32 practical power saving: external and ULP wake up
    6. ESP32 practical power saving: UART and GPIO wake up
  5. ESP32: integrated LittleFS FileSystem
  6. ESP32: integrated FFat (Fat/exFAT) FileSystem
  7. ESP32-wroom-32
    1. ESP32-wroom-32: flash, pinout, specs and IDE configuration
  8. ESP32-CAM
    1. ESP32-CAM: pinout, specs and Arduino IDE configuration
    2. ESP32-CAM: upgrade CamerWebServer with flash features
  9. ESP32: use ethernet w5500 with plain (HTTP) and SSL (HTTPS)
  10. ESP32: use ethernet enc28j60 with plain (HTTP) and SSL (HTTPS)
  11. How to use SD card with esp32
  12. esp32 and esp8266: FAT filesystem on external SPI flash memory
  1. Firmware and OTA update management
    1. Firmware management
      1. ESP32: flash compiled firmware (.bin)
      2. ESP32: flash compiled firmware and filesystem (.bin) with GUI tools
    2. OTA update with Arduino IDE
      1. ESP32 OTA update with Arduino IDE: filesystem, firmware, and password
    3. OTA update with Web Browser
      1. ESP32 OTA update with Web Browser: firmware, filesystem, and authentication
      2. ESP32 OTA update with Web Browser: upload in HTTPS (SSL/TLS) with self-signed certificate
      3. ESP32 OTA update with Web Browser: custom web interface
    4. Self OTA uptate from HTTP server
      1. ESP32 self OTA update firmware from the server
      2. ESP32 self OTA update firmware from the server with version check
      3. ESP32 self-OTA update in HTTPS (SSL/TLS) with trusted self-signed certificate
    5. Non-standard Firmware update
      1. ESP32 firmware and filesystem update from SD card
      2. ESP32 firmware and filesystem update with FTP client
  1. Integrating LAN8720 with ESP32 for Ethernet Connectivity with plain (HTTP) and SSL (HTTPS)
  2. Connecting the EByte E70 to ESP32 c3/s3 devices and a simple sketch example
  3. ESP32-C3: pinout, specs and Arduino IDE configuration
  4. Integrating W5500 with ESP32 Using Core 3: Native Ethernet Protocol Support with SSL and Other Features
  5. Integrating LAN8720 with ESP32 Using Core 3: Native Ethernet Protocol Support with SSL and Other Features
  6. Dallas ds18b20:

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *