M5Unit-DISTANCE 0.2.1 git rev:66f796f
Loading...
Searching...
No Matches
unit_RCWL9620.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_DISTANCE_UNIT_RCWL9620_HPP
11#define M5_UNIT_DISTANCE_UNIT_RCWL9620_HPP
12
13#include <M5UnitComponent.hpp>
14#include <m5_utility/container/circular_buffer.hpp>
15#include <limits> // NaN
16#include <cmath>
17#include <array>
18
19namespace m5 {
20namespace unit {
21
26namespace rcwl9620 {
27
32struct Data {
33 std::array<uint8_t, 3> raw{};
34
35 static constexpr float MAX_DISTANCE{4500.f};
36 static constexpr float MIN_DISTANCE{20.f};
37
40 inline float distance() const
41 {
42 float fd = raw_distance() / 1000.f;
43 return std::fmax(std::fmin(fd, MAX_DISTANCE), MIN_DISTANCE);
44 }
47 inline uint32_t raw_distance() const
48 {
49 return (static_cast<uint32_t>(raw[0]) << 16) | (static_cast<uint32_t>(raw[1]) << 8) |
50 static_cast<uint32_t>(raw[2]);
51 }
52};
53
54} // namespace rcwl9620
55
62class UnitRCWL9620 : public Component, public PeriodicMeasurementAdapter<UnitRCWL9620, rcwl9620::Data> {
63 M5_UNIT_COMPONENT_HPP_BUILDER(UnitRCWL9620, 0x57);
64
65public:
70 struct config_t {
72 bool start_periodic{true};
74 uint32_t interval_ms{150};
75 };
76
79 explicit UnitRCWL9620(const uint8_t addr = DEFAULT_ADDRESS)
80 : Component(addr), _data{new m5::container::CircularBuffer<rcwl9620::Data>(1)}
81 {
82 auto ccfg = component_config();
83 ccfg.clock = 100 * 1000U;
84 component_config(ccfg);
85 }
86 virtual ~UnitRCWL9620()
87 {
88 }
89
92 virtual bool begin() override;
95 virtual void update(const bool force = false) override;
96
99
102 {
103 return _cfg;
104 }
107 inline void config(const config_t& cfg)
108 {
109 _cfg = cfg;
110 }
112
117 float distance() const
118 {
119 return !empty() ? oldest().distance() : std::numeric_limits<float>::quiet_NaN();
120 }
122
125
130 inline bool startPeriodicMeasurement(const uint32_t interval)
131 {
132 return PeriodicMeasurementAdapter<UnitRCWL9620, rcwl9620::Data>::startPeriodicMeasurement(interval);
133 }
139 {
140 return PeriodicMeasurementAdapter<UnitRCWL9620, rcwl9620::Data>::stopPeriodicMeasurement();
141 }
143
146
155
157 // Class that abstracts the interaction between classes and adapters
158 class Interface {
159 public:
160 explicit Interface(UnitRCWL9620& u) : _unit{u}
161 {
162 }
163 virtual ~Interface()
164 {
165 }
166 virtual bool read_measurement(rcwl9620::Data&, bool&) = 0;
167 virtual bool request_measurement() = 0;
168
169 protected:
170 UnitRCWL9620& _unit;
171 };
173
174protected:
175 bool request_measurement();
176 bool read_measurement(rcwl9620::Data& d, bool& timeouted);
177
178 bool start_periodic_measurement(const uint32_t interval);
179 bool stop_periodic_measurement();
180
181 inline Interface* interface()
182 {
183 return _interface.get();
184 }
185
186 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitRCWL9620, rcwl9620::Data);
187
188 std::unique_ptr<m5::container::CircularBuffer<rcwl9620::Data>> _data{};
189
190 inline virtual uint32_t minimum_interval() const
191 {
192 // Datasheet says
193 // 向模块写入 0X01 ,模块开始测距;等待 100mS 模块最大测距时间
194 // Note : Max is assumed to be 50+100 since there is no description of Max.
195 // A larger value would be considered better?
196
197 // As a result of the experiment, it seems that in 100ms, 263 in requestFrom is returned in many cases.
198 // Therefore, the value should be increased.
199 return 150; // for I2C
200 }
201
202private:
203 std::unique_ptr<Interface> _interface{};
204 config_t _cfg{};
205};
206
208namespace rcwl9620 {
209namespace command {
210constexpr uint8_t MEASURE_DISTANCE{0x01};
211} // namespace command
212} // namespace rcwl9620
214
215} // namespace unit
216} // namespace m5
217#endif
@cond0
Definition unit_RCWL9620.hpp:158
An ultrasonic distance measuring sensor unit.
config_t config()
Gets the configuration.
Definition unit_RCWL9620.hpp:101
virtual bool begin() override
Begin communication and optionally start periodic measurement.
Definition unit_RCWL9620.cpp:106
bool startPeriodicMeasurement(const uint32_t interval)
Start periodic measurement.
Definition unit_RCWL9620.hpp:130
UnitRCWL9620(const uint8_t addr=DEFAULT_ADDRESS)
Constructor.
Definition unit_RCWL9620.hpp:79
bool measureSingleshot(rcwl9620::Data &data)
Measurement single shot.
Definition unit_RCWL9620.cpp:176
float distance() const
Oldest distance (mm)
Definition unit_RCWL9620.hpp:117
virtual void update(const bool force=false) override
Update periodic measurement.
Definition unit_RCWL9620.cpp:153
bool stopPeriodicMeasurement()
Stop periodic measurement.
Definition unit_RCWL9620.hpp:138
void config(const config_t &cfg)
Set the configuration.
Definition unit_RCWL9620.hpp:107
Top level namespace of M5Stack.
For RCWL9620.
Unit-related namespace.
Settings for begin.
Definition unit_RCWL9620.hpp:70
uint32_t interval_ms
Interval time if start on begin (ms) (I2C:150-, GPIO:50-)
Definition unit_RCWL9620.hpp:74
bool start_periodic
Start periodic measurement on begin?
Definition unit_RCWL9620.hpp:72
Measurement data group.
Definition unit_RCWL9620.hpp:32
uint32_t raw_distance() const
Get raw distance (um)
Definition unit_RCWL9620.hpp:47
static constexpr float MAX_DISTANCE
Maximum distance (mm)
Definition unit_RCWL9620.hpp:35
std::array< uint8_t, 3 > raw
Raw data (3 bytes, MSB first)
Definition unit_RCWL9620.hpp:33
float distance() const
Get distance (mm)
Definition unit_RCWL9620.hpp:40
static constexpr float MIN_DISTANCE
Minimum distance (mm)
Definition unit_RCWL9620.hpp:36