M5Unit-THERMO 0.3.1 git rev:c2bfb11
Loading...
Searching...
No Matches
unit_MLX90614.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_THERMO_UNIT_MLX90614_HPP
11#define M5_UNIT_THERMO_UNIT_MLX90614_HPP
12
13#include <M5UnitComponent.hpp>
14#include <m5_utility/container/circular_buffer.hpp>
15#include <limits> // NaN
16#include <array>
17
18namespace m5 {
19namespace unit {
20
25namespace mlx90614 {
26
31enum class Output : uint8_t {
32 TA_TO1,
33 TA_TO2,
35 TO1_TO2,
36};
37
42enum class IIR : uint8_t {
43 Filter50,
44 Filter25,
45 Filter17,
46 Filter13,
47 Filter100,
48 Filter80,
49 Filter67,
50 Filter57,
51};
52
57enum class FIR : uint8_t {
58 Filter8,
59 Filter16,
60 Filter32,
61 Filter64,
62 Filter128,
63 Filter256,
64 Filter512,
66
67};
68
73enum class Gain : uint8_t {
74 Coeff1,
75 Coeff3,
76 Coeff6,
77 Coeff12_5,
78 Coeff25,
79 Coeff50,
80 Coeff100,
81 // [7] Coeff100 (duplicate)
82};
83
88enum class IRSensor : uint8_t {
89 Single,
90 Dual
91};
92
97struct Data {
98 std::array<uint16_t, 3> raw{};
99
101 inline float ambientKelvin() const
102 {
103 return ((raw[0] & 0x8000) == 0) ? raw[0] * 0.02f : std::numeric_limits<float>::quiet_NaN();
104 }
106 inline float ambientTemperature() const
107 {
108 return ambientCelsius();
109 }
111 inline float ambientCelsius() const
112 {
113 return ambientKelvin() - 273.15f;
114 }
116 inline float ambientFahrenheit() const
117 {
118 return ambientCelsius() * 9.0f / 5.0f + 32.f;
119 }
120
122 inline float objectKelvin1() const
123 {
124 return ((raw[1] & 0x8000) == 0) ? raw[1] * 0.02f : std::numeric_limits<float>::quiet_NaN();
125 }
127 inline float objectTemperature1() const
128 {
129 return objectCelsius1();
130 }
132 inline float objectCelsius1() const
133 {
134 return objectKelvin1() - 273.15f;
135 }
137 inline float objectFahrenheit1() const
138 {
139 return objectCelsius1() * 9.0f / 5.0f + 32.f;
140 }
141
143 inline float objectKelvin2() const
144 {
145 return ((raw[2] & 0x8000) == 0) ? raw[2] * 0.02f : std::numeric_limits<float>::quiet_NaN();
146 }
148 inline float objectTemperature2() const
149 {
150 return objectCelsius2();
151 }
153 inline float objectCelsius2() const
154 {
155 return objectKelvin2() - 273.15f;
156 }
158 inline float objectFahrenheit2() const
159 {
160 return objectCelsius2() * 9.0f / 5.0f + 32.f;
161 }
162};
163
168struct EEPROM {
169 uint16_t toMax{}, toMin{},
175 id[4]{};
176};
177
178} // namespace mlx90614
179
187class UnitMLX90614 : public Component, public PeriodicMeasurementAdapter<UnitMLX90614, mlx90614::Data> {
188 M5_UNIT_COMPONENT_HPP_BUILDER(UnitMLX90614, 0x5A);
189
190public:
195 struct config_t {
197 bool start_periodic{true};
199 mlx90614::IIR iir{mlx90614::IIR::Filter100};
201 mlx90614::FIR fir{mlx90614::FIR::Filter1024};
203 mlx90614::Gain gain{mlx90614::Gain::Coeff12_5};
205 mlx90614::IRSensor irs{mlx90614::IRSensor::Single};
207 float emissivity{1.0f};
208 };
209
210 explicit UnitMLX90614(const uint8_t addr = DEFAULT_ADDRESS)
211 : Component(addr), _data{new m5::container::CircularBuffer<mlx90614::Data>(1)}
212 {
213 auto ccfg = component_config();
214 ccfg.clock = 100 * 1000U;
215 component_config(ccfg);
216 }
217 virtual ~UnitMLX90614()
218 {
219 }
220
221 virtual bool begin() override;
222 virtual void update(const bool force = false) override;
223
226
228 {
229 return _cfg;
230 }
232 inline void config(const config_t& cfg)
233 {
234 _cfg = cfg;
235 }
237
240 {
241 return _eeprom;
242 }
243
247 inline float ambientKelvin() const
248 {
249 return !empty() ? oldest().ambientKelvin() : std::numeric_limits<float>::quiet_NaN();
250 }
252 inline float ambientTemperature() const
253 {
254 return !empty() ? oldest().ambientTemperature() : std::numeric_limits<float>::quiet_NaN();
255 }
257 inline float ambientCelsius() const
258 {
259 return !empty() ? oldest().ambientCelsius() : std::numeric_limits<float>::quiet_NaN();
260 }
262 inline float ambientFahrenheit() const
263 {
264 return !empty() ? oldest().ambientFahrenheit() : std::numeric_limits<float>::quiet_NaN();
265 }
267 inline float objectKelvin1() const
268 {
269 return !empty() ? oldest().objectKelvin1() : std::numeric_limits<float>::quiet_NaN();
270 }
272 inline float objectTemperature1() const
273 {
274 return !empty() ? oldest().objectTemperature1() : std::numeric_limits<float>::quiet_NaN();
275 }
277 inline float objectCelsius1() const
278 {
279 return !empty() ? oldest().objectCelsius1() : std::numeric_limits<float>::quiet_NaN();
280 }
282 inline float objectFahrenheit1() const
283 {
284 return !empty() ? oldest().objectFahrenheit1() : std::numeric_limits<float>::quiet_NaN();
285 }
287 inline float objectKelvin2() const
288 {
289 return !empty() ? oldest().objectKelvin2() : std::numeric_limits<float>::quiet_NaN();
290 }
292 inline float objectTemperature2() const
293 {
294 return !empty() ? oldest().objectTemperature2() : std::numeric_limits<float>::quiet_NaN();
295 }
297 inline float objectCelsius2() const
298 {
299 return !empty() ? oldest().objectCelsius2() : std::numeric_limits<float>::quiet_NaN();
300 }
302 inline float objectFahrenheit2() const
303 {
304 return !empty() ? oldest().objectFahrenheit2() : std::numeric_limits<float>::quiet_NaN();
305 }
307
310
318 inline bool startPeriodicMeasurement(const mlx90614::IIR iir, const mlx90614::FIR fir, const mlx90614::Gain gain,
319 const mlx90614::IRSensor irs)
320 {
321 return PeriodicMeasurementAdapter<UnitMLX90614, mlx90614::Data>::startPeriodicMeasurement(iir, fir, gain, irs);
322 }
325 {
326 return PeriodicMeasurementAdapter<UnitMLX90614, mlx90614::Data>::startPeriodicMeasurement();
327 }
333 {
334 return PeriodicMeasurementAdapter<UnitMLX90614, mlx90614::Data>::stopPeriodicMeasurement();
335 }
337
343
348 bool readConfig(uint16_t& v);
356 bool writeConfig(const uint16_t v, const bool apply = true);
372 bool writeOutput(const mlx90614::Output o, const bool apply = true);
378 bool readIIR(mlx90614::IIR& iir);
386 bool writeIIR(const mlx90614::IIR iir, const bool apply = true);
392 bool readFIR(mlx90614::FIR& fir);
400 bool writeFIR(const mlx90614::FIR fir, const bool apply = true);
406 bool readGain(mlx90614::Gain& gain);
415 bool writeGain(const mlx90614::Gain gain, const bool apply = true);
430 bool writeIRSensor(const mlx90614::IRSensor irs, const bool apply = true);
437 bool readPositiveKs(bool& pos);
446 bool writePositiveKs(const bool pos, const bool apply = true);
453 bool readPositiveKf2(bool& pos);
462 bool writePositiveKf2(const bool pos, const bool apply = true);
464
470
476 bool readObjectMinMax(uint16_t& toMin, uint16_t& toMax);
483 bool readObjectMinMax(float& toMin, float& toMax);
491 template <typename T, typename std::enable_if<std::is_integral<T>::value, std::nullptr_t>::type = nullptr>
492 inline bool writeObjectMinMax(const T toMin, const T toMax, const bool apply = true)
493 {
494 return write_object_minmax((uint16_t)toMin, (uint16_t)toMax, apply);
495 }
504 bool writeObjectMinMax(const float toMin, const float toMax, const bool apply = true);
511 bool readAmbientMinMax(uint8_t& taMin, uint8_t& taMax);
518 bool readAmbientMinMax(float& taMin, float& taMax);
526 template <typename T, typename std::enable_if<std::is_integral<T>::value, std::nullptr_t>::type = nullptr>
527 inline bool writeAmbientMinMax(const T taMin, const T taMax, const bool apply = true)
528 {
529 return write_ambient_minmax((uint8_t)taMin, (uint8_t)taMax, apply);
530 }
539 bool writeAmbientMinMax(const float taMin, const float taMax, const bool apply = true);
541
546
551 bool readEmissivity(uint16_t& emiss);
557 bool readEmissivity(float& emiss);
565 template <typename T, typename std::enable_if<std::is_integral<T>::value, std::nullptr_t>::type = nullptr>
566 inline bool writeEmissivity(const T emiss, const bool apply = true)
567 {
568 return write_emissivity((uint16_t)emiss, apply);
569 }
577 bool writeEmissivity(const float emiss, const bool apply = true);
579
583
590 bool changeI2CAddress(const uint8_t i2c_address);
596 bool readI2CAddress(uint8_t& i2c_address);
598
604 bool sleep();
611 bool wakeup();
619 inline bool applySettings()
620 {
621 return sleep() && wakeup();
622 }
623
624protected:
625 bool read_eeprom(mlx90614::EEPROM& e);
626 bool read_register16(const uint8_t reg, uint16_t& v, const bool stopbit = false);
627 bool write_register16(const uint8_t reg, const uint16_t val);
628 bool write_eeprom(const uint8_t reg, const uint16_t val, const bool apply = true);
629 bool write_object_minmax(const uint16_t toMin, const uint16_t toMax, const bool apply = true);
630 bool write_ambient_minmax(const uint8_t taMin, const uint8_t taMax, const bool apply = true);
631 bool write_emissivity(const uint16_t emiss, const bool apply = true);
632 bool read_measurement(mlx90614::Data& d, const uint16_t config);
633
634 bool start_periodic_measurement(const mlx90614::IIR iir, const mlx90614::FIR fir, const mlx90614::Gain gain,
635 const mlx90614::IRSensor irs);
636 bool start_periodic_measurement();
637 bool stop_periodic_measurement();
638
639 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitMLX90614, mlx90614::Data);
640
641 virtual uint32_t get_interval(const mlx90614::IIR iir, const mlx90614::FIR fir);
642 virtual bool has_dual_sensors() const
643 {
644 return false;
645 }
646
647private:
648 std::unique_ptr<m5::container::CircularBuffer<mlx90614::Data>> _data{};
649 mlx90614::EEPROM _eeprom{};
650 config_t _cfg{};
651};
652
658 M5_UNIT_COMPONENT_HPP_BUILDER(UnitMLX90614BAA, 0x5A);
659
660public:
661 explicit UnitMLX90614BAA(const uint8_t addr = DEFAULT_ADDRESS) : UnitMLX90614(addr)
662 {
663 }
664
665protected:
666 virtual uint32_t get_interval(const mlx90614::IIR iir, const mlx90614::FIR fir);
667 inline virtual bool has_dual_sensors() const
668 {
669 return true;
670 }
671};
672
674namespace mlx90614 {
675namespace command {
676// Category bits
677constexpr uint8_t COMMAND_RAM{0x00}; // 000xxxxx
678constexpr uint8_t COMMAND_EEPROM{0x20}; // 001xxxxx
679constexpr uint8_t COMMAND_READ_FLAGS{0xF0}; // 11110000
680constexpr uint8_t COMMAND_ENTER_SLEEP{0xFF}; // 11111111 This mode is not available for the 5V supply version
681// RAM
682constexpr uint8_t READ_RAW_AMBIENT{0x03};
683constexpr uint8_t READ_RAW_IR1{0x04};
684constexpr uint8_t READ_RAW_IR2{0x05};
685constexpr uint8_t READ_TAMBIENT{0x06};
686constexpr uint8_t READ_TOBJECT_1{0x07};
687constexpr uint8_t READ_TOBJECT_2{0x08};
688// EEPROM
689constexpr uint8_t EEPROM_TO_MAX{0x20};
690constexpr uint8_t EEPROM_TO_MIN{0x21};
691constexpr uint8_t EEPROM_PWMCTRL{0x22};
692constexpr uint8_t EEPROM_TARANGE{0x23};
693constexpr uint8_t EEPROM_EMISSIVITY{0x24};
694constexpr uint8_t EEPROM_CONFIG{0x25};
695constexpr uint8_t EEPROM_ADDR{0x2E};
696constexpr uint8_t EEPROM_ID0{0x3C};
697constexpr uint8_t EEPROM_ID1{0x3D};
698constexpr uint8_t EEPROM_ID2{0x3E};
699constexpr uint8_t EEPROM_ID3{0x3F};
700
701} // namespace command
702} // namespace mlx90614
704
705} // namespace unit
706} // namespace m5
707
708#endif
MLX90614BAA dual IR sensor unit (NCIR, SKU:U028)
Definition unit_MLX90614.hpp:657
Base class of the UnitMLX90614 series.
bool writeConfig(const uint16_t v, const bool apply=true)
Write the configuration.
Definition unit_MLX90614.cpp:297
bool startPeriodicMeasurement()
Start periodic measurement in the current settings.
Definition unit_MLX90614.hpp:324
float ambientKelvin() const
Oldest ambient kelvin.
Definition unit_MLX90614.hpp:247
const mlx90614::EEPROM & eeprom() const
Gets the EEPROM structure.
Definition unit_MLX90614.hpp:239
float objectFahrenheit1() const
Oldest object 1 temperature (Fahrenheit)
Definition unit_MLX90614.hpp:282
bool stopPeriodicMeasurement()
Stop periodic measurement.
Definition unit_MLX90614.hpp:332
float ambientTemperature() const
Oldest ambient temperature (Celsius)
Definition unit_MLX90614.hpp:252
bool readPositiveKs(bool &pos)
Read the sign of Ks (Config Register1 bit7)
Definition unit_MLX90614.cpp:417
float objectTemperature2() const
Oldest object 2 temperature (Celsius)
Definition unit_MLX90614.hpp:292
bool startPeriodicMeasurement(const mlx90614::IIR iir, const mlx90614::FIR fir, const mlx90614::Gain gain, const mlx90614::IRSensor irs)
Start periodic measurement.
Definition unit_MLX90614.hpp:318
config_t config()
Gets the configuration.
Definition unit_MLX90614.hpp:227
bool readEmissivity(uint16_t &emiss)
Read the emissivity.
Definition unit_MLX90614.cpp:544
bool readGain(mlx90614::Gain &gain)
Read the Gain.
Definition unit_MLX90614.cpp:377
float objectCelsius1() const
Oldest object 1 temperature (Celsius)
Definition unit_MLX90614.hpp:277
bool applySettings()
Apply EEPROM settings.
Definition unit_MLX90614.hpp:619
bool readConfig(uint16_t &v)
Read the configuration.
Definition unit_MLX90614.cpp:292
bool wakeup()
Wakeup.
Definition unit_MLX90614.cpp:642
bool writeEmissivity(const T emiss, const bool apply=true)
Write the emissivity.
Definition unit_MLX90614.hpp:566
bool readOutput(mlx90614::Output &o)
Read the Output.
Definition unit_MLX90614.cpp:311
bool writeFIR(const mlx90614::FIR fir, const bool apply=true)
Write the FIR.
Definition unit_MLX90614.cpp:361
float objectKelvin1() const
Oldest object 1 kelvin.
Definition unit_MLX90614.hpp:267
float objectCelsius2() const
Oldest object 2 temperature (Celsius)
Definition unit_MLX90614.hpp:297
bool writeGain(const mlx90614::Gain gain, const bool apply=true)
Write the Gain.
Definition unit_MLX90614.cpp:387
bool readIRSensor(mlx90614::IRSensor &irs)
Read the IRSensor mode.
Definition unit_MLX90614.cpp:397
bool writeOutput(const mlx90614::Output o, const bool apply=true)
Write the Output.
Definition unit_MLX90614.cpp:321
float ambientCelsius() const
Oldest ambient temperature (Celsius)
Definition unit_MLX90614.hpp:257
bool readIIR(mlx90614::IIR &iir)
Read the IIR.
Definition unit_MLX90614.cpp:331
bool writeIRSensor(const mlx90614::IRSensor irs, const bool apply=true)
Write the IRSensor mode.
Definition unit_MLX90614.cpp:407
bool sleep()
Sleep.
Definition unit_MLX90614.cpp:610
float ambientFahrenheit() const
Oldest ambient temperature (Fahrenheit)
Definition unit_MLX90614.hpp:262
bool readPositiveKf2(bool &pos)
Read the sign of Kt2 (Config Register1 bit14)
Definition unit_MLX90614.cpp:437
bool writeObjectMinMax(const T toMin, const T toMax, const bool apply=true)
Write the minimum and maximum temperatures of the measurement for the object.
Definition unit_MLX90614.hpp:492
bool writePositiveKf2(const bool pos, const bool apply=true)
Write the sign of Kt2 (Config Register1 bit14)
Definition unit_MLX90614.cpp:447
bool readI2CAddress(uint8_t &i2c_address)
Read device I2C address.
Definition unit_MLX90614.cpp:582
bool readObjectMinMax(uint16_t &toMin, uint16_t &toMax)
Read the minimum and maximum temperatures of the measurement for the object.
Definition unit_MLX90614.cpp:457
float objectKelvin2() const
Oldest object 2 kelvin.
Definition unit_MLX90614.hpp:287
float objectFahrenheit2() const
Oldest object 2 temperature (Fahrenheit)
Definition unit_MLX90614.hpp:302
bool writeAmbientMinMax(const T taMin, const T taMax, const bool apply=true)
Write the minimum and maximum temperatures of the measurement for the ambient.
Definition unit_MLX90614.hpp:527
float objectTemperature1() const
Oldest object 1 temperature (Celsius)
Definition unit_MLX90614.hpp:272
void config(const config_t &cfg)
Set the configuration.
Definition unit_MLX90614.hpp:232
bool readAmbientMinMax(uint8_t &taMin, uint8_t &taMax)
Read the minimum and maximum temperatures of the measurement for the ambient.
Definition unit_MLX90614.cpp:497
bool changeI2CAddress(const uint8_t i2c_address)
Change device I2C address.
Definition unit_MLX90614.cpp:592
bool writeIIR(const mlx90614::IIR iir, const bool apply=true)
Write the IIR.
Definition unit_MLX90614.cpp:341
bool readFIR(mlx90614::FIR &fir)
Read the FIR.
Definition unit_MLX90614.cpp:351
bool writePositiveKs(const bool pos, const bool apply=true)
Write the sign of Ks (Config Register1 bit7)
Definition unit_MLX90614.cpp:427
Top level namespace of M5stack.
For mlx90614.
Unit-related namespace.
Settings for begin.
Definition unit_MLX90614.hpp:195
float emissivity
Emissivity if start on begin.
Definition unit_MLX90614.hpp:207
mlx90614::Gain gain
Gain if start on begin.
Definition unit_MLX90614.hpp:203
mlx90614::IIR iir
IIR filter if start on begin.
Definition unit_MLX90614.hpp:199
mlx90614::FIR fir
FIR filter if start on begin.
Definition unit_MLX90614.hpp:201
mlx90614::IRSensor irs
IRSensor if start on begin.
Definition unit_MLX90614.hpp:205
bool start_periodic
Start periodic measurement on begin?
Definition unit_MLX90614.hpp:197
Measurement data group.
Definition unit_MLX90614.hpp:97
float ambientTemperature() const
Gets ambient temperature in Celsius (alias of ambientCelsius)
Definition unit_MLX90614.hpp:106
float objectFahrenheit2() const
Gets object2 temperature in Fahrenheit (dual sensor only)
Definition unit_MLX90614.hpp:158
float ambientKelvin() const
Gets ambient temperature in Kelvin.
Definition unit_MLX90614.hpp:101
float objectKelvin2() const
Gets object2 temperature in Kelvin (dual sensor only)
Definition unit_MLX90614.hpp:143
float objectTemperature1() const
Gets object1 temperature in Celsius (alias of objectCelsius1)
Definition unit_MLX90614.hpp:127
float objectTemperature2() const
Gets object2 temperature in Celsius (alias of objectCelsius2)
Definition unit_MLX90614.hpp:148
float objectFahrenheit1() const
Gets object1 temperature in Fahrenheit.
Definition unit_MLX90614.hpp:137
float objectCelsius1() const
Gets object1 temperature in Celsius.
Definition unit_MLX90614.hpp:132
float objectKelvin1() const
Gets object1 temperature in Kelvin.
Definition unit_MLX90614.hpp:122
float ambientCelsius() const
Gets ambient temperature in Celsius.
Definition unit_MLX90614.hpp:111
float ambientFahrenheit() const
Gets ambient temperature in Fahrenheit.
Definition unit_MLX90614.hpp:116
float objectCelsius2() const
Gets object2 temperature in Celsius (dual sensor only)
Definition unit_MLX90614.hpp:153
std::array< uint16_t, 3 > raw
Linearized raw [0]:Ambient [1]:Object1 [2]:Object2.
Definition unit_MLX90614.hpp:98
EEPROM structure values.
Definition unit_MLX90614.hpp:168
uint16_t pwmCtrl
Pulse Width Modulation control.
Definition unit_MLX90614.hpp:170
uint16_t addr
I2C address(Using low byte)
Definition unit_MLX90614.hpp:174
uint16_t config
Configuration.
Definition unit_MLX90614.hpp:173
uint16_t toMin
Max,Min of the Object Temperature.
Definition unit_MLX90614.hpp:169
uint16_t taRange
Range of the Ambient Temperature (H/L)
Definition unit_MLX90614.hpp:171
uint16_t emissivity
Emissivity.
Definition unit_MLX90614.hpp:172
IRSensor
Infra-Red Sensor mode.
Definition unit_MLX90614.hpp:88
@ Single
Single IR Sensor.
IIR
Infinite Impulse Response.
Definition unit_MLX90614.hpp:42
@ Filter25
25% (a1 = 0.25, b1 = 0.75)
@ Filter50
50% (a1 = 0.5, b1 = 0.5)
@ Filter67
67% (a1 = 0.666, b1 = 0.333)
@ Filter80
80% (a1 = 0.8, b1 = 0.2)
@ Filter13
13% (a1 = 0.125, b1 = 0.875)
@ Filter100
100% (a1 = 1, b1 = 0)
@ Filter57
57% (a1 = 0.571, b1 = 0.428)
@ Filter17
17% (a1 = 0.166(6), b1 = 0.833(3))
Gain
Amplifier gain.
Definition unit_MLX90614.hpp:73
FIR
Finite Impulse Response.
Definition unit_MLX90614.hpp:57
@ Filter8
8 Not recommended
@ Filter32
32 Not recommended
@ Filter16
16 Not recommended
@ Filter64
64 Not recommended
Output
PWM output mode.
Definition unit_MLX90614.hpp:31
@ TO1_TO2
PWM1: To1 PWM2:To2 (Object 1 & 2)
@ TA_TO1
PWM1: Ta PWM2:To1 (Ambient & Object 1)
@ TA_TO2
PWM1: Ta PWM2:To2 (Ambient & Object 2)
@ TO2_Undefined
PWM1: To2 PWM2:Undefined (Object 2)