Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

1-Wire Bus Programming Guide

The 1-Wire bus driver provides a generic interface for communicating with Dallas/Maxim 1-Wire devices. It supports multiple hardware backends (RMT and UART) and handles the low-level timing requirements of the 1-Wire protocol automatically.

Overview

1-Wire is a device communications bus system that uses a single data line plus ground for communication. Common 1-Wire devices include temperature sensors (DS18B20), EEPROMs (DS2431), and real-time clocks (DS3234).

This driver provides:

  • Automatic 1-Wire bus initialization with RMT or UART backend
  • Device discovery and enumeration on the bus
  • Read/write operations at bit and byte level
  • Built-in CRC8 calculation for data integrity

Add the Component to Your Project

Add the onewire_bus component to your project via the ESP Component Registry:

idf.py add-dependency "espressif/onewire_bus"

Allocate 1-Wire Bus with RMT Backend

The RMT backend is the recommended approach for most ESP32 chips that support the RMT peripheral. It provides precise timing control for 1-Wire communication.

#include "onewire_bus.h"

// 1-Wire bus configuration
onewire_bus_config_t bus_config = {
    .bus_gpio_num = 4,              // GPIO pin connected to the 1-Wire bus data line
    .flags = {
        .en_pull_up = false,        // Set true to enable internal pull-up (external pull-up recommended)
    }
};

// RMT backend specific configuration
onewire_bus_rmt_config_t rmt_config = {
    .max_rx_bytes = 10,             // Maximum bytes expected in a single receive operation
};

// Create the 1-Wire bus handle
onewire_bus_handle_t bus = NULL;
ESP_ERROR_CHECK(onewire_new_bus_rmt(&bus_config, &rmt_config, &bus));

Notes on RMT Backend

  • The RMT backend uses a pair of RMT TX and RX channels internally
  • The max_rx_bytes value determines the size of the internal receive buffer. Set this based on the maximum response size you expect from your devices
  • An external 4.7kΩ pull-up resistor is recommended for reliable communication, especially when multiple devices are on the bus or cable lengths are long

Allocate 1-Wire Bus with UART Backend

The UART backend is an alternative that uses the UART peripheral with open-drain configuration. This is useful when RMT channels are not available.

#include "onewire_bus.h"

// 1-Wire bus configuration
onewire_bus_config_t bus_config = {
    .bus_gpio_num = 4,              // GPIO pin connected to the 1-Wire bus data line
    .flags = {
        .en_pull_up = false,        // Set true to enable internal pull-up (external pull-up recommended)
    }
};

// UART backend specific configuration
onewire_bus_uart_config_t uart_config = {
    .uart_port_num = 1,             // UART port number to use
};

// Create the 1-Wire bus handle
onewire_bus_handle_t bus = NULL;
ESP_ERROR_CHECK(onewire_new_bus_uart(&bus_config, &uart_config, &bus));

Notes on UART Backend

  • Both the UART TX and RX paths are configured to the same GPIO pin (bus_gpio_num)
  • The GPIO is automatically configured as open-drain mode

Enumerate Devices on the Bus

After initializing the bus, you can discover all 1-Wire devices connected to it. Each 1-Wire device has a unique 64-bit ROM address.

// Create a device iterator
onewire_device_iter_handle_t iter = NULL;
ESP_ERROR_CHECK(onewire_new_device_iter(bus, &iter));

// Enumerate all devices on the bus
onewire_device_t dev;
while (onewire_device_iter_get_next(iter, &dev) == ESP_OK) {
    ESP_LOGI("example", "Found device with address: %016llX", dev.address);
}

// Delete the iterator when done
ESP_ERROR_CHECK(onewire_del_device_iter(iter));

Notes on Device Enumeration

  • The iterator performs a 1-Wire search algorithm to find all devices on the bus
  • Each call to onewire_device_iter_get_next() returns the next device found
  • The device address contains the family code (first byte), serial number (middle 6 bytes), and CRC (last byte)
  • Call the iterator functions again if you need to re-scan the bus for newly connected devices

Communicate with Devices

Reset the Bus

Before each communication sequence, send a reset pulse to check for device presence:

esp_err_t ret = onewire_bus_reset(bus);
if (ret == ESP_OK) {
    ESP_LOGI("example", "Device(s) present on the bus");
} else if (ret == ESP_ERR_NOT_FOUND) {
    ESP_LOGW("example", "No devices found on the bus");
}

Send Commands and Data

You can communicate with devices using the byte-level or bit-level functions:

// Send a command byte (e.g., SKIP ROM command to address all devices)
uint8_t cmd = ONEWIRE_CMD_SKIP_ROM;
ESP_ERROR_CHECK(onewire_bus_write_bytes(bus, &cmd, 1));

// Write a read temperature command to a DS18B20
uint8_t convert_cmd = 0x44;
ESP_ERROR_CHECK(onewire_bus_write_bytes(bus, &convert_cmd, 1));

// Read response data
uint8_t scratchpad[9];
ESP_ERROR_CHECK(onewire_bus_read_bytes(bus, scratchpad, 9));

Working with a Specific Device

When multiple devices are on the bus, use the MATCH ROM command to address a specific device:

// First, find the device address using the iterator (shown above)
onewire_device_iter_handle_t iter = NULL;
ESP_ERROR_CHECK(onewire_new_device_iter(bus, &iter));

onewire_device_t dev;
if (onewire_device_iter_get_next(iter, &dev) == ESP_OK) {
    // Reset and send MATCH ROM command followed by the device address
    ESP_ERROR_CHECK(onewire_bus_reset(bus));

    uint8_t match_cmd = ONEWIRE_CMD_MATCH_ROM;
    ESP_ERROR_CHECK(onewire_bus_write_bytes(bus, &match_cmd, 1));
    ESP_ERROR_CHECK(onewire_bus_write_bytes(bus, (uint8_t *)&dev.address, 8));

    // Now you can communicate with this specific device
    uint8_t read_cmd = 0xBE;  // Read scratchpad command for DS18B20
    ESP_ERROR_CHECK(onewire_bus_write_bytes(bus, &read_cmd, 1));

    uint8_t data[9];
    ESP_ERROR_CHECK(onewire_bus_read_bytes(bus, data, 9));
}

ESP_ERROR_CHECK(onewire_del_device_iter(iter));

Verify Data with CRC

The 1-Wire protocol uses CRC8 for data integrity. The driver provides a CRC8 utility function:

#include "onewire_crc.h"

// Calculate CRC8 for received data
uint8_t data[9];  // Received scratchpad data
ESP_ERROR_CHECK(onewire_bus_read_bytes(bus, data, 9));

// Verify CRC - the result should be 0 if data is correct
uint8_t crc = onewire_crc8(0, data, 9);
if (crc == 0) {
    ESP_LOGI("example", "Data CRC verified OK");
} else {
    ESP_LOGE("example", "Data CRC mismatch");
}

Free Resources

When you are done using the 1-Wire bus, free the allocated resources:

ESP_ERROR_CHECK(onewire_bus_del(bus));

Common 1-Wire Commands

The driver provides commonly used 1-Wire command definitions:

CommandValueDescription
ONEWIRE_CMD_SEARCH_NORMAL0xF0Search for all devices on the bus
ONEWIRE_CMD_MATCH_ROM0x55Address a specific device by its ROM address
ONEWIRE_CMD_SKIP_ROM0xCCAddress all devices on the bus simultaneously
ONEWIRE_CMD_SEARCH_ALARM0xECSearch for devices in alarm condition
ONEWIRE_CMD_READ_POWER_SUPPLY0xB4Check if devices are parasitically powered

FAQ

  • Do I need an external pull-up resistor?

    • Yes, a 4.7kΩ pull-up resistor is recommended for reliable communication. The internal pull-up may not provide enough current for some devices, especially with longer cables or multiple devices.
  • Which backend should I use, RMT or UART?

    • Use RMT backend if your chip supports it and you have free RMT channels. It provides more precise timing. Use UART backend when RMT is unavailable or all channels are in use.
  • How many devices can I connect to a single 1-Wire bus?

    • The 1-Wire protocol supports many devices on a single bus (limited by the 64-bit address space). In practice, the limit is determined by bus capacitance and power supply capabilities.
  • How do I communicate with a specific device when multiple devices are on the bus?

    • First enumerate devices using the device iterator to get their addresses. Then use the ONEWIRE_CMD_MATCH_ROM command followed by the 8-byte device address to select a specific device before sending commands.
  • Where can I find a complete example?

API Reference

Header files

File include/onewire_bus.h

Functions

TypeName
esp_err_tonewire_bus_del (onewire_bus_handle_t bus)
Free 1-Wire bus resources.
esp_err_tonewire_bus_read_bit (onewire_bus_handle_t bus, uint8_t *rx_bit)
Read a bit from 1-wire bus.
esp_err_tonewire_bus_read_bytes (onewire_bus_handle_t bus, uint8_t *rx_buf, size_t rx_buf_size)
Read bytes from 1-wire bus.
esp_err_tonewire_bus_reset (onewire_bus_handle_t bus)
Send reset pulse to the bus, and check if there are devices attached to the bus.
esp_err_tonewire_bus_write_bit (onewire_bus_handle_t bus, uint8_t tx_bit)
Write a bit to 1-wire bus, this is a blocking function.
esp_err_tonewire_bus_write_bytes (onewire_bus_handle_t bus, const uint8_t *tx_data, uint8_t tx_data_size)
Write bytes to 1-wire bus.

Functions Documentation

function onewire_bus_del

Free 1-Wire bus resources.

esp_err_t onewire_bus_del (
    onewire_bus_handle_t bus
) 

Parameters:

  • bus 1-Wire bus handle

Returns:

  • ESP_OK: Free resources successfully
  • ESP_FAIL: Free resources failed because error occurred

function onewire_bus_read_bit

Read a bit from 1-wire bus.

esp_err_t onewire_bus_read_bit (
    onewire_bus_handle_t bus,
    uint8_t *rx_bit
) 

Parameters:

  • bus 1-wire bus handle
  • rx_bit received bit, 0 for zero bit, 1 for one bit

Returns:

  • ESP_OK Read bit from 1-wire bus successfully.
  • ESP_ERR_INVALID_ARG Invalid argument.

function onewire_bus_read_bytes

Read bytes from 1-wire bus.

esp_err_t onewire_bus_read_bytes (
    onewire_bus_handle_t bus,
    uint8_t *rx_buf,
    size_t rx_buf_size
) 

Parameters:

  • bus 1-wire bus handle
  • rx_buf pointer to buffer to store received data
  • rx_buf_size size of buffer to store received data, in bytes

Returns:

  • ESP_OK: Read bytes from 1-Wire bus successfully
  • ESP_ERR_INVALID_ARG: Read bytes from 1-Wire bus failed because of invalid argument
  • ESP_FAIL: Read bytes from 1-Wire bus failed because of other errors

function onewire_bus_reset

Send reset pulse to the bus, and check if there are devices attached to the bus.

esp_err_t onewire_bus_reset (
    onewire_bus_handle_t bus
) 

Parameters:

  • bus 1-Wire bus handle

Returns:

  • ESP_OK: Reset 1-Wire bus successfully and find device on the bus
  • ESP_ERR_NOT_FOUND: Reset 1-Wire bus successfully but no device found on the bus
  • ESP_FAIL: Reset 1-Wire bus failed because of other errors

function onewire_bus_write_bit

Write a bit to 1-wire bus, this is a blocking function.

esp_err_t onewire_bus_write_bit (
    onewire_bus_handle_t bus,
    uint8_t tx_bit
) 

Parameters:

  • bus 1-wire bus handle
  • tx_bit bit to transmit, 0 for zero bit, other for one bit

Returns:

  • ESP_OK Write bit to 1-wire bus successfully.
  • ESP_ERR_INVALID_ARG Invalid argument.

function onewire_bus_write_bytes

Write bytes to 1-wire bus.

esp_err_t onewire_bus_write_bytes (
    onewire_bus_handle_t bus,
    const uint8_t *tx_data,
    uint8_t tx_data_size
) 

Parameters:

  • bus 1-Wire bus handle
  • tx_data pointer to data to be sent
  • tx_data_size size of data to be sent, in bytes

Returns:

  • ESP_OK: Write bytes to 1-Wire bus successfully
  • ESP_ERR_INVALID_ARG: Write bytes to 1-Wire bus failed because of invalid argument
  • ESP_FAIL: Write bytes to 1-Wire bus failed because of other errors

File include/onewire_bus_impl_rmt.h

Structures and Types

TypeName
structonewire_bus_rmt_config_t
1-Wire bus RMT specific configuration

Functions

TypeName
esp_err_tonewire_new_bus_rmt (const onewire_bus_config_t *bus_config, const onewire_bus_rmt_config_t *rmt_config, onewire_bus_handle_t *ret_bus)
Create 1-Wire bus with RMT backend.

Structures and Types Documentation

struct onewire_bus_rmt_config_t

1-Wire bus RMT specific configuration

Variables:

  • uint32_t max_rx_bytes
    Set the largest possible single receive size, which determines the size of the internal buffer that used to save the receiving RMT symbols

Functions Documentation

function onewire_new_bus_rmt

Create 1-Wire bus with RMT backend.

esp_err_t onewire_new_bus_rmt (
    const onewire_bus_config_t *bus_config,
    const onewire_bus_rmt_config_t *rmt_config,
    onewire_bus_handle_t *ret_bus
) 

Note:

One 1-Wire bus utilizes a pair of RMT TX and RX channels

Parameters:

  • bus_config 1-Wire bus configuration
  • rmt_config RMT specific configuration
  • ret_bus Returned 1-Wire bus handle

Returns:

  • ESP_OK: create 1-Wire bus handle successfully
  • ESP_ERR_INVALID_ARG: create 1-Wire bus handle failed because of invalid argument
  • ESP_ERR_NO_MEM: create 1-Wire bus handle failed because of out of memory
  • ESP_FAIL: create 1-Wire bus handle failed because some other error

File include/onewire_bus_impl_uart.h

Structures and Types

TypeName
structonewire_bus_uart_config_t
1-Wire bus UART specific configuration

Functions

TypeName
esp_err_tonewire_new_bus_uart (const onewire_bus_config_t *bus_config, const onewire_bus_uart_config_t *uart_config, onewire_bus_handle_t *ret_bus)
Create 1-Wire bus with UART backend.

Structures and Types Documentation

struct onewire_bus_uart_config_t

1-Wire bus UART specific configuration

Variables:

  • int uart_port_num
    UART port number, e.g. UART_NUM_1

Functions Documentation

function onewire_new_bus_uart

Create 1-Wire bus with UART backend.

esp_err_t onewire_new_bus_uart (
    const onewire_bus_config_t *bus_config,
    const onewire_bus_uart_config_t *uart_config,
    onewire_bus_handle_t *ret_bus
) 

Note:

TX and RX will both be configured to bus_config->bus_gpio_num. And this GPIO will be configured as open-drain mode.

Parameters:

  • bus_config 1-Wire bus configuration
  • uart_config UART specific configuration
  • ret_bus Returned 1-Wire bus handle

Returns:

  • ESP_OK: create 1-Wire bus handle successfully
  • ESP_ERR_INVALID_ARG: create 1-Wire bus handle failed because of invalid argument
  • ESP_ERR_NO_MEM: create 1-Wire bus handle failed because of out of memory
  • ESP_FAIL: create 1-Wire bus handle failed because some other error

File include/onewire_cmd.h

Macros

Macros Documentation

define ONEWIRE_CMD_MATCH_ROM

#define ONEWIRE_CMD_MATCH_ROM 0x55

define ONEWIRE_CMD_READ_POWER_SUPPLY

#define ONEWIRE_CMD_READ_POWER_SUPPLY 0xB4

define ONEWIRE_CMD_SEARCH_ALARM

#define ONEWIRE_CMD_SEARCH_ALARM 0xEC

define ONEWIRE_CMD_SEARCH_NORMAL

#define ONEWIRE_CMD_SEARCH_NORMAL 0xF0

define ONEWIRE_CMD_SKIP_ROM

#define ONEWIRE_CMD_SKIP_ROM 0xCC

File include/onewire_crc.h

Functions

TypeName
uint8_tonewire_crc8 (uint8_t init_crc, uint8_t *input, size_t input_size)
Calculate Dallas CRC8 value of a given buffer.

Functions Documentation

function onewire_crc8

Calculate Dallas CRC8 value of a given buffer.

uint8_t onewire_crc8 (
    uint8_t init_crc,
    uint8_t *input,
    size_t input_size
) 

Parameters:

  • init_crc Initial CRC value
  • input Input buffer to calculate CRC value
  • input_size Size of input buffer, in bytes

Returns:

CRC8 result of the input buffer

File include/onewire_device.h

Structures and Types

TypeName
structonewire_device_t
1-Wire device generic type
typedef struct onewire_device_tonewire_device_t
1-Wire device generic type

Functions

TypeName
esp_err_tonewire_del_device_iter (onewire_device_iter_handle_t iter)
Delete the device iterator.
esp_err_tonewire_device_iter_get_next (onewire_device_iter_handle_t iter, onewire_device_t *dev)
Get the next 1-Wire device from the iterator.
esp_err_tonewire_new_device_iter (onewire_bus_handle_t bus, onewire_device_iter_handle_t *ret_iter)
Create an iterator to enumerate the 1-Wire devices on the bus.

Structures and Types Documentation

struct onewire_device_t

1-Wire device generic type

Variables:

typedef onewire_device_t

1-Wire device generic type

typedef struct onewire_device_t onewire_device_t;

Functions Documentation

function onewire_del_device_iter

Delete the device iterator.

esp_err_t onewire_del_device_iter (
    onewire_device_iter_handle_t iter
) 

Parameters:

  • iter Device iterator handle

Returns:

  • ESP_OK: Delete device iterator successfully
  • ESP_ERR_INVALID_ARG: Invalid argument
  • ESP_FAIL: Other errors

function onewire_device_iter_get_next

Get the next 1-Wire device from the iterator.

esp_err_t onewire_device_iter_get_next (
    onewire_device_iter_handle_t iter,
    onewire_device_t *dev
) 

Parameters:

  • iter Device iterator handle
  • dev Returned 1-Wire device handle

Returns:

  • ESP_OK: Get next device successfully
  • ESP_ERR_INVALID_ARG: Invalid argument
  • ESP_ERR_NOT_FOUND: No more device to get
  • ESP_FAIL: Other errors

function onewire_new_device_iter

Create an iterator to enumerate the 1-Wire devices on the bus.

esp_err_t onewire_new_device_iter (
    onewire_bus_handle_t bus,
    onewire_device_iter_handle_t *ret_iter
) 

Parameters:

  • bus 1-Wire bus handle
  • ret_iter Returned created device iterator

Returns:

  • ESP_OK: Create device iterator successfully
  • ESP_ERR_INVALID_ARG: Invalid argument
  • ESP_ERR_NO_MEM: No memory to create device iterator
  • ESP_FAIL: Other errors

File include/onewire_types.h

Structures and Types

TypeName
structonewire_bus_config_t
1-Wire bus configuration
structonewire_bus_config_flags
typedef struct onewire_bus_t *onewire_bus_handle_t
Type of 1-Wire bus handle.
typedef uint64_tonewire_device_address_t
Type of the address for a 1-Wire compatible device.
typedef struct onewire_device_iter_t *onewire_device_iter_handle_t
Type of 1-Wire device iterator handle.

Structures and Types Documentation

struct onewire_bus_config_t

1-Wire bus configuration

Variables:

struct onewire_bus_config_t::onewire_bus_config_flags

Variables:

  • uint32_t en_pull_up
    Set true to enable internal pull-up resistor. Please note the internal pull-up resistor cannot provide enough current for some devices, so external pull-up resistor is still recommended.

typedef onewire_bus_handle_t

Type of 1-Wire bus handle.

typedef struct onewire_bus_t* onewire_bus_handle_t;

typedef onewire_device_address_t

Type of the address for a 1-Wire compatible device.

typedef uint64_t onewire_device_address_t;

typedef onewire_device_iter_handle_t

Type of 1-Wire device iterator handle.

typedef struct onewire_device_iter_t* onewire_device_iter_handle_t;

File interface/onewire_bus_interface.h

Structures and Types

TypeName
structonewire_bus_t
1-Wire bus interface definition
typedef struct onewire_bus_tonewire_bus_t

Structures and Types Documentation

struct onewire_bus_t

1-Wire bus interface definition

Variables:

  • esp_err_t(* del
    Free 1-Wire bus resources.
    Parameters:
  • bus 1-Wire bus handle

Returns:

  • ESP_OK: Free resources successfully
  • ESP_FAIL: Free resources failed because error occurred
  • esp_err_t(* read_bit
    Read a bit from 1-wire bus.
    Parameters:
  • handle 1-wire bus handle
  • rx_bit received bit, 0 for zero bit, 1 for one bit

Returns:

  • ESP_OK Read bit from 1-wire bus successfully.
  • ESP_ERR_INVALID_ARG Invalid argument.
  • esp_err_t(* read_bytes
    Read bytes from 1-wire bus.
    Parameters:
  • bus 1-wire bus handle
  • rx_buf pointer to buffer to store received data
  • rx_buf_size size of buffer to store received data, in bytes

Returns:

  • ESP_OK: Read bytes from 1-Wire bus successfully
  • ESP_ERR_INVALID_ARG: Read bytes from 1-Wire bus failed because of invalid argument
  • ESP_FAIL: Read bytes from 1-Wire bus failed because of other errors
  • esp_err_t(* reset
    Send reset pulse to the bus, and check if there are devices attached to the bus.
    Parameters:
  • bus 1-Wire bus handle

Returns:

  • ESP_OK: Reset 1-Wire bus successfully and find device on the bus
  • ESP_ERR_NOT_FOUND: Reset 1-Wire bus successfully but no device found on the bus
  • ESP_FAIL: Reset 1-Wire bus failed because of other errors
  • esp_err_t(* write_bit
    Write a bit to 1-wire bus, this is a blocking function.
    Parameters:
  • handle 1-wire bus handle
  • tx_bit bit to transmit, 0 for zero bit, other for one bit

Returns:

  • ESP_OK Write bit to 1-wire bus successfully.
  • ESP_ERR_INVALID_ARG Invalid argument.
  • esp_err_t(* write_bytes
    Write bytes to 1-wire bus.
    Note:

This is a blocking function

Parameters:

  • bus 1-Wire bus handle
  • tx_data pointer to data to be sent
  • tx_data_size size of data to be sent, in bytes

Returns:

  • ESP_OK: Write bytes to 1-Wire bus successfully
  • ESP_ERR_INVALID_ARG: Write bytes to 1-Wire bus failed because of invalid argument
  • ESP_FAIL: Write bytes to 1-Wire bus failed because of other errors

typedef onewire_bus_t

typedef struct onewire_bus_t onewire_bus_t;

Type of 1-Wire bus