OneWire Protocol

Technical reference for the Dallas OneWire (1-Wire) protocol on ESP32 — bus topology, addressing, timing, and common pitfalls

OneWire (also written 1-Wire) is a communication protocol designed by Dallas Semiconductor (now Maxim Integrated / Analog Devices). It allows multiple devices to share a single data wire plus a ground return, making it one of the simplest bus protocols you will encounter. The most common OneWire device in ESP32 projects is the DS18B20 temperature sensor, but the protocol is also used by iButton keys, EEPROMs, and battery monitors.

🔗How It Works

OneWire is a master-slave protocol. The ESP32 acts as the bus master and controls all communication. Slave devices (sensors) only respond when the master addresses them. Data travels in both directions over the same wire -- the master pulls the line low to send commands, and slaves pull it low to send data back.

Every OneWire device has a unique 64-bit ROM address programmed at the factory. This address consists of:

BytesFieldPurpose
1Family codeIdentifies the device type (e.g., 0x28 = DS18B20)
6Serial numberUnique identifier
1CRCError checking

Because each device has a unique address, you can connect many devices to the same bus and talk to each one individually.

🔗Bus Topology

graph LR
    VCC[3.3V] --- R[4.7 kΩ pull-up]
    R --- DATA[Data line]
    ESP32[ESP32 GPIO] --- DATA
    DATA --- S1[DS18B20 #1]
    DATA --- S2[DS18B20 #2]
    DATA --- S3[DS18B20 #3]
    S1 --- GND1[GND]
    S2 --- GND2[GND]
    S3 --- GND3[GND]

All devices share the same data line. The bus only requires two connections to each device: data and ground. Power can come from a separate VCC wire (three-wire mode) or from the data line itself (parasitic power mode).

🔗The Pull-Up Resistor

A $4.7\,\text{k}\Omega$ pull-up resistor between the data line and VCC is essential. OneWire uses an open-drain bus -- devices communicate by pulling the line low, and the pull-up resistor returns it to a high state when released. Without this resistor, the bus stays in an undefined state and communication fails completely.

Bus lengthRecommended pull-up
Short (< 1 m)$4.7\,\text{k}\Omega$ (standard)
Medium (1--20 m)$4.7\,\text{k}\Omega$
Long (20--100 m)$2.2\,\text{k}\Omega$ to $3.3\,\text{k}\Omega$ (stronger pull-up needed)

Tip: Many DS18B20 breakout boards include a pull-up resistor on the PCB. Check before adding a second one -- two pull-up resistors in parallel lower the effective resistance and can cause problems.

🔗Parasitic Power vs External VCC

The OneWire protocol supports two power modes:

ModeWires neededHow it worksLimitations
External VCC (recommended)3 (VCC, Data, GND)Device powered by VCC pinNone -- reliable in all conditions
Parasitic power2 (Data, GND)Device charges internal capacitor from data lineUnreliable above $100\,\text{°C}$, limits number of devices on bus, timing-sensitive

Parasitic power is useful when running long cable lengths with only two conductors, but for most ESP32 projects, external VCC is simpler and more reliable.

🔗ESP32 Pin Selection

OneWire is a software protocol -- it does not require dedicated hardware peripherals. You can use any GPIO pin with one exception:

Pin typeGPIOsOneWire compatible?
General purpose0--33 (most)Yes
Input-only34, 35, 36, 39No -- these pins cannot be driven low by the ESP32

GPIO 4 is a common choice because it has no secondary function that might conflict.

🔗Timing

OneWire communication is timing-critical. All operations begin with the master pulling the data line low for a precise duration.

OperationDurationNotes
Reset pulse$480\,\mu\text{s}$ minimumMaster pulls low; devices respond with presence pulse
Write "0"$60$--$120\,\mu\text{s}$ lowMaster holds line low
Write "1"$1$--$15\,\mu\text{s}$ low, then releaseShort pulse, line returns high
Read slot$60\,\mu\text{s}$ totalMaster initiates, slave drives data
Temperature conversion (12-bit)750 msSensor is busy; bus reads 0 until done

The $750\,\text{ms}$ conversion time at 12-bit resolution is the bottleneck in most projects. Lower resolutions are faster:

ResolutionIncrementConversion time
9-bit$0.5\,\text{°C}$~$94\,\text{ms}$
10-bit$0.25\,\text{°C}$~$188\,\text{ms}$
11-bit$0.125\,\text{°C}$~$375\,\text{ms}$
12-bit$0.0625\,\text{°C}$~$750\,\text{ms}$

🔗Code Example: Discover Devices on the Bus

This sketch scans the OneWire bus and prints the 64-bit ROM address of every device it finds. This is useful when you have multiple sensors and need to know which address belongs to which physical device.

#include <OneWire.h>

#define ONE_WIRE_PIN 4

OneWire bus(ONE_WIRE_PIN);

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("Scanning OneWire bus...\n");

  byte address[8];
  int count = 0;

  while (bus.search(address)) {
    count++;
    Serial.printf("Device %d: ", count);

    for (int i = 0; i < 8; i++) {
      if (address[i] < 0x10) Serial.print("0");
      Serial.print(address[i], HEX);
      if (i < 7) Serial.print(":");
    }

    // Check CRC
    if (OneWire::crc8(address, 7) != address[7]) {
      Serial.println("  (CRC ERROR)");
    } else {
      // Identify device type by family code
      switch (address[0]) {
        case 0x28: Serial.println("  (DS18B20)"); break;
        case 0x10: Serial.println("  (DS18S20)"); break;
        case 0x22: Serial.println("  (DS1822)");  break;
        default:   Serial.println("  (Unknown)"); break;
      }
    }
  }

  bus.reset_search();
  Serial.printf("\nFound %d device(s).\n", count);
}

void loop() {
  // Nothing to do here
}

Upload this sketch, open the Serial Monitor at 115200 baud, and it will list every OneWire device connected to GPIO 4 along with its address and type.

🔗Common Issues

ProblemCauseFix
No devices foundMissing pull-up resistorAdd $4.7\,\text{k}\Omega$ between data and VCC
No devices foundUsing input-only pin (34--39)Switch to a general-purpose GPIO
Intermittent reads / CRC errorsWire too long or poor connectionsUse shorter cable, stronger pull-up, or shielded wire
Reads $-127\,\text{°C}$Sensor not respondingCheck wiring; ensure pull-up is present
Reads $85\,\text{°C}$Reading before conversion completesWait at least $750\,\text{ms}$ after requesting temperature
Parasitic power failsCurrent draw too high during conversionSwitch to external VCC power

Cable length: OneWire can theoretically work over distances up to ~$100\,\text{m}$, but this requires a strong pull-up ($2.2\,\text{k}\Omega$ or lower), good quality cable, and external VCC. For reliable operation, keep runs under $20\,\text{m}$.

🔗Arduino Libraries

LibraryAuthorPurpose
OneWirePaul StoffregenLow-level OneWire protocol (bus scan, read, write)
DallasTemperatureMiles BurtonHigh-level API for DS18B20/DS18S20 sensors (wraps OneWire)

Install both via the Arduino Library Manager.

🔗Used In

The following pages on this site use the OneWire protocol: