The 1-Wire Protocol: Principles and Application (DS18B20)
Beginner1/8/2026- Author: IoTSpark Maker

The 1-Wire Protocol: Principles and Application (DS18B20)

The 1-Wire protocol explained (a single-wire open-drain bus, 64-bit ROM addressing), with hands-on DS18B20 temperature reading on an ESP32 DevKit and a 4.7kΩ pull-up resistor.

1-WireprotocolESP32DS18B20kien-thuc-nen-tang
0 steps3 components

1-Wire is a serial communication protocol developed by Dallas Semiconductor (now part of Maxim/Analog Devices), notable for using only a single DATA signal wire for both sending and receiving (plus GND, and optionally VCC if not using "parasite power" drawn from the DATA line itself).

It's an open-drain bus, so a pull-up resistor (typically 4.7kΩ) between DATA and the supply rail is mandatory. The most distinctive feature: every 1-Wire chip (like the DS18B20) ships with a unique 64-bit ROM address burned in at the factory, letting many sensors share a single DATA wire while each remains individually addressable — unlike I2C, where addresses must be configured in hardware/software and are limited to 7 bits (max 128 values).

This lesson reads temperature from a DS18B20 sensor via GPIO4 on an ESP32 DevKit.

Detailed guide

1-Wire principles (a single-wire open-drain bus, 64-bit ROM addressing), with hands-on DS18B20 temperature reading on an ESP32 DevKit.

1. Introduction

1-Wire is a half-duplex serial protocol developed by Dallas Semiconductor, distinguished by using only a single DATA wire for both sending commands from the master and receiving data from the slave (plus GND for a common ground). Like I2C, it's an open-drain bus, so a pull-up resistor (typically 4.7kΩ) between DATA and the supply rail is mandatory — without it, the bus always reads low and no communication can happen.

The key difference from I2C: every 1-Wire chip ships with a globally unique 64-bit ROM address burned in at the factory (8-bit family code + 48-bit serial number + 8-bit CRC), needing no configuration like a 7-bit I2C address. This lets you wire dozens of DS18B20 sensors onto a single shared DATA line while still reading each one individually by its ROM address, with no address-collision worries like with I2C. This lesson reads temperature from a single DS18B20 sensor via GPIO4 on an ESP32 DevKit.

2. Components Needed

ComponentQtyNote
ESP32 DevKit V41Main board
DS18B20 (1-Wire temperature sensor)1Range -55°C to 125°C, accuracy ±0.5°C
4.7kΩ Resistor1Mandatory pull-up for the DATA line (an open-drain bus)
Jumper wires3VCC, GND, DATA

3. Wiring Diagram

DS18B20ESP32
VCC (red)3V3
GND (black)GND
DATA (yellow)GPIO4

A 4.7kΩ resistor connects between the DATA pin (GPIO4) and 3V3 — this pull-up is mandatory, not optional: without it, the DATA line stays low (because it's open-drain) and sensors.getDeviceCount() will always return 0.

4. Example #1 — Reading Temperature, Printing the ROM Address

A sketch using the OneWire + DallasTemperature libraries, detecting the number of devices on the bus with sensors.getDeviceCount(), printing the first sensor's 64-bit ROM address, setting 12-bit resolution, then reading the temperature every 2 seconds.

/*
  The 1-Wire Protocol: Principles and Application — Example #1: Reading DS18B20 Temperature
  Board: ESP32 DevKit V4 + DS18B20 (1-Wire) + 4.7kΩ pull-up resistor

  Wiring:
    DS18B20 VCC  -> 3V3
    DS18B20 GND  -> GND
    DS18B20 DATA -> GPIO4  (also connected via a 4.7kΩ resistor up to 3V3 - a
                             mandatory pull-up since 1-Wire is an open-drain bus)

  1-Wire lets multiple DS18B20 sensors share a single DATA wire, distinguished
  by each chip's unique, factory-burned 64-bit ROM address (unlike I2C, which
  uses a 7-bit address configured in hardware/software).
*/

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

#define ONE_WIRE_PIN 4

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

DeviceAddress sensorAddress;
bool sensorFound = false;

void printAddress(DeviceAddress addr) {
  for (uint8_t i = 0; i < 8; i++) {
    if (addr[i] < 16) Serial.print('0');
    Serial.print(addr[i], HEX);
  }
}

void setup() {
  Serial.begin(115200);
  delay(300);
  Serial.println(F("=== DS18B20 1-Wire demo boot ==="));

  sensors.begin();
  uint8_t count = sensors.getDeviceCount();
  Serial.printf("So thiet bi 1-Wire tim thay tren bus: %u\n", count);

  if (count > 0 && sensors.getAddress(sensorAddress, 0)) {
    sensorFound = true;
    Serial.print(F("Dia chi ROM 64-bit cua cam bien #0: "));
    printAddress(sensorAddress);
    Serial.println();
    sensors.setResolution(sensorAddress, 12); // do phan giai 12-bit (~750ms/lan doc)
  } else {
    Serial.println(F("[WARN] Khong tim thay DS18B20 - kiem tra pull-up 4.7k va day DATA"));
  }
}

void loop() {
  static unsigned long lastRead = 0;
  if (millis() - lastRead >= 2000) {
    lastRead = millis();

    sensors.requestTemperatures(); // gui lenh convert T tren bus 1-Wire

    if (sensorFound) {
      float tempC = sensors.getTempC(sensorAddress);
      if (tempC == DEVICE_DISCONNECTED_C) {
        Serial.println(F("[WARN] Cam bien mat ket noi giua chung"));
      } else {
        Serial.printf("Nhiet do: %.2f C (do phan giai 12-bit)\n", tempC);
      }
    } else {
      Serial.println(F("Khong co cam bien de doc"));
    }
  }
}

5. Example #2 — The Real Application: a Temperature Threshold Alert

A second variant that uses the onboard LED on GPIO2 to trigger an alert when temperature crosses a 30°C threshold — simulating a real temperature-monitoring application (an electrical cabinet, a server, an aquaculture tank).

/*
  The 1-Wire Protocol — Example #2: The Real Application — a Temperature Threshold Alert
  Board: ESP32 DevKit V4 + DS18B20 (DATA=GPIO4, 4.7kΩ pull-up to 3V3)
  Simulated application: turns on the onboard LED (GPIO2) when temperature exceeds a threshold.
*/

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

#define ONE_WIRE_PIN 4
#define ALERT_LED_PIN 2
#define TEMP_THRESHOLD_C 30.0F

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

void setup() {
  Serial.begin(115200);
  delay(300);
  Serial.println(F("=== DS18B20 canh bao nguong nhiet do ==="));

  pinMode(ALERT_LED_PIN, OUTPUT);
  digitalWrite(ALERT_LED_PIN, LOW);

  sensors.begin();
  Serial.printf("Nguong canh bao: %.1f C\n", TEMP_THRESHOLD_C);
}

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

  if (tempC == DEVICE_DISCONNECTED_C) {
    Serial.println(F("[WARN] Khong doc duoc cam bien - kiem tra day 1-Wire"));
    digitalWrite(ALERT_LED_PIN, LOW);
  } else {
    bool alert = tempC >= TEMP_THRESHOLD_C;
    digitalWrite(ALERT_LED_PIN, alert ? HIGH : LOW);
    Serial.printf("Nhiet do: %.2f C -> LED canh bao: %s\n", tempC, alert ? "BAT" : "TAT");
  }

  delay(2000);
}

6. Real Applications & Extensions

1-Wire's built-in 64-bit ROM addressing (needing no configuration) makes it well suited for multi-point temperature-monitoring systems: a long cable run through several rooms/electrical cabinets, with a DS18B20 at each point — all sharing a single DATA wire back to the central board, with no address-collision concerns.

Common applications: multi-point cold-storage temperature monitoring, floor heating systems, battery/electrical-cabinet temperature monitoring. The DS18B20 also supports "parasite power" (drawing power directly from the DATA line, eliminating the VCC wire entirely) — useful for very long cable runs and minimizing wire count, though this configuration requires a stronger pull-up MOSFET in the code.

7. Common Issues

IssueCauseFix
getDeviceCount() always returns 0Missing the 4.7kΩ pull-up resistor on the DATA lineAdd a 4.7kΩ resistor between DATA and 3V3
Reading -127.00 or 85.00-127 means the sensor is disconnected; 85 is the default reset value from reading too soon after the convert commandRecheck the DATA wiring; wait long enough for conversion (~750ms at 12-bit) before reading
The temperature reading is way off from realityResolution set below 12-bit, or the sensor is picking up thermal noise from nearby componentsCall setResolution(addr, 12); place the sensor away from heat sources (the ESP32, the power supply)
Multiple sensors on the same wire report the same valueThe code only reads index 0 instead of looping through each ROM addressUse sensors.getAddress() to fetch each sensor's correct ROM address when there are multiple devices

8. Summary

1-Wire is the most wire-efficient of the three protocols (just a single DATA wire), thanks to its built-in 64-bit ROM addressing from the factory, needing no address configuration like I2C.

The trade-off is lower speed and a more intricate low-level protocol (precise microsecond timing), but libraries like OneWire/DallasTemperature hide all that complexity. This is the classic choice for distributed temperature sensing, long cable runs, and many measurement points.