M5Unit-METER 0.4.1 git rev:5bdc3fe
Loading...
Searching...
No Matches
unit_KmeterISO.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_METER_UNIT_KMETERISO_HPP
11#define M5_UNIT_METER_UNIT_KMETERISO_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
21namespace kmeter_iso {
22
27enum class MeasurementUnit : uint8_t {
28 Celsius,
29 Fahrenheit,
30};
31
36struct Data {
37 std::array<uint8_t, 4> raw{};
38
41 inline float temperature() const
42 {
43 return static_cast<int32_t>((static_cast<uint32_t>(raw[3]) << 24) | (static_cast<uint32_t>(raw[2]) << 16) |
44 (static_cast<uint32_t>(raw[1]) << 8) | static_cast<uint32_t>(raw[0])) *
45 0.01f;
46 }
47};
48} // namespace kmeter_iso
49
54class UnitKmeterISO : public Component, public PeriodicMeasurementAdapter<UnitKmeterISO, kmeter_iso::Data> {
55 M5_UNIT_COMPONENT_HPP_BUILDER(UnitKmeterISO, 0x66);
56
57public:
62 struct config_t {
64 bool start_periodic{true};
66 uint32_t interval{100};
68 kmeter_iso::MeasurementUnit measurement_unit{kmeter_iso::MeasurementUnit::Celsius};
69 };
70
71 explicit UnitKmeterISO(const uint8_t addr = DEFAULT_ADDRESS)
72 : Component(addr), _data{new m5::container::CircularBuffer<kmeter_iso::Data>(1)}
73 {
74 // 100 kHz: the firmware's slave data setup time (STM32F030, I2CCLK 8 MHz) does not meet the Fast-mode worst
75 // case (RM0360 22.4.5), and the official driver also uses 100 kHz
76 auto ccfg = component_config();
77 ccfg.clock = 100 * 1000U;
78 component_config(ccfg);
79 }
80 virtual ~UnitKmeterISO()
81 {
82 }
83
84 virtual bool begin() override;
85 virtual void update(const bool force = false) override;
86
89
91 {
92 return _cfg;
93 }
95 inline void config(const config_t& cfg)
96 {
97 _cfg = cfg;
98 }
100
106 {
107 return _munit;
108 }
112 {
113 _munit = munit;
114 }
116
120 inline float temperature() const
121 {
122 return !empty() ? oldest().temperature() : std::numeric_limits<float>::quiet_NaN();
123 }
125
128
133 {
134 return PeriodicMeasurementAdapter<UnitKmeterISO, kmeter_iso::Data>::startPeriodicMeasurement();
135 }
142 inline bool startPeriodicMeasurement(const uint32_t interval,
143 const kmeter_iso::MeasurementUnit munit = kmeter_iso::MeasurementUnit::Celsius)
144 {
145 return PeriodicMeasurementAdapter<UnitKmeterISO, kmeter_iso::Data>::startPeriodicMeasurement(interval, munit);
146 }
152 {
153 return PeriodicMeasurementAdapter<UnitKmeterISO, kmeter_iso::Data>::stopPeriodicMeasurement();
154 }
156
162 bool readStatus(uint8_t& status);
163
169 bool readFirmwareVersion(uint8_t& ver);
170
173
182 const kmeter_iso::MeasurementUnit munit = kmeter_iso::MeasurementUnit::Celsius,
183 const uint32_t timeoutMs = 100);
193 const kmeter_iso::MeasurementUnit munit = kmeter_iso::MeasurementUnit::Celsius,
194 const uint32_t timeoutMs = 100);
196
200
206 bool changeI2CAddress(const uint8_t i2c_address);
212 bool readI2CAddress(uint8_t& i2c_address);
214
215protected:
216 bool start_periodic_measurement();
217 bool start_periodic_measurement(const uint32_t interval, const kmeter_iso::MeasurementUnit munit);
218 bool stop_periodic_measurement();
219
220 bool read_measurement(kmeter_iso::Data& d, const kmeter_iso::MeasurementUnit munit);
221 bool read_internal_measurement(kmeter_iso::Data& d, const kmeter_iso::MeasurementUnit munit);
222
223 bool is_data_ready()
224 {
225 uint8_t s{};
226 return readStatus(s) && (s == 0U);
227 }
228 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitKmeterISO, kmeter_iso::Data);
229
230protected:
231 std::unique_ptr<m5::container::CircularBuffer<kmeter_iso::Data>> _data{};
232 kmeter_iso::MeasurementUnit _munit{kmeter_iso::MeasurementUnit::Celsius};
233 config_t _cfg{};
234};
235
236namespace kmeter_iso {
237namespace command {
239// See also https://github.com/m5stack/M5Unit-KMeterISO/blob/main/docs/Unit_KmeterISO_I2C_Protocol.pdf
240constexpr uint8_t TEMPERATURE_CELSIUS_REG{0X00};
241constexpr uint8_t TEMPERATURE_FAHRENHEIT_REG{0X04};
242constexpr uint8_t INTERNAL_TEMPERATURE_CELSIUS_REG{0X10};
243constexpr uint8_t INTERNAL_TEMPERATURE_FAHRENHEIT_REG{0X14};
244constexpr uint8_t STATUS_REG{0x20};
245constexpr uint8_t TEMPERATURE_CELSIUS_STRING_REG{0x30};
246constexpr uint8_t TEMPERATURE_FAHRENHEIT_STRING_REG{0x40};
247constexpr uint8_t INTERNAL_TEMPERATURE_CELSIUS_STRING_REG{0x50};
248constexpr uint8_t INTERNAL_TEMPERATURE_FAHRENHEIT_STRING_REG{0x60};
249constexpr uint8_t FIRMWARE_VERSION_REG{0xFE};
250constexpr uint8_t I2C_ADDRESS_REG{0xFF};
252} // namespace command
253} // namespace kmeter_iso
254
255} // namespace unit
256} // namespace m5
257#endif
bool measureSingleshot(kmeter_iso::Data &data, const kmeter_iso::MeasurementUnit munit=kmeter_iso::MeasurementUnit::Celsius, const uint32_t timeoutMs=100)
Measure temperature single shot.
Definition unit_KmeterISO.cpp:122
bool readFirmwareVersion(uint8_t &ver)
Read firmware version.
Definition unit_KmeterISO.cpp:117
bool readI2CAddress(uint8_t &i2c_address)
Read device I2C address.
Definition unit_KmeterISO.cpp:187
void setMeasurementUnit(const kmeter_iso::MeasurementUnit munit)
Set the measurement unit on periodic measurement.
Definition unit_KmeterISO.hpp:111
bool stopPeriodicMeasurement()
Stop periodic measurement.
Definition unit_KmeterISO.hpp:151
bool readStatus(uint8_t &status)
Read status.
Definition unit_KmeterISO.cpp:111
kmeter_iso::MeasurementUnit measurementUnit() const
Gets the measurement unit on periodic measurement.
Definition unit_KmeterISO.hpp:105
bool startPeriodicMeasurement()
Start periodic measurement in the current settings.
Definition unit_KmeterISO.hpp:132
bool changeI2CAddress(const uint8_t i2c_address)
Change device I2C address.
Definition unit_KmeterISO.cpp:162
bool startPeriodicMeasurement(const uint32_t interval, const kmeter_iso::MeasurementUnit munit=kmeter_iso::MeasurementUnit::Celsius)
Start periodic measurement.
Definition unit_KmeterISO.hpp:142
config_t config()
Gets the configuration.
Definition unit_KmeterISO.hpp:90
void config(const config_t &cfg)
Set the configuration.
Definition unit_KmeterISO.hpp:95
float temperature() const
Oldest temperature.
Definition unit_KmeterISO.hpp:120
bool measureInternalSingleshot(kmeter_iso::Data &data, const kmeter_iso::MeasurementUnit munit=kmeter_iso::MeasurementUnit::Celsius, const uint32_t timeoutMs=100)
Measure internal temperature single shot.
Definition unit_KmeterISO.cpp:142
Top level namespace of M5stack.
Unit-related namespace.
Settings for begin.
Definition unit_KmeterISO.hpp:62
uint32_t interval
periodic interval(ms) if start on begin
Definition unit_KmeterISO.hpp:66
bool start_periodic
Start periodic measurement on begin?
Definition unit_KmeterISO.hpp:64
Measurement data group.
Definition unit_KmeterISO.hpp:36
std::array< uint8_t, 4 > raw
Raw data.
Definition unit_KmeterISO.hpp:37
float temperature() const
Temperature value.
Definition unit_KmeterISO.hpp:41
MeasurementUnit
measurement unit on periodic measurement
Definition unit_KmeterISO.hpp:27