Dallas ds18b20 with esp32 and esp8266: all OneWire topologies, long stubs and more devices

Spread the love

The Dallas DS18B20 temperature sensor is a versatile and widely used device for measuring temperature in various applications. When combined with the powerful ESP32 microcontroller or esp8266, connecting multiple DS18B20 sensors in a single circuit and even over long distances becomes possible.

Dallas ds18b20 with esp32: all OneWire topologies, long stubs, and multiple devices
Dallas ds18b20 with esp32: all OneWire topologies, long stubs, and multiple devices

This article will explore how to use the OneWire protocol to communicate with multiple Dallas DS18B20 temperature sensors and how to interface them with an ESP32 or esp8266 board. We will also cover how to deal with issues that may arise when working with long OneWire lines and multiple devices.

Whether you are a hobbyist, engineer, or DIY enthusiast, this article will provide a comprehensive guide to getting started with the Dallas DS18B20 and ESP32 and esp8266.

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

OneWire Network: Introduction

When you create a network, you must pay attention to the current-sense amplifiers (CSAs), which are used to measure the current flowing through a circuit. CSAs have benefits in various applications, including power management, motor control, and battery monitoring. There are different types of CSAs, including high-side and low-side amplifiers, and the various architectures used in their design.

We aren’t going into dept into the key specifications and performance parameters of CSAs, such as input offset voltage, bandwidth, and common-mode rejection ratio (CMRR). But we are going to describe different types of current-sensing resistors and how to select the right one for a particular application.

We move on to discuss practical considerations for using CSAs, including layout and grounding techniques, noise reduction, and temperature compensation. We show different application circuits for CSAs, such as simple voltage-to-current conversion, differential voltage sensing, and shunt-based current sensing.

OneWire network performance factors

The two critical measurements in 1-Wire network performance: are radius and weight. The radius of a 1-Wire network is the wire distance between the master and the farthest slave and is measured in meters. The weight of a 1-Wire network is the total length of wire in the network, also measured in meters.

For example, a 1-Wire network with a star configuration that has three branches of 10m, 20m, and 30m would have a radius of 30m (the distance from the master to the furthest slave) and a weight of 60m (the total length of wire in the network, which is 10m + 20m + 30m).

In general, the weight of the network limits the rise time on the cable, while the radius determines the timing of the slowest signal reflections. This information is essential for designing and troubleshooting 1-Wire networks to ensure that they operate efficiently and reliably.

OneWire Network Topologies

Although OneWire networks are often reasonably “free form” in structure, they usually fit into a few generalized categories based on the distribution of the 1-Wire slaves and the organization of the interconnecting wires.

Linear topology

OneWire networks: linear topology
OneWire networks: linear topology

The 1-Wire bus is a single pair, starting from the master and extending to the farthest slave device. Other slaves are attached to the 1-Wire bus with insignificant (< 3m) branches or “stubs.”

Stubbed topology

OneWire networks: stubbed topology
OneWire networks: stubbed topology

The 1-Wire bus is a single main line, starting at the master and extending to the farthest slave. Other slaves are attached to the main line through branches or stubs 3m or more in length.

Star topology

OneWire networks: star topology
OneWire networks: star topology

The 1-Wire bus is split at or near the master end and extends in multiple branches of varying lengths. There are slave devices along or at the ends of the branches.

Testing has shown that unswitched star-type network topologies (i.e., those with several branches diverging at the master) are the most difficult to make reliable. The junction of various branches presents highly mismatched impedances; reflections from the end of one branch can travel distances equal to nearly the weight of the network (rather than the radius) and cause data errors. For this reason, the unswitched star topology is not recommended, and no guarantees can be made about its performance.

When different topologies are intermixed, it becomes much more challenging to determine the practical limitations of the network. As a rule, the designer should apply the most conservative of the criteria in these cases.

Switched Networks

To allow networks to grow in complexity without growing in weight and radius, the network is divided into sections that are electronically switched on one at a time.

Using low-impedance, single-supply analog switches, the network can physically resemble one topology but electrically resemble another. This means that a star configuration with a switch on each branch would actually resemble a linear topology.

OneWire networks: switched
OneWire networks: switched

In this case, only one branch is active at any time. The example above appears like a star topology network with a radius of 150m and a weight of 450m. However, when each switched path is considered individually, the network is actually a linear topology, and the weight is only 150m. As a rule, our discussion of non-switched networks can be applied to each segment of a switched network.

OneWire network limitations

The maximum radius and weight of a OneWire network which is determined by several factors. Some of these factors can be controlled, while others cannot. The master-end interface plays a crucial role in determining the allowable size of a OneWire network. It must provide sufficient drive current to overcome the weight of the cable and slaves, generate OneWire waveforms with timings that are within specification and optimized for the charge and discharge times of the network, and provide a suitable impedance match to the network.

The radius of a 1-Wire network is limited by several factors, including the timing of waveform reflections, the time delay produced by the cable, the resistance of the cable, and the degradation of signal levels. The weight of the network is limited by the cable’s ability to be charged and discharged quickly enough to satisfy the 1-Wire protocol.

A simple resistor pullup has a weight limitation of about 200m. In comparison, the weight limit can be extended to over 500m by using sophisticated 1-Wire master designs with active pull-ups that provide higher currents under logic control.

The radius is limited by factors such as timing and cable resistance, while the weight is limited by the cable’s ability to be charged and discharged quickly enough. Active pull-ups can extend the weight limit of a 1-Wire network beyond the limitations of simple resistor pullups.

esp8266 wemos d1 multiple ds18b20 temperature sensors
esp8266 wemos d1 multiple ds18b20 temperature sensors

Parasite mode issues

The 1-Wire communication protocol not only facilitates communication but also provides operating power for the slaves. The slaves draw power from the bus when the voltage on the bus is greater than the voltage on their internal energy storage capacitor.

However, in networks with too many slaves, the current delivered by the master may not be sufficient to maintain operating voltage in the slaves, causing intermittent failures that are data-dependent.

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

The worst-case scenario for parasite power is a long sequence of zero bits issued by the master, as the bus spends most of its time in the low state, and there is little opportunity to recharge the slaves.

As the voltage in each slave drops, the slave’s ability to drive the bus decreases, eventually leading to a reset state where the slave stops responding.

When the slave receives sufficient operating voltage again, it will issue a presence pulse, which can corrupt other bus activity.

A possible solution is shown in the image above. In particular, it is used for ds18b20 temperature sensors.

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.

Distribute impedance matching

The OneWire bus design is simple and low-cost, and additional components have typically been avoided.

However, when a stub is connected to the bus, there is an impedance mismatch at the branch point, which can cause reflections that interfere with other slaves on the network.

To mitigate this issue, a resistor in series with the stub can reduce the severity of the mismatch and the amplitude of the reflected energy.

OneWire networks: distribuited impedance matching
OneWire networks: distributed impedance matching

The most successful implementation of this concept uses 150½ resistors at each point where a stub is connected to the main trunk (consider 5v logic level). This reduces the mismatch at the connection point by about 20% and attenuates the resulting reflections by about 40%. However, caution is necessary as the added resistance can degrade noise immunity by about 80%.

Alternatively, 100½ resistor values have shown good performance and do not degrade noise immunity as much.

Pull-up resistor choice to fix troubleshooting

After some search in the network, I found some interesting solutions to improve the distance in a network with 3.3v logic.

In a medium distance network with DS18B20, worked on short cable, failed on 5M CAT3 cable. to resolve the problem, someone added an 80-ohm (a semi-randomly picked low value) resistor in series with the data line at both ends of the cable, which lowered the slew rate and fixed the problem for me.

With an unshielded CAT5 cable of about 40m and 7 sensors DS18B20. GROUND is connected to 2 wires from different twisted pairs. The last wires from these twisted pairs are used for DATA and power. Between GPIO4 and 3.3v, there is a 2.2k pullup resistor. The maker corrects data from the last 2 sensors on the wire, while one sensor in the middle always shows 85000. For me, it started to work when I changed the pullup resistor from 4,7k to 2.2k.

Wiring

The One-Wire library Is a standard for all microcontrollers, so the device can be used with many microcontrollers. We already show the connection of the single sensor, now we are going to connect and manage multiple sensors.

If you need to connect only one sensor, refer to the previous article, “Dallas ds18b20 with esp32 and esp8266: introduction and parasite mode”.

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

Normal mode multiple devices

Now the connection schema with a linear topology of 5 ds18b20

esp32: multiple ds18b20 in linear topology
esp32: multiple ds18b20 in linear topology

Or in star topology

esp32: multiple ds18b20 in star topology
esp32: multiple ds18b20 in star topology

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

Parasite mode multiple devices

Here the same thing in linear topology.

esp32: multiple parasite ds18b20 in linear topology
esp32: multiple parasite ds18b20 in linear topology

and in start topology.

esp32: multiple parasite ds18b20 in star topology
esp32: multiple parasite ds18b20 in star topology

esp8266

Normal mode

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

Normal mode multiple sensors

esp8266 and ds18b20: multiple sensors on linear topology
esp8266 and ds18b20: multiple sensors on linear topology

Parasite mode

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

Parasite mode multiple sensors

esp8266 and ds18b20: multiple sensors in parasite on linear topology
esp8266 and ds18b20: multiple sensors in parasite on linear topology

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.

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.

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

When you operate with multiple devices, It’s essential to identify them univocally. We must remember that the ds18b20 has an internal address that can be used as uuid.

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

Search all sensors connected to the network

Here is a simple example that searches all OneWire devices connected to an interval of pins and generate a list of address that can be used to manage the ds18b20.

/**
 * OneWire Library example
 * Find all device (select starting end ending pin)
 *
 * Renzo Mischianti <www.mischianti.org>
 */

#define STARTING_PIN 22
#define ENDING_PIN 22

uint8_t findDevices(int pin);

#include <OneWire.h>

void setup()
{
  Serial.begin(115200);
  Serial.println("//\n// Start oneWire search \n//");

  for (uint8_t pin = STARTING_PIN; pin <= ENDING_PIN; pin++)
  {
    findDevices(pin);
  }
  Serial.println("\n//\n// End oneWire search \n//");
}

void loop()
{
}

uint8_t findDevices(int pin)
{
  OneWire ow(pin);

  uint8_t address[8];
  uint8_t count = 0;


  if (ow.search(address))
  {
    Serial.print("\nDeviceAddress pin");
    Serial.print(pin, DEC);
    Serial.println("[] = {");
    do {
      count++;
      Serial.print(" {");
      for (uint8_t i = 0; i < 8; i++)
      {
        Serial.print("0x");
        if (address[i] < 0x10) Serial.print("0");
        Serial.print(address[i], HEX);
        if (i < 7) Serial.print(", ");
      }
      Serial.println("  },");
    } while (ow.search(address));

    Serial.println("};");
    Serial.print("// nr devices found: ");
    Serial.println(count);
  }

  return count;
}

In my case, the Serial output is:

//
// Start oneWire search 
//

DeviceAddress pin22[] = {
 {0x28, 0xFF, 0x64, 0x0E, 0x6C, 0x63, 0xD0, 0x15  },
 {0x28, 0xFF, 0x64, 0x0E, 0x6C, 0x6F, 0x7A, 0x89  },
 {0x28, 0xFF, 0x64, 0x0E, 0x6D, 0x64, 0x7F, 0x3E  },
 {0x28, 0xFF, 0x64, 0x0E, 0x6D, 0x5C, 0x1A, 0x3F  },
 {0x28, 0xFF, 0x64, 0x0E, 0x6D, 0x5D, 0x66, 0xA0  },
};
// nr devices found: 5

//
// End oneWire search 
//

It correctly found 5 ds18b20 and generated the array of addresses.

For esp8266, the result becomes:

// Start oneWire search 
//

DeviceAddress pin4[] = {
 {0x28, 0xFF, 0x64, 0x0E, 0x6C, 0x63, 0xD0, 0x15  },
 {0x28, 0xFF, 0x64, 0x0E, 0x6C, 0x6F, 0x7A, 0x89  },
 {0x28, 0xFF, 0x64, 0x0E, 0x6D, 0x64, 0x7F, 0x3E  },
 {0x28, 0xFF, 0x64, 0x0E, 0x6D, 0x5C, 0x1A, 0x3F  },
 {0x28, 0xFF, 0x64, 0x0E, 0x6D, 0x5D, 0x66, 0xA0  },
};
// nr devices found: 5

//
// End oneWire search 
//

Get info and temperature from an array of address

esp32 wemos lolin32 multiple ds18b20 temperature sensors
esp32 wemos lolin32 multiple ds18b20 temperature sensors

With the array of the previous sketch, we are going to do a sketch to read the temperature.

/**
 * From a list of thermostat address
 * generated with the previous search sketch
 * we are going to  get the
 * temperature of every device
 *
 * by Renzo Mischianti <www.mischianti.org>
 *
 * https://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
#define TEMPERATURE_PRECISION 9

// 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 array generated from the search sketch
DeviceAddress pin22[] = {
 {0x28, 0xFF, 0x64, 0x0E, 0x6C, 0x63, 0xD0, 0x15  },
 {0x28, 0xFF, 0x64, 0x0E, 0x6C, 0x6F, 0x7A, 0x89  },
 {0x28, 0xFF, 0x64, 0x0E, 0x6D, 0x64, 0x7F, 0x3E  },
 {0x28, 0xFF, 0x64, 0x0E, 0x6D, 0x5C, 0x1A, 0x3F  },
 {0x28, 0xFF, 0x64, 0x0E, 0x6D, 0x5D, 0x66, 0xA0  },
};

void setup(void)
{
  // start serial port
  Serial.begin(115200);
  Serial.println("Dallas Temperature IC Control ");

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

  // set the temperature accurancy
  for (int i = 0; i < 5; i++) {
	  // set the resolution to 9 bit per device
	   sensors.setResolution(pin22[i], TEMPERATURE_PRECISION);
  }
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  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.print(DallasTemperature::toFahrenheit(tempC));
}

/*
   Main function, calls the temperatures in a loop.
*/
void loop(void)
{
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");

  for (int i = 0; i < 5; i++) {
	  // print the device information
	  Serial.print("Device Address: ");
	  printAddress(pin22[i]);
	  Serial.print(" of ");
	  Serial.print(i);
	  Serial.print(" sensor -> ");
	  printTemperature(pin22[i]);
	  Serial.println();
  }

  delay(2000);
}

The result in the Serial output:

Dallas Temperature IC Control 
Locating devices...Found 5 devices.
Parasite power is: OFF
Requesting temperatures...DONE
Device Address: 28FF640E6C63D015 of 0 sensor -> Temp C: 21.12 Temp F: 70.03
Device Address: 28FF640E6C6F7A89 of 1 sensor -> Temp C: 21.37 Temp F: 70.47
Device Address: 28FF640E6D647F3E of 2 sensor -> Temp C: 21.25 Temp F: 70.25
Device Address: 28FF640E6D5C1A3F of 3 sensor -> Temp C: 21.25 Temp F: 70.25
Device Address: 28FF640E6D5D66A0 of 4 sensor -> Temp C: 21.19 Temp F: 70.14
Requesting temperatures...DONE
Device Address: 28FF640E6C63D015 of 0 sensor -> Temp C: 21.19 Temp F: 70.14
Device Address: 28FF640E6C6F7A89 of 1 sensor -> Temp C: 21.37 Temp F: 70.47
Device Address: 28FF640E6D647F3E of 2 sensor -> Temp C: 21.25 Temp F: 70.25
Device Address: 28FF640E6D5C1A3F of 3 sensor -> Temp C: 21.25 Temp F: 70.25
Device Address: 28FF640E6D5D66A0 of 4 sensor -> Temp C: 21.19 Temp F: 70.14

Indexing the sensors and getting the temperature

A not very real solution is to index the sensors and get the temperature. This solution is not very useful because you can’t know which sensor becomes 0, 1.. and so on.

For simplicity, I reduce the sensors in line to 4.

/**
 * Indexing thermometer and read the temperature
 *
 * by Renzo Mischianti <www.mischianti.org>
 *
 * https://mischianti.org
 */
#include <OneWire.h>
#include <DallasTemperature.h>

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

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

DeviceAddress firstThermometer, secondThermometer, thirdThermometer, fourthThermometer;

void setup(void)
{
  // start serial port
  Serial.begin(115200);
  Serial.println("Dallas Temperature IC Control Library Demo");

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

  // assigns the first address found to insideThermometer
  if (!oneWire.search(firstThermometer)) Serial.println("Unable to find 1 address for insideThermometer");
  // assigns the second address found to insideThermometer
  if (!oneWire.search(secondThermometer)) Serial.println("Unable to find 2 address for insideThermometer");
  // assigns the third address found to insideThermometer
  if (!oneWire.search(thirdThermometer)) Serial.println("Unable to find 3 address for insideThermometer");
  // assigns the fourth address found to insideThermometer
  if (!oneWire.search(fourthThermometer)) Serial.println("Unable to find 4 address for insideThermometer");

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

  Serial.print("Device 1 Address: ");
  printAddress(secondThermometer);
  Serial.println();

  Serial.print("Device 2 Address: ");
  printAddress(thirdThermometer);
  Serial.println();

  Serial.print("Device 3 Address: ");
  printAddress(fourthThermometer);
  Serial.println();

  // set the resolution to 9 bit per device
  sensors.setResolution(firstThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(secondThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(thirdThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(fourthThermometer, TEMPERATURE_PRECISION);

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

  Serial.print("Device 1 Resolution: ");
  Serial.print(sensors.getResolution(secondThermometer), DEC);
  Serial.println();

  Serial.print("Device 2 Resolution: ");
  Serial.print(sensors.getResolution(thirdThermometer), DEC);
  Serial.println();

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

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  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.print(DallasTemperature::toFahrenheit(tempC));
}

// function to print a device's resolution
void printResolution(DeviceAddress deviceAddress)
{
  Serial.print("Resolution: ");
  Serial.print(sensors.getResolution(deviceAddress));
  Serial.println();
}

// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(" ");
  printTemperature(deviceAddress);
  Serial.println();
}

/*
   Main function, calls the temperatures in a loop.
*/
void loop(void)
{
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");

  // print the device information
  printData(firstThermometer);
  printData(secondThermometer);
  printData(thirdThermometer);
  printData(fourthThermometer);

  delay(2000);
}

Every time you do a search, a new index is generated and assigned, and the search returns 1 when no other sensors are found It returns 0.

  // assigns the first address found to insideThermometer
  if (!oneWire.search(firstThermometer)) Serial.println("Unable to find 1 address for insideThermometer");
  // assigns the second address found to insideThermometer
  if (!oneWire.search(secondThermometer)) Serial.println("Unable to find 2 address for insideThermometer");
  // assigns the third address found to insideThermometer
  if (!oneWire.search(thirdThermometer)) Serial.println("Unable to find 3 address for insideThermometer");
  // assigns the fourth address found to insideThermometer
  if (!oneWire.search(fourthThermometer)) Serial.println("Unable to find 4 address for insideThermometer");
  // assigns the fifth address found to insideThermometer
  if (!oneWire.search(fifthThermometer)) Serial.println("Unable to find 5 address for insideThermometer");
  // assigns the sixth address found to insideThermometer
  if (!oneWire.search(sixthThermometer)) Serial.println("Unable to find 6 address for insideThermometer");

So the relevant and newest part of Serial output is highlighted.

Dallas Temperature IC Control Library Demo
Locating devices...Found 4 devices.
Parasite power is: OFF
Unable to find 5 address for thermometer
Device 0 Address: 28FF640E6C6F7A89
Device 1 Address: 28FF640E6D647F3E
Device 2 Address: 28FF640E6D5C1A3F
Device 3 Address: 28FF640E6D5D66A0
Device 0 Resolution: 12
Device 1 Resolution: 12
Device 2 Resolution: 12
Device 3 Resolution: 12
Requesting temperatures...DONE
Device Address: 28FF640E6C6F7A89 Temp C: 21.31 Temp F: 70.36
Device Address: 28FF640E6D647F3E Temp C: 21.19 Temp F: 70.14
Device Address: 28FF640E6D5C1A3F Temp C: 21.31 Temp F: 70.36
Device Address: 28FF640E6D5D66A0 Temp C: 21.19 Temp F: 70.14
Requesting temperatures...DONE
Device Address: 28FF640E6C6F7A89 Temp C: 21.31 Temp F: 70.36
Device Address: 28FF640E6D647F3E Temp C: 21.19 Temp F: 70.14
Device Address: 28FF640E6D5C1A3F Temp C: 21.25 Temp F: 70.25
Device Address: 28FF640E6D5D66A0 Temp C: 21.19 Temp F: 70.14

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 *