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. |
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.
- Connect Power and Ground: Wire the Red (VDD) to the Arduino 5V pin, and Black (GND) to the Arduino GND pin.
- Connect the Data Line: Wire the Yellow/White (DQ) to Arduino Digital Pin 2.
- 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.
- 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Ω.
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
- The 4.7kΩ Pull-Up Resistor: Is it physically present? Is it connected between 5V and the Data pin, not Data and GND?
- 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. - Pin Assignment Match: Does
#define ONE_WIRE_BUS 2exactly 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.






