Arduino IDEでの非ブロッキング遅延の遅延()の置き換え

Arduinoをマスターする初心者が最初に遭遇するのは、delay()関数の不快なプロパティ-プログラムの実行をブロックすることです。 インターネット上の多くの例ではこの機能を使用していますが、実際のアプリケーションでは、この機能を使用しない方が良いと示唆しています。



初心者にふさわしいとして、私は自転車がノンブロッキング遅延を実装するようしました 。 タスクは次のとおりです。





Arduinoライブラリの大部分がOOPを使用して作成されていることを確認したので、Arduino IDEに追加したり、gitクローンを〜/ Arduino / libraries /



結果はこれです。



#include <SmartDelay.h> SmartDelay foo(1000000UL); //   void loop () { if (foo.Now()) { //       ,    . } //  }
      
      





間隔が経過すると、Now()メソッドはtrueを返します。 この場合、同じ間隔でカウントダウンが再び開始されます。 つまり、Now()が毎回自動的に「リチャージ」されます。



従来のLEDの点滅は、2回点滅するまですぐに複雑になる可能性があります。 たとえば、電球は脚12と11に接続されており、それぞれ1秒と777ミリ秒の間隔で点滅します。



 #include <SmartDelay.h> SmartDelay led12(1000000UL); SmartDelay led11(777000UL); setup () { pinMode(12,OUTPUT); pinMode(11,OUTPUT); } byte led12state=0; byte led11state=0; void loop () { if (led12.Now()) { digitalWrite(12,led12state); led12state=!led12state; } if (led11.Now()) { digitalWrite(11,led11state); led11state=!led11state; } }
      
      





ループでは、他のことを行うことができます。LEDの点滅はこのコードの実行をブロックしません。



これは、一定時間フローを停止するdelay()の完全な代替ではないことは明らかであり、プログラムを常にMCA(ステートマシンメカニズム)として記述する必要があります。 つまり、状態を保存し、それに応じて、コード内の適切な場所に移動します。



古いバージョン:



 ... action1(); delay(1000); action2(); delay(500); action3(); ...
      
      





新しいオプション:



 byte state=0; SmartDelay d(); ... switch (state) { case 0: action1(); d.Set(1000000UL); state=1; break; case 1: if (d.Now()) { action2(); d.Set(500000UL); state=2; } break; case 2: if (d.Now()) { action3(); d.Stop(); state=0; } break; } ...
      
      





Setメソッド(間隔)は、新しい間隔を設定し、古い間隔を返します。 Get()メソッドを使用して間隔を見ることができます。



Stop()は処理を停止し、Now()は常にfalseを返します。



Start()は作業を再開し、Now()は通常どおり動作を開始します。



タイムカウントを遅くする必要があるが、まったく停止しない場合、つまり、Wait()メソッド。 たとえば、LED 12が点滅しているが、ボタンを押しても点滅しない場合は、上記の2つのダイオードを使用した例のloop()にこのコードを追加します。



 ... if (digitalRead(9)) led12.Wait(); ...
      
      





そのため、9本のレグで高い信号レベルを使用すると、12個のダイオードは点滅せず、0が表示されると継続します。



たとえば、このような「タイマー」を使用して画面を描画し、ボタンを並行して処理する場合、ボタンをクリックした直後に画面またはパーツを再描画し、間隔が終了するのを待たないことが必要になる場合があります。 これを行うには、Reset()メソッドを使用します。その後、Now()への次の呼び出しはtrueを返します。 例:



 SmartDelay display(1000000UL); void loop() { if (btClick()) display.Reset(); //   ,   . if (display.Now()) screenRedraw(); //  . }
      
      





バグから、マイクロ秒カウンターのオーバーフローは考慮されていないことがわかりますが、そうでない場合は、コードをクリーンアップする必要があります。 考えている間にReset()がどのように行われるかが気に入らない。



オブジェクトアプローチが好きでした。ライブラリ内のすべてのコードを非表示にすることができ、後で調べることはできません。 今、この小さなライブラリは私のすべてのプロジェクトに住んでいます:)



GitHubのプロジェクト



All Articles