esp-idf-lib/ds18x20

1.3.1

Latest
uploaded 6 hours ago
Driver for DS18B20/DS18S20 families of 1-Wire temperature sensor ICs

Readme

# esp-idf-lib/ds18x20

[![Build examples](https://github.com/esp-idf-lib/ds18x20/actions/workflows/build.yml/badge.svg)](https://github.com/esp-idf-lib/ds18x20/actions/workflows/build.yml)
[![Build docs](https://github.com/esp-idf-lib/ds18x20/actions/workflows/build-docs.yml/badge.svg)](https://github.com/esp-idf-lib/ds18x20/actions/workflows/build-docs.yml)
[![Validation](https://github.com/esp-idf-lib/ds18x20/actions/workflows/validate-component.yml/badge.svg)](https://github.com/esp-idf-lib/ds18x20/actions/workflows/validate-component.yml)

Driver for the DS18B20/DS18S20 families of 1-Wire temperature sensors.

* [Documentation](https://esp-idf-lib.github.io/ds18x20/)
* [Repository](https://github.com/esp-idf-lib/ds18x20)
* [Issues](https://github.com/esp-idf-lib/ds18x20/issues)
* [Discussions and questions](https://github.com/esp-idf-lib/core/discussions)
* [Component page at the ESP Component Registry](https://components.espressif.com/components/esp-idf-lib/ds18x20)

The driver works on top of a 1-Wire bus implementation, and there are two of them to choose from: the bit-banging driver of [esp-idf-lib/onewire](https://github.com/esp-idf-lib/onewire) and the RMT driver of [espressif/onewire_bus](https://components.espressif.com/components/espressif/onewire_bus). The choice is made in `menuconfig`, see [1-Wire backends](#1-wire-backends).

## Supported sensors

| Family code | Part | Resolution | LSB | Notes |
| --- | --- | --- | --- | --- |
| `0x10` | DS18S20, DS1820 | 9 bit | 0.5 °C | Fixed resolution, the scratchpad carries the count remainder and the count per °C, which the driver uses to refine the reading |
| `0x22` | DS1822 | 9–12 bit | 0.0625 °C | Same register layout as the DS18B20 |
| `0x28` | DS18B20 | 9–12 bit | 0.0625 °C | The most common part, including the waterproof probes |
| `0x3B` | DS1825 | 9–12 bit | 0.0625 °C | Shares the family code with the MAX31850; the driver reads it with the 14-bit formula, which is correct because the two unused low bits are zero |
| `0x3B` | MAX31850, MAX31851 | 14 bit | 0.0625 °C | Thermocouple-to-digital converter, `ds18x20_read_temperature()` handles it |
| `0x42` | DS28EA00 | 9–12 bit | 0.0625 °C | Sequence detect and PIO pins, both unused by the driver |

`ds18x20_scan_devices()` returns all devices of the families above, and `ds18x20_read_temperature()` picks the right formula by the family code. The per-family functions (`ds18s20_read_temperature()`, `ds18b20_read_temperature()`, `max31850_read_temperature()`) remain available for the cases where the address is known in advance.

## 1-Wire backends

The backend is selected in `menuconfig` → `Component config` → `DS18x20` → `1-Wire backend`. The bit-banging driver is the default.

| | `CONFIG_DS18X20_ONEWIRE_BACKEND_BITBANG` (default) | `CONFIG_DS18X20_ONEWIRE_BACKEND_ESPRESSIF` |
| --- | --- | --- |
| Implementation | [esp-idf-lib/onewire](https://github.com/esp-idf-lib/onewire) | [espressif/onewire_bus](https://components.espressif.com/components/espressif/onewire_bus) |
| Hardware | A GPIO pin, no peripheral | A pair of RMT channels per bus |
| Interrupts | Disabled while a byte is transferred | The RMT peripheral does the timing, interrupts stay enabled |
| Parasitic power | Supported with a strong pull-up | Not supported, the sensors must have a power pin |
| Number of buses | Any number of pins | Up to `CONFIG_DS18X20_MAX_BUSES` (4 by default) |
| Timing accuracy | Depends on the interrupt latency | Generated by the hardware |

Pick the bit-banging backend when the sensors are parasitically powered, when RMT channels are needed elsewhere, or when the application already uses `esp-idf-lib/onewire`. Pick the RMT backend when long interrupt latencies or a busy WiFi stack make the bit-banging unreliable.

Both backends are declared as dependencies in `idf_component.yml`, because the dependency set is resolved before `sdkconfig` exists and cannot depend on the chosen backend. Both components are therefore downloaded and compiled, but only the selected one is linked into the image: the other one has no references, so the linker drops it.

The public API does not change with the backend: every function takes a GPIO pin, and the RMT bus object is created on the first access to the pin and kept until `ds18x20_bus_free()` is called. `ds18x20_bus_init()` creates the bus eagerly and lets the application detect the failure at a known place; with the bit-banging backend both functions only validate the pin.

### Parasitic power and the 85 °C reading

A sensor without a power pin takes the power from the data line and needs the bus to be held high with a strong pull-up during the conversion, which takes up to 750 ms. Only the bit-banging backend can do that: `ds18x20_measure()` with `wait = true` drives the pin as a push-pull output for the whole conversion.

The RMT backend cannot drive the bus during the conversion, because the pin belongs to the RMT peripheral. Such a sensor never converts and keeps the power-on value in its temperature register, which reads as 85 °C. The driver recognizes the pattern (85 °C together with the reserved byte `0x0C`) and returns `ESP_ERR_INVALID_RESPONSE` instead of a plausible-looking value, and logs the reason. Use externally powered sensors with the RMT backend, or add a transistor-based strong pull-up to the board.

### Pull-up resistor

The internal pull-up of the ESP32 is about 47 kΩ and does not meet the requirements of the 1-Wire bus. It works with one or two sensors on short wires, but a real application needs an external 4.7 kΩ resistor between the data line and 3.3 V.

## Resolution

The DS1822, DS18B20, DS1825 and DS28EA00 convert with 9, 10, 11 or 12 bits of resolution, which changes the conversion time and the step of the result:

| Resolution | Step | Conversion time |
| --- | --- | --- |
| 9 bit | 0.5 °C | 93.75 ms |
| 10 bit | 0.25 °C | 187.5 ms |
| 11 bit | 0.125 °C | 375 ms |
| 12 bit | 0.0625 °C | 750 ms |

`ds18x20_set_resolution()` writes the new value to the scratchpad and copies it to the EEPROM of the sensor, so it survives a power cycle. `ds18x20_get_resolution()` reads the value the sensor currently uses. The driver masks the bits that are undefined at the configured resolution, so a 9-bit sensor never reports a step finer than 0.5 °C.

`ds18x20_measure()` always waits for the longest conversion, 750 ms, so the code works with any resolution. The DS18S20 has a fixed 9-bit resolution, and the MAX31850 has a fixed 14-bit one: both functions return `ESP_ERR_NOT_SUPPORTED` for them.

## Examples

* [`examples/default`](examples/default) scans the bus, takes the first sensor it finds, prints its address and family, and reads the temperature once a second. It does not need the address of the sensor.
* [`examples/multi`](examples/multi) scans the bus and reads every sensor it finds, several times per second.

## Installation

```sh
idf.py add-dependency esp-idf-lib/ds18x20
```

## Support

For questions and discussions about the component, please use
[Discussions](https://github.com/esp-idf-lib/core/discussions)
at [esp-idf-lib/core](https://github.com/esp-idf-lib/core).

## Contributing

Please read [CONTRIBUTING.md](https://github.com/esp-idf-lib/core/blob/main/CONTRIBUTING.md)
at [esp-idf-lib/core](https://github.com/esp-idf-lib/core).

Links

Supports all targets

Maintainer

  • Ruslan V. Uss (@UncleRus) <unclerus@gmail.com>
To add this component to your project, run:

idf.py add-dependency "esp-idf-lib/ds18x20^1.3.1"

download archive

Stats

  • Archive size
    Archive size ~ 28.92 KB
  • Downloaded in total
    Downloaded in total 17.4k times
  • Weekly Downloads Weekly Downloads (All Versions)
  • Downloaded this version
    This version: 0 times

Badge

esp-idf-lib/ds18x20 version: 1.3.1
|