如果循环中的其他条件及其代码在一定时间后没有执行,我可以使用什么来在循环中执行函数?可以延迟完成,还是有其他功能?
答案 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
}
答案 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)
我认为这就是你要找的东西
答案 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();
}