M5Unit-WEIGHT 0.1.0 git rev:dab2ce0
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 <limits> // NaN
18
19namespace m5 {
20namespace unit {
21
22namespace weighti2c {
23
28enum class Mode : uint8_t { Float, Int };
29
34struct Data {
35 static_assert(sizeof(float) == 4, "Invalid float size");
36 std::array<uint8_t, 4> raw{};
37 bool is_float{};
38
39 inline float weight() const
40 {
41 return is_float ? *(float*)raw.data() : std::numeric_limits<float>::quiet_NaN();
42 }
43 inline int32_t iweight() const
44 {
45 return !is_float ? (int32_t)((uint32_t)raw[0] | ((uint32_t)raw[1] << 8) | ((uint32_t)raw[2] << 16) |
46 ((uint32_t)raw[3] << 24))
47 : std::numeric_limits<int32_t>::min();
48 }
49};
50} // namespace weighti2c
51
56class UnitWeightI2C : public Component, public PeriodicMeasurementAdapter<UnitWeightI2C, weighti2c::Data> {
57 M5_UNIT_COMPONENT_HPP_BUILDER(UnitWeightI2C, 0x26);
58
59public:
64 struct config_t {
66 bool lp_enable{true};
68 uint8_t avg_filter_level{10};
69 // Exponential Moving Average Filter alpha (0-99)
70 uint8_t ema_filter_alpha{10};
72 bool start_periodic{true};
74 weighti2c::Mode mode{weighti2c::Mode::Float};
76 uint32_t interval{80};
77 };
78
79 explicit UnitWeightI2C(const uint8_t addr = DEFAULT_ADDRESS)
80 : Component(addr), _data{new m5::container::CircularBuffer<weighti2c::Data>(1)}
81 {
82 auto ccfg = component_config();
83 ccfg.clock = 100 * 1000U;
84 component_config(ccfg);
85 }
86 virtual ~UnitWeightI2C()
87 {
88 }
89
90 virtual bool begin() override;
91 virtual void update(const bool force = false) override;
92
95
97 {
98 return _cfg;
99 }
101 inline void config(const config_t& cfg)
102 {
103 _cfg = cfg;
104 }
106
110
114 inline float weight() const
115 {
116 return !empty() ? oldest().weight() : std::numeric_limits<float>::quiet_NaN();
117 }
122 inline int32_t iweight() const
123 {
124 return !empty() ? oldest().iweight() : std::numeric_limits<int32_t>::min();
125 }
127
130
136 inline bool startPeriodicMeasurement(const weighti2c::Mode mode, const uint32_t interval = 80)
137 {
138 return PeriodicMeasurementAdapter<UnitWeightI2C, weighti2c::Data>::startPeriodicMeasurement(mode, interval);
139 }
145 {
146 return PeriodicMeasurementAdapter<UnitWeightI2C, weighti2c::Data>::stopPeriodicMeasurement();
147 }
149
152
159 bool measureSingleshot(weighti2c::Data& data, const weighti2c::Mode mode);
167 bool measureSingleshot(char* buf);
169
172
177 bool readGap(float& gap);
184 bool writeGap(const float gap, const uint32_t duration = 100);
186
191 bool resetOffset();
192
195
200 bool isEnabledLPFilter(bool& enabled);
206 bool enableLPFilter(const bool enable);
212 bool readAvgFilterLevel(uint8_t& level);
219 bool writeAvgFilterLevel(const uint8_t level);
225 bool readEmaFilterAlpha(uint8_t& alpha);
232 bool writeEmaFilterAlpha(const uint8_t alpha);
234
240 bool readRawADC(int32_t& value);
241
245
250 bool readI2CAddress(uint8_t& i2c_address);
256 bool changeI2CAddress(const uint8_t i2c_address);
258
259protected:
260 bool read_register(const uint8_t reg, uint8_t* buf, const size_t len);
261 inline bool read_register8(const uint8_t reg, uint8_t& val)
262 {
263 return read_register(reg, &val, 1);
264 }
265
266 bool start_periodic_measurement(const weighti2c::Mode mode, const uint32_t interval);
267 bool stop_periodic_measurement();
268 bool read_measurement(weighti2c::Data& d, const weighti2c::Mode m);
269 bool read_filter(uint8_t* buf3);
270 bool write_filter(const uint8_t* buf3);
271
272 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitWeightI2C, weighti2c::Data);
273
274protected:
275 weighti2c::Mode _mode{};
276 std::unique_ptr<m5::container::CircularBuffer<weighti2c::Data>> _data{};
277 config_t _cfg{};
278};
279
280namespace weighti2c {
281namespace command {
283// clang-format off
284constexpr uint8_t RAW_ADC_REG {0x00}; // R
285constexpr uint8_t WEIGHT_REG {0x10}; // R
286constexpr uint8_t GAP_REG {0x40}; // R/W
287constexpr uint8_t OFFSET_REG {0x50}; // W
288constexpr uint8_t WEIGHTX100_INT_REG {0x60}; // R
289constexpr uint8_t WEIGHTX100_STRING_REG {0x70}; // R
290constexpr uint8_t FILTER_REG {0x80}; // R/W
291constexpr uint8_t FILTER_LP_REG {0x80}; // R/W
292constexpr uint8_t FILTER_AVG_REG {0x81}; // R/W
293constexpr uint8_t FILTER_EMA_REG {0x82}; // R/W
294constexpr uint8_t FIRMWARE_VERSION_REG {0xFE}; // R
295constexpr uint8_t I2C_ADDRESS_REG {0xFF}; // R/W
296// clang-format on
298} // namespace command
299} // namespace weighti2c
300
301} // namespace unit
302} // namespace m5
303#endif
WeightI2C unit.
Definition unit_WeightI2C.hpp:56
bool writeAvgFilterLevel(const uint8_t level)
Write the Averaging Filter level.
Definition unit_WeightI2C.cpp:168
bool startPeriodicMeasurement(const weighti2c::Mode mode, const uint32_t interval=80)
Start periodic measurement.
Definition unit_WeightI2C.hpp:136
bool measureSingleshot(weighti2c::Data &data, const weighti2c::Mode mode)
Measurement single shot.
Definition unit_WeightI2C.cpp:89
bool isEnabledLPFilter(bool &enabled)
Is enabled the Low-Pass Filter?
Definition unit_WeightI2C.cpp:147
config_t config()
Gets the configration.
Definition unit_WeightI2C.hpp:96
bool readEmaFilterAlpha(uint8_t &alpha)
Read the Exponential Moving Average Filter alpha.
Definition unit_WeightI2C.cpp:177
bool changeI2CAddress(const uint8_t i2c_address)
Change unit I2C address.
Definition unit_WeightI2C.cpp:197
bool writeGap(const float gap, const uint32_t duration=100)
Write the gap value.
Definition unit_WeightI2C.cpp:121
bool readAvgFilterLevel(uint8_t &level)
Read the Averaging Filter level.
Definition unit_WeightI2C.cpp:163
void config(const config_t &cfg)
Set the configration.
Definition unit_WeightI2C.hpp:101
bool stopPeriodicMeasurement()
Stop periodic measurement.
Definition unit_WeightI2C.hpp:144
bool writeEmaFilterAlpha(const uint8_t alpha)
Write the Exponential Moving Average Filter alpha.
Definition unit_WeightI2C.cpp:182
bool readRawADC(int32_t &value)
Read the Raw ADC.
Definition unit_WeightI2C.cpp:137
bool enableLPFilter(const bool enable)
Enable the Low-Pass Filter.
Definition unit_WeightI2C.cpp:158
int32_t iweight() const
Oldest measured weight (integer)
Definition unit_WeightI2C.hpp:122
bool readI2CAddress(uint8_t &i2c_address)
Read the I2C address.
Definition unit_WeightI2C.cpp:191
bool resetOffset()
Reset offset.
Definition unit_WeightI2C.cpp:132
bool readGap(float &gap)
Read the gap value.
Definition unit_WeightI2C.cpp:111
float weight() const
Oldest measured weight (float)
Definition unit_WeightI2C.hpp:114
Top level namespace of M5stack.
Unit-related namespace.
Settings for begin.
Definition unit_WeightI2C.hpp:64
bool start_periodic
Start periodic measurement on begin?
Definition unit_WeightI2C.hpp:72
bool lp_enable
Enable the Low-Pass Filter.
Definition unit_WeightI2C.hpp:66
uint8_t avg_filter_level
Averaging Filter level (0 - 50)
Definition unit_WeightI2C.hpp:68
uint32_t interval
Measurement interval if start on begin.
Definition unit_WeightI2C.hpp:76
weighti2c::Mode mode
Measurement mode if start on begin.
Definition unit_WeightI2C.hpp:74
Measurement data group.
Definition unit_WeightI2C.hpp:34
std::array< uint8_t, 4 > raw
RAW data.
Definition unit_WeightI2C.hpp:36
Mode
Measurement mode.
Definition unit_WeightI2C.hpp:28