web-dev-qa-db-ja.com

x時間後に機能を実行する

ループ内の他の条件とそのコードが一定時間後に実行されなかった場合、ループ内の関数を実行するために何を使用できますか?それは遅れて行うことができますか、それとも他の機能がありますか?

11
Markaj

Arduinoには内部時計がないため、実装は不可能だと思います。

EDIT:millis() 関数を使用して、ボードの開始からの時間を計算することができます。

unsigned long previousMillis = 0; // last time update
long interval = 2000; // interval at which to do something (milliseconds)

void setup(){
}

void loop(){
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
     previousMillis = currentMillis;  

     // do something
  }
}
11
ndeverge

Arduinoタイマー割り込みを試してください。プロセッサは16MHzのクロックと見なすことができるため、外部ライブラリや追加のハードウェアは必要ありません。

#include <avr/io.h>
#include <avr/interrupt.h>

void setup ()
{

  // INITIALIZE TIMER INTERRUPTS
  cli(); // disable global interrupts

  TCCR1A = 0; // set entire TCCR1A register to 0
  TCCR1B = 0; // same for TCCR1B

  OCR1A = 15624; // set compare match register to desired timer count. 16 MHz with 1024 prescaler = 15624 counts/s
  TCCR1B |= (1 << WGM12); // turn on CTC mode. clear timer on compare match

  TCCR1B |= (1 << CS10); // Set CS10 and CS12 bits for 1024 prescaler
  TCCR1B |= (1 << CS12);

  TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt

  sei(); // enable global interrupts

}

// TIMER VECTOR, gets called once a second (depends on prescaler and match register)
ISR(TIMER1_COMPA_vect)
{
  // do your timeing based stuff here
}

割り込みに関する詳細情報が必要ですか?

6
mrv

私の友人delay()delayMicroseconds()はすべてあなたを助けます。

他の返信に関する限り。

mills()-Arduinoボードが現在のプログラムの実行を開始してからのミリ秒数を返します。この数は、約50日後にオーバーフローします(ゼロに戻ります)。

参照: http://arduino.cc/en/Reference/millis

同様に、

micros()-Arduinoボードが現在のプログラムの実行を開始してからのマイクロ秒数を返します。参照: http://arduino.cc/en/Reference/Micros

私はあなたがあなたのケースでうまくいくためにこれらの2つに少し取り組む必要があると思います。

1
Zeeshan Ali

これがあなたが探しているものだと思います

http://playground.arduino.cc/Code/time

1
Kreker

メトロライブラリ を試してみてください。これにより、定期的なイベントを定期的に実行できます。必要に応じて、ループ内のタイマーの頻度を変更できます。

1
Dang Khoa

これらのタイマールーチンには多くのバージョンがあり、タイムアウトに達した場合、またはタイムアウトを超えた場合は、タイマー変数をmillis()からリセットすると想定しています。違う。あなたが忙しくてタイムスロットをはるかに過ぎているとしたらどうでしょう..今ではたくさんのことが引き伸ばされています。

それで、50msごとに何かをしたいとしましょう。保留になり、最後のチェックから55ミリ秒経過したとします。チェックします...タイマー変数を上書きして、50ミリ秒で一致するようにします。しかし、今は5ミリ秒遅れています。遅れたことと、この時点でオーバーフローが発生した場合にどうなるかを補う必要があります。

1
Peter Scargill

以下のサンプルコードを使用できます。ここでは、1ミリ秒ごとに手順を繰り返します。

#include <SimpleTimer.h>

// the timer object
SimpleTimer timer;

// a function to be executed periodically
void repeatMe() 
{
  Serial.print("Uptime (s): ");
  Serial.println(millis() / 1000);
}

void setup()
{
  Serial.begin(9600);
  timer.setInterval(1000, repeatMe);
}

void loop() 
{
  timer.run();
}
1
AMPS

Arduinoの再起動後も存続するタイマーは、外部部品なしで実装することは不可能です。問題は、リセットがトリガーされた時間を把握する手段がないことです。さらに、ブートローダーは再起動中に不明な時間を消費する可能性があります。したがって、外部のリアルタイムクロックが必要になります。

イベントの期間実行に関して、私のお気に入りはmsTimer2ライブラリです。私の例のいくつかについては、ここを参照してください。

http://blog.blinkenlight.net/experiments/basic-effects/persistence-of-vision/

http://blog.blinkenlight.net/experiments/removing-flicker/heartbeat/

http://blog.blinkenlight.net/experiments/basic-effects/lighthouses/

1
Udo Klein

millis()関数は、arduinoの再起動後もタイムアウトを維持したい場合を除いて、通常はこれで十分に機能します。

_some_condition_が最後に満たされた時間を追跡するTimerクラスを実装します。

_class Timer
{
public:
    Timer(void);
    void set_max_delay(unsigned long v);
    void set(void);
    boolean check(void);
private:
    unsigned long max_delay;
    unsigned long last_set;
};

Timer::Timer(void)
{
    max_delay = 3600000UL; // default 1 hour
}

void Timer::set_max_delay(unsigned long v)
{
    max_delay = v;
    set();
}

void Timer::set()
{
    last_set = millis();
}

boolean Timer::check()
{
    unsigned long now = millis();
    if (now - last_set > max_delay) {
        last_set = now;
        return true;
    }
    return false;
}

Timer timer;

void setup()
{
   timer.set_max_delay(60000); // 1 minute
}

void loop()
{
   boolean some_condition = false;
   if (some_condition) {
       timer.set();
   }
   if (timer.check()) {
      // nothing happened for a long time
   }
   delay(500);
}
_

_some_condition_が満たされない限り、タイマーの_last_set_値は更新されません。最終的には、check()trueを返します(間隔ごとに1回、check()が_last_set_値を設定するため)

チェックがプロセッサのリセット後も存続する必要がある場合は、バッテリバックアップ(リアルタイム)クロックが必要であり、EEPROMから_last_set_を保存および取得します。

1
Anthon