M5Unit-THERMO 0.3.1 git rev:c2bfb11
Loading...
Searching...
No Matches
unit_Thermal2.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_THERMO_UNIT_THERMAL2_HPP
11#define M5_UNIT_THERMO_UNIT_THERMAL2_HPP
12#include <M5UnitComponent.hpp>
13#include <m5_utility/container/circular_buffer.hpp>
14#include <limits> // NaN
15#include <cmath>
16#include <array>
17
18namespace m5 {
19namespace unit {
24namespace thermal2 {
25
29constexpr uint8_t button_is_pressed{0x01};
30constexpr uint8_t button_was_pressed{0x02};
31constexpr uint8_t button_was_released{0x04};
32constexpr uint8_t button_was_clicked{0x08};
33constexpr uint8_t button_was_hold{0x10};
35
39constexpr uint8_t enabled_function_buzzer{0x01};
40constexpr uint8_t enabled_function_led{0x02};
41constexpr uint8_t enabled_function_auto_refresh{0x04};
43
47constexpr uint8_t enabled_low_temperature_low{0x01};
48constexpr uint8_t enabled_med_temperature_low{0x02};
49constexpr uint8_t enabled_ave_temperature_low{0x04};
50constexpr uint8_t enabled_high_temperature_low{0x08};
51constexpr uint8_t enabled_low_temperature_high{0x10};
52constexpr uint8_t enabled_med_temperature_high{0x20};
53constexpr uint8_t enabled_ave_temperature_high{0x40};
54constexpr uint8_t enabled_high_temperature_high{0x80};
56
61enum class Refresh : uint8_t {
62 Rate0_5Hz,
63 Rate1Hz,
64 Rate2Hz,
65 Rate4Hz,
66 Rate8Hz,
67 Rate16Hz,
68 Rate32Hz,
69 Rate64Hz,
70};
71
73inline static uint16_t celsius_to_raw(const float f)
74{
75 int i = std::round((f + 64) * 128);
76 return static_cast<uint16_t>(std::max(std::min(i, static_cast<int>(std::numeric_limits<uint16_t>::max())), 0));
77}
79inline static float raw_to_celsius(const uint16_t u16)
80{
81 return u16 / 128.0f - 64;
82}
83
84#pragma pack(push)
85#pragma pack(1)
90struct Data {
91 uint8_t subpage{};
92 union {
93 uint16_t temp[8]{};
94 struct {
98 uint8_t most_diff_x;
99 uint8_t most_diff_y;
106 };
107 };
108 uint16_t raw[384]{};
109
111 inline float medianTemperature() const
112 {
113 return thermal2::raw_to_celsius(temp[0]);
114 }
116 inline float averageTemperature() const
117 {
118 return thermal2::raw_to_celsius(temp[1]);
119 }
121 inline float mostDiffTemperature() const
122 {
123 return thermal2::raw_to_celsius(temp[2]);
124 }
126 inline float lowestTemperature() const
127 {
128 return thermal2::raw_to_celsius(temp[4]);
129 }
131 inline float highestTemperature() const
132 {
133 return thermal2::raw_to_celsius(temp[6]);
134 }
135
139 inline float temperature(const uint_fast16_t idx) const
140 {
141 return (idx < 384) ? thermal2::raw_to_celsius(raw[idx]) : std::numeric_limits<float>::quiet_NaN();
142 }
143};
144#pragma pack(pop)
145
146} // namespace thermal2
147
152class UnitThermal2 : public Component, public PeriodicMeasurementAdapter<UnitThermal2, thermal2::Data> {
153 M5_UNIT_COMPONENT_HPP_BUILDER(UnitThermal2, 0x32);
154
155public:
160 struct config_t {
162 bool start_periodic{true};
164 thermal2::Refresh rate{thermal2::Refresh::Rate16Hz};
166 uint8_t monitor_width{15};
168 uint8_t monitor_height{11};
170 uint8_t function_control{thermal2::enabled_function_led};
172 uint32_t button_interval{20};
173 };
174
175 explicit UnitThermal2(const uint8_t addr = DEFAULT_ADDRESS)
176 : Component(addr), _data{new m5::container::CircularBuffer<thermal2::Data>(1)}
177 {
178 auto ccfg = component_config();
179 ccfg.clock = 400 * 1000U;
180 component_config(ccfg);
181 }
182 virtual ~UnitThermal2()
183 {
184 }
185
186 virtual bool begin() override;
187 virtual void update(const bool force = false) override;
188
191
193 {
194 return _cfg;
195 }
197 inline void config(const config_t& cfg)
198 {
199 _cfg = cfg;
200 }
202
205
211 {
212 return PeriodicMeasurementAdapter<UnitThermal2, thermal2::Data>::startPeriodicMeasurement(rate);
213 }
216 {
217 return PeriodicMeasurementAdapter<UnitThermal2, thermal2::Data>::startPeriodicMeasurement();
218 }
224 {
225 return PeriodicMeasurementAdapter<UnitThermal2, thermal2::Data>::stopPeriodicMeasurement();
226 }
228
231
243
246
252 bool readFunctionControl(uint8_t& value);
254 inline bool readBuzzerEnabled(bool& enabled)
255 {
256 return read_function_control_bit(thermal2::enabled_function_buzzer, enabled);
257 }
259 inline bool readLEDEnabled(bool& enabled)
260 {
261 return read_function_control_bit(thermal2::enabled_function_led, enabled);
262 }
270 bool writeFunctionControl(const uint8_t value, const bool verify = true);
272 inline bool writeBuzzerEnabled(const bool enabled)
273 {
274 return write_function_control_bit(thermal2::enabled_function_buzzer, enabled);
275 }
277 inline bool writeLEDEnabled(const bool enabled)
278 {
279 return write_function_control_bit(thermal2::enabled_function_led, enabled);
280 }
281
294 bool writeRefreshRate(const thermal2::Refresh rate);
295
302 bool readNoiseFilterLevel(uint8_t& level);
309 bool writeNoiseFilterLevel(const uint8_t level);
310
317 bool readTemperatureMonitorSize(uint8_t& wid, uint8_t& hgt);
324 bool writeTemperatureMonitorSize(const uint8_t wid, const uint8_t hgt);
325
327 [[deprecated("Use readTemperatureMonitorSize")]] inline bool readTemeratureMonitorSize(uint8_t& wid, uint8_t& hgt)
328 {
329 return readTemperatureMonitorSize(wid, hgt);
330 }
332 [[deprecated("Use writeTemperatureMonitorSize")]] inline bool writeTemeratureMonitorSize(const uint8_t wid,
333 const uint8_t hgt)
334 {
335 return writeTemperatureMonitorSize(wid, hgt);
336 }
338
341
346 bool readAlarmEnabled(uint8_t& enabled_bits);
352 bool writeAlarmEnabled(const uint8_t enabled_bits);
353
360 bool readAlarmTemperature(const bool highlow, uint16_t& raw);
367 bool readAlarmTemperature(const bool highlow, float& celsius);
376 bool writeAlarmTemperature(const bool highlow, const uint16_t raw);
383 template <typename T, typename std::enable_if<std::is_floating_point<T>::value, std::nullptr_t>::type = nullptr>
384 inline bool writeAlarmTemperature(const bool highlow, const T celsius)
385 {
386 return writeAlarmTemperature(highlow, thermal2::celsius_to_raw(static_cast<float>(celsius)));
387 }
388
395 bool readAlarmLED(const bool highlow, uint32_t& rgb);
402 inline bool writeAlarmLED(const bool highlow, const uint32_t rgb)
403 {
404 return writeAlarmLED(highlow, rgb >> 16, rgb >> 8, rgb & 0xFF);
405 }
414 bool writeAlarmLED(const bool highlow, const uint8_t r, const uint8_t g, const uint8_t b);
415
424 bool readAlarmBuzzer(const bool highlow, uint16_t& freq, uint8_t& interval);
433 bool writeAlarmBuzzer(const bool highlow, const uint16_t freq, const uint8_t interval);
435
439
447 bool readBuzzer(uint16_t& freq, uint8_t& duty);
457 bool writeBuzzer(const uint16_t freq, const uint8_t duty, const bool verify = true);
465 bool writeBuzzerDuty(const uint8_t duty);
466
472 inline bool readBuzzerControl(bool& enabled)
473 {
474 return readBuzzerEnabled(enabled);
475 }
481 inline bool writeBuzzerControl(const bool enabled)
482 {
483 return writeBuzzerEnabled(enabled);
484 }
486
490
495 bool readLED(uint32_t& rgb);
502 inline bool writeLED(const uint32_t rgb, const bool verify = true)
503 {
504 return writeLED(rgb >> 16, rgb >> 8, rgb & 0xFF, verify);
505 }
514 bool writeLED(const uint8_t r, const uint8_t g, const uint8_t b, const bool verify = true);
516
519
524 bool readButtonStatus(uint8_t& bs);
525
531 inline bool isPressed() const
532 {
533 return _button & thermal2::button_is_pressed;
534 }
540 inline bool wasPressed() const
541 {
542 return _button & thermal2::button_was_pressed;
543 }
549 inline bool wasReleased() const
550 {
551 return _button & thermal2::button_was_released;
552 }
558 inline bool wasClicked() const
559 {
560 return _button & thermal2::button_was_clicked;
561 }
567 inline bool wasHold() const
568 {
569 return _button & thermal2::button_was_hold;
570 }
576 inline bool isHolding() const
577 {
578 return isPressed() && _holding;
579 }
581
587 bool readFirmwareVersion(uint16_t& ver);
588
592
598 bool changeI2CAddress(const uint8_t i2c_address);
604 bool readI2CAddress(uint8_t& i2c_address);
606
607protected:
608 bool read_function_control_bit(const uint8_t bit, bool& enabled);
609 bool write_function_control_bit(const uint8_t bit, const bool enabled);
610
611 bool request_data();
612 bool read_data_status(uint8_t s[2]); // [0]:data refresh ctrl, [1]subpage information
613 bool read_data(thermal2::Data& data);
614
615 bool start_periodic_measurement(const thermal2::Refresh rate);
616 bool start_periodic_measurement();
617 bool stop_periodic_measurement();
618
619 inline bool read_register(const uint8_t reg, uint8_t* v, const uint32_t len)
620 {
621 return readRegister(reg, v, len, 0, false /* stopbit false */);
622 }
623
624 inline bool read_register8(const uint8_t reg, uint8_t& v)
625 {
626 return readRegister8(reg, v, 0, false /* stopbit false */);
627 }
628
629 inline bool read_register16LE(const uint8_t reg, uint16_t& v)
630 {
631 return readRegister16LE(reg, v, 0, false /* stopbit false */);
632 }
633
634 inline bool read_register16BE(const uint8_t reg, uint16_t& v)
635 {
636 return readRegister16BE(reg, v, 0, false /* stopbit false */);
637 }
638
639 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitThermal2, thermal2::Data);
640
641private:
642 std::unique_ptr<m5::container::CircularBuffer<thermal2::Data>> _data{};
643 uint8_t _button{}, _holding{};
644 uint32_t _button_interval{20};
645 types::elapsed_time_t _latest_button{};
646 config_t _cfg{};
647};
648
649namespace thermal2 {
651namespace command {
652constexpr uint8_t BUTTON_STATUS_REG{0x00}; // R/W
653constexpr uint8_t TEMPERATURE_ALARM_STATUS_REG{0x01}; // R
654// constexpr uint8_t DEVICE_STATUS_REG{0x02}; // R 2
655constexpr uint8_t DEVICE_ID_REG{0x04}; // R 2
656constexpr uint8_t FIRMWARE_VERSION_REG{0x06}; // R 2
657constexpr uint8_t I2C_ADDRESS_REG{0x08}; // R/W 2 (0x09:bit inverted) I
658constexpr uint8_t FUNCTION_CONTROL_REG{0x0A}; // R/W
659constexpr uint8_t REFRESH_RATE_CONFIG_REG{0x0B}; // R/W I
660constexpr uint8_t NOISE_FILTER_CONFIG_REG{0x0C}; // R/W I
661
662constexpr uint8_t TEMPERATURE_MONITOR_SIZE_REG{0x10}; // R/W I
663constexpr uint8_t ENABLE_TEMPERATURE_ALARM_REG{0x11}; // R/W I
664constexpr uint8_t BUZZER_FREQ_REG{0x12}; // R/W 2
665constexpr uint8_t BUZZER_DUTY_REG{0x14}; // R/W
666constexpr uint8_t LED_REG{0x15}; // R/W 3(R,G,B)
667
668constexpr uint8_t LOW_ALARM_THRESHOLD_REG{0x20}; // R/W 2 I
669constexpr uint8_t LOW_ALARM_BUZZER_FREQ_REG{0x22}; // R/W 2 I
670constexpr uint8_t LOW_ALARM_INTERVAL_REG{0x24}; // R/W I
671constexpr uint8_t LOW_ALARM_LED_REG{0x25}; // R/W 3 I
672
673constexpr uint8_t HIGH_ALARM_THRESHOLD_REG{0x30}; // R/W 2 I
674constexpr uint8_t HIGH_ALARM_BUZZER_FREQ_REG{0x32}; // R/W 2 I
675constexpr uint8_t HIGH_ALARM_INTERVAL_REG{0x34}; // R/W I
676constexpr uint8_t HIGH_ALARM_LED_REG{0x35}; // R/W 3 I
677
678constexpr uint8_t DATA_REFRESH_CONTROL_REG{0x6E}; // R/W I
679constexpr uint8_t SUB_PAGE_INFORMATION_REG{0x6F}; // R
680
681constexpr uint8_t MEDIAN_TEMPERATURE_REG{0x70}; // R 2
682constexpr uint8_t AVERAGE_TEMPERATURE_REG{0x72}; // R 2
683constexpr uint8_t MOST_DIFF_TEMPERATURE_REG{0x74}; // R 2
684constexpr uint8_t MOST_DIFF_X_POS_REG{0x76}; // R
685constexpr uint8_t MOST_DIFF_Y_POS_REG{0x77}; // R
686constexpr uint8_t LOWEST_TEMPERATURE_REG{0x78}; // R 2
687constexpr uint8_t LOWEST_DIFF_X_POS_REG{0x7A}; // R
688constexpr uint8_t LOWEST_DIFF_Y_POS_REG{0x7B}; // R
689constexpr uint8_t HIGHEST_TEMPERATURE_REG{0x7C}; // R 2
690constexpr uint8_t HIGHEST_DIFF_X_POS_REG{0x7E}; // R
691constexpr uint8_t HIGHEST_DIFF_Y_POS_REG{0x7F}; // R
692
693constexpr uint8_t TEMPERATURE_DATA_REG{0x80}; // R 768
694} // namespace command
696} // namespace thermal2
697
698} // namespace unit
699} // namespace m5
700#endif
Unit Thermal2 (MLX90640 32x24 thermal camera, SKU:U149)
bool wasHold() const
Was button hold?
Definition unit_Thermal2.hpp:567
bool changeI2CAddress(const uint8_t i2c_address)
Change device I2C address.
Definition unit_Thermal2.cpp:452
bool readBuzzerControl(bool &enabled)
Read the Buzzer control.
Definition unit_Thermal2.hpp:472
bool readNoiseFilterLevel(uint8_t &level)
Read the noise filter level.
Definition unit_Thermal2.cpp:251
bool wasPressed() const
Was button pressed?
Definition unit_Thermal2.hpp:540
bool writeBuzzerControl(const bool enabled)
Write the Buzzer control.
Definition unit_Thermal2.hpp:481
bool readLED(uint32_t &rgb)
Read the LED color.
Definition unit_Thermal2.cpp:410
bool writeTemperatureMonitorSize(const uint8_t wid, const uint8_t hgt)
Write the temperature monitor size.
Definition unit_Thermal2.cpp:277
bool writeTemeratureMonitorSize(const uint8_t wid, const uint8_t hgt)
Definition unit_Thermal2.hpp:332
bool wasReleased() const
Was button released?
Definition unit_Thermal2.hpp:549
bool writeAlarmTemperature(const bool highlow, const uint16_t raw)
Write the alarm temperature threshold.
Definition unit_Thermal2.cpp:316
void config(const config_t &cfg)
Set the configuration.
Definition unit_Thermal2.hpp:197
bool startPeriodicMeasurement(const thermal2::Refresh rate)
Start periodic measurement.
Definition unit_Thermal2.hpp:210
bool isPressed() const
Is button pressed?
Definition unit_Thermal2.hpp:531
bool readAlarmTemperature(const bool highlow, uint16_t &raw)
Read the alarm temperature threshold.
Definition unit_Thermal2.cpp:297
bool readLEDEnabled(bool &enabled)
Reads the LED enabled.
Definition unit_Thermal2.hpp:259
bool writeBuzzerEnabled(const bool enabled)
Write the buzzer enable status.
Definition unit_Thermal2.hpp:272
bool writeAlarmEnabled(const uint8_t enabled_bits)
Read the alarm control.
Definition unit_Thermal2.cpp:292
bool writeAlarmTemperature(const bool highlow, const T celsius)
Write the alarm temperature threshold.
Definition unit_Thermal2.hpp:384
bool writeRefreshRate(const thermal2::Refresh rate)
Write the refresh rate.
Definition unit_Thermal2.cpp:242
bool readTemeratureMonitorSize(uint8_t &wid, uint8_t &hgt)
Definition unit_Thermal2.hpp:327
bool readTemperatureMonitorSize(uint8_t &wid, uint8_t &hgt)
Read the temperature monitor size.
Definition unit_Thermal2.cpp:265
bool writeNoiseFilterLevel(const uint8_t level)
Write the noise filter level.
Definition unit_Thermal2.cpp:256
bool writeAlarmLED(const bool highlow, const uint32_t rgb)
Write the alarm LED color.
Definition unit_Thermal2.hpp:402
bool stopPeriodicMeasurement()
Stop periodic measurement.
Definition unit_Thermal2.hpp:223
bool readFirmwareVersion(uint16_t &ver)
Read the firmware version.
Definition unit_Thermal2.cpp:446
bool readAlarmEnabled(uint8_t &enabled_bits)
Read the alarm control.
Definition unit_Thermal2.cpp:287
bool wasClicked() const
Was button clicked?
Definition unit_Thermal2.hpp:558
bool readAlarmLED(const bool highlow, uint32_t &rgb)
Read the alarm LED color.
Definition unit_Thermal2.cpp:322
bool readI2CAddress(uint8_t &i2c_address)
Read device I2C address.
Definition unit_Thermal2.cpp:465
bool writeLEDEnabled(const bool enabled)
Write the LED enable status.
Definition unit_Thermal2.hpp:277
bool measureSingleshot(thermal2::Data &page0, thermal2::Data &page1)
Measurement single shot.
Definition unit_Thermal2.cpp:150
bool writeBuzzer(const uint16_t freq, const uint8_t duty, const bool verify=true)
Write the buzzer settings.
Definition unit_Thermal2.cpp:385
bool writeBuzzerDuty(const uint8_t duty)
Write the buzzer duty settings.
Definition unit_Thermal2.cpp:405
bool startPeriodicMeasurement()
Start periodic measurement in the current settings.
Definition unit_Thermal2.hpp:215
bool isHolding() const
Is button holding?
Definition unit_Thermal2.hpp:576
bool readFunctionControl(uint8_t &value)
Read the function control.
Definition unit_Thermal2.cpp:186
bool writeFunctionControl(const uint8_t value, const bool verify=true)
Write the function control.
Definition unit_Thermal2.cpp:192
bool readButtonStatus(uint8_t &bs)
Read the button status.
Definition unit_Thermal2.cpp:437
bool writeLED(const uint32_t rgb, const bool verify=true)
Write the LED color.
Definition unit_Thermal2.hpp:502
config_t config()
Gets the configuration.
Definition unit_Thermal2.hpp:192
bool readBuzzer(uint16_t &freq, uint8_t &duty)
Read the buzzer settings.
Definition unit_Thermal2.cpp:372
bool readAlarmBuzzer(const bool highlow, uint16_t &freq, uint8_t &interval)
Read the alarm buzzer settings.
Definition unit_Thermal2.cpp:343
bool readBuzzerEnabled(bool &enabled)
Read the buzzer enabled.
Definition unit_Thermal2.hpp:254
bool readRefreshRate(thermal2::Refresh &rate)
Read the refresh rate.
Definition unit_Thermal2.cpp:231
bool writeAlarmBuzzer(const bool highlow, const uint16_t freq, const uint8_t interval)
Write the alarm buzzer settings.
Definition unit_Thermal2.cpp:357
Top level namespace of M5stack.
For UnitThermal2.
Unit-related namespace.
Settings for begin.
Definition unit_Thermal2.hpp:160
uint8_t function_control
Function control bits.
Definition unit_Thermal2.hpp:170
uint8_t monitor_height
Temperature monitor height.
Definition unit_Thermal2.hpp:168
uint32_t button_interval
Button status update interval(ms)
Definition unit_Thermal2.hpp:172
thermal2::Refresh rate
Refresh rate if start on begin.
Definition unit_Thermal2.hpp:164
bool start_periodic
Start periodic measurement on begin?
Definition unit_Thermal2.hpp:162
uint8_t monitor_width
Temperature monitor width.
Definition unit_Thermal2.hpp:166
Measurement data group.
Definition unit_Thermal2.hpp:90
float medianTemperature() const
Gets median temperature in Celsius.
Definition unit_Thermal2.hpp:111
uint8_t most_diff_x
Most different pixel X.
Definition unit_Thermal2.hpp:98
uint16_t raw[384]
Raw pixel data (1/2)
Definition unit_Thermal2.hpp:108
uint16_t average_temperature
Average temperature (raw)
Definition unit_Thermal2.hpp:96
uint8_t most_diff_y
Most different pixel Y.
Definition unit_Thermal2.hpp:99
uint8_t subpage
Subpage 0:even 1:odd.
Definition unit_Thermal2.hpp:91
float temperature(const uint_fast16_t idx) const
Gets pixel temperature in Celsius.
Definition unit_Thermal2.hpp:139
uint8_t highest_diff_x
Highest pixel X.
Definition unit_Thermal2.hpp:104
uint16_t highest_temperature
Highest temperature (raw)
Definition unit_Thermal2.hpp:103
uint16_t median_temperature
Median temperature (raw)
Definition unit_Thermal2.hpp:95
float averageTemperature() const
Gets average temperature in Celsius.
Definition unit_Thermal2.hpp:116
uint16_t most_diff_temperature
Most different temperature (raw)
Definition unit_Thermal2.hpp:97
float highestTemperature() const
Gets highest temperature in Celsius.
Definition unit_Thermal2.hpp:131
float mostDiffTemperature() const
Gets most different temperature in Celsius.
Definition unit_Thermal2.hpp:121
uint16_t temp[8]
Temperature information.
Definition unit_Thermal2.hpp:93
uint8_t highest_diff_y
Highest pixel Y.
Definition unit_Thermal2.hpp:105
float lowestTemperature() const
Gets lowest temperature in Celsius.
Definition unit_Thermal2.hpp:126
uint8_t lowest_diff_x
Lowest pixel X.
Definition unit_Thermal2.hpp:101
uint8_t lowest_diff_y
Lowest pixel Y.
Definition unit_Thermal2.hpp:102
uint16_t lowest_temperature
Lowest temperature (raw)
Definition unit_Thermal2.hpp:100
constexpr uint8_t enabled_low_temperature_low
Low temp reached low threshold.
Definition unit_Thermal2.hpp:47
constexpr uint8_t enabled_high_temperature_low
High temp reached low threshold.
Definition unit_Thermal2.hpp:50
constexpr uint8_t enabled_ave_temperature_low
Ave temp reached low threshold.
Definition unit_Thermal2.hpp:49
constexpr uint8_t enabled_med_temperature_high
Med temp reached high threshold.
Definition unit_Thermal2.hpp:52
constexpr uint8_t enabled_high_temperature_high
High temp reached high threshold.
Definition unit_Thermal2.hpp:54
constexpr uint8_t enabled_low_temperature_high
Low temp reached high threshold.
Definition unit_Thermal2.hpp:51
constexpr uint8_t enabled_ave_temperature_high
Ave temp reached high threshold.
Definition unit_Thermal2.hpp:53
constexpr uint8_t enabled_med_temperature_low
Med temp reached low threshold.
Definition unit_Thermal2.hpp:48
Refresh
Refresh rate(Hz)
Definition unit_Thermal2.hpp:61