ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
dallas_temp.cpp
Go to the documentation of this file.
1#include "dallas_temp.h"
2#include "esphome/core/log.h"
3
5
6static const char *const TAG = "dallas.temp.sensor";
7
8static const uint8_t DALLAS_MODEL_DS18S20 = 0x10;
9static const uint8_t DALLAS_COMMAND_START_CONVERSION = 0x44;
10static const uint8_t DALLAS_COMMAND_READ_SCRATCH_PAD = 0xBE;
11static const uint8_t DALLAS_COMMAND_WRITE_SCRATCH_PAD = 0x4E;
12static const uint8_t DALLAS_COMMAND_COPY_SCRATCH_PAD = 0x48;
13
15 switch (this->resolution_) {
16 case 9:
17 return 94;
18 case 10:
19 return 188;
20 case 11:
21 return 375;
22 default:
23 return 750;
24 }
25}
26
28 ESP_LOGCONFIG(TAG, "Dallas Temperature Sensor:");
29 if (this->address_ == 0) {
30 ESP_LOGW(TAG, " Unable to select an address");
31 return;
32 }
33 LOG_ONE_WIRE_DEVICE(this);
34 ESP_LOGCONFIG(TAG, " Resolution: %u bits", this->resolution_);
35 LOG_UPDATE_INTERVAL(this);
36}
37
39 if (this->address_ == 0)
40 return;
41
43
44 this->send_command_(DALLAS_COMMAND_START_CONVERSION);
45
46 this->set_timeout(this->get_address_name().c_str(), this->millis_to_wait_for_conversion_(), [this] {
47 if (!this->read_scratch_pad_() || !this->check_scratch_pad_()) {
48 this->publish_state(NAN);
49 return;
50 }
51
52 float tempc = this->get_temp_c_();
53 ESP_LOGD(TAG, "'%s': Got Temperature=%f°C", this->get_name().c_str(), tempc);
54 this->publish_state(tempc);
55 });
56}
57
59 bool success = this->send_command_(DALLAS_COMMAND_READ_SCRATCH_PAD);
60 if (success) {
61 for (uint8_t &i : this->scratch_pad_) {
62 i = this->bus_->read8();
63 }
64 } else {
65 ESP_LOGW(TAG, "'%s' - reading scratch pad failed bus reset", this->get_name().c_str());
66 this->status_set_warning(LOG_STR("bus reset failed"));
67 }
68 return success;
69}
70
72 if (!this->check_address_or_index_())
73 return;
74 if (!this->read_scratch_pad_())
75 return;
76 if (!this->check_scratch_pad_())
77 return;
78
79 if ((this->address_ & 0xff) == DALLAS_MODEL_DS18S20) {
80 // DS18S20 doesn't support resolution.
81 ESP_LOGW(TAG, "DS18S20 doesn't support setting resolution");
82 return;
83 }
84
85 uint8_t res;
86 switch (this->resolution_) {
87 case 12:
88 res = 0x7F;
89 break;
90 case 11:
91 res = 0x5F;
92 break;
93 case 10:
94 res = 0x3F;
95 break;
96 case 9:
97 default:
98 res = 0x1F;
99 break;
100 }
101
102 if (this->scratch_pad_[4] == res)
103 return;
104 this->scratch_pad_[4] = res;
105
106 if (this->send_command_(DALLAS_COMMAND_WRITE_SCRATCH_PAD)) {
107 this->bus_->write8(this->scratch_pad_[2]); // high alarm temp
108 this->bus_->write8(this->scratch_pad_[3]); // low alarm temp
109 this->bus_->write8(this->scratch_pad_[4]); // resolution
110 }
111
112 // write value to EEPROM
113 this->send_command_(DALLAS_COMMAND_COPY_SCRATCH_PAD);
114}
115
117 bool chksum_validity = (crc8(this->scratch_pad_, 8) == this->scratch_pad_[8]);
118
119#ifdef ESPHOME_LOG_LEVEL_VERY_VERBOSE
120 ESP_LOGVV(TAG, "Scratch pad: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X (%02X)", this->scratch_pad_[0],
121 this->scratch_pad_[1], this->scratch_pad_[2], this->scratch_pad_[3], this->scratch_pad_[4],
122 this->scratch_pad_[5], this->scratch_pad_[6], this->scratch_pad_[7], this->scratch_pad_[8],
123 crc8(this->scratch_pad_, 8));
124#endif
125 if (!chksum_validity) {
126 this->status_set_warning(LOG_STR("scratch pad checksum invalid"));
127 ESP_LOGD(TAG, "Scratch pad: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X (%02X)", this->scratch_pad_[0],
128 this->scratch_pad_[1], this->scratch_pad_[2], this->scratch_pad_[3], this->scratch_pad_[4],
129 this->scratch_pad_[5], this->scratch_pad_[6], this->scratch_pad_[7], this->scratch_pad_[8],
130 crc8(this->scratch_pad_, 8));
131 }
132 return chksum_validity;
133}
134
136 int16_t temp = (this->scratch_pad_[1] << 8) | this->scratch_pad_[0];
137 if ((this->address_ & 0xff) == DALLAS_MODEL_DS18S20) {
138 if (this->scratch_pad_[7] == 0) {
139 return NAN;
140 }
141 return (temp >> 1) + (this->scratch_pad_[7] - this->scratch_pad_[6]) / float(this->scratch_pad_[7]) - 0.25;
142 }
143 switch (this->resolution_) {
144 case 9:
145 temp &= 0xfff8;
146 break;
147 case 10:
148 temp &= 0xfffc;
149 break;
150 case 11:
151 temp &= 0xfffe;
152 break;
153 case 12:
154 default:
155 break;
156 }
157
158 return temp / 16.0f;
159}
160
161} // namespace esphome::dallas_temp
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") void set_timeout(const std voi set_timeout)(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition component.h:493
void status_clear_warning()
Definition component.h:289
const StringRef & get_name() const
Definition entity_base.h:71
uint16_t millis_to_wait_for_conversion_() const
Get the number of milliseconds we have to wait for the conversion phase.
virtual void write8(uint8_t val)=0
Write a word to the bus. LSB first.
virtual uint8_t read8()=0
Read an 8 bit word from the bus.
OneWireBus * bus_
pointer to OneWireBus instance
Definition one_wire.h:33
bool send_command_(uint8_t cmd)
send command on the bus
Definition one_wire.cpp:20
const std::string & get_address_name()
Helper to create (and cache) the name for this sensor. For example "0xfe0000031f1eaf29".
Definition one_wire.cpp:7
bool check_address_or_index_()
find an address if necessary should be called from setup
Definition one_wire.cpp:27
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:68
uint8_t crc8(const uint8_t *data, uint8_t len, uint8_t crc, uint8_t poly, bool msb_first)
Calculate a CRC-8 checksum of data with size len.
Definition helpers.cpp:59