在x时间后执行功能

时间:2012-05-27 10:59:02

标签: arduino

如果循环中的其他条件及其代码在一定时间后没有执行,我可以使用什么来在循环中执行函数?可以延迟完成,还是有其他功能?

9 个答案:

答案 0 :(得分:10)

我认为没有可能实现,因为Arduino没有内部时钟。

编辑: 可以使用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
  }
}

答案 1 :(得分:5)

尝试arduino计时器中断。不需要外部库甚至是额外的硬件,因为处理器可以被认为是16 MHz的时钟。

#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
}

need more info on interrupts?

答案 2 :(得分:1)

试用Metro library,它可让您重复定时活动。如果这是理想的事情,你可以在循环中改变计时器的频率。

答案 3 :(得分:1)

millis()函数通常可以正常工作,除非你希望在重启arduino后能够存活超时。

我会实现一个Timer类来跟踪上次遇到some_condition的时间:

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,Timer的last_set值就不会更新。最终导致check()返回true(每个区间一次,check()设置last_set

如果检查需要在处理器复位后继续存在,那么您需要备用电池(实时)时钟并从EEPROM中存储和检索last_set

答案 4 :(得分:1)

这些计时器例程有很多版本,都假设如果达到或超过超时,则从millis()重置计时器变量。错误。如果你一直很忙并且已经过了时间段,那该怎么办呢......现在这个地方已经被拉长了。

所以我们想说我们想要每隔50毫秒做一些事情。让我们说我们坚持了,现在是最后一次检查后55ms ...我们检查......确定我们覆盖了计时器变量,所以我们将在50ms内得到一个匹配。但现在我们落后了5ms。我们需要弥补迟到的情况以及如果此时出现溢出会发生什么......

答案 5 :(得分:1)

我认为这就是你要找的东西

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

答案 6 :(得分:1)

在没有外部部件的情况下实现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/

答案 7 :(得分:1)

我的朋友延迟() delayMicroseconds()将为您提供全部帮助。

就其他答复而言。

mills() - 返回自Arduino开始运行当前程序以来的毫秒数。大约50天后,这个数字会溢出(回到零)。

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

类似地,

micros() - 返回自Arduino开始运行当前程序以来的微秒数。 请参阅:http://arduino.cc/en/Reference/Micros

我想你需要在这两个方面努力解决这个问题。

答案 8 :(得分:1)

您可以使用以下示例代码。每1ms重复一次步骤。

#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();
}