複数の独立したLEDパターン


8

私は問題を抱えていますが、最初は(そしてArduinoを初めて使うのは)と思いましたが、Arduinoに最適なアプリケーションでした。しかし、それを実装しようとして失敗した後、私は自分自身を疑っています!

単に-私は多くのLEDを個別に制御する必要があります。それらの多くは独自のパターンを持っています-たとえば、「5秒オン-5秒オフ」。「連続点滅」-または「2回点滅、一時停止、1回点滅」などのシーケンス。明らかにスレッドの贅沢がなければ、私は少し行き詰まっています。a)Arduinoが最良の選択であり、b)もしそうである場合、どうすればこれに対処できますか?

前もって感謝します :)


1
プロトスレッドを調べましたか?プロジェクトにプロトスレッドを簡単に組み込むことができるArduinoライブラリがいくつかあります。
サクリーン2014

回答:


9

同時に複数のパターンを処理することは、Arduinoのようなプラットフォームで確かに可能であり、それに対処する方法はいくつかあります。

私が検討する1つの方法は、各パターンを数学的に効果的に表す関数を記述することです。これまでにプログラムで経過した合計時間を渡すだけで、その特定の瞬間に適切なアクションを実行します。その後すぐに戻ります(遅延などはありません)。

そのためには、最初にパターンの1サイクルがどれだけ続くかを知る必要があります。次に、モジュロ演算子を使用して、現在のサイクルをどれだけ進んでいるかを把握できます。そこから、あなたがしなければならないことはif、いつでも何をすべきかを決定するためのいくつかの条件を持つことです。

「5秒オン、5秒オフ」のパターンは次のようになります。

function pattern5on5off(unsigned long totalTime)
{
  // Calculate how far through the current cycle we are
  const unsigned long cycleTime = totalTime % 10000;

  // If we're in the first 5 seconds of the cycle then turn the light on.
  // Otherwise, turn it off.
  if (cycleTime < 5000)
    digitalWrite(3, HIGH);
  else
    digitalWrite(3, LOW);
}

確かに、digitalWrite()技術的に必要がないときに絶えず電話をかけることは、あまり効率的ではありません。ただし、問題が発生することはなく、必要に応じて最適化するのもかなり簡単です。

上記の例をスケッチで使用するには、それをで呼び出しloop()、取得した数値を渡すだけですmillis()。例えば:

void loop()
{
  const unsigned long totalTime = millis();

  pattern5on5off(totalTime);

  // call other patterns here...
}

他のパターンはより複雑になりますが、同じ原理に従います。適切なifステートメントを使用してロジックを表現するだけです。

覚えておくべき重要なことは、関数が特定の瞬間を表すということです。プログラムを一時停止したり遅延させたりしてはなりません。そうしないと、他のパターンの実行が妨げられます。

編集:最初のサイクルのタイミング
jfpoilpretがコメントに記載されているように、最初のサイクルはランダムなポイントから始まります。これは、最初にを呼び出しmillis()たときにloop()、0からは開始されないためです(デバイスは、loop()呼び出される前にすでに短時間実行されています)。ただし、必要に応じて簡単に解決できます。

これtotalTimeは、最初に取得した任意の値で値をオフセットすることによって行いますloop()。例えば:

unsigned long g_startTime = 0;

void loop()
{
  unsigned long totalTime = 0;

  if (g_startTime == 0) {
    // This is the first cycle.
    // Store the start time so we can compensate later.
    g_startTime = millis();

  } else {
    // This is not the first cycle.
    // Compensate for the start time.
    totalTime = millis() - g_startTime;
  }

  pattern5on5off(totalTime);
  // etc..
}

どうもありがとうございました。私は間違いなく間違ったアプローチで壁に頭をぶつけていました... :)
Nickos 14

1
この%アプローチの問題は、最初はランダムであるため、タイミングが最初は正しくないことです。
jfpoilpret 2014

1
@jfpoilpretそうですね。ただし、修正は簡単なので、答えに追加しました。:)
Peter Bloomfield、

別のオプションはmillis、ループで1回実行して、その値をパラメーターとしてすべてのled関数に渡す代わりに、各関数をパラメーターなしの関数として設定し、それぞれの内部でミリを実行することです。これにより、各関数がより正確な値を取得できるようになります。これは、ループ内の各関数の実行にかかる時間、およびアプリケーションのタイミングの正確さの要件に応じて重要な場合と重要でない場合があります。
Heltonbiker 2015

4

この作業にはArduinoが最適です。簡単に始められます。重要なのは、非ブロッキングコードを記述することです。BlinkWithoutDelayの例をご覧ください。

私はあなたの仕事を提案しました:

// Timing suquences for the LED's in milliseconds
// First value is on time, second value is off time,
// third value on time and so on (up to 10 values)
// One row for each LED
unsigned int led_timing[][10] = {
  {5000, 5000},
  {100, 1000},
  {100, 100, 100, 1500, 100, 1500}
};

// The pins the LED's are connected to
byte led_pins[] = {11, 12, 13};

// Keep track of timing sequence
// Array size taken from led_pins
unsigned long last_change[sizeof(led_pins)/sizeof(led_pins[0])];
byte timing_i[sizeof(led_pins)/sizeof(led_pins[0])];

void setup()
{
  // Initialize LED's as output
  for (byte i = 0; i < sizeof(led_pins)/sizeof(led_pins[0]); i++)
  {
    pinMode(led_pins[i], OUTPUT);
    digitalWrite(led_pins[i], HIGH);
  }
}


void loop()
{
  // Current timestamp
  unsigned long now = millis();

  // Keep track of sequence for each LED
  for (byte i = 0; i < sizeof(led_pins)/sizeof(led_pins[0]); i++)
  {
    if (now - last_change[i] >= led_timing[i][timing_i[i]])
    {
      digitalWrite(led_pins[i], !digitalRead(led_pins[i]));
      timing_i[i]++;

      // Start over at the end of timing sequence
      timing_i[i] %= sizeof(led_timing[i])/sizeof(led_timing[i][0]);

      last_change[i] = now;
    }
  }
}

0

私は投稿が古いことを知っていますが、配列ベースのアプローチで例をチェックしました、そして私の意見では:

sizeof(led_timing[i])/sizeof(led_timing[i][0])

配列の割り当てられたサイズ(要素の数)が常に生成されます。この場合は10です。したがって、未定義の要素を使用して、配列の「終わり」に達するまで、タイミングは再開されません。LED "0"の場合:

int led_timing[0][10]:
5000,5000, <undefined>, <undefined>, <undefined>, <undefined>, <undefined>, <undefined>, <undefined>, <undefined>

挨拶トミー

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.