ESPHome 2025.5.0
Loading...
Searching...
No Matches
mlx90614.cpp
Go to the documentation of this file.
1#include "mlx90614.h"
2
3#include "esphome/core/hal.h"
4#include "esphome/core/log.h"
5
6namespace esphome {
7namespace mlx90614 {
8
9static const uint8_t MLX90614_RAW_IR_1 = 0x04;
10static const uint8_t MLX90614_RAW_IR_2 = 0x05;
11static const uint8_t MLX90614_TEMPERATURE_AMBIENT = 0x06;
12static const uint8_t MLX90614_TEMPERATURE_OBJECT_1 = 0x07;
13static const uint8_t MLX90614_TEMPERATURE_OBJECT_2 = 0x08;
14
15static const uint8_t MLX90614_TOMAX = 0x20;
16static const uint8_t MLX90614_TOMIN = 0x21;
17static const uint8_t MLX90614_PWMCTRL = 0x22;
18static const uint8_t MLX90614_TARANGE = 0x23;
19static const uint8_t MLX90614_EMISSIVITY = 0x24;
20static const uint8_t MLX90614_CONFIG = 0x25;
21static const uint8_t MLX90614_ADDR = 0x2E;
22static const uint8_t MLX90614_ID1 = 0x3C;
23static const uint8_t MLX90614_ID2 = 0x3D;
24static const uint8_t MLX90614_ID3 = 0x3E;
25static const uint8_t MLX90614_ID4 = 0x3F;
26
27static const char *const TAG = "mlx90614";
28
30 ESP_LOGCONFIG(TAG, "Setting up MLX90614...");
31 if (!this->write_emissivity_()) {
32 ESP_LOGE(TAG, "Communication with MLX90614 failed!");
33 this->mark_failed();
34 return;
35 }
36}
37
39 if (std::isnan(this->emissivity_))
40 return true;
41 uint16_t value = (uint16_t) (this->emissivity_ * 65535);
42 if (!this->write_bytes_(MLX90614_EMISSIVITY, 0)) {
43 return false;
44 }
45 delay(10);
46 if (!this->write_bytes_(MLX90614_EMISSIVITY, value)) {
47 return false;
48 }
49 delay(10);
50 return true;
51}
52
53uint8_t MLX90614Component::crc8_pec_(const uint8_t *data, uint8_t len) {
54 uint8_t crc = 0;
55 for (uint8_t i = 0; i < len; i++) {
56 uint8_t in = data[i];
57 for (uint8_t j = 0; j < 8; j++) {
58 bool carry = (crc ^ in) & 0x80;
59 crc <<= 1;
60 if (carry)
61 crc ^= 0x07;
62 in <<= 1;
63 }
64 }
65 return crc;
66}
67
68bool MLX90614Component::write_bytes_(uint8_t reg, uint16_t data) {
69 uint8_t buf[5];
70 buf[0] = this->address_ << 1;
71 buf[1] = reg;
72 buf[2] = data & 0xFF;
73 buf[3] = data >> 8;
74 buf[4] = this->crc8_pec_(buf, 4);
75 return this->write_bytes(reg, buf + 2, 3);
76}
77
79 ESP_LOGCONFIG(TAG, "MLX90614:");
80 LOG_I2C_DEVICE(this);
81 if (this->is_failed()) {
82 ESP_LOGE(TAG, "Communication with MLX90614 failed!");
83 }
84 LOG_UPDATE_INTERVAL(this);
85 LOG_SENSOR(" ", "Ambient", this->ambient_sensor_);
86 LOG_SENSOR(" ", "Object", this->object_sensor_);
87}
88
90
92 uint8_t emissivity[3];
93 if (this->read_register(MLX90614_EMISSIVITY, emissivity, 3, false) != i2c::ERROR_OK) {
94 this->status_set_warning();
95 return;
96 }
97 uint8_t raw_object[3];
98 if (this->read_register(MLX90614_TEMPERATURE_OBJECT_1, raw_object, 3, false) != i2c::ERROR_OK) {
99 this->status_set_warning();
100 return;
101 }
102
103 uint8_t raw_ambient[3];
104 if (this->read_register(MLX90614_TEMPERATURE_AMBIENT, raw_ambient, 3, false) != i2c::ERROR_OK) {
105 this->status_set_warning();
106 return;
107 }
108
109 float ambient = raw_ambient[1] & 0x80 ? NAN : encode_uint16(raw_ambient[1], raw_ambient[0]) * 0.02f - 273.15f;
110 float object = raw_object[1] & 0x80 ? NAN : encode_uint16(raw_object[1], raw_object[0]) * 0.02f - 273.15f;
111
112 ESP_LOGD(TAG, "Got Temperature=%.1f°C Ambient=%.1f°C", object, ambient);
113
114 if (this->ambient_sensor_ != nullptr && !std::isnan(ambient))
115 this->ambient_sensor_->publish_state(ambient);
116 if (this->object_sensor_ != nullptr && !std::isnan(object))
117 this->object_sensor_->publish_state(object);
118 this->status_clear_warning();
119}
120
121} // namespace mlx90614
122} // 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:53
bool write_bytes_(uint8_t reg, uint16_t data)
Definition mlx90614.cpp:68
float get_setup_priority() const override
Definition mlx90614.cpp:89
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:19
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:301
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:191
void IRAM_ATTR HOT delay(uint32_t ms)
Definition core.cpp:28