如果循环中的其他条件及其代码在一定时间后都没有执行,我可以使用什么来执行循环中的函数?可以延迟完成,还是有其他功能?
9 回答
我认为不可能实现,因为 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
}
}
尝试 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
}
我的朋友delay()和delayMicroseconds()将为您提供全部帮助。
至于其他答复。
mills() - 返回自 Arduino 板开始运行当前程序以来的毫秒数。大约 50 天后,此数字将溢出(回到零)。
参考:http ://arduino.cc/en/Reference/millis
相似地,
micros () - 返回自 Arduino 板开始运行当前程序以来的微秒数。参考:http ://arduino.cc/en/Reference/Micros
我想您需要在这两个方面进行一些工作才能解决您的问题。
我想这就是你要找的
试用Metro 库,它可以让您执行重复的定时事件。如果需要,您可以在循环中更改计时器的频率。
如果没有外部部件,将无法在 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/
您可以使用下面的示例代码。这里每 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();
}
该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 存储和检索。
这些计时器例程有许多版本,都假定如果您已达到或超过超时时间,则您从 millis() 重置计时器变量。错误的。如果你一直很忙并且已经过了时间段怎么办……现在已经很紧张了。
所以假设我们想每 50 毫秒做一次。假设我们被阻止了,现在是上次检查后的 55 毫秒......我们检查......果然我们覆盖了计时器变量,所以我们将在 50 毫秒内得到匹配。但现在我们落后了 5 毫秒。我们需要补偿迟到,如果此时出现溢出会发生什么......