M5Unit-WEIGHT 0.1.1 git rev:97a7989
Loading...
Searching...
No Matches
unit_WeightI2C.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_WEIGHT_I2C_UNIT_WEIGHT_I2C_HPP
11#define M5_UNIT_WEIGHT_I2C_UNIT_WEIGHT_I2C_HPP
12
13#include <M5UnitComponent.hpp>
14#include <m5_utility/container/circular_buffer.hpp>
15#include <m5_utility/types.hpp>
16#include <array>
17#include <cstring> // std::memcpy
18#include <limits> // NaN
19
20namespace m5 {
21namespace unit {
22
23namespace weighti2c {
24
29enum class Mode : uint8_t { Float, Int };
30
35struct Data {
36 static_assert(sizeof(float) == 4, "Invalid float size"); // I2C protocol assumes IEEE 754 float (4 bytes)
37 std::array<uint8_t, 4> raw{};
39 bool is_float{};
40
45 inline float weight() const
46 {
47 if (!is_float) {
48 return std::numeric_limits<float>::quiet_NaN();
49 }
50 float val{};
51 std::memcpy(&val, raw.data(), raw.size());
52 return val;
53 }
58 inline int32_t iweight() const
59 {
60 return !is_float
61 ? static_cast<int32_t>(static_cast<uint32_t>(raw[0]) | (static_cast<uint32_t>(raw[1]) << 8) |
62 (static_cast<uint32_t>(raw[2]) << 16) | (static_cast<uint32_t>(raw[3]) << 24))
63 : std::numeric_limits<int32_t>::min();
64 }
65};
66} // namespace weighti2c
67
72class UnitWeightI2C : public Component, public PeriodicMeasurementAdapter<UnitWeightI2C, weighti2c::Data> {
73 M5_UNIT_COMPONENT_HPP_BUILDER(UnitWeightI2C, 0x26);
74
75public:
80 struct config_t {
82 bool lp_enable{true};
84 uint8_t avg_filter_level{10};
86 uint8_t ema_filter_alpha{10};
88 bool start_periodic{true};
90 weighti2c::Mode mode{weighti2c::Mode::Float};
92 uint32_t interval{80};
93 };
94
95 explicit UnitWeightI2C(const uint8_t addr = DEFAULT_ADDRESS)
96 : Component(addr), _data{new m5::container::CircularBuffer<weighti2c::Data>(1)}
97 {
98 auto ccfg = component_config();
99 ccfg.clock = 100 * 1000U;
100 component_config(ccfg);
101 }
102 virtual ~UnitWeightI2C()
103 {
104 }
105
110 virtual bool begin() override;
115 virtual void update(const bool force = false) override;
116
119
121 {
122 return _cfg;
123 }
125 inline void config(const config_t& cfg)
126 {
127 _cfg = cfg;
128 }
130
134
138 inline float weight() const
139 {
140 return !empty() ? oldest().weight() : std::numeric_limits<float>::quiet_NaN();
141 }
146 inline int32_t iweight() const
147 {
148 return !empty() ? oldest().iweight() : std::numeric_limits<int32_t>::min();
149 }
151
154
160 inline bool startPeriodicMeasurement(const weighti2c::Mode mode, const uint32_t interval = 80)
161 {
162 return PeriodicMeasurementAdapter<UnitWeightI2C, weighti2c::Data>::startPeriodicMeasurement(mode, interval);
163 }
169 {
170 return PeriodicMeasurementAdapter<UnitWeightI2C, weighti2c::Data>::stopPeriodicMeasurement();
171 }
173
176
183 bool measureSingleshot(weighti2c::Data& data, const weighti2c::Mode mode);
191 bool measureSingleshot(char* buf);
193
196
201 bool readGap(float& gap);
208 bool writeGap(const float gap, const uint32_t duration = 100);
210
215 bool resetOffset();
216
219
224 bool isEnabledLPFilter(bool& enabled);
230 bool enableLPFilter(const bool enable);
236 bool readAvgFilterLevel(uint8_t& level);
243 bool writeAvgFilterLevel(const uint8_t level);
249 bool readEmaFilterAlpha(uint8_t& alpha);
256 bool writeEmaFilterAlpha(const uint8_t alpha);
258
264 bool readRawADC(int32_t& value);
265
269
274 bool readI2CAddress(uint8_t& i2c_address);
280 bool changeI2CAddress(const uint8_t i2c_address);
282
283protected:
284 bool read_register(const uint8_t reg, uint8_t* buf, const size_t len);
285 inline bool read_register8(const uint8_t reg, uint8_t& val)
286 {
287 return read_register(reg, &val, 1);
288 }
289
290 bool start_periodic_measurement(const weighti2c::Mode mode, const uint32_t interval);
291 bool stop_periodic_measurement();
292 bool read_measurement(weighti2c::Data& d, const weighti2c::Mode m);
293 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitWeightI2C, weighti2c::Data);
294
295protected:
296 weighti2c::Mode _mode{};
297 std::unique_ptr<m5::container::CircularBuffer<weighti2c::Data>> _data{};
298 config_t _cfg{};
299};
300
301namespace weighti2c {
302namespace command {
304// clang-format off
305constexpr uint8_t RAW_ADC_REG {0x00}; // R
306constexpr uint8_t WEIGHT_REG {0x10}; // R
307constexpr uint8_t GAP_REG {0x40}; // R/W
308constexpr uint8_t OFFSET_REG {0x50}; // W
309constexpr uint8_t WEIGHTX100_INT_REG {0x60}; // R
310constexpr uint8_t WEIGHTX100_STRING_REG {0x70}; // R
311constexpr uint8_t FILTER_REG {0x80}; // R/W
312constexpr uint8_t FILTER_LP_REG {0x80}; // R/W
313constexpr uint8_t FILTER_AVG_REG {0x81}; // R/W
314constexpr uint8_t FILTER_EMA_REG {0x82}; // R/W
315constexpr uint8_t FIRMWARE_VERSION_REG {0xFE}; // R
316constexpr uint8_t I2C_ADDRESS_REG {0xFF}; // R/W
317// clang-format on
319} // namespace command
320} // namespace weighti2c
321
322} // namespace unit
323} // namespace m5
324#endif
WeightI2C unit.
Definition unit_WeightI2C.hpp:72
bool writeAvgFilterLevel(const uint8_t level)
Write the Averaging Filter level.
Definition unit_WeightI2C.cpp:185
bool startPeriodicMeasurement(const weighti2c::Mode mode, const uint32_t interval=80)
Start periodic measurement.
Definition unit_WeightI2C.hpp:160
bool measureSingleshot(weighti2c::Data &data, const weighti2c::Mode mode)
Measurement single shot.
Definition unit_WeightI2C.cpp:102
bool isEnabledLPFilter(bool &enabled)
Is enabled the Low-Pass Filter?
Definition unit_WeightI2C.cpp:164
config_t config()
Gets the configuration.
Definition unit_WeightI2C.hpp:120
bool readEmaFilterAlpha(uint8_t &alpha)
Read the Exponential Moving Average Filter alpha.
Definition unit_WeightI2C.cpp:194
bool changeI2CAddress(const uint8_t i2c_address)
Change unit I2C address.
Definition unit_WeightI2C.cpp:214
bool writeGap(const float gap, const uint32_t duration=100)
Write the gap value.
Definition unit_WeightI2C.cpp:137
bool readAvgFilterLevel(uint8_t &level)
Read the Averaging Filter level.
Definition unit_WeightI2C.cpp:180
void config(const config_t &cfg)
Set the configuration.
Definition unit_WeightI2C.hpp:125
bool stopPeriodicMeasurement()
Stop periodic measurement.
Definition unit_WeightI2C.hpp:168
bool writeEmaFilterAlpha(const uint8_t alpha)
Write the Exponential Moving Average Filter alpha.
Definition unit_WeightI2C.cpp:199
bool readRawADC(int32_t &value)
Read the Raw ADC.
Definition unit_WeightI2C.cpp:153
bool enableLPFilter(const bool enable)
Enable the Low-Pass Filter.
Definition unit_WeightI2C.cpp:175
int32_t iweight() const
Oldest measured weight (integer)
Definition unit_WeightI2C.hpp:146
bool readI2CAddress(uint8_t &i2c_address)
Read the I2C address.
Definition unit_WeightI2C.cpp:208
bool resetOffset()
Reset offset.
Definition unit_WeightI2C.cpp:148
bool readGap(float &gap)
Read the gap value.
Definition unit_WeightI2C.cpp:127
virtual void update(const bool force=false) override
Update the cached periodic measurement data.
Definition unit_WeightI2C.cpp:67
float weight() const
Oldest measured weight (float)
Definition unit_WeightI2C.hpp:138
virtual bool begin() override
Initialize the unit and apply the current configuration.
Definition unit_WeightI2C.cpp:25
Top level namespace of M5Stack.
Unit-related namespace.
Settings for begin.
Definition unit_WeightI2C.hpp:80
bool start_periodic
Start periodic measurement on begin?
Definition unit_WeightI2C.hpp:88
bool lp_enable
Enable the Low-Pass Filter.
Definition unit_WeightI2C.hpp:82
uint8_t avg_filter_level
Averaging Filter level (0 - 50)
Definition unit_WeightI2C.hpp:84
uint8_t ema_filter_alpha
Exponential Moving Average Filter alpha (0-99)
Definition unit_WeightI2C.hpp:86
uint32_t interval
Measurement interval if start on begin.
Definition unit_WeightI2C.hpp:92
weighti2c::Mode mode
Measurement mode if start on begin.
Definition unit_WeightI2C.hpp:90
Measurement data group.
Definition unit_WeightI2C.hpp:35
int32_t iweight() const
Get the measured weight as an integer value multiplied by 100.
Definition unit_WeightI2C.hpp:58
float weight() const
Get the measured weight as a floating-point value.
Definition unit_WeightI2C.hpp:45
std::array< uint8_t, 4 > raw
True if the payload should be interpreted with weight()
Definition unit_WeightI2C.hpp:37
Mode
Measurement mode.
Definition unit_WeightI2C.hpp:29