ESP32重要库示例详解(二):定时器之Ticker/TickTwo库

在Arduino开发中,定时器是一个关键的工具,它允许我们在特定时间间隔执行预定的任务。本篇文章将介绍如何使用Ticker库创建和管理多个定时器,以实现多任务定时操作。

在这里插入图片描述

在ESP32使用Ticker库之前,我先介绍一下不同IDE下Ticker库的位置以及由于系统自带的Ticker与我们安装的Ticker冲突的解决办法:

Arduino IDE的Ticker文件夹位置

  1. Arduino IDE安装ESP32开发包后, ESP32目录下自带的Ticker:
C:\Users\UserName\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.14\libraries\Ticker
  1. 你通过下图方式安装Ticker后的位置,根据你项目目录的不同,位置也不同,可以通过“文件”-“首选项…”-“项目文件夹地址”来查看。
    在这里插入图片描述
    如果此时编译,系统默认用的是文件夹1所在的位置。编译文中代码时,会出错。

Ticker名称解决方法有两种:

  • 删除ESP32文件夹下的Ticker目录,编译时IDE会使用你自己安装的Ticker4.4.0库
  • 用TickTwo库,TickTwo库是专门针对这个ESP32自带的Ticker库名称冲突而开发的,其使用方法与Ticker4.4.0一样,除了导入时要导入TickTwo库,创建对象时要创建TickTwo对象。

PlatformIO IDE的Ticker文件夹位置

  1. 在VSCode里安装PlatformIO后, ESP32目录下自带的Ticker:
C:\Users\UserName\.platformio\packages\framework-arduinoespressif32\libraries\Ticker

2.众所周知,PlatformIO安装的库都在下面的位置:

项目所在目录\.pio\libdeps\esp32dev\Ticker

Ticker名称解决方法有两种:

  • 如果你在你的项目里已经安装了Ticker, PlatformIDE会优先使用项目文件夹内的Ticker库,编译不会出错,你可以放心大胆地的Ticker,不存在因为名称冲突造成编译出错的问题
  • 如果你既用PlatformIO也用Arduino IDE,那你就直接用TickTwo,代码在两个IDE复制的时候,不会改来改去。

示例代码:

#include <Arduino.h>

#include "TickTwo.h"

#define LED_BUILTIN 2

void printMessage();
void printCounter();
void printCountdown();
void blink();
void printCountUS();

bool ledState;
int counterUS;

/** 创建一个Ticker对象
 *
 * @param callback 要调用的函数名称
 * @param timer 间隔长度,以毫秒或微秒为单位
 * @param repeat 默认为0,表示无限循环,repeat > 0 表示重复次数
 * @param resolution 默认为MICROS,适用于70分钟以下的ticker,对于超过70分钟的ticker,请使用MILLIS
 *
 */ 

// 创建五个定时器对象,分别用于不同的功能
TickTwo timer1(printMessage, 0, 1);                  // 执行一次,立即执行
TickTwo timer2(printCounter, 1000, 0, MILLIS);       // 每1000毫秒触发一次printCounter函数,使用毫秒单位
TickTwo timer3(printCountdown, 1000, 5);             // 执行5次,每次间隔1秒,即1000毫钞
TickTwo timer4(blink, 500);                          // 创建一个定时器,每500毫钞触发一次blink函数
TickTwo timer5(printCountUS, 100, 0, MICROS_MICROS); // 每100*10000微秒(即100*10毫秒)触发一次printCountUS函数,使用10毫秒为单位

/** Ticker 内部时基设定
 *
 * @param MICROS 默认值,时基单位为微秒,最大可设置周期为70分钟,实际最小分辨率为16MHz CPU时钟下的4微秒。
 * @param MILLIS 将时基设置为毫秒,适用于超过70分钟的更长周期。
 * Firmin123456备注:不管是MICROS还是MILLIS,都是以毫秒为单位计数。。MICROS_MICROS是以10毫秒为单位计数。
 */


void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  delay(2000);
  timer1.start();
  timer2.start();
  timer3.start();
  timer4.start();
  timer5.start();
}

void loop()
{
  timer1.update();
  timer2.update();
  timer3.update();
  timer4.update();
  timer5.update();
if (timer4.counter() == 20)
    timer4.interval(200); // 当计数器等于20时,将定时器的间隔时间调整为200毫秒
if (timer4.counter() == 80)
    timer4.interval(1000); // 当计数器等于80时,将定时器的间隔时间调整为1000毫秒
}

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;
  }
}

这个示例比较简单,所有重点都在注释里说明了,但请注意loop()里条件判断重设interval()的部分,当计数器等于20时,将定时器的间隔时间调整为200毫秒,当计数器等于80时,将定时器的间隔时间调整为1000毫秒。
你可以通过观察板载LED D2的闪烁看到周期变化。

安装TickTwo库的话,修改一下相应内容,其功能也是一样的,修改后的代码

#include <Arduino.h>

#include "Ticker.h"

#define LED_BUILTIN 2

void printMessage();
void printCounter();
void printCountdown();
void blink();
void printCountUS();

bool ledState;
int counterUS;

/** 创建一个Ticker对象
 *
 * @param callback 要调用的函数名称
 * @param timer 间隔长度,以毫秒或微秒为单位
 * @param repeat 默认为0,表示无限循环,repeat > 0 表示重复次数
 * @param resolution 默认为MICROS,适用于70分钟以下的ticker,对于超过70分钟的ticker,请使用MILLIS
 *
 */ 

// 创建五个定时器对象,分别用于不同的功能
Ticker timer1(printMessage, 0, 1);                  // 执行一次,立即执行
Ticker timer2(printCounter, 1000, 0, MILLIS);       // 每1000毫秒触发一次printCounter函数,使用毫秒单位
Ticker timer3(printCountdown, 1000, 5);             // 执行5次,每次间隔1秒,即1000毫钞
Ticker timer4(blink, 500);                          // 创建一个定时器,每500毫钞触发一次blink函数
Ticker timer5(printCountUS, 100, 0, MICROS_MICROS); // 每100*10000微秒(即100*10毫秒)触发一次printCountUS函数,使用10000微秒为单位

/** Ticker 内部时基设定
 *
 * @param MICROS 默认值,时基单位为微秒,最大可设置周期为70分钟,实际最小分辨率为16MHz CPU时钟下的4微秒。
 * @param MILLIS 将时基设置为毫秒,适用于超过70分钟的更长周期。
 * Firmin123456备注:不管是MICROS还是MILLIS,都是以毫秒为单位计数。。MICROS_MICROS是以10毫秒为单位计数。
 */

/** Ticker 内部时基设定
 */

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  delay(2000);
  timer1.start();
  timer2.start();
  timer3.start();
  timer4.start();
  timer5.start();
}

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);
}

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;
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值