ESPHome 2025.9.0-dev
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 this->spi_setup();
15
16 // assert on any fault
19
21 this->set_noise_filter_();
22}
23
25 LOG_SENSOR("", "MAX31856", this);
26 LOG_PIN(" CS Pin: ", this->cs_);
27 ESP_LOGCONFIG(TAG, " Mains Filter: %s",
28 (filter_ == FILTER_60HZ ? "60 Hz" : (filter_ == FILTER_50HZ ? "50 Hz" : "Unknown!")));
30 ESP_LOGCONFIG(TAG, " Thermocouple Type: Unknown");
31 } else {
32 ESP_LOGCONFIG(TAG, " Thermocouple Type: %c", "BEJKNRST"[this->thermocouple_type_]);
33 }
34
35 LOG_UPDATE_INTERVAL(this);
36}
37
39 ESP_LOGVV(TAG, "update");
40
42
43 // Datasheet max conversion time for 1 shot is 155ms for 60Hz / 185ms for 50Hz
44 auto f = std::bind(&MAX31856Sensor::read_thermocouple_temperature_, this);
45 this->set_timeout("MAX31856Sensor::read_thermocouple_temperature_", filter_ == FILTER_60HZ ? 155 : 185, f);
46}
47
49 if (this->has_fault_()) {
50 // Faults have been logged, clear it for next loop
51 this->clear_fault_();
52 } else {
53 int32_t temp24 = this->read_register24_(MAX31856_LTCBH_REG);
54 if (temp24 & 0x800000) {
55 temp24 |= 0xFF000000; // fix sign
56 }
57
58 temp24 >>= 5; // bottom 5 bits are unused
59
60 float temp_c = temp24;
61 temp_c *= 0.0078125;
62
63 ESP_LOGD(TAG, "Got thermocouple temperature: %.2f°C", temp_c);
64 this->publish_state(temp_c);
65 }
66}
67
69 ESP_LOGVV(TAG, "one_shot_temperature_");
71
72 uint8_t t = this->read_register_(MAX31856_CR0_REG);
73
74 t &= ~MAX31856_CR0_AUTOCONVERT; // turn off autoconversion mode
75 t |= MAX31856_CR0_1SHOT; // turn on one shot mode
76
78}
79
81 ESP_LOGVV(TAG, "read_fault_");
82 uint8_t faults = this->read_register_(MAX31856_SR_REG);
83
84 if (faults == 0) {
85 ESP_LOGV(TAG, "status_set_warning");
87 return false;
88 }
89
90 ESP_LOGV(TAG, "status_set_warning");
91 this->status_set_warning();
92
94 ESP_LOGW(TAG, "Cold Junction Out-of-Range: '%s'", this->name_.c_str());
95 }
97 ESP_LOGW(TAG, "Thermocouple Out-of-Range: '%s'", this->name_.c_str());
98 }
100 ESP_LOGW(TAG, "Cold-Junction High Fault: '%s'", this->name_.c_str());
101 }
102 if ((faults & MAX31856_FAULT_CJLOW) == MAX31856_FAULT_CJLOW) {
103 ESP_LOGW(TAG, "Cold-Junction Low Fault: '%s'", this->name_.c_str());
104 }
106 ESP_LOGW(TAG, "Thermocouple Temperature High Fault: '%s'", this->name_.c_str());
107 }
108 if ((faults & MAX31856_FAULT_TCLOW) == MAX31856_FAULT_TCLOW) {
109 ESP_LOGW(TAG, "Thermocouple Temperature Low Fault: '%s'", this->name_.c_str());
110 }
111 if ((faults & MAX31856_FAULT_OVUV) == MAX31856_FAULT_OVUV) {
112 ESP_LOGW(TAG, "Overvoltage or Undervoltage Input Fault: '%s'", this->name_.c_str());
113 }
114 if ((faults & MAX31856_FAULT_OPEN) == MAX31856_FAULT_OPEN) {
115 ESP_LOGW(TAG, "Thermocouple Open-Circuit Fault (possibly not connected): '%s'", this->name_.c_str());
116 }
117
118 return true;
119}
120
122 ESP_LOGV(TAG, "clear_fault_");
123 uint8_t t = this->read_register_(MAX31856_CR0_REG);
124
125 t |= MAX31856_CR0_FAULT; // turn on fault interrupt mode
126 t |= MAX31856_CR0_FAULTCLR; // enable the fault status clear bit
127
129}
130
134 type = MAX31856_TCTYPE_K;
135 } else {
136 type = this->thermocouple_type_;
137 }
138 ESP_LOGCONFIG(TAG, "set_thermocouple_type_: 0x%02X", type);
139 uint8_t t = this->read_register_(MAX31856_CR1_REG);
140 t &= 0xF0; // mask off bottom 4 bits
141 t |= (uint8_t) type & 0x0F;
143}
144
146 ESP_LOGCONFIG(TAG, "set_noise_filter_: 0x%02X", filter_);
147 uint8_t t = this->read_register_(MAX31856_CR0_REG);
148 if (filter_ == FILTER_50HZ) {
149 t |= 0x01;
150 ESP_LOGCONFIG(TAG, "set_noise_filter_: 50 Hz, t==0x%02X", t);
151 } else {
152 t &= 0xfe;
153 ESP_LOGCONFIG(TAG, "set_noise_filter_: 60 Hz, t==0x%02X", t);
154 }
156}
157
158void MAX31856Sensor::write_register_(uint8_t reg, uint8_t value) {
159 ESP_LOGVV(TAG, "write_register_ raw reg=0x%02X value=0x%02X", reg, value);
160 reg |= SPI_WRITE_M;
161 ESP_LOGVV(TAG, "write_register_ masked reg=0x%02X value=0x%02X", reg, value);
162 this->enable();
163 ESP_LOGVV(TAG, "write_byte reg=0x%02X", reg);
164 this->write_byte(reg);
165 ESP_LOGVV(TAG, "write_byte value=0x%02X", value);
166 this->write_byte(value);
167 this->disable();
168 ESP_LOGV(TAG, "write_register_ 0x%02X: 0x%02X", reg, value);
169}
170
171uint8_t MAX31856Sensor::read_register_(uint8_t reg) {
172 ESP_LOGVV(TAG, "read_register_ 0x%02X", reg);
173 this->enable();
174 ESP_LOGVV(TAG, "write_byte reg=0x%02X", reg);
175 this->write_byte(reg);
176 const uint8_t value(this->read_byte());
177 ESP_LOGVV(TAG, "read_byte value=0x%02X", value);
178 this->disable();
179 ESP_LOGV(TAG, "read_register_ reg=0x%02X: value=0x%02X", reg, value);
180 return value;
181}
182
183uint32_t MAX31856Sensor::read_register24_(uint8_t reg) {
184 ESP_LOGVV(TAG, "read_register_24_ 0x%02X", reg);
185 this->enable();
186 ESP_LOGVV(TAG, "write_byte reg=0x%02X", reg);
187 this->write_byte(reg);
188 const uint8_t msb(this->read_byte());
189 ESP_LOGVV(TAG, "read_byte msb=0x%02X", msb);
190 const uint8_t mid(this->read_byte());
191 ESP_LOGVV(TAG, "read_byte mid=0x%02X", mid);
192 const uint8_t lsb(this->read_byte());
193 ESP_LOGVV(TAG, "read_byte lsb=0x%02X", lsb);
194 this->disable();
195 const uint32_t value((msb << 16) | (mid << 8) | lsb);
196 ESP_LOGV(TAG, "read_register_24_ reg=0x%02X: value=0x%06" PRIX32, reg, value);
197 return value;
198}
199
201
202} // namespace max31856
203} // 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.
constexpr const char * c_str() const
Definition string_ref.h:69
void write_register_(uint8_t reg, uint8_t value)
Definition max31856.cpp:158
float get_setup_priority() const override
Definition max31856.cpp:200
MAX31856ConfigFilter filter_
Definition max31856.h:87
MAX31856ThermocoupleType thermocouple_type_
Definition max31856.h:88
uint32_t read_register24_(uint8_t reg)
Definition max31856.cpp:183
uint8_t read_register_(uint8_t reg)
Definition max31856.cpp:171
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:45
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:50
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7