ESPHome 2025.6.2
Loading...
Searching...
No Matches
mlx90614.cpp
Go to the documentation of this file.
1#include "mlx90614.h"
2
3#include "esphome/core/hal.h"
5#include "esphome/core/log.h"
6
7namespace esphome {
8namespace mlx90614 {
9
10static const uint8_t MLX90614_RAW_IR_1 = 0x04;
11static const uint8_t MLX90614_RAW_IR_2 = 0x05;
12static const uint8_t MLX90614_TEMPERATURE_AMBIENT = 0x06;
13static const uint8_t MLX90614_TEMPERATURE_OBJECT_1 = 0x07;
14static const uint8_t MLX90614_TEMPERATURE_OBJECT_2 = 0x08;
15
16static const uint8_t MLX90614_TOMAX = 0x20;
17static const uint8_t MLX90614_TOMIN = 0x21;
18static const uint8_t MLX90614_PWMCTRL = 0x22;
19static const uint8_t MLX90614_TARANGE = 0x23;
20static const uint8_t MLX90614_EMISSIVITY = 0x24;
21static const uint8_t MLX90614_CONFIG = 0x25;
22static const uint8_t MLX90614_ADDR = 0x2E;
23static const uint8_t MLX90614_ID1 = 0x3C;
24static const uint8_t MLX90614_ID2 = 0x3D;
25static const uint8_t MLX90614_ID3 = 0x3E;
26static const uint8_t MLX90614_ID4 = 0x3F;
27
28static const char *const TAG = "mlx90614";
29
31 ESP_LOGCONFIG(TAG, "Running setup");
32 if (!this->write_emissivity_()) {
33 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
34 this->mark_failed();
35 return;
36 }
37}
38
40 if (std::isnan(this->emissivity_))
41 return true;
42 uint16_t value = (uint16_t) (this->emissivity_ * 65535);
43 if (!this->write_bytes_(MLX90614_EMISSIVITY, 0)) {
44 return false;
45 }
46 delay(10);
47 if (!this->write_bytes_(MLX90614_EMISSIVITY, value)) {
48 return false;
49 }
50 delay(10);
51 return true;
52}
53
54uint8_t MLX90614Component::crc8_pec_(const uint8_t *data, uint8_t len) {
55 uint8_t crc = 0;
56 for (uint8_t i = 0; i < len; i++) {
57 uint8_t in = data[i];
58 for (uint8_t j = 0; j < 8; j++) {
59 bool carry = (crc ^ in) & 0x80;
60 crc <<= 1;
61 if (carry)
62 crc ^= 0x07;
63 in <<= 1;
64 }
65 }
66 return crc;
67}
68
69bool MLX90614Component::write_bytes_(uint8_t reg, uint16_t data) {
70 uint8_t buf[5];
71 buf[0] = this->address_ << 1;
72 buf[1] = reg;
73 buf[2] = data & 0xFF;
74 buf[3] = data >> 8;
75 buf[4] = this->crc8_pec_(buf, 4);
76 return this->write_bytes(reg, buf + 2, 3);
77}
78
80 ESP_LOGCONFIG(TAG, "MLX90614:");
81 LOG_I2C_DEVICE(this);
82 if (this->is_failed()) {
83 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
84 }
85 LOG_UPDATE_INTERVAL(this);
86 LOG_SENSOR(" ", "Ambient", this->ambient_sensor_);
87 LOG_SENSOR(" ", "Object", this->object_sensor_);
88}
89
91
93 uint8_t emissivity[3];
94 if (this->read_register(MLX90614_EMISSIVITY, emissivity, 3, false) != i2c::ERROR_OK) {
95 this->status_set_warning();
96 return;
97 }
98 uint8_t raw_object[3];
99 if (this->read_register(MLX90614_TEMPERATURE_OBJECT_1, raw_object, 3, false) != i2c::ERROR_OK) {
100 this->status_set_warning();
101 return;
102 }
103
104 uint8_t raw_ambient[3];
105 if (this->read_register(MLX90614_TEMPERATURE_AMBIENT, raw_ambient, 3, false) != i2c::ERROR_OK) {
106 this->status_set_warning();
107 return;
108 }
109
110 float ambient = raw_ambient[1] & 0x80 ? NAN : encode_uint16(raw_ambient[1], raw_ambient[0]) * 0.02f - 273.15f;
111 float object = raw_object[1] & 0x80 ? NAN : encode_uint16(raw_object[1], raw_object[0]) * 0.02f - 273.15f;
112
113 ESP_LOGD(TAG, "Got Temperature=%.1f°C Ambient=%.1f°C", object, ambient);
114
115 if (this->ambient_sensor_ != nullptr && !std::isnan(ambient))
116 this->ambient_sensor_->publish_state(ambient);
117 if (this->object_sensor_ != nullptr && !std::isnan(object))
118 this->object_sensor_->publish_state(object);
119 this->status_clear_warning();
120}
121
122} // namespace mlx90614
123} // namespace esphome
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
void status_set_warning(const char *message="unspecified")
void status_clear_warning()
bool write_bytes(uint8_t a_register, const uint8_t *data, uint8_t len, bool stop=true)
Definition i2c.h:252
uint8_t address_
store the address of the device on the bus
Definition i2c.h:273
I2CRegister reg(uint8_t a_register)
calls the I2CRegister constructor
Definition i2c.h:153
ErrorCode read_register(uint8_t a_register, uint8_t *data, size_t len, bool stop=true)
reads an array of bytes from a specific register in the I²C device
Definition i2c.cpp:10
uint8_t crc8_pec_(const uint8_t *data, uint8_t len)
Definition mlx90614.cpp:54
bool write_bytes_(uint8_t reg, uint16_t data)
Definition mlx90614.cpp:69
float get_setup_priority() const override
Definition mlx90614.cpp:90
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:39
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:13
const float DATA
For components that import data from directly connected sensors like DHT.
Definition component.cpp:20
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:302
constexpr uint16_t encode_uint16(uint8_t msb, uint8_t lsb)
Encode a 16-bit value given the most and least significant byte.
Definition helpers.h:192
void IRAM_ATTR HOT delay(uint32_t ms)
Definition core.cpp:29