idfxx 1.0.0
Modern C++23 components for ESP-IDF
Loading...
Searching...
No Matches
ds18x20.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Chris Leishman
3
4#pragma once
5
21#include <idfxx/error>
22#include <idfxx/gpio>
23#include <idfxx/onewire>
24
25#include <array>
26#include <cstdint>
27#include <span>
28#include <string>
29#include <thermo/thermo>
30#include <vector>
31
36namespace idfxx::ds18x20 {
37
45enum class family : uint8_t {
46 ds18s20 = 0x10,
47 ds1822 = 0x22,
48 ds18b20 = 0x28,
49 max31850 = 0x3B,
50};
51
59enum class resolution : uint8_t {
60 bits_9 = 0x1F,
61 bits_10 = 0x3F,
62 bits_11 = 0x5F,
63 bits_12 = 0x7F,
64};
65
66class device;
67
68#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
81[[nodiscard]] inline std::vector<device> scan_devices(idfxx::gpio pin, size_t max_devices = 8);
82
94[[nodiscard]] inline std::vector<thermo::millicelsius> measure_and_read_multi(std::span<const device> devices);
95#endif
96
109
122
123#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
124inline std::vector<device> scan_devices(idfxx::gpio pin, size_t max_devices) {
125 return unwrap(try_scan_devices(pin, max_devices));
126}
127
128inline std::vector<thermo::millicelsius> measure_and_read_multi(std::span<const device> devices) {
130}
131#endif
132
154class device {
155public:
156#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
166#endif
167
177
178 // Copyable and movable
179 device(const device&) = default;
180 device(device&&) = default;
181 device& operator=(const device&) = default;
182 device& operator=(device&&) = default;
183
185 [[nodiscard]] constexpr bool operator==(const device&) const noexcept = default;
186
188 [[nodiscard]] constexpr idfxx::gpio pin() const { return _pin; }
189
191 [[nodiscard]] constexpr onewire::address addr() const { return _addr; }
192
193 // Temperature measurement
194#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
203 void measure(bool wait = true) { unwrap(try_measure(wait)); }
204
212 [[nodiscard]] thermo::millicelsius read_temperature() const { return unwrap(try_read_temperature()); }
213
223 [[nodiscard]] thermo::millicelsius measure_and_read() { return unwrap(try_measure_and_read()); }
224#endif
225
233 [[nodiscard]] result<void> try_measure(bool wait = true);
234
241
250
251 // Resolution configuration
252#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
264
275#endif
276
287
296
297 // Low-level scratchpad access
298#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
306 [[nodiscard]] std::array<uint8_t, 9> read_scratchpad() const { return unwrap(try_read_scratchpad()); }
307
315 void write_scratchpad(std::span<const uint8_t, 3> data) { unwrap(try_write_scratchpad(data)); }
316
327#endif
328
335
342 [[nodiscard]] result<void> try_write_scratchpad(std::span<const uint8_t, 3> data);
343
353
354private:
356
358 struct validated {};
360 : _pin(pin)
361 , _addr(addr) {}
364 idfxx::gpio _pin;
365 onewire::address _addr;
366};
367
// end of idfxx_ds18x20
369
370} // namespace idfxx::ds18x20
371
372namespace idfxx {
373
381[[nodiscard]] inline std::string to_string(ds18x20::family f) {
382 switch (f) {
384 return "DS18S20";
386 return "DS1822";
388 return "DS18B20";
390 return "MAX31850";
391 default: {
392 static constexpr char hex[] = "0123456789ABCDEF";
393 auto v = static_cast<uint8_t>(std::to_underlying(f));
394 return std::string("unknown(0x") + hex[v >> 4] + hex[v & 0xF] + ')';
395 }
396 }
397}
398
406[[nodiscard]] inline std::string to_string(ds18x20::resolution r) {
407 switch (r) {
409 return "9-bit";
411 return "10-bit";
413 return "11-bit";
415 return "12-bit";
416 default: {
417 static constexpr char hex[] = "0123456789ABCDEF";
418 auto v = static_cast<uint8_t>(std::to_underlying(r));
419 return std::string("unknown(0x") + hex[v >> 4] + hex[v & 0xF] + ')';
420 }
421 }
422}
423
424} // namespace idfxx
425
426#include "sdkconfig.h"
427#ifdef CONFIG_IDFXX_STD_FORMAT
429#include <algorithm>
430#include <format>
431namespace std {
432template<>
433struct formatter<idfxx::ds18x20::family> {
434 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
435
436 template<typename FormatContext>
437 auto format(idfxx::ds18x20::family f, FormatContext& ctx) const {
438 auto s = idfxx::to_string(f);
439 return std::copy(s.begin(), s.end(), ctx.out());
440 }
441};
442
443template<>
444struct formatter<idfxx::ds18x20::resolution> {
445 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
446
447 template<typename FormatContext>
448 auto format(idfxx::ds18x20::resolution r, FormatContext& ctx) const {
449 auto s = idfxx::to_string(r);
450 return std::copy(s.begin(), s.end(), ctx.out());
451 }
452};
453} // namespace std
455#endif // CONFIG_IDFXX_STD_FORMAT
DS18x20 1-Wire temperature sensor device.
Definition ds18x20.hpp:154
result< void > try_measure(bool wait=true)
Initiates a temperature conversion.
result< void > try_set_resolution(resolution res)
Sets the ADC resolution.
static result< device > make(idfxx::gpio pin, onewire::address addr=onewire::address::any())
Creates a validated device.
resolution get_resolution() const
Gets the current ADC resolution.
Definition ds18x20.hpp:274
void set_resolution(resolution res)
Sets the ADC resolution.
Definition ds18x20.hpp:263
constexpr onewire::address addr() const
Returns the device address.
Definition ds18x20.hpp:191
result< resolution > try_get_resolution() const
Gets the current ADC resolution.
thermo::millicelsius read_temperature() const
Reads the last converted temperature.
Definition ds18x20.hpp:212
void measure(bool wait=true)
Initiates a temperature conversion.
Definition ds18x20.hpp:203
device(device &&)=default
result< thermo::millicelsius > try_read_temperature() const
Reads the last converted temperature.
result< void > try_copy_scratchpad()
Copies the scratchpad to EEPROM.
device(const device &)=default
device(idfxx::gpio pin, onewire::address addr=onewire::address::any())
Constructs a validated device.
device & operator=(device &&)=default
void write_scratchpad(std::span< const uint8_t, 3 > data)
Writes 3 bytes to the scratchpad (TH, TL, configuration register).
Definition ds18x20.hpp:315
thermo::millicelsius measure_and_read()
Measures and reads the temperature in a single operation.
Definition ds18x20.hpp:223
result< thermo::millicelsius > try_measure_and_read()
Measures and reads the temperature in a single operation.
friend result< std::vector< device > > try_scan_devices(idfxx::gpio pin, size_t max_devices)
Scans for DS18x20 devices on a 1-Wire bus.
void copy_scratchpad()
Copies the scratchpad to EEPROM.
Definition ds18x20.hpp:326
result< void > try_write_scratchpad(std::span< const uint8_t, 3 > data)
Writes 3 bytes to the scratchpad (TH, TL, configuration register).
constexpr bool operator==(const device &) const noexcept=default
Compares two devices for equality.
std::array< uint8_t, 9 > read_scratchpad() const
Reads the 9-byte scratchpad memory.
Definition ds18x20.hpp:306
result< std::array< uint8_t, 9 > > try_read_scratchpad() const
Reads the 9-byte scratchpad memory.
constexpr idfxx::gpio pin() const
Returns the GPIO pin.
Definition ds18x20.hpp:188
device & operator=(const device &)=default
A GPIO pin.
Definition gpio.hpp:61
1-Wire device address.
Definition onewire.hpp:47
static constexpr address any()
Returns the wildcard address for single-device buses.
Definition onewire.hpp:67
std::string to_string(core_id c)
Returns a string representation of a CPU core identifier.
Definition cpu.hpp:52
std::vector< device > scan_devices(idfxx::gpio pin, size_t max_devices=8)
Scans for DS18x20 devices on a 1-Wire bus.
Definition ds18x20.hpp:124
result< std::vector< thermo::millicelsius > > try_measure_and_read_multi(std::span< const device > devices)
Measures and reads temperatures from multiple devices.
resolution
DS18B20 ADC resolution configuration.
Definition ds18x20.hpp:59
family
DS18x20 device family identifiers.
Definition ds18x20.hpp:45
std::vector< thermo::millicelsius > measure_and_read_multi(std::span< const device > devices)
Measures and reads temperatures from multiple devices.
Definition ds18x20.hpp:128
result< std::vector< device > > try_scan_devices(idfxx::gpio pin, size_t max_devices=8)
Scans for DS18x20 devices on a 1-Wire bus.
@ bits_11
11-bit resolution (~375ms conversion)
@ bits_12
12-bit resolution (~750ms conversion, default)
@ bits_9
9-bit resolution (~93.75ms conversion)
@ bits_10
10-bit resolution (~187.5ms conversion)
@ ds18s20
DS18S20 (9-bit, +/-0.5C)
@ ds1822
DS1822 (12-bit, +/-2C)
@ max31850
MAX31850 (14-bit, +/-0.25C)
@ ds18b20
DS18B20 (12-bit, +/-0.5C)
DS18x20 1-Wire temperature sensor classes and utilities.
Definition ds18x20.hpp:36
T unwrap(result< T > result)
Throws a std::system_error if the result is an error.
Definition error.hpp:307
std::expected< T, std::error_code > result
result type wrapping a value or error code.
Definition error.hpp:120