什么是Arduino Ticker库?
Arduino中的Ticker库可以帮助你执行固定间隔的操作。它是使用**delay()**作为间隔的一个很好的替代方案,因为它可以提供非阻塞的使用方式。此库不使用任何硬件定时器中断。相反,它使用**micros()**和**millis()**来组织你的任务。你只需要为此库提供要调用的函数名称、间隔时间以及应该重复多少次。库会完成其余的工作。
示例
要安装此库,请打开库管理器,搜索“**Ticker**”。安装Stefan Staub的库。
安装库后,转到**文件 → 示例 → Ticker → Ticker**。
示例草图以包含库开头。
#include "Ticker.h"
然后,声明我们将用作回调的5个函数。此外,还定义了几个全局变量。使用Ticker库,回调的数量没有限制。
void printMessage(); void printCounter(); void printCountdown(); void blink(); void printCountUS(); bool ledState; int counterUS;
下一部分很重要。定义了5个Ticker对象。
Ticker timer1(printMessage, 0, 1); Ticker timer2(printCounter, 1000, 0, MILLIS); Ticker timer3(printCountdown, 1000, 5); Ticker timer4(blink, 500); Ticker timer5(printCountUS, 100, 0, MICROS_MICROS);
Ticker对象构造函数的语法为:
Ticker ticker_name(fptr callback, uint32_t timer, uint16_t repeats, interval_t mode)
其中,
**callback**是要调用的函数
**timer**是毫秒或微秒的时间间隔,具体取决于模式。
**repeats**是应触发此回调的次数(0表示无限次,是默认选项)
**mode**可以有3个值:
**MILLIS** - 定时器单位为毫秒,内部分辨率为毫秒
**MICROS** - 定时器单位为毫秒,内部分辨率为微秒(默认)
**MICROS_MICROS** - 定时器单位为微秒,内部分辨率为微秒
使用默认模式(MICROS),你可以拥有长达70分钟的时间间隔。对于更长的时间间隔,请使用MILLIS。因此,
timer1回调仅触发一次,并且立即触发(间隔=0)
timer2回调每1000毫秒触发一次,间隔分辨率为毫秒。
timer3回调触发5次,每秒一次。
timer4回调每500毫秒触发一次。
timer5回调每100微秒触发一次,内部分辨率为微秒。
在setup中,你启动了之前定义的Ticker对象。
void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(9600); delay(2000); timer1.start(); timer2.start(); timer3.start(); timer4.start(); timer5.start(); }
在loop中,你不断调用**.update()**函数,该函数本质上检查Ticker并在必要时运行**callback**函数。
void loop() { timer1.update(); timer2.update(); timer3.update(); timer4.update(); timer5.update(); if (timer4.counter() == 20) timer4.interval(200); if (timer4.counter() == 80) timer4.interval(1000); }
请注意,loop中没有**delay()**,即使在定时器启动后的setup中也没有。根据官方文档,“如果你使用**delay()**,Ticker将被忽略!你不能将**delay()**命令与**TimerObject**一起使用。代替使用delay,你可以使用Ticker本身。例如,如果你需要你的循环每秒运行两次,只需创建一个间隔为500毫秒的Ticker。它将与**delay**(500)具有相同的结果,但你的代码将始终处于状态。”
本质上,Ticker函数使用**delay()**使用的底层定时器。因此,你不能将delay与Ticker对象一起使用。
**.counter()**函数返回已执行的**callback**数量。因此,我们在触发20次后更改timer4的间隔,然后在触发80次后再次更改。
稍后,给出了5个回调函数的定义,这些函数或多或少是不言自明的。
void printCounter() { Serial.print("Counter "); Serial.println(timer2.counter()); } void printCountdown() { Serial.print("Countdowm "); Serial.println(5 - timer3.counter()); } void printMessage() { Serial.println("Hello!"); } void blink() { digitalWrite(LED_BUILTIN, ledState); ledState = !ledState; } void printCountUS() { counterUS++; if (counterUS == 10000) { Serial.println("10000 * 100us"); counterUS = 0; } }
你可以使用此库以固定间隔执行任务,无论是无限次还是特定次数。