質問: 0xFF0CF3) 連続作動中に例えばsw1で停止させる方法が分からない // digitalWrite(9,LOW); } } } } ここに質問の内容を詳しく書いてください。 (例)PHP(CakePHP)で●●なシステムを作っています。 ■■な機能を実装中に以下のエラーメッセージが発生しました。 ### 発生している問題・エラーメッセージ ``` エラーメッセージ ``` ### 該当のソースコード ``` ソースコード ``` ### 試したこと ここに問題に対して試したことを記載してください。 ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。
回答: これだと、連続動作中もそうなのですけど、通常の動作中もリモコン操作は受け付けないですよね? 必ず一連の操作が終わらないとリモコン受信にならないし、逆にリモコン受信の所に行けばそれ以外の動作は出来ません。 簡単に言えば、この手法だと詰んでいる=スケッチを大きく変えないとならない、という事です。 パッと思い付く方法は3つですね。 ・リモコン受信に外部割り込みを使う。※外部割り込みでは直ぐcliにして、サーボライブラリが動くようにする。 ・タイマー割り込みで、サーボ処理を行う。=リモコン部はそのまま ・0.1~0.3ms程度のポーリング(タイマ割り込みでもloop関数でも良い)で、リモコン、サーボ操作の両方とも書き換え 今後の事を考えれば、ポーリングでリモコン受信させた方が良さそうには思いますけど... いずれにしても、現在のサーボ処理のスケッチは割り込み処理の形(カウントして計測する)に変える事になると思います。 ※VarSpeedServoライブラリが裏でタイマ1を使い、タイマ割り込みで動作している、という事も頭に入れておいてください。 <追記1> 外部割り込みでリモコン取得も、開始信号から信号最期、或いはエラーまで専有するやり方と、毎回時間を計測して、直ぐに終了するやり方があると思うけど、 前者なら、現在のスケッチからの変更は少ないです。けれども、他の動作に支障が出やすいです。 後者なら、書き直しになりますけど、こちらの方がベーシックなやり方だと思いますし、他のスケッチと共存し易いです。 で、後者の方を教えます。 まず、リモコン通信のフォーマットを確認して下さい。 ChaNさんの所が参考になります。http://elm-chan.org/docs/ir_format.html そこに書いてあるようにNECフォーマットの場合は562μsが基準となり、信号の長さで0と1が決まります。 受信側からけば、HIGHの長さが基本ですから、HIGHの長さだけ測っておけばいいです。 ※送信信号が有る時は、受信側はLOWです。何もないときはHIGHです。その図からは反転します。 (といっても、受信側の回路にもよりますけど) 考え方は、HIGHになった時に、測定開始時刻を記録、LOWになった時に、HIGHの時間を算出。 その時間が、ちゃんとフォーマットの通りに来ていれば記録を続けるけれども、一度でも範囲外なら、そこまでのデータは捨てます。 で、32bit分送られて来たら、どのSWかの判定です。 実際のRAWデータで、どの位の時間なのかを確認した方が良いです。案外いい加減なものですから、範囲を外している場合があります。 ↓が外部割り込み関数のサンプルです。 ※つらつらと書いただけで、検証はしていません。内容を読み取ってください。 ``` volatile byte ir_num=0;//割り込みとloop関数両方で参照する変数は外部変数で、volatileを付ける。 void recv() {//外部割り込み関数 static byte state=0;//0:測定前、1~:受信中 static uint32_t up=0,length=0,result=0; if(digitalRead(pin))up=micros(); else { length=micros()-up; if(length>4000 &&length>5000)state=1;//開始条件8T=4496 else if(state) { if(length>460 && length<760)state++;//T=562 else if(length>1400 && length<1900) {//3T=1686 result|=(0x80000000UL>>(state-1)); state++; } else {//範囲外ならやり直し state=0; result=0; } if(state==33) {//データが揃ったら switch (result) { case 0xFF0CF30D: ir_num=1; break; case 0xFF18E718: ir_num=2; break; case 0xFF5EA15E: ir_num=3; break; default: ir_num=4; } state=0; result=0; } } } } ``` で、この結果(ir_num)を受けて、サーボを操作するわけですけど、リモコン信号が来た場合に、 ・即時に停止、或いは次の動作へ移行。(停止の場合はその場に停止か、HOME位置へ戻すか?) ・サイクルを実行してから次の動作平行 があると思います。 (現在はサイクルな訳ですけど。その場合、ちゃんと受信しているのか判りにくくなります。 今回のトグル動作とかも、長いサイクルの場合は判り難く、2回押す事も考えられます) もう一点、現在、myservo○.write(○,○,true);(終わるまで待機)を使っていますけど、 1台のサーボなら兎も角、複数だと、1台ずつしか動かせません。 本当にそれで良いのでしょうか? (つまり、現在のスケッチが、狙い通りの動きなのか、書き方が判らないからそうなっているのかが判断付きません) 処理的には複雑にはなりますけど、2台を別のタイミングでそれぞれ同時に操作する事は可能です。 そのあたりをちょっと聞いてから追記します。 ※「sw1で停止」のみの対応なら簡単です。