回答編集履歴

1

追記1

2020/10/21 12:36

投稿

nac_tnk
nac_tnk

スコア512

test CHANGED
@@ -23,3 +23,177 @@
23
23
 
24
24
 
25
25
  ※VarSpeedServoライブラリが裏でタイマ1を使い、タイマ割り込みで動作している、という事も頭に入れておいてください。
26
+
27
+
28
+
29
+
30
+
31
+ <追記1>
32
+
33
+ 外部割り込みでリモコン取得も、開始信号から信号最期、或いはエラーまで専有するやり方と、毎回時間を計測して、直ぐに終了するやり方があると思うけど、
34
+
35
+ 前者なら、現在のスケッチからの変更は少ないです。けれども、他の動作に支障が出やすいです。
36
+
37
+ 後者なら、書き直しになりますけど、こちらの方がベーシックなやり方だと思いますし、他のスケッチと共存し易いです。
38
+
39
+
40
+
41
+ で、後者の方を教えます。
42
+
43
+
44
+
45
+ まず、リモコン通信のフォーマットを確認して下さい。
46
+
47
+ ChaNさんの所が参考になります。http://elm-chan.org/docs/ir_format.html
48
+
49
+
50
+
51
+ そこに書いてあるようにNECフォーマットの場合は562μsが基準となり、信号の長さで0と1が決まります。
52
+
53
+ 受信側からけば、HIGHの長さが基本ですから、HIGHの長さだけ測っておけばいいです。
54
+
55
+ ※送信信号が有る時は、受信側はLOWです。何もないときはHIGHです。その図からは反転します。
56
+
57
+  (といっても、受信側の回路にもよりますけど)
58
+
59
+
60
+
61
+ 考え方は、HIGHになった時に、測定開始時刻を記録、LOWになった時に、HIGHの時間を算出。
62
+
63
+ その時間が、ちゃんとフォーマットの通りに来ていれば記録を続けるけれども、一度でも範囲外なら、そこまでのデータは捨てます。
64
+
65
+ で、32bit分送られて来たら、どのSWかの判定です。
66
+
67
+
68
+
69
+ 実際のRAWデータで、どの位の時間なのかを確認した方が良いです。案外いい加減なものですから、範囲を外している場合があります。
70
+
71
+
72
+
73
+ ↓が外部割り込み関数のサンプルです。
74
+
75
+ ※つらつらと書いただけで、検証はしていません。内容を読み取ってください。
76
+
77
+
78
+
79
+ ```Arduino
80
+
81
+ volatile byte ir_num=0;//割り込みとloop関数両方で参照する変数は外部変数で、volatileを付ける。
82
+
83
+
84
+
85
+ void recv() {//外部割り込み関数
86
+
87
+ static byte state=0;//0:測定前、1~:受信中
88
+
89
+ static uint32_t up=0,length=0,result=0;
90
+
91
+
92
+
93
+ if(digitalRead(pin))up=micros();
94
+
95
+ else {
96
+
97
+ length=micros()-up;
98
+
99
+ if(length>4000 &&length>5000)state=1;//開始条件8T=4496
100
+
101
+ else if(state) {
102
+
103
+ if(length>460 && length<760)state++;//T=562
104
+
105
+ else if(length>1400 && length<1900) {//3T=1686
106
+
107
+ result|=(0x80000000UL>>(state-1));
108
+
109
+ state++;
110
+
111
+ } else {//範囲外ならやり直し
112
+
113
+ state=0;
114
+
115
+ result=0;
116
+
117
+ }
118
+
119
+ if(state==33) {//データが揃ったら
120
+
121
+ switch (result) {
122
+
123
+ case 0xFF0CF30D:
124
+
125
+ ir_num=1;
126
+
127
+ break;
128
+
129
+ case 0xFF18E718:
130
+
131
+ ir_num=2;
132
+
133
+ break;
134
+
135
+ case 0xFF5EA15E:
136
+
137
+ ir_num=3;
138
+
139
+ break;
140
+
141
+ default:
142
+
143
+ ir_num=4;
144
+
145
+
146
+
147
+ }
148
+
149
+ state=0;
150
+
151
+ result=0;
152
+
153
+ }
154
+
155
+ }
156
+
157
+ }
158
+
159
+ }
160
+
161
+
162
+
163
+ ```
164
+
165
+
166
+
167
+ で、この結果(ir_num)を受けて、サーボを操作するわけですけど、リモコン信号が来た場合に、
168
+
169
+ ・即時に停止、或いは次の動作へ移行。(停止の場合はその場に停止か、HOME位置へ戻すか?)
170
+
171
+ ・サイクルを実行してから次の動作平行
172
+
173
+ があると思います。
174
+
175
+ (現在はサイクルな訳ですけど。その場合、ちゃんと受信しているのか判りにくくなります。
176
+
177
+ 今回のトグル動作とかも、長いサイクルの場合は判り難く、2回押す事も考えられます)
178
+
179
+
180
+
181
+ もう一点、現在、myservo○.write(○,○,true);(終わるまで待機)を使っていますけど、
182
+
183
+ 1台のサーボなら兎も角、複数だと、1台ずつしか動かせません。
184
+
185
+ 本当にそれで良いのでしょうか?
186
+
187
+
188
+
189
+ (つまり、現在のスケッチが、狙い通りの動きなのか、書き方が判らないからそうなっているのかが判断付きません)
190
+
191
+
192
+
193
+ 処理的には複雑にはなりますけど、2台を別のタイミングでそれぞれ同時に操作する事は可能です。
194
+
195
+
196
+
197
+ そのあたりをちょっと聞いてから追記します。
198
+
199
+ ※「sw1で停止」のみの対応なら簡単です。