DS18B20 Waterproof Temperature Sensor: Wiring, Code and the 4.7k Pull-Up

The DS18B20 is the easiest way to read a real temperature on an Arduino or ESP32: one data pin, a sealed stainless probe you can drop in water, and as many sensors as you like on the same wire. There is exactly one thing that catches people out, and it is a 4.7k resistor.

What the DS18B20 is

The DS18B20 is a digital temperature sensor from Dallas/Maxim. In the version most people buy, the chip is potted inside a 304 stainless steel probe on a length of cable, which makes it IP67 waterproof and safe to put in a fish tank, a fermenter, a hot water cylinder or a bucket of soil.

Because it is digital, there is no analogue voltage to convert and no calibration to do. You ask it for a temperature and it hands back a number in degrees Celsius. It speaks a protocol called 1-Wire, which needs a single GPIO pin no matter how many sensors you connect, because every DS18B20 has a unique 64-bit address burned in at the factory.

  • -55 to +125Degrees C range
  • ±0.5°CAccuracy, -10 to 85
  • 1 pinFor any number
  • 3.0-5.5VSupply

What you need

The 4.7k pull-up, and why nothing works without it

1-Wire is an open-drain bus. The sensor can only pull the data line low; it has no way to drive it high again. Something has to do that for it, and that something is a resistor between the data wire and the supply. Without it the line never returns high, the microcontroller never sees a valid response, and you get one of two numbers instead of a temperature:

You see What it means
85.00 The sensor's power-on default value. It powered up but never completed a conversion, so you are reading the factory register.
-127.00 No communication at all. The library could not find a device on the bus.

Both usually mean the same thing: no pull-up, or the pull-up is on the wrong pin. Fit a 4.7kΩ resistor between the yellow data wire and the red supply wire and both numbers turn into a real temperature.

If you would rather not fiddle with a loose resistor, the DS18B20 adapter module is a small breakout with the 4.7k already fitted and screw terminals for the probe wires. It turns this whole section into a non-issue.

Wiring it up

The probe has three wires. They are the same on the 1m, 3m and 5m versions.

Wire Goes to
Red VCC (3.3V or 5V)
Black GND
Yellow Data (any GPIO)
  1. Red to 5V on an Arduino Uno, or 3.3V on an ESP32. Do not feed 5V into an ESP32 pin.
  2. Black to GND.
  3. Yellow to a data pin. Pin 2 on an Arduino Uno, or GPIO4 on an ESP32 are good defaults.
  4. Fit the 4.7kΩ resistor between the yellow wire and the red wire. On a breadboard, that is one leg in the data row and one leg in the supply row.

On an ESP32, pull up to 3.3V, not 5V. The pull-up sets the voltage the data line rises to, so a 5V pull-up puts 5V on a 3.3V pin. Also avoid the strapping pins (GPIO0, 2, 12 and 15 on a WROOM-32) for the data line, since a sensor holding them at boot can stop the board starting.

The code

Two libraries do the work. In the Arduino IDE, open Tools → Manage Libraries and install OneWire by Paul Stoffregen and DallasTemperature by Miles Burton. Then upload this:

#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2      // yellow wire. Use 4 on an ESP32.

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(9600);
  sensors.begin();
}

void loop() {
  sensors.requestTemperatures();
  float tempC = sensors.getTempCByIndex(0);

  if (tempC == DEVICE_DISCONNECTED_C) {
    Serial.println("No probe found. Check the wiring and the 4.7k pull-up.");
  } else {
    Serial.print(tempC);
    Serial.println(" C");
  }

  delay(1000);
}

Open the Serial Monitor at 9600 baud and you should see the room temperature once a second. Hold the probe in your hand and watch it climb.

On an ESP32 with native USB (the C3, C6, H2, S2 and S3 boards), set Tools → USB CDC On Boot → Enabled before uploading or the Serial Monitor stays blank.

Several probes on one pin

This is the DS18B20's best trick. Wire every probe's red to red, black to black and yellow to yellow, use a single 4.7k pull-up for the whole bus, and read them by index:

#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(9600);
  sensors.begin();
  Serial.print(sensors.getDeviceCount());
  Serial.println(" probes found");
}

void loop() {
  sensors.requestTemperatures();

  for (int i = 0; i < sensors.getDeviceCount(); i++) {
    Serial.print("Probe ");
    Serial.print(i);
    Serial.print(": ");
    Serial.print(sensors.getTempCByIndex(i));
    Serial.println(" C");
  }

  delay(2000);
}

The catch with index numbers is that they follow bus order, not the order you plugged them in, and they can shift if you add a probe later. For anything permanent, read each sensor's unique address once with sensors.getAddress(), write those addresses into your sketch, and call getTempC(address) instead. Then "the probe in the tank" stays the probe in the tank.

Raspberry Pi

No library needed. Enable 1-Wire in raspi-config, or add dtoverlay=w1-gpio to /boot/config.txt and reboot. Wire the yellow data line to GPIO4 (physical pin 7), red to 3.3V, black to GND, with the same 4.7k pull-up. Each probe then appears as a folder under /sys/bus/w1/devices/ starting with 28-, and cat on the w1_slave file inside gives you the reading in thousandths of a degree.

Troubleshooting

Symptom Fix
Reads 85.00 Missing or wrong pull-up, or the supply is not connected properly. Check the 4.7k sits between data and VCC.
Reads -127.00 No device on the bus. Check the data wire is on the pin your sketch names, and that GND is shared.
Readings jump around on a long cable Use twisted pair or Cat5 with data and ground as one pair, and try dropping the pull-up to 3.3k or 2.2k. Keep the run away from mains cable and motor leads.
Only some probes appear Usually a marginal bus. Shorten the run, drop the pull-up value, or split long chains onto separate pins.
Nothing on the Serial Monitor Check the baud rate is 9600. On a native-USB ESP32, enable USB CDC On Boot.
Board will not boot with the probe attached The data wire is on a strapping pin. Move it to GPIO4 on an ESP32.

You may also see parasite power mentioned, where the sensor runs from the data line and only two wires are used. It works, but it is fussy about timing and pull-up strength. With a three-wire probe in your hand there is no reason to bother.

Which cable length?

All three are the same sensor. Only the cable differs, so pick the run between the probe and your controller.

Length Best for
1m Benchtop work, small tanks, fermenters, anything within reach of the board
3m Most fixed installs, where the controller is on a wall nearby
5m Controller across the room, outside, or in a different cabinet

The probe itself is IP67 and handles full submersion. For a permanent install, try to keep the point where the cable leaves the water above the waterline.

Wiring this on a breadboard for the first time? Breadboard Basics covers how the rows and rails connect. Not sure which board to pair it with? See Which ESP32 board should you buy.

Get the probe

Sealed stainless DS18B20 in 1m, 3m or 5m, shipped from New Zealand. Add the adapter module and the pull-up is already sorted.

Shop the DS18B20 probe

Practical help from New Zealand

Still stuck? Send us a photo.

Tell us what you’re building and what the circuit is doing. Our small NZ team knows these parts and can help you spot a wiring problem or choose what you need next.

Ask NZN for help Browse more guides