使用Arduino开发ESP32(07):系统时间和定时任务调度器Ticker

本文介绍ESP32平台下系统时间操作及定时任务调度器Ticker的使用方法,包括系统时间获取、延时操作、定时任务设置等,通过实例演示如何精确控制任务执行时间。

实战派 ESP32-S3,双模无线开发板

ESP32-S3 原生支持 ESP-IDF,WiFi + 蓝牙一次搞定

目的

开发中经常会用到时间相关操作,主要就是用到系统时间、延时操作、定时任务调度等,本文介绍Arduino core for the ESP32中相关的一些功能。

系统时间及应用

系统时间相关方法如下:

unsigned long micros(); //返回微秒为单位系统时间
unsigned long millis(); //返回毫秒为单位系统时间
void delay(uint32_t); //设置毫秒级延时
void delayMicroseconds(uint32_t us); //设置微秒级延时

在这里插入图片描述
上图中微秒时间差稍大于1000us,因为读取时间及串口操作本身有一定耗时;

系统时间还可以像下面那样使用:

//该程序用于每一秒或以上时间打印输出一次时间

unsigned long previousMillis = 0; //毫秒时间记录
const long interval = 1000;       //时间间隔

void setup()
{
  Serial.begin(115200);
  Serial.println();
}

void loop()
{
  unsigned long currentMillis = millis();         //读取当前时间
  if (currentMillis - previousMillis >= interval) //如果和前次时间大于等于时间间隔
  {
    previousMillis = currentMillis; //更新时间记录
    Serial.println(millis());       //打印当前时间
  }
}

在这里插入图片描述

定时任务调度器Ticker

Ticker可以让你设置以固定时间间隔反复执行某个任务,相比上面的方法,使用Ticker时间上会更加精确,并且代码编写维护也更加方便;

使用步骤

  • 引入头文件#include <Ticker.h>
  • 建立Ticker对象;
  • 编写回调函数(同之前文章中的事件方法一样,这个回调函数中不推荐进行耗时操作);
  • 设置调度时间间隔并启用调度任务;

常用方法

  • void attach(float seconds, callback_t callback)
    void attach(float seconds, void (*callback)(TArg), TArg arg)
    设置调度任务,该任务会反复执行,输入参数分别为时间间隔(秒)、回调函数、不大于四字节的数据;
  • void attach_ms(uint32_t milliseconds, callback_t callback)
    void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
    设置调度任务,该任务会反复执行,输入参数分别为时间间隔(毫秒)、回调函数、不大于四字节的数据;
  • void once(float seconds, callback_t callback)
    void once(float seconds, void (*callback)(TArg), TArg arg)
    设置调度任务,该任务只执行一次,输入参数分别为时间间隔(秒)、回调函数、不大于四字节的数据;
  • void once_ms(uint32_t milliseconds, callback_t callback)
    void once_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
    设置调度任务,该任务只执行一次,输入参数分别为时间间隔(毫秒)、回调函数、不大于四字节的数据;
  • void detach()
    停止任务调度;

使用事例

事例一

#include <Ticker.h> //调用Ticker.h库

Ticker ticker1; //声明Ticker对象
Ticker ticker2; //声明Ticker对象

void callback1() //回调函数
{
  Serial.print(millis());
  Serial.println(": callback1 triggered!");
}

void callback2() //回调函数
{
  Serial.print(millis());
  Serial.println(": callback2 triggered!");
}

void setup()
{
  Serial.begin(115200);
  Serial.println();

  ticker1.attach(0.5, callback1);   //每0.5秒调用callback1
  ticker2.once_ms(2000, callback2); //2000毫秒后调用一次callback2
}

void loop()
{
}

在这里插入图片描述

事例二

#include <Ticker.h> //调用Ticker.h库

Ticker ticker1; //声明Ticker对象
Ticker ticker2; //声明Ticker对象

void callback2(int data) //回调函数
{
  Serial.print(millis());
  Serial.print(": callback2 data is ");
  Serial.println(data);
}

void setup()
{
  Serial.begin(115200);
  Serial.println();

  ticker1.attach_ms(500, [](){Serial.printf("%d: callback1 triggered!\r\n", millis());}); //匿名函数方式

  ticker2.once(2, callback2, 1234567890); //2秒后调用一次callback2

  // ticker2.once(4, callback2, std::bind(callback2, millis())); //使用绑定方式...用不了-.-!
}

void loop()
{
}

在这里插入图片描述

事例三

#include <Ticker.h> //调用Ticker.h库

Ticker ticker1; //声明Ticker对象
Ticker ticker2; //声明Ticker对象
Ticker ticker3; //声明Ticker对象

void callback1() //回调函数
{
  Serial.print(millis());
  Serial.println(": callback1 triggered!");
}

void callback2() //回调函数
{
  Serial.print(millis());
  Serial.println(": callback2 triggered!");
  ticker1.detach(); //停止ticker1
}

void callback3() //回调函数
{
  Serial.print(millis());
  Serial.println(": callback3 triggered!");
  ticker1.attach(0.5, callback1); //重新设置ticker1
}

void setup()
{
  Serial.begin(115200);
  Serial.println();

  ticker1.attach(0.5, callback1);
  ticker2.once(2, callback2);
  ticker3.once(4, callback3);
}

void loop()
{
}

在这里插入图片描述

总结

上面两块主要用来为程序设计提供便利性,在多任务应用开发中协调各项任务运行,更多内容可以参考如下:
https://github.com/espressif/arduino-esp32/tree/master/libraries/Ticker

实战派 ESP32-S3,双模无线开发板

ESP32-S3 原生支持 ESP-IDF,WiFi + 蓝牙一次搞定

评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Naisu Xu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值