ESPHome  2022.12.8
max31855.cpp
Go to the documentation of this file.
1 #include "max31855.h"
2 
3 #include "esphome/core/log.h"
4 
5 namespace esphome {
6 namespace max31855 {
7 
8 static const char *const TAG = "max31855";
9 
11  this->enable();
12  delay(1);
13  // conversion initiated by rising edge
14  this->disable();
15 
16  // Conversion time typ: 170ms, max: 220ms
17  auto f = std::bind(&MAX31855Sensor::read_data_, this);
18  this->set_timeout("value", 220, f);
19 }
20 
22  ESP_LOGCONFIG(TAG, "Setting up MAX31855Sensor '%s'...", this->name_.c_str());
23  this->spi_setup();
24 }
26  ESP_LOGCONFIG(TAG, "MAX31855:");
27  LOG_PIN(" CS Pin: ", this->cs_);
28  LOG_UPDATE_INTERVAL(this);
29  LOG_SENSOR(" ", "Thermocouple", this);
30  if (this->temperature_reference_) {
31  LOG_SENSOR(" ", "Reference", this->temperature_reference_);
32  } else {
33  ESP_LOGCONFIG(TAG, " Reference temperature disabled.");
34  }
35 }
38  this->enable();
39  delay(1);
40  uint8_t data[4];
41  this->read_array(data, 4);
42  this->disable();
43 
44  const uint32_t mem = encode_uint32(data[0], data[1], data[2], data[3]);
45 
46  // Verify we got data
47  if (mem != 0xFFFFFFFF) {
48  this->status_clear_error();
49  } else {
50  ESP_LOGE(TAG, "No data received from MAX31855 (0x%08X). Check wiring!", mem);
51  this->publish_state(NAN);
52  if (this->temperature_reference_) {
54  }
55  this->status_set_error();
56  return;
57  }
58 
59  // Internal reference temperature always works
60  if (this->temperature_reference_) {
61  int16_t val = (mem & 0x0000FFF0) >> 4;
62  if (val & 0x0800) {
63  val |= 0xF000; // Pad out 2's complement
64  }
65  const float t_ref = float(val) * 0.0625f;
66  ESP_LOGD(TAG, "Got reference temperature: %.4f°C", t_ref);
68  }
69 
70  // Check thermocouple faults
71  if (mem & 0x00000001) {
72  ESP_LOGW(TAG, "Thermocouple open circuit (not connected) fault from MAX31855 (0x%08X)", mem);
73  this->publish_state(NAN);
74  this->status_set_warning();
75  return;
76  }
77  if (mem & 0x00000002) {
78  ESP_LOGW(TAG, "Thermocouple short circuit to ground fault from MAX31855 (0x%08X)", mem);
79  this->publish_state(NAN);
80  this->status_set_warning();
81  return;
82  }
83  if (mem & 0x00000004) {
84  ESP_LOGW(TAG, "Thermocouple short circuit to VCC fault from MAX31855 (0x%08X)", mem);
85  this->publish_state(NAN);
86  this->status_set_warning();
87  return;
88  }
89  if (mem & 0x00010000) {
90  ESP_LOGW(TAG, "Got faulty reading from MAX31855 (0x%08X)", mem);
91  this->publish_state(NAN);
92  this->status_set_warning();
93  return;
94  }
95 
96  // Decode thermocouple temperature
97  int16_t val = (mem & 0xFFFC0000) >> 18;
98  if (val & 0x2000) {
99  val |= 0xC000; // Pad out 2's complement
100  }
101  const float t_sense = float(val) * 0.25f;
102  ESP_LOGD(TAG, "Got thermocouple temperature: %.2f°C", t_sense);
103  this->publish_state(t_sense);
104  this->status_clear_warning();
105 }
106 
107 } // namespace max31855
108 } // namespace esphome
float get_setup_priority() const override
Definition: max31855.cpp:36
const float DATA
For components that import data from directly connected sensors like DHT.
Definition: component.cpp:18
std::string name_
Definition: entity_base.h:54
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:68
constexpr uint32_t encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4)
Encode a 32-bit value given four bytes in most to least significant byte order.
Definition: helpers.h:175
sensor::Sensor * temperature_reference_
Definition: max31855.h:25
void status_clear_warning()
Definition: component.cpp:149
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:72
void status_set_warning()
Definition: component.cpp:141
void status_clear_error()
Definition: component.cpp:150
Definition: a4988.cpp:4
uint32_t val
Definition: datatypes.h:85
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:27