M5Unit-METER 0.4.1 git rev:5bdc3fe
Loading...
Searching...
No Matches
unit_DualKmeter.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_METER_UNIT_DUAL_KMETER_HPP
11#define M5_UNIT_METER_UNIT_DUAL_KMETER_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 dual_kmeter {
26
31enum class Channel : uint8_t {
32 One,
33 Two,
34};
35
40enum class MeasurementUnit : uint8_t {
41 Celsius,
43};
44
49struct Data {
50 std::array<uint8_t, 4> raw{};
52
55 inline float temperature() const
56 {
57 return static_cast<int32_t>((static_cast<uint32_t>(raw[3]) << 24) | (static_cast<uint32_t>(raw[2]) << 16) |
58 (static_cast<uint32_t>(raw[1]) << 8) | static_cast<uint32_t>(raw[0])) *
59 0.01f;
60 }
61};
62
63} // namespace dual_kmeter
64
90class UnitDualKmeter : public Component, public PeriodicMeasurementAdapter<UnitDualKmeter, dual_kmeter::Data> {
91 M5_UNIT_COMPONENT_HPP_BUILDER(UnitDualKmeter, 0x11);
92
93public:
98 struct config_t {
100 bool start_periodic{true};
102 uint32_t interval{100};
104 dual_kmeter::Channel measurement_channel{dual_kmeter::Channel::One};
106 dual_kmeter::MeasurementUnit measurement_unit{dual_kmeter::MeasurementUnit::Celsius};
107 };
108
109 explicit UnitDualKmeter(const uint8_t addr = DEFAULT_ADDRESS)
110 : Component(addr), _data{new m5::container::CircularBuffer<dual_kmeter::Data>(1)}
111 {
112 // 100 kHz: the firmware's slave data setup time (STM32F030, I2CCLK 8 MHz) does not meet the Fast-mode worst
113 // case (RM0360 22.4.5), and the official driver also uses 100 kHz
114 auto ccfg = component_config();
115 ccfg.clock = 100 * 1000U;
116 component_config(ccfg);
117 }
118 virtual ~UnitDualKmeter()
119 {
120 }
121
122 virtual bool begin() override;
123 virtual void update(const bool force = false) override;
124
127
129 {
130 return _cfg;
131 }
133 inline void config(const config_t& cfg)
134 {
135 _cfg = cfg;
136 }
138
144 {
145 return _munit;
146 }
150 {
151 return _channel;
152 }
156 {
157 _munit = munit;
158 }
160
164 inline float temperature() const
165 {
166 return !empty() ? oldest().temperature() : std::numeric_limits<float>::quiet_NaN();
167 }
169
172
177 {
178 return PeriodicMeasurementAdapter<UnitDualKmeter, dual_kmeter::Data>::startPeriodicMeasurement();
179 }
188 const uint32_t interval, const dual_kmeter::Channel channel = dual_kmeter::Channel::One,
189 const dual_kmeter::MeasurementUnit munit = dual_kmeter::MeasurementUnit::Celsius)
190 {
191 return PeriodicMeasurementAdapter<UnitDualKmeter, dual_kmeter::Data>::startPeriodicMeasurement(interval,
192 channel, munit);
193 }
199 {
200 return PeriodicMeasurementAdapter<UnitDualKmeter, dual_kmeter::Data>::stopPeriodicMeasurement();
201 }
203
209 bool readStatus(uint8_t& status);
210
216 bool readFirmwareVersion(uint8_t& ver);
217
220
230 dual_kmeter::MeasurementUnit munit = dual_kmeter::MeasurementUnit::Celsius,
231 const uint32_t timeoutMs = 100);
242 const dual_kmeter::MeasurementUnit munit = dual_kmeter::MeasurementUnit::Celsius,
243 const uint32_t timeoutMs = 100);
245
248
259 bool writeCurrentChannel(const dual_kmeter::Channel channel);
261
262protected:
263 inline bool read_register(const uint8_t reg, uint8_t* rbuf, const uint32_t len)
264 {
265 return readRegister(reg, rbuf, len, 0, false);
266 }
267 inline bool read_register8(const uint8_t reg, uint8_t& v)
268 {
269 return readRegister8(reg, v, 0, false);
270 }
271
272 bool start_periodic_measurement();
273 bool start_periodic_measurement(const uint32_t interval, const dual_kmeter::Channel channel,
274 const dual_kmeter::MeasurementUnit munit);
275 bool stop_periodic_measurement();
276
277 bool read_measurement(dual_kmeter::Data& d, const dual_kmeter::MeasurementUnit munit);
278 bool read_internal_measurement(dual_kmeter::Data& d, const dual_kmeter::MeasurementUnit munit);
279
280 bool is_data_ready()
281 {
282 uint8_t s{};
283 return readStatus(s) && (s == 0U);
284 }
285 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitDualKmeter, dual_kmeter::Data);
286
287protected:
288 std::unique_ptr<m5::container::CircularBuffer<dual_kmeter::Data>> _data{};
289 dual_kmeter::MeasurementUnit _munit{dual_kmeter::MeasurementUnit::Celsius};
290 dual_kmeter::Channel _channel{}, _current_channel{};
291 config_t _cfg{};
292};
293
294namespace dual_kmeter {
296namespace command {
297constexpr uint8_t TEMPERATURE_CELSIUS_REG{0x00}; // R
298constexpr uint8_t TEMPERATURE_FAHRENHEIT_REG{0x04}; // R
299constexpr uint8_t INTERNAL_TEMPERATURE_CELSIUS_REG{0x10}; // R
300constexpr uint8_t INTERNAL_TEMPERATURE_FAHRENHEIT_REG{0x14}; // R
301constexpr uint8_t CHANNEL_REG{0x20}; // R/W
302constexpr uint8_t STATUS_REG{0x30}; // R
303constexpr uint8_t TEMPERATURE_CELSIUS_STRING_REG{0x40}; // R
304constexpr uint8_t TEMPERATURE_FAHRENHEIT_STRING_REG{0x50}; // R
305constexpr uint8_t INTERNAL_TEMPERATURE_CELSIUS_STRING_REG{0x60}; // R
306constexpr uint8_t INTERNAL_TEMPERATURE_FAHRENHEIT_STRING_REG{0x70}; // R
307constexpr uint8_t FIRMWARE_VERSION_REG{0xFE}; // R
308} // namespace command
310} // namespace dual_kmeter
311
312} // namespace unit
313} // namespace m5
314
315#endif
config_t config()
Gets the configuration.
Definition unit_DualKmeter.hpp:128
bool stopPeriodicMeasurement()
Stop periodic measurement.
Definition unit_DualKmeter.hpp:198
bool measureInternalSingleshot(dual_kmeter::Data &data, const dual_kmeter::Channel channel, const dual_kmeter::MeasurementUnit munit=dual_kmeter::MeasurementUnit::Celsius, const uint32_t timeoutMs=100)
Measure internal temperature single shot.
Definition unit_DualKmeter.cpp:145
bool readStatus(uint8_t &status)
Read status.
Definition unit_DualKmeter.cpp:109
dual_kmeter::MeasurementUnit measurementUnit() const
Gets the measurement unit on periodic measurement.
Definition unit_DualKmeter.hpp:143
bool startPeriodicMeasurement()
Start periodic measurement in the current settings.
Definition unit_DualKmeter.hpp:176
bool writeCurrentChannel(const dual_kmeter::Channel channel)
Write the current measure channel.
Definition unit_DualKmeter.cpp:179
float temperature() const
Oldest temperature.
Definition unit_DualKmeter.hpp:164
void setMeasurementUnit(const dual_kmeter::MeasurementUnit munit)
Set the measurement unit on periodic measurement.
Definition unit_DualKmeter.hpp:155
bool readFirmwareVersion(uint8_t &ver)
Read firmware version.
Definition unit_DualKmeter.cpp:115
bool startPeriodicMeasurement(const uint32_t interval, const dual_kmeter::Channel channel=dual_kmeter::Channel::One, const dual_kmeter::MeasurementUnit munit=dual_kmeter::MeasurementUnit::Celsius)
Start periodic measurement.
Definition unit_DualKmeter.hpp:187
bool measureSingleshot(dual_kmeter::Data &data, const dual_kmeter::Channel channel, dual_kmeter::MeasurementUnit munit=dual_kmeter::MeasurementUnit::Celsius, const uint32_t timeoutMs=100)
Measure temperature single shot.
Definition unit_DualKmeter.cpp:121
dual_kmeter::Channel measurementChannel() const
Gets the measurement channel on periodic measurement.
Definition unit_DualKmeter.hpp:149
void config(const config_t &cfg)
Set the configuration.
Definition unit_DualKmeter.hpp:133
bool readCurrentChannel(dual_kmeter::Channel &channel)
Read the current measure channel.
Definition unit_DualKmeter.cpp:169
For DualKmeter.
Top level namespace of M5stack.
Unit-related namespace.
Settings for begin.
Definition unit_DualKmeter.hpp:98
bool start_periodic
Start periodic measurement on begin?
Definition unit_DualKmeter.hpp:100
uint32_t interval
periodic interval(ms) if start on begin
Definition unit_DualKmeter.hpp:102
dual_kmeter::Channel measurement_channel
measurement unit if start on begin
Definition unit_DualKmeter.hpp:104
Measurement data group.
Definition unit_DualKmeter.hpp:49
float temperature() const
Temperature value.
Definition unit_DualKmeter.hpp:55
std::array< uint8_t, 4 > raw
Raw data.
Definition unit_DualKmeter.hpp:50
Channel channel
Which channel?
Definition unit_DualKmeter.hpp:51
@ One
Assert after one conversion.
@ Two
Assert after two conversion.
MeasurementUnit
measurement unit on periodic measurement
Definition unit_DualKmeter.hpp:40
@ Celsius
Temperature unit is celsius.
@ Fahrenheit
Temperature unit is fahrenheit.
Channel
Channel to be measured.
Definition unit_DualKmeter.hpp:31