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