UdonLibrary 1.0.0
機械システム研究部 C++ ライブラリ
読み取り中…
検索中…
一致する文字列を見つけられません
E220Reader.hpp
[詳解]
1//
2// E220 無線モジュール受信クラス
3//
4// Copyright (c) 2022-2024 udonrobo
5//
6
7#pragma once
8
12#include "E220Base.hpp"
13
14namespace Udon
15{
16
19 template <typename T>
21 : public Impl::E220Base
22 {
23 public:
25 static constexpr size_t Size = Udon::SerializedSize<T>();
26
28 using MessageType = T;
29
32 E220Reader(const E220Base::Config& config) = delete;
33
36 E220Reader(E220Base::Config&& config)
38 {
39 }
40
42 void begin() noexcept
43 {
44 E220Base::begin();
45 delay(100);
46 darkAttachInterrupt(config.aux);
47 }
48
51 void begin(uint8_t channel) noexcept
52 {
53 config.channel = channel;
54 begin();
55 }
56
61 int getRssi() const noexcept
62 {
64
65 if (rawRssi == 0)
66 {
67 // アンテナ同士が近すぎると 0 になる
68 return 0;
69 }
70 else
71 {
72 return -(256 - rawRssi);
73 }
74 }
75
81 {
83
84 if (received)
85 {
86 lastReceiveMs = millis(); // 割り込み内でのmillis()は正確な値を取得できないため、このタイミングで取得
87 received = false;
88 }
89
90 if (millis() - lastReceiveMs > 500)
91 {
92 // 受信タイムアウト
93 return Udon::nullopt;
94 }
95
96 return Udon::Deserialize<MessageType>(buffer);
97 }
98
99 private:
100 uint32_t lastReceiveMs = 0;
101
102 // 排他制御必須 (割り込み関数内で使用)
103 bool received = false;
104 uint8_t buffer[Size];
105 uint8_t rawRssi;
106
107 void onRisingEdge()
108 {
109 if (config.serial.available() == Size + 1 /* RSSIバイト*/)
110 {
111 config.serial.readBytes(buffer, sizeof buffer);
112 rawRssi = config.serial.read();
113 received = true;
114 }
115 else
116 {
117 while (config.serial.available())
118 {
119 (void)config.serial.read();
120 }
121 }
122 }
123
124 static E220Reader** InstanceList()
125 {
126 static E220Reader* instanceList[60];
127 return instanceList;
128 }
129
130 void darkAttachInterrupt(uint8_t pin)
131 {
132 if (pin >= 60)
133 {
134 return;
135 }
136
137 // attachInterrupt は this ポインタの情報がないためメンバ関数を呼び出すことができない
138 // そこでピン番号とthisポインタを紐づけて、無理やりメンバ関数を呼び出す
139
140 InstanceList()[pin] = this;
141
142 // clang-format off
143 switch (pin)
144 {
145 case 0: attachInterrupt(digitalPinToInterrupt( 0), [](){ InstanceList()[ 0]->onRisingEdge(); }, RISING); break;
146 case 1: attachInterrupt(digitalPinToInterrupt( 1), [](){ InstanceList()[ 1]->onRisingEdge(); }, RISING); break;
147 case 2: attachInterrupt(digitalPinToInterrupt( 2), [](){ InstanceList()[ 2]->onRisingEdge(); }, RISING); break;
148 case 3: attachInterrupt(digitalPinToInterrupt( 3), [](){ InstanceList()[ 3]->onRisingEdge(); }, RISING); break;
149 case 4: attachInterrupt(digitalPinToInterrupt( 4), [](){ InstanceList()[ 4]->onRisingEdge(); }, RISING); break;
150 case 5: attachInterrupt(digitalPinToInterrupt( 5), [](){ InstanceList()[ 5]->onRisingEdge(); }, RISING); break;
151 case 6: attachInterrupt(digitalPinToInterrupt( 6), [](){ InstanceList()[ 6]->onRisingEdge(); }, RISING); break;
152 case 7: attachInterrupt(digitalPinToInterrupt( 7), [](){ InstanceList()[ 7]->onRisingEdge(); }, RISING); break;
153 case 8: attachInterrupt(digitalPinToInterrupt( 8), [](){ InstanceList()[ 8]->onRisingEdge(); }, RISING); break;
154 case 9: attachInterrupt(digitalPinToInterrupt( 9), [](){ InstanceList()[ 9]->onRisingEdge(); }, RISING); break;
155 case 10: attachInterrupt(digitalPinToInterrupt(10), [](){ InstanceList()[10]->onRisingEdge(); }, RISING); break;
156 case 11: attachInterrupt(digitalPinToInterrupt(11), [](){ InstanceList()[11]->onRisingEdge(); }, RISING); break;
157 case 12: attachInterrupt(digitalPinToInterrupt(12), [](){ InstanceList()[12]->onRisingEdge(); }, RISING); break;
158 case 13: attachInterrupt(digitalPinToInterrupt(13), [](){ InstanceList()[13]->onRisingEdge(); }, RISING); break;
159 case 14: attachInterrupt(digitalPinToInterrupt(14), [](){ InstanceList()[14]->onRisingEdge(); }, RISING); break;
160 case 15: attachInterrupt(digitalPinToInterrupt(15), [](){ InstanceList()[15]->onRisingEdge(); }, RISING); break;
161 case 16: attachInterrupt(digitalPinToInterrupt(16), [](){ InstanceList()[16]->onRisingEdge(); }, RISING); break;
162 case 17: attachInterrupt(digitalPinToInterrupt(17), [](){ InstanceList()[17]->onRisingEdge(); }, RISING); break;
163 case 18: attachInterrupt(digitalPinToInterrupt(18), [](){ InstanceList()[18]->onRisingEdge(); }, RISING); break;
164 case 19: attachInterrupt(digitalPinToInterrupt(19), [](){ InstanceList()[19]->onRisingEdge(); }, RISING); break;
165 case 20: attachInterrupt(digitalPinToInterrupt(20), [](){ InstanceList()[20]->onRisingEdge(); }, RISING); break;
166 case 21: attachInterrupt(digitalPinToInterrupt(21), [](){ InstanceList()[21]->onRisingEdge(); }, RISING); break;
167 case 22: attachInterrupt(digitalPinToInterrupt(22), [](){ InstanceList()[22]->onRisingEdge(); }, RISING); break;
168 case 23: attachInterrupt(digitalPinToInterrupt(23), [](){ InstanceList()[23]->onRisingEdge(); }, RISING); break;
169 case 24: attachInterrupt(digitalPinToInterrupt(24), [](){ InstanceList()[24]->onRisingEdge(); }, RISING); break;
170 case 25: attachInterrupt(digitalPinToInterrupt(25), [](){ InstanceList()[25]->onRisingEdge(); }, RISING); break;
171 case 26: attachInterrupt(digitalPinToInterrupt(26), [](){ InstanceList()[26]->onRisingEdge(); }, RISING); break;
172 case 27: attachInterrupt(digitalPinToInterrupt(27), [](){ InstanceList()[27]->onRisingEdge(); }, RISING); break;
173 case 28: attachInterrupt(digitalPinToInterrupt(28), [](){ InstanceList()[28]->onRisingEdge(); }, RISING); break;
174 case 29: attachInterrupt(digitalPinToInterrupt(29), [](){ InstanceList()[29]->onRisingEdge(); }, RISING); break;
175 case 30: attachInterrupt(digitalPinToInterrupt(30), [](){ InstanceList()[30]->onRisingEdge(); }, RISING); break;
176 case 31: attachInterrupt(digitalPinToInterrupt(31), [](){ InstanceList()[31]->onRisingEdge(); }, RISING); break;
177 case 32: attachInterrupt(digitalPinToInterrupt(32), [](){ InstanceList()[32]->onRisingEdge(); }, RISING); break;
178 case 33: attachInterrupt(digitalPinToInterrupt(33), [](){ InstanceList()[33]->onRisingEdge(); }, RISING); break;
179 case 34: attachInterrupt(digitalPinToInterrupt(34), [](){ InstanceList()[34]->onRisingEdge(); }, RISING); break;
180 case 35: attachInterrupt(digitalPinToInterrupt(35), [](){ InstanceList()[35]->onRisingEdge(); }, RISING); break;
181 case 36: attachInterrupt(digitalPinToInterrupt(36), [](){ InstanceList()[36]->onRisingEdge(); }, RISING); break;
182 case 37: attachInterrupt(digitalPinToInterrupt(37), [](){ InstanceList()[37]->onRisingEdge(); }, RISING); break;
183 case 38: attachInterrupt(digitalPinToInterrupt(38), [](){ InstanceList()[38]->onRisingEdge(); }, RISING); break;
184 case 39: attachInterrupt(digitalPinToInterrupt(39), [](){ InstanceList()[39]->onRisingEdge(); }, RISING); break;
185 case 40: attachInterrupt(digitalPinToInterrupt(40), [](){ InstanceList()[40]->onRisingEdge(); }, RISING); break;
186 case 41: attachInterrupt(digitalPinToInterrupt(41), [](){ InstanceList()[41]->onRisingEdge(); }, RISING); break;
187 case 42: attachInterrupt(digitalPinToInterrupt(42), [](){ InstanceList()[42]->onRisingEdge(); }, RISING); break;
188 case 43: attachInterrupt(digitalPinToInterrupt(43), [](){ InstanceList()[43]->onRisingEdge(); }, RISING); break;
189 case 44: attachInterrupt(digitalPinToInterrupt(44), [](){ InstanceList()[44]->onRisingEdge(); }, RISING); break;
190 case 45: attachInterrupt(digitalPinToInterrupt(45), [](){ InstanceList()[45]->onRisingEdge(); }, RISING); break;
191 case 46: attachInterrupt(digitalPinToInterrupt(46), [](){ InstanceList()[46]->onRisingEdge(); }, RISING); break;
192 case 47: attachInterrupt(digitalPinToInterrupt(47), [](){ InstanceList()[47]->onRisingEdge(); }, RISING); break;
193 case 48: attachInterrupt(digitalPinToInterrupt(48), [](){ InstanceList()[48]->onRisingEdge(); }, RISING); break;
194 case 49: attachInterrupt(digitalPinToInterrupt(49), [](){ InstanceList()[49]->onRisingEdge(); }, RISING); break;
195 case 50: attachInterrupt(digitalPinToInterrupt(50), [](){ InstanceList()[50]->onRisingEdge(); }, RISING); break;
196 case 51: attachInterrupt(digitalPinToInterrupt(51), [](){ InstanceList()[51]->onRisingEdge(); }, RISING); break;
197 case 52: attachInterrupt(digitalPinToInterrupt(52), [](){ InstanceList()[52]->onRisingEdge(); }, RISING); break;
198 case 53: attachInterrupt(digitalPinToInterrupt(53), [](){ InstanceList()[53]->onRisingEdge(); }, RISING); break;
199 case 54: attachInterrupt(digitalPinToInterrupt(54), [](){ InstanceList()[54]->onRisingEdge(); }, RISING); break;
200 case 55: attachInterrupt(digitalPinToInterrupt(55), [](){ InstanceList()[55]->onRisingEdge(); }, RISING); break;
201 case 56: attachInterrupt(digitalPinToInterrupt(56), [](){ InstanceList()[56]->onRisingEdge(); }, RISING); break;
202 case 57: attachInterrupt(digitalPinToInterrupt(57), [](){ InstanceList()[57]->onRisingEdge(); }, RISING); break;
203 case 58: attachInterrupt(digitalPinToInterrupt(58), [](){ InstanceList()[58]->onRisingEdge(); }, RISING); break;
204 case 59: attachInterrupt(digitalPinToInterrupt(59), [](){ InstanceList()[59]->onRisingEdge(); }, RISING); break;
205 default: break;
206 }
207 // clang-format on
208 }
209 };
210
211} // namespace Udon
E220 受信クラス
Definition E220Reader.hpp:22
Udon::Optional< MessageType > getMessage() noexcept
メッセージを受信
Definition E220Reader.hpp:80
void begin() noexcept
受信開始
Definition E220Reader.hpp:42
static constexpr size_t Size
メッセージサイズ
Definition E220Reader.hpp:25
T MessageType
メッセージ型
Definition E220Reader.hpp:28
void begin(uint8_t channel) noexcept
受信開始
Definition E220Reader.hpp:51
int getRssi() const noexcept
RSSI 強度取得
Definition E220Reader.hpp:61
E220Reader(const E220Base::Config &config)=delete
コピーコンストラクタ
E220Reader(E220Base::Config &&config)
ムーブコンストラクタ
Definition E220Reader.hpp:36
E220 ベースクラス
Definition E220Base.hpp:12
Config config
Definition E220Base.hpp:58
E220Base(const Config &config)
コンストラクタ
Definition E220Base.hpp:62
オプショナル型
Definition Optional.hpp:62
割り込みロック、アンロックをスコープの範囲で制御するクラス
Definition ScopedInterruptLocker.hpp:11
Definition Bit.hpp:12
Udon::Optional< T > Deserialize(ArrayView< const uint8_t > buffer)
バイト列からオブジェクトに逆シリアル化します
Definition Serializer.hpp:87
constexpr size_t SerializedSize() noexcept
Tをシリアライズした際のバイト列の要素数を取得する
Definition Serializer.hpp:22
constexpr NulloptT nullopt
無効値
Definition Optional.hpp:52
HardwareSerial & serial
Definition E220Base.hpp:17
uint8_t aux
Definition E220Base.hpp:21
uint8_t channel
チャンネル
Definition E220Base.hpp:26