Two DS18B20 temperature sensors on one Arduino wire
Intermediate
Or see every lesson.
- 261parts on the bench
- 31boards running now
- 1.00xreal time, on every board
The DS18B20 is a small digital thermometer. It looks like a transistor, or comes sealed in a steel waterproof probe. It measures from -55 to 125 °C (-67 to 257 °F) and sends the answer as a number, so there is nothing to calibrate. Its best trick is the wire it uses. Every sensor has its own serial number, so many of them can share one data pin.
The circuit above has two DS18B20s on pin 2 of an Arduino Uno, with one 4.7k pull-up resistor for both. The sketch finds them by their serial numbers and prints each one’s temperature. Drag a sensor’s slider to warm it or cool it. It runs in your browser on the sketch below.
What you need
- An Arduino Uno
- One or more DS18B20 sensors (bare, or in a waterproof probe)
- One 4.7k ohm resistor for the whole bus
- A half-size breadboard and jumper wires
Wiring
| Part and pin | Goes to | Note |
|---|---|---|
| DS18B20 GND | GND | The left leg, with the flat face toward you |
| DS18B20 DQ | Pin 2 | The middle leg; every sensor shares this pin |
| DS18B20 VDD | 5 V | The right leg; 3.0 to 5.5 volts |
| 4.7k resistor | Between DQ and 5 V | One for the whole bus, not one per sensor |
The pull-up resistor is not optional
The data line is open drain. Each sensor can pull it LOW, but nothing pulls it HIGH unless you add a resistor. So a 4.7k resistor goes from the data line to 5 V. One resistor serves every sensor on the wire.
Leave it out and the sensors are never found. Try it: open the circuit in the editor, delete the resistor and press Run. The serial monitor prints "0 sensors on the wire". Put it back and both come back.
Some DS18B20s come on a small module board with three pins. Those usually have the resistor on the board already, so you do not add another one.
The sketch: find them once, then read each by name
The sketch uses two libraries, OneWire and DallasTemperature, the same ones a real Uno uses. In setup(), it counts the sensors and saves each one’s address. In loop(), requestTemperatures() tells every sensor to measure at the same time. Then it reads each one by its saved address.
The example prints with whole-number math to stay small on the Uno. In your own sketch, getTempCByIndex(0) is the simplest way to read a single sensor. It hands back a float in °C that you can print, and getTempFByIndex(0) does the same in °F.
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(2);
DallasTemperature sensors(&oneWire);
void setup() {
Serial.begin(9600);
sensors.begin();
}
void loop() {
sensors.requestTemperatures();
float c = sensors.getTempCByIndex(0);
if (c != DEVICE_DISCONNECTED_C) {
Serial.print(c);
Serial.print(" C ");
Serial.print(c * 1.8 + 32);
Serial.println(" F");
}
delay(1000);
}Waterproof probes
The steel probe version is the same sensor inside a tube, with three wires instead of three legs. The wires are usually red for VDD, black for GND and yellow or white for data, but sellers differ, so check the note that came with yours. It still needs the 4.7k pull-up.
Probes are great for a fish tank, soil, a fridge or a pot of water on the stove. The sensor is slow to follow a sudden change, because the steel has to warm up or cool down first.
Why a reading takes 750 ms
At its full 12-bit resolution, a DS18B20 needs up to 750 milliseconds to measure. requestTemperatures() waits that long. If you need faster readings, set a lower resolution. At 9 bits, a reading takes about 94 ms, but it is only good to half a degree instead of a sixteenth.
Try it in the editor
Drag the second sensor down to 0 °C and print a warning when it drops below 2 °C, the way a fridge alarm would.
Add a third DS18B20 from the parts bin. Wire its DQ to the same pin, and its power and ground to the rails. In the sketch, change found[2] to found[3] and the limit of 2 to 3, then run it again. The search finds the new sensor by its own serial number.
Common mistakes
Forgetting the 4.7k pull-up, so the sensor is never found.
Wiring it backwards. With the flat face toward you, the legs are GND, DQ, VDD from left to right. A real one wired backwards gets hot fast.
Reading 85 °C. That is the value the sensor holds at power-up, before it has measured anything. It means the sketch read without calling requestTemperatures() first.
Reading -127 °C. That is DEVICE_DISCONNECTED_C, the library’s way of saying the sensor did not answer. Check the wiring and the pull-up.
Questions
What resistor does a DS18B20 need?
A 4.7k ohm pull-up from the data line to VDD. One resistor serves every sensor on that wire.
How many DS18B20 sensors can I put on one pin?
Many. Each has its own 64-bit serial number, and the library’s search finds them one by one. On long wires with lots of sensors, a smaller pull-up can help on real hardware.
Why does my DS18B20 read 85 degrees?
That is its power-up value. The sketch read the sensor before it finished a measurement. Call requestTemperatures() before you read.
Is the DS18B20 in Mokxi exact?
It reports the slider’s temperature exactly, to its resolution. A real one can be off by up to half a degree. Parasite power, where a sensor runs off the data line alone, is not modeled.
Build this for real
Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.