The Arduino DS18B20 is a 1-Wire digital temperature sensor that outputs calibrated, high-resolution Celsius data without needing an analog-to-digital converter. Unlike thermistors, it does not suffer from voltage drop over long wire runs, making it the definitive choice for remote environmental monitoring, 3D printer thermistors, and outdoor weather stations. This guide provides the exact wiring, non-blocking C++ code, and a decision-tree for debugging the most common 1-Wire bus failures.

The Quick Decision: Which DS18B20 Variant to Buy?

Not all DS18B20 sensors are packaged equally. Use this decision matrix to select the exact hardware variant for your build environment.

Environment / Use Case Recommended Variant Why This Wins
Breadboard prototyping, indoor ambient air DS18B20+ TO-92 (Through-hole) Cheap, fits standard 0.1" breadboards, fast thermal response in air.
Liquids, outdoors, buried in soil, long runs Waterproof Stainless Steel Probe (3m cable) IP67 sealed, stranded wires resist fatigue, stainless sleeve acts as a thermal mass for stable liquid readings.
Custom PCB, tight space constraints DS18B20Z (SOIC-8 Surface Mount) Reflow solderable, minimal footprint, ideal for custom carrier boards.
Default Pick: If you are unsure, buy the Waterproof Stainless Steel Probe with pre-wired bare ends. It costs roughly $4-$6, survives accidental submersion, and the 3-meter cable allows you to keep the noisy microcontroller away from the measurement zone.
Counterfeit Alert: The market is flooded with fake DS18B20 chips (especially in TO-92 packages from budget marketplaces). Clones often fail above 60°C, exhibit high noise, or hard-lock at 85.0°C. Always source genuine Analog Devices / Maxim Integrated parts from authorized distributors like DigiKey or Mouser for mission-critical builds.

Parts List and Pin Mapping

This build targets the Arduino Uno R3 and Arduino Nano v3 (both ATmega328P-based). The logic is identical for ESP32, though ESP32 requires stricter 1-Wire timing libraries.

Bill of Materials (BOM)

  • Microcontroller: Arduino Uno R3 or Nano v3 (ATmega328P, 5V logic)
  • Sensor: Genuine DS18B20+ (TO-92 or Waterproof Probe)
  • Resistor: 4.7kΩ through-hole (1/4W, 5% tolerance) — Mandatory for 1-Wire pull-up
  • Wiring: 22 AWG solid core for breadboard, or 24 AWG stranded for probe extensions

Pin Mapping Table (External Power Mode)

DS18B20 Pin (TO-92 Flat Face) Waterproof Probe Wire Color Arduino Uno/Nano Pin Notes
Pin 1 (Left) - GND Black GND System Ground
Pin 2 (Middle) - DQ (Data) Yellow or White Digital Pin 2 Requires 4.7kΩ pull-up to 5V
Pin 3 (Right) - VDD Red 5V External power (3.0V to 5.5V)

Step-by-Step Wiring and Pull-Up Resistor Rules

The 1-Wire protocol relies on an open-drain bus. The microcontroller pulls the line low to transmit, and a physical resistor pulls it high to idle. Without the pull-up, the data line floats, resulting in garbage data or bus lockups.

  1. Connect Power and Ground: Wire the Red (VDD) to the Arduino 5V pin, and Black (GND) to the Arduino GND pin.
  2. Connect the Data Line: Wire the Yellow/White (DQ) to Arduino Digital Pin 2.
  3. Install the Pull-Up Resistor: Insert one leg of the 4.7kΩ resistor into the 5V rail, and the other leg into the Digital Pin 2 rail on your breadboard. This physically bridges VCC and DQ.
  4. Verify Connections: Use a multimeter in continuity mode. Check that DQ is not shorted to GND. Measure the resistance between 5V and DQ; it should read exactly ~4.7kΩ.
Wire Length Physics: The 4.7kΩ value is optimized for bus capacitances up to ~1000pF (roughly 10 meters of standard Cat5e cable). If you extend the waterproof probe beyond 15 meters, the bus capacitance increases, slowing the RC rise time. For runs up to 30 meters, drop the pull-up resistor to 2.2kΩ to provide more current and steepen the rising edge of the digital signal.

Complete Arduino DS18B20 Code (Target: Uno R3 / Nano)

This code uses the industry-standard OneWire and DallasTemperature libraries. It implements a non-blocking millis() timer to prevent the 750ms conversion delay from freezing your main loop, and includes explicit error handling for disconnected sensors.

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

// Pin definition - MUST match your physical wiring
#define ONE_WIRE_BUS 2
#define SENSOR_RESOLUTION 12 // 9 to 12 bits (12-bit = 0.0625°C resolution)

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

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

// Timing variables for non-blocking reads
unsigned long lastTempRequest = 0;
unsigned long conversionDelay = 0;
float currentTempC = -127.0;
bool waitingForConversion = false;

void setup() {
  Serial.begin(115200);
  while (!Serial); // Wait for serial port (Leonardo/Micro only)
  
  sensors.begin();
  sensors.setResolution(SENSOR_RESOLUTION);
  
  // Calculate exact delay needed based on resolution
  // 12-bit = 750ms, 11-bit = 375ms, 10-bit = 187ms, 9-bit = 93ms
  conversionDelay = 750 / (1 << (12 - SENSOR_RESOLUTION));
  
  Serial.println("DS18B20 Initialized. Requesting first reading...");
  sensors.requestTemperatures();
  lastTempRequest = millis();
  waitingForConversion = true;
}

void loop() {
  if (waitingForConversion) {
    if (millis() - lastTempRequest >= conversionDelay) {
      // Conversion complete, read the value
      currentTempC = sensors.getTempCByIndex(0);
      
      // ERROR HANDLING: Check for disconnected device
      if (currentTempC == DEVICE_DISCONNECTED_C) {
        Serial.println("ERROR: -127.00°C - Device disconnected or bus fault!");
      } else {
        Serial.print("Temperature: ");
        Serial.print(currentTempC, 2);
        Serial.println(" °C");
      }
      
      // Request next reading immediately
      sensors.requestTemperatures();
      lastTempRequest = millis();
      waitingForConversion = true;
    }
  }
  
  // Your main loop code runs here without blocking!
  // Example: blink an LED, read buttons, update displays
}

Debugging: Fixing the "-127.00°C" and "85.00°C" Errors

When a 1-Wire bus fails, it fails in highly specific, predictable ways. If your serial monitor outputs anomalous data, follow this diagnostic path.

The First Three Things to Check

  1. The 4.7kΩ Pull-Up Resistor: Is it physically present? Is it connected between 5V and the Data pin, not Data and GND?
  2. Parasitic vs. External Power Mode: If you wired VDD to GND (parasitic mode), did you call sensors.setParasitePower(true) in the code? If not, the sensor lacks the current to perform the ADC conversion.
  3. Pin Assignment Match: Does #define ONE_WIRE_BUS 2 exactly match the physical digital pin you wired to the yellow/white data line?

Error String Decision Tree

Exact Error String / Symptom Ranked Causes (Most Likely First) Fix / Measurement Threshold
-127.00°C or DEVICE_DISCONNECTED_C 1. Missing pull-up resistor.
2. Broken data wire.
3. Data pin shorted to GND.
Measure resistance between Data pin and GND. It should read >10kΩ. If near 0Ω, you have a short.
Constant 85.00°C (Never changes) 1. Parasitic power mode without setParasitePower(true).
2. Pull-up resistor too weak (e.g., 10kΩ used).
3. Counterfeit/Clone chip.
85°C is the factory power-on reset value. The sensor is waking up but failing the conversion phase due to voltage sag on the bus. Switch to external 5V power or lower pull-up to 2.2kΩ.
NO_MORE_DEVICES during bus scan 1. Bus shorted to VCC.
2. Sensor wired backwards (VDD and GND swapped).
Check TO-92 pinout. Flat face towards you: Left=GND, Mid=Data, Right=VDD. Swapping VDD/GND will instantly overheat and destroy the silicon.

Extending and Simplifying the Build

Once you have a single sensor reading reliably, you will likely want to scale the system. Here is how to push the hardware in both directions.

How to Extend: Multi-Drop Bus (Up to 15 Sensors on One Pin)

The 1-Wire protocol allows you to daisy-chain multiple DS18B20 sensors on the exact same data pin. Wiring: Wire all Red wires to 5V, all Black wires to GND, and all Yellow wires together to Pin 2. You still only need one single 4.7kΩ pull-up resistor on the bus. Code: Use sensors.getDeviceCount() to find how many are attached, and iterate through them using sensors.getTempCByIndex(i). For production firmware, extract the unique 64-bit ROM address of each sensor using the OneWire Address Search example sketch, and hardcode those addresses into your array so sensor swapping doesn't change your data logging indices.

How to Simplify: Parasitic Power Mode (2 Wires Instead of 3)

If running 3 wires through a conduit or long tether is impractical, you can power the DS18B20 directly from the data line. Wiring: Connect the sensor's VDD (Red) pin directly to its GND (Black) pin, and tie both to the Arduino GND. Run only the Data (Yellow) and GND wires to the Arduino. Code: You must add sensors.setParasitePower(true); in your setup() block. This tells the library to hold the data line HIGH via the microcontroller's internal push-pull GPIO during the 750ms conversion window, acting as a temporary power source. Limitation: Parasitic mode limits cable length to roughly 3-5 meters due to voltage drop and the current limits of the ATmega328P GPIO pins (max 20mA). For longer runs, stick to the 3-wire external power method.