才学arduino 时,学习过在arduino 下使用定时期,最后的感觉是好像能用又好像不能用,哪里出现了问题没有搞明白,也没有深入研究过。最近重新折腾了一下总结经验于此:
#include <Ticker.h>
Ticker myTicker;
void setup() {
Serial.begin(115200);
myTicker.attach(3,testT,23);
}
void testT(int t){
Serial.println("aaa");
ESP.wdtFeed();
}
void loop() {
Serial.println("dddaaaaaaaa");
delay(1);
}
上面是一个最简单的使用定时器的代码,可以工作正常,具体无非是
引入库文件
#include <Ticker.h>
创建对象:
Ticker myTicker;
设计定时函数
void testT(int t){
Serial.println("aaa");
ESP.wdtFeed();
}
和附加定时:
myTicker.attach(3,testT,23);
上面这个attach后面的那个3代表是3秒,如果要设置更短的定时可以使用attach_ms
上面的代码很简单,定时3秒输出一个aaa,在loop中循环再输出一个字符串。
很多告诉你如何在esp或者arduino中使用定时器的内容都到此截至了,因为也确实可以正常运行;然而实例演示和实际使用是相差很大的。
我们使用定时器的目的其实很简单就是不希望上面所示的testT这个里面运行的内容尽量不影响loop中其他代码的循环运行,否则还不如直接放到loop中。
如果testT这个函数执行的时长是10秒,而attach定时只有3秒呢?
这就会导致一个结果,loop中内容无法运行,系统一直在运行testT,这就是本文最初所说的有的时候运行有的时候不运行的原因了。
attach设置的定时时间必须大于函数的执行时间。
最初对于这个定时器以为它是异步在调度,函数如果里面有delay的时候loop会运行,其实并不是这样。它是堵塞单线程方式运行的,你可以认为loop和testT是两个独立的函数,testT优先级更高,如果它被ticker调用的情况下会持续运行,除非有空闲时间。
换个思路,假设loop中两个函数:
loop{
t();
p();
}
如果都在loop中t和p的运行次数是一样的;如果给t设置1秒一次,那么就是t每秒一次,p就运行无数次;不会因为t的运行堵塞p的运行。
至于t设置的具体时间要具体t里面的内容来决定。
当然在t运行的时候,p是不会运行的,最简单的例子是t是花费3秒完成一个led屏幕显示,在这3秒中,从传感器读取数据的p是不会有任何输入的。
其实这点是非常不爽的:因为我希望单片机在处理某个任务的时候能够收到指令,在loop这种情况下是不可能的。
突然一下想到应该用中断来收集指令,但是另外一个问题来了,ticker在执行的时候,如果产生了硬件中断,这个中断是否有更高的优先级插入到ticker中运行,等结束后在恢复ticker的运行。
硬件中断在loop中是具有更高的优先级的。
注意:Non OS下和RTOS下是否有不同不知道,本文所述的内容是在Non OS下。