12

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

4

9 回答 9

13

我认为不可能实现,因为 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
  }
}
于 2012-05-27T11:05:21.430 回答
6

尝试 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
}

需要更多关于中断的信息?

于 2013-08-16T13:14:24.143 回答
1

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

至于其他答复。

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

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

相似地,

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

我想您需要在这两个方面进行一些工作才能解决您的问题。

于 2013-04-18T07:06:18.103 回答
1

我想这就是你要找的

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

于 2013-01-07T15:28:30.543 回答
1

试用Metro 库,它可以让您执行重复的定时事件。如果需要,您可以在循环中更改计时器的频率。

于 2012-05-29T17:43:30.537 回答
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/

于 2013-02-04T18:09:19.283 回答
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();
}
于 2014-01-08T12:42:48.067 回答
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不满足last_set,Timer 的值就不会更新。最终导致check()返回true(每个间隔一次,check()设置last_set值)

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

于 2012-05-31T18:51:08.910 回答
1

这些计时器例程有许多版本,都假定如果您已达到或超过超时时间,则您从 millis() 重置计时器变量。错误的。如果你一直很忙并且已经过了时间段怎么办……现在已经很紧张了。

所以假设我们想每 50 毫秒做一次。假设我们被阻止了,现在是上次检查后的 55 毫秒......我们检查......果然我们覆盖了计时器变量,所以我们将在 50 毫秒内得到匹配。但现在我们落后了 5 毫秒。我们需要补偿迟到,如果此时出现溢出会发生什么......

于 2012-06-25T13:02:23.897 回答