The Arduino temp sensor DS18B20 is the industry standard for digital temperature measurement in embedded DIY projects. Unlike analog thermistors that require complex Steinhart-Hart equation math and suffer from voltage reference drift, the DS18B20 outputs a fully calibrated digital value over Maxim’s 1-Wire protocol. You get 9-bit to 12-bit resolution, a unique 64-bit serial ROM embedded in every single chip, and the ability to daisy-chain dozens of sensors on a single microcontroller GPIO pin.
However, the 1-Wire protocol is notoriously unforgiving regarding timing and pull-up resistor values. If your pull-up is too weak, or if you misunderstand the sensor's Power-On Reset (POR) state, your serial monitor will spit out garbage data or lock up entirely. This guide provides the exact wiring topologies, production-ready C++ code with error handling, and a decision-tree for debugging the most common 1-Wire bus failures.
DS18B20 Specifications and Operating Modes
Before wiring the sensor, you must understand its timing constraints and power delivery options. The DS18B20 does not stream data continuously; it requires a specific conversion command, followed by a mandatory wait period that scales with your chosen resolution.
Sensor Specification Sheet
| Parameter | Value | Engineering Notes |
|---|---|---|
| Operating Voltage | 3.0V to 5.5V | Can be powered directly from ESP32 (3.3V) or Arduino (5V) VCC pins. |
| Temperature Range | -55°C to +125°C | Accuracy is ±0.5°C only between -10°C and +85°C. Degrades to ±2°C at extremes. |
| Conversion Time (9-bit) | 93.75 ms | 0.5°C resolution. Fastest mode, ideal for rapid environmental logging. |
| Conversion Time (12-bit) | 750.0 ms | 0.0625°C resolution. Default POR state. Mandatory wait time before reading. |
| Standby Current | 1.0 µA (max) | Negligible battery drain during idle states. |
| Active Current | 1.5 mA (typ) | Spikes during the analog-to-digital conversion phase. |
External Power vs. Parasitic Power Mode
The DS18B20 can be wired in two distinct topologies. Your wiring choice dictates how you must initialize the DallasTemperature library in your code.
| Feature | External Power Mode (3-Wire) | Parasitic Power Mode (2-Wire) |
|---|---|---|
| Wiring | VDD to 5V/3.3V, GND to GND, Data to GPIO | VDD tied to GND, GND to GND, Data to GPIO |
| Power Delivery | Dedicated power rail | Harvests power from the data line via internal capacitor |
| Pull-up Resistor | 4.7kΩ standard | 4.7kΩ standard, plus a "strong pull-up" MOSFET for conversions |
| Reliability | Highly reliable over long cable runs | Prone to brownouts during 12-bit conversions on long cables |
| Best Use Case | Breadboards, standard indoor projects | Sealed waterproof probes where only 2 wires can pass through a gland |
Parts List and Pin Mapping
This build targets the Arduino Uno R3 (ATmega328P) operating at 5V logic. If you are migrating to an ESP32 later in this guide, you will need a logic level shifter or a dedicated 3.3V pull-up to avoid damaging the ESP32's GPIO pins.
Bill of Materials (BOM)
- Microcontroller: Arduino Uno R3 (or compatible ATmega328P clone)
- Sensor: Waterproof DS18B20 Probe (Stainless steel tube, PVC jacketed cable). Note: The MAX31820 is the modern, drop-in replacement from Analog Devices and works identically.
- Resistor: 4.7kΩ (1/4W, 5% tolerance) pull-up resistor
- Hardware: Half-size breadboard, male-to-male jumper wires
- Estimated Cost: $12 - $18 (excluding the microcontroller)
Pin Mapping Table (External Power Mode)
Waterproof probes typically use a three-wire color code. Always verify with a multimeter if your probe uses non-standard colors.
| Probe Wire Color | DS18B20 Pin Name | Arduino Uno R3 Connection | Notes |
|---|---|---|---|
| Red | VDD (Pin 3) | 5V Pin | Provides dedicated power to the internal ADC. |
| Black | GND (Pin 1) | GND Pin | Common ground reference. |
| Yellow (or White) | DQ (Pin 2) | Digital Pin 2 | 1-Wire data line. Requires 4.7kΩ pull-up to 5V. |
Step-by-Step Wiring and Compilable Code
Physical Wiring Steps
- Insert the 4.7kΩ resistor into the breadboard, bridging the 5V rail and the row designated for Digital Pin 2.
- Connect the sensor's Red wire to the 5V rail.
- Connect the sensor's Black wire to the GND rail.
- Connect the sensor's Yellow (Data) wire to the same row as one leg of the 4.7kΩ resistor, and run a jumper from that row to the Arduino's Digital Pin 2.
- Double-check that the resistor is acting as a bridge between 5V and the Data line. Without this, the 1-Wire bus will float and fail.
Production-Ready C++ Code
This code requires the OneWire and DallasTemperature libraries (installable via the Arduino Library Manager). It includes robust error handling for the two most common DS18B20 failure states: the disconnected state (-127°C) and the Power-On Reset state (85°C).
#include <OneWire.h>
#include <DallasTemperature.h>
// Target Board: Arduino Uno R3 (ATmega328P)
// Hardware setup: External Power Mode (3-wire)
#define ONE_WIRE_BUS 2
#define SENSOR_RESOLUTION 12
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
void setup() {
Serial.begin(115200);
while (!Serial); // Wait for serial monitor (native USB boards)
Serial.println("Initializing DS18B20 1-Wire Bus...");
sensors.begin();
// Set resolution to 12-bit (default is 12, but explicit is better)
// Note: 12-bit requires a 750ms conversion delay
sensors.setResolution(SENSOR_RESOLUTION);
// Disable blocking delays if you want to do other tasks during conversion
// sensors.setWaitForConversion(false);
}
void loop() {
// Command all sensors on the bus to perform a temperature conversion
sensors.requestTemperatures();
// Read the first sensor found on the bus (Index 0)
float tempC = sensors.getTempCByIndex(0);
// ERROR HANDLING: Check for physical disconnection
if (tempC == DEVICE_DISCONNECTED_C) { // Evaluates to -127.0
Serial.println("ERROR: Sensor disconnected or bus shorted (-127.00 C).");
}
// ERROR HANDLING: Check for Power-On Reset (POR) artifact
else if (tempC == 85.0) {
Serial.println("ERROR: Read POR default (85.00 C). Conversion failed or brownout occurred.");
}
// Valid reading
else {
Serial.print("Temperature: ");
Serial.print(tempC, 2);
Serial.println(" °C");
}
delay(1000); // 1 second polling interval
}
Debugging: Exact Error Strings and Failure Modes
When a 1-Wire bus fails, it rarely fails silently. The DallasTemperature library returns specific sentinel values, and the OneWire library outputs distinct console strings during ROM searches. Here is how to diagnose them.
- Measure the Pull-Up Resistor: Use a multimeter in continuity/resistance mode (power off) to verify exactly 4.7kΩ (±5%) between the Data pin and VCC. A missing or blown pull-up is the cause of 80% of 1-Wire failures.
- Verify VDD Wiring (External vs Parasitic): If you are using Parasitic mode but left the VDD pin floating, the sensor will brownout during the 12-bit conversion. Ensure VDD is tied to GND for parasitic, or tied to 5V for external.
- Check Pin Definitions vs Physical Wiring: Confirm that
#define ONE_WIRE_BUS 2in your code matches the physical wire plugged into Digital Pin 2, not Analog Pin 2 (which is A2 / D16 on the Uno).
Symptom 1: Serial Monitor prints "No more addresses." or "Device not found"
This occurs during the sensors.begin() ROM search phase. The microcontroller sends a search command, but no sensor pulls the bus low to acknowledge.
- Cause 1 (Most Likely): Missing or incorrect pull-up resistor. The data line is floating high, so the sensor's open-drain transistor cannot register a logic LOW.
- Cause 2: Broken data wire inside the waterproof probe's PVC jacket. Perform a continuity test from the probe tip to the bare wire ends.
- Cause 3: Counterfeit sensor with a corrupted ROM table. The OneWire CRC check fails silently in some library versions, dropping the device from the bus.
Symptom 2: Constant "85.00 °C" Readings
85°C is not a random error; it is the hardcoded Power-On Reset (POR) value stored in the DS18B20's scratchpad register upon boot. If you read 85°C, it means you are reading the scratchpad before the sensor has successfully completed an analog-to-digital conversion.
- Cause 1 (Most Likely): Parasitic power brownout. During a 12-bit conversion, the sensor draws up to 1.5mA. In parasitic mode, the 4.7kΩ pull-up resistor limits current too severely (I = V/R = 5V/4700Ω = ~1mA), causing the internal voltage to sag and the conversion to abort. Fix: Switch to external power mode, or implement a strong pull-up MOSFET circuit.
- Cause 2: Code timing error. You called
getTempCByIndex()immediately afterrequestTemperatures()without allowing the 750ms conversion time to elapse (ifsetWaitForConversion(false)is used).
Symptom 3: Constant "-127.00 °C" (DEVICE_DISCONNECTED_C)
The library explicitly returns -127°C when the OneWire bus returns a CRC mismatch or all bits read high (disconnected).
- Cause 1: The sensor is physically unplugged or the data wire is severed.
- Cause 2: Severe electrical noise (EMI) on the data line. If your probe cable runs parallel to AC mains or high-current DC motor lines, the noise will corrupt the 1-Wire timing pulses. Fix: Use shielded twisted-pair cable for the probe extension and tie the shield to GND at the microcontroller end only.
Extending the Build: Multi-Drop Buses and ESP32 Migration
Scaling Up: The 1-Wire Multi-Drop Bus
The true power of the DS18B20 is the multi-drop bus. Because every chip is laser-trimmed with a unique 64-bit ROM serial number, you can wire up to 100+ sensors in parallel on the exact same GPIO pin and 4.7kΩ pull-up resistor.
To read specific sensors in a multi-drop array, you must stop using getTempCByIndex(0), as the index order can shift during power cycles. Instead, extract the unique ROM address and query it directly:
DeviceAddress insideProbe = {0x28, 0xFF, 0x64, 0x1D, 0x86, 0x16, 0x03, 0x3F};
// Later in loop:
float temp = sensors.getTempC(insideProbe);
Reference: You can find your sensor's unique ROM address by running the DS18x20_Search example included in the DallasTemperature library.
Migrating to ESP32 (3.3V Logic)
If you are moving this project to an ESP32 DevKit V1 for WiFi/MQTT integration, you must adjust your hardware design. The ESP32 operates at 3.3V logic. While the DS18B20 can be powered by 3.3V, the 1-Wire protocol's rise times become marginal at lower voltages over long cable runs.
- Pin Selection: Avoid ESP32 strapping pins (GPIO 0, 2, 12, 15) for the 1-Wire bus, as the pull-up resistor will interfere with the boot sequence. Use GPIO 4, 5, or 16.
- Pull-up Voltage: Tie the 4.7kΩ pull-up resistor to the ESP32's 3V3 pin, not the 5V VIN pin. Pulling a 3.3V GPIO pin up to 5V will back-feed voltage into the ESP32's silicon, potentially destroying the GPIO pad over time.
- Cable Length: At 3.3V, reliable 1-Wire communication drops to roughly 10-15 meters. For longer runs, power the DS18B20 VDD pin with 5V (from the ESP32 VIN), but use a bidirectional logic level shifter (like a BSS138 MOSFET circuit) on the data line to translate the 5V sensor signals down to 3.3V for the ESP32.
By respecting the strict timing requirements of the 1-Wire protocol and implementing proper error handling for the 85°C and -127°C edge cases, your Arduino temp sensor DS18B20 build will transition from a fragile breadboard experiment to a robust, deployment-ready environmental monitor.
Sources and Further Reading:
Analog Devices DS18B20 Official Datasheet
PJRC OneWire Library Documentation and Timing Analysis
Arduino Official 1-Wire Communication Guide






