ESPHome 2025.5.0
Loading...
Searching...
No Matches
max31856.cpp
Go to the documentation of this file.
1#include "max31856.h"
2
3#include "esphome/core/log.h"
4#include <cmath>
5
6namespace esphome {
7namespace max31856 {
8
9static const char *const TAG = "max31856";
10
11// Based on Adafruit's library: https://github.com/adafruit/Adafruit_MAX31856
12
14 ESP_LOGCONFIG(TAG, "Setting up MAX31856Sensor '%s'...", this->name_.c_str());
15 this->spi_setup();
16
17 // assert on any fault
18 ESP_LOGCONFIG(TAG, "Setting up assertion on all faults");
20
21 ESP_LOGCONFIG(TAG, "Setting up open circuit fault detection");
23
25 this->set_noise_filter_();
26
27 ESP_LOGCONFIG(TAG, "Completed setting up MAX31856Sensor '%s'...", this->name_.c_str());
28}
29
31 LOG_SENSOR("", "MAX31856", this);
32 LOG_PIN(" CS Pin: ", this->cs_);
33 ESP_LOGCONFIG(TAG, " Mains Filter: %s",
34 (filter_ == FILTER_60HZ ? "60 Hz" : (filter_ == FILTER_50HZ ? "50 Hz" : "Unknown!")));
36 ESP_LOGCONFIG(TAG, " Thermocouple Type: Unknown");
37 } else {
38 ESP_LOGCONFIG(TAG, " Thermocouple Type: %c", "BEJKNRST"[this->thermocouple_type_]);
39 }
40
41 LOG_UPDATE_INTERVAL(this);
42}
43
45 ESP_LOGVV(TAG, "update");
46
48
49 // Datasheet max conversion time for 1 shot is 155ms for 60Hz / 185ms for 50Hz
50 auto f = std::bind(&MAX31856Sensor::read_thermocouple_temperature_, this);
51 this->set_timeout("MAX31856Sensor::read_thermocouple_temperature_", filter_ == FILTER_60HZ ? 155 : 185, f);
52}
53
55 if (this->has_fault_()) {
56 // Faults have been logged, clear it for next loop
57 this->clear_fault_();
58 } else {
59 int32_t temp24 = this->read_register24_(MAX31856_LTCBH_REG);
60 if (temp24 & 0x800000) {
61 temp24 |= 0xFF000000; // fix sign
62 }
63
64 temp24 >>= 5; // bottom 5 bits are unused
65
66 float temp_c = temp24;
67 temp_c *= 0.0078125;
68
69 ESP_LOGD(TAG, "Got thermocouple temperature: %.2f°C", temp_c);
70 this->publish_state(temp_c);
71 }
72}
73
75 ESP_LOGVV(TAG, "one_shot_temperature_");
77
78 uint8_t t = this->read_register_(MAX31856_CR0_REG);
79
80 t &= ~MAX31856_CR0_AUTOCONVERT; // turn off autoconversion mode
81 t |= MAX31856_CR0_1SHOT; // turn on one shot mode
82
84}
85
87 ESP_LOGVV(TAG, "read_fault_");
88 uint8_t faults = this->read_register_(MAX31856_SR_REG);
89
90 if (faults == 0) {
91 ESP_LOGV(TAG, "status_set_warning");
93 return false;
94 }
95
96 ESP_LOGV(TAG, "status_set_warning");
97 this->status_set_warning();
98
100 ESP_LOGW(TAG, "Cold Junction Out-of-Range: '%s'...", this->name_.c_str());
101 }
103 ESP_LOGW(TAG, "Thermocouple Out-of-Range: '%s'...", this->name_.c_str());
104 }
106 ESP_LOGW(TAG, "Cold-Junction High Fault: '%s'...", this->name_.c_str());
107 }
108 if ((faults & MAX31856_FAULT_CJLOW) == MAX31856_FAULT_CJLOW) {
109 ESP_LOGW(TAG, "Cold-Junction Low Fault: '%s'...", this->name_.c_str());
110 }
112 ESP_LOGW(TAG, "Thermocouple Temperature High Fault: '%s'...", this->name_.c_str());
113 }
114 if ((faults & MAX31856_FAULT_TCLOW) == MAX31856_FAULT_TCLOW) {
115 ESP_LOGW(TAG, "Thermocouple Temperature Low Fault: '%s'...", this->name_.c_str());
116 }
117 if ((faults & MAX31856_FAULT_OVUV) == MAX31856_FAULT_OVUV) {
118 ESP_LOGW(TAG, "Overvoltage or Undervoltage Input Fault: '%s'...", this->name_.c_str());
119 }
120 if ((faults & MAX31856_FAULT_OPEN) == MAX31856_FAULT_OPEN) {
121 ESP_LOGW(TAG, "Thermocouple Open-Circuit Fault (possibly not connected): '%s'...", this->name_.c_str());
122 }
123
124 return true;
125}
126
128 ESP_LOGV(TAG, "clear_fault_");
129 uint8_t t = this->read_register_(MAX31856_CR0_REG);
130
131 t |= MAX31856_CR0_FAULT; // turn on fault interrupt mode
132 t |= MAX31856_CR0_FAULTCLR; // enable the fault status clear bit
133
135}
136
140 type = MAX31856_TCTYPE_K;
141 } else {
142 type = this->thermocouple_type_;
143 }
144 ESP_LOGCONFIG(TAG, "set_thermocouple_type_: 0x%02X", type);
145 uint8_t t = this->read_register_(MAX31856_CR1_REG);
146 t &= 0xF0; // mask off bottom 4 bits
147 t |= (uint8_t) type & 0x0F;
149}
150
152 ESP_LOGCONFIG(TAG, "set_noise_filter_: 0x%02X", filter_);
153 uint8_t t = this->read_register_(MAX31856_CR0_REG);
154 if (filter_ == FILTER_50HZ) {
155 t |= 0x01;
156 ESP_LOGCONFIG(TAG, "set_noise_filter_: 50 Hz, t==0x%02X", t);
157 } else {
158 t &= 0xfe;
159 ESP_LOGCONFIG(TAG, "set_noise_filter_: 60 Hz, t==0x%02X", t);
160 }
162}
163
164void MAX31856Sensor::write_register_(uint8_t reg, uint8_t value) {
165 ESP_LOGVV(TAG, "write_register_ raw reg=0x%02X value=0x%02X", reg, value);
166 reg |= SPI_WRITE_M;
167 ESP_LOGVV(TAG, "write_register_ masked reg=0x%02X value=0x%02X", reg, value);
168 this->enable();
169 ESP_LOGVV(TAG, "write_byte reg=0x%02X", reg);
170 this->write_byte(reg);
171 ESP_LOGVV(TAG, "write_byte value=0x%02X", value);
172 this->write_byte(value);
173 this->disable();
174 ESP_LOGV(TAG, "write_register_ 0x%02X: 0x%02X", reg, value);
175}
176
177uint8_t MAX31856Sensor::read_register_(uint8_t reg) {
178 ESP_LOGVV(TAG, "read_register_ 0x%02X", reg);
179 this->enable();
180 ESP_LOGVV(TAG, "write_byte reg=0x%02X", reg);
181 this->write_byte(reg);
182 const uint8_t value(this->read_byte());
183 ESP_LOGVV(TAG, "read_byte value=0x%02X", value);
184 this->disable();
185 ESP_LOGV(TAG, "read_register_ reg=0x%02X: value=0x%02X", reg, value);
186 return value;
187}
188
189uint32_t MAX31856Sensor::read_register24_(uint8_t reg) {
190 ESP_LOGVV(TAG, "read_register_24_ 0x%02X", reg);
191 this->enable();
192 ESP_LOGVV(TAG, "write_byte reg=0x%02X", reg);
193 this->write_byte(reg);
194 const uint8_t msb(this->read_byte());
195 ESP_LOGVV(TAG, "read_byte msb=0x%02X", msb);
196 const uint8_t mid(this->read_byte());
197 ESP_LOGVV(TAG, "read_byte mid=0x%02X", mid);
198 const uint8_t lsb(this->read_byte());
199 ESP_LOGVV(TAG, "read_byte lsb=0x%02X", lsb);
200 this->disable();
201 const uint32_t value((msb << 16) | (mid << 8) | lsb);
202 ESP_LOGV(TAG, "read_register_24_ reg=0x%02X: value=0x%06" PRIX32, reg, value);
203 return value;
204}
205
207
208} // namespace max31856
209} // namespace esphome
void status_set_warning(const char *message="unspecified")
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.
Definition component.cpp:72
constexpr const char * c_str() const
Definition string_ref.h:68
void write_register_(uint8_t reg, uint8_t value)
Definition max31856.cpp:164
float get_setup_priority() const override
Definition max31856.cpp:206
MAX31856ConfigFilter filter_
Definition max31856.h:87
MAX31856ThermocoupleType thermocouple_type_
Definition max31856.h:88
uint32_t read_register24_(uint8_t reg)
Definition max31856.cpp:189
uint8_t read_register_(uint8_t reg)
Definition max31856.cpp:177
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:39
uint8_t type
MAX31856ThermocoupleType
Multiple types of thermocouples supported by the chip.
Definition max31856.h:54
@ MAX31856_CR0_1SHOT
Config 0 one shot convert flag.
Definition max31856.h:17
@ MAX31856_CR1_REG
Config 1 register.
Definition max31856.h:25
@ MAX31856_FAULT_TCLOW
Fault status Thermocouple Temperature Low Fault flag.
Definition max31856.h:46
@ MAX31856_CR0_FAULT
Config 0 fault mode flag.
Definition max31856.h:22
@ MAX31856_LTCBH_REG
Linearized TC Temperature, Byte 2.
Definition max31856.h:36
@ MAX31856_FAULT_TCRANGE
Fault status Thermocouple Out-of-Range flag.
Definition max31856.h:42
@ MAX31856_CR0_REG
Config 0 register.
Definition max31856.h:15
@ MAX31856_CJTO_REG
Cold-Junction Temperature Offset Register.
Definition max31856.h:33
@ MAX31856_FAULT_OPEN
Fault status Thermocouple Open-Circuit Fault flag.
Definition max31856.h:48
@ MAX31856_FAULT_CJHIGH
Fault status Cold-Junction High Fault flag.
Definition max31856.h:43
@ MAX31856_SR_REG
Fault Status Register.
Definition max31856.h:39
@ MAX31856_MASK_REG
Fault Mask register.
Definition max31856.h:26
@ MAX31856_FAULT_CJLOW
Fault status Cold-Junction Low Fault flag.
Definition max31856.h:44
@ MAX31856_FAULT_OVUV
Fault status Overvoltage or Undervoltage Input Fault flag.
Definition max31856.h:47
@ MAX31856_CR0_OCFAULT01
Config 0 open circuit fault 01 flag.
Definition max31856.h:19
@ MAX31856_FAULT_TCHIGH
Fault status Thermocouple Temperature High Fault flag.
Definition max31856.h:45
@ MAX31856_FAULT_CJRANGE
Fault status Cold Junction Out-of-Range flag.
Definition max31856.h:41
@ MAX31856_CR0_FAULTCLR
Config 0 fault clear flag.
Definition max31856.h:23
const float DATA
For components that import data from directly connected sensors like DHT.
Definition component.cpp:19
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7