# esp-idf-lib/ds18x20 [](https://github.com/esp-idf-lib/ds18x20/actions/workflows/build.yml) [](https://github.com/esp-idf-lib/ds18x20/actions/workflows/build-docs.yml) [](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).
6c8e85980e2f49e4bfe019577e94414b2622bf0c
idf.py add-dependency "esp-idf-lib/ds18x20^1.3.1"