视频链接:https://www.bilibili.com/video/BV1L7411c7jw?p=22&spm_id_from=333.851.header_right.history_list.click&vd_source=b91967c499b23106586d7aa35af46413
资料链接:http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-tips/ticker/
ESP8266 在运行过程中,只能依次执行一条线。然而,在开发物联网项目时,我们可能需要 ESP8266 其他任务也可以在执行任务的过程中处理。例如,我们使用它 ESP8266 在控制电机运行的同时,还需要定期检查用户是否按下某个引脚上的连接按钮。
我们可以使用它来解决上述问题 Ticker 库来解决这个问题。
ESP8266 多任务处理 – Ticker 库使用说明
1、Ticker 库基本操作
程序功能:开发板通过 PWM 控制 LED 当灯具产生呼吸灯效果时,通过串口发送信息。
/********************************************************************** 项目名称/Project : 零基础入门学用物联网 程序名称/Program name : a_basic_tinker 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com) 作者/Author : CYNO朔 日期/Date(YYYYMMDD) : 20200703 程序目的/Purpose : 该程序旨在演示如何使用它Ticker库定期执行操作。 如需了解本程序的详细说明,请参考以下函数: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-tips/ticker/ ----------------------------------------------------------------------- 其它说明 / Other Description: 该程序为太极创客团队制作的免费视频教程《零基础入门学习物联网》 》中一部分。教程系统 向您讲述ESP8266物联网应用相关软硬件知识。以下是教程目录页: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/ ***********************************************************************/ #include <Ticker.h> Ticker ticker;// 建立Ticker用于实现定时功能 int count; // 计数用变量 void setup() {
Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); // 每隔一秒调用一次sayHi函数一次,attach函数的第一个参数 // 是控制时间间隔的变量。参数为秒。第二个参数是 // 函数名称定期执行。 ticker.attach(1, sayHi); } void loop() {
// 用LED演示呼吸灯效果Tinker在对象控制下,ESP8266可以定时 // 执行其它任务 for (int fadeValue = 0 ; fadeValue <= 1023; fadeValue = 5) {
analogWrite(LED_BUILTIN, fadeValue); delay(10); } for (int fadeValue = 1023 ; fadeValue >= 0; fadeValue -= 5) {
analogWrite(LED_BUILTIN, fadeValue);
delay(10);
}
delay(3000);
}
// 在Tinker对象控制下,此函数将会定时执行。
void sayHi(){
count++;
Serial.print("Hi ");
Serial.println(count);
}
程序说明:
2、停止定时执行函数
假设,我们只想让 sayHi 这个函数执行有限的次数,又应该如何处理呢?
// 在Tinker对象控制下,此函数将会定时执行。
void sayHi(){
count++;
Serial.print("Hi ");
Serial.println(count);
if(count >= 10){
ticker.detach();// 当定时调用了10次后,停止定时调用函数
Serial.print("ticker.detach()");
}
}
运行结果如下,
3、向定时调用函数传递参数
我们可以向 Ticker 库定时调用的函数来传递参数。不过要注意的是,传递参数的数量只能是一个。
如下面示例程序所示,语句 ticker.attach(1, sayHi, 8) 有 3 个参数。其中第三个参数就是向定时调用的sayHi函数所传递的参数。
/********************************************************************** 项目名称/Project : 零基础入门学用物联网 程序名称/Program name : a_basic_tinker 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com) 作者/Author : CYNO朔 日期/Date(YYYYMMDD) : 20200703 程序目的/Purpose : 本程序旨在演示如何使用Ticker库来定时执行操作。 如需了解本程序的详细说明,请参考以下函数: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-tips/ticker/ ----------------------------------------------------------------------- 其它说明 / Other Description: 本程序为太极创客团队制作的免费视频教程《零基础入门学用物联网 》中一部分。该教程系统的 向您讲述ESP8266的物联网应用相关的软件和硬件知识。以下是该教程目录页: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/ ***********************************************************************/
#include <Ticker.h>
Ticker ticker;// 建立Ticker用于实现定时功能
int count; // 计数用变量
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
analogWriteRange(1023);
// 每隔一秒钟调用sayHi函数一次,attach函数的第一个参数
// 是控制定时间隔的变量。该参数的单位为秒。第二个参数是
// 定时执行的函数名称。
ticker.attach(1, sayHi, 10);
}
void loop() {
// 用LED呼吸灯效果来演示在Tinker对象控制下,ESP8266可以定时
// 执行其它任务
for (int fadeValue = 0 ; fadeValue <= 1023; fadeValue += 5) {
analogWrite(LED_BUILTIN, fadeValue);
delay(10);
}
for (int fadeValue = 1023 ; fadeValue >= 0; fadeValue -= 5) {
analogWrite(LED_BUILTIN, fadeValue);
delay(10);
}
delay(3000);
}
// 在Tinker对象控制下,此函数将会定时执行。
void sayHi(int hiTimes){
count++;
Serial.print("Hi ");
Serial.println(count);
if(count >= hiTimes){
ticker.detach();// 当定时调用了10次后,停止定时调用函数
Serial.print("ticker.detach()");
}
}
运行结果如下,
示例4. 利用多个Ticker对象让ESP8266处理多任务
我们可以建立多个 Ticker 对象,让多个 Ticker 对象来实现 ESP8266 的多任务处理。
如下实例程序所示,我们通过语句 Ticker buttonTicker;来建立第二个 Ticker 对象。
然后再使用 buttonTicker.attach_ms(100, buttonCheck) 来实现第二个 Ticker 对象的任务处理。
这里我们使用了 attach_ms 函数,该函数与 attach 函数功能相似,唯一区别是 attach 函数的时间单位是秒,而 attach_ms 的时间单位是毫秒。也就是说,这条语句将会让 ESP8266 每隔 100 毫秒执行一次 buttonCheck 函数。
/********************************************************************** 项目名称/Project : 零基础入门学用物联网 程序名称/Program name : a_basic_tinker 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com) 作者/Author : CYNO朔 日期/Date(YYYYMMDD) : 20200703 程序目的/Purpose : 本程序旨在演示如何使用Ticker库来定时执行操作。 如需了解本程序的详细说明,请参考以下函数: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-tips/ticker/ ----------------------------------------------------------------------- 其它说明 / Other Description: 本程序为太极创客团队制作的免费视频教程《零基础入门学用物联网 》中一部分。该教程系统的 向您讲述ESP8266的物联网应用相关的软件和硬件知识。以下是该教程目录页: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/ ***********************************************************************/
#include <Ticker.h>
Ticker ticker;// 建立Ticker用于实现定时功能
Ticker buttonTicker;
int count; // 计数用变量
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
analogWriteRange(1023);
pinMode(D3, INPUT_PULLUP);
// 每隔一秒钟调用sayHi函数一次,attach函数的第一个参数
// 是控制定时间隔的变量。该参数的单位为秒。第二个参数是
// 定时执行的函数名称。
ticker.attach(1, sayHi, 60);
buttonTicker.attach_ms(100, buttonCheck);
}
void loop() {
// 用LED呼吸灯效果来演示在Tinker对象控制下,ESP8266可以定时
// 执行其它任务
for (int fadeValue = 0 ; fadeValue <= 1023; fadeValue += 5) {
analogWrite(LED_BUILTIN, fadeValue);
delay(10);
}
for (int fadeValue = 1023 ; fadeValue >= 0; fadeValue -= 5) {
analogWrite(LED_BUILTIN, fadeValue);
delay(10);
}
delay(3000);
}
// 在Tinker对象控制下,此函数将会定时执行。
void sayHi(int hiTimes){
count++;
Serial.print("Hi ");
Serial.println(count);
if(count >= hiTimes){
ticker.detach();// 当定时调用了10次后,停止定时调用函数
Serial.print("ticker.detach()");
}
}
void buttonCheck(){
if (digitalRead(D3) == LOW){
Serial.println("D3 Button Pushed...");
}
}
示例5. 使用”计数器”来控制 ESP8266 定时执行较复杂的函数
/********************************************************************** 项目名称/Project : 零基础入门学用物联网 程序名称/Program name : e_timer_http 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com) 作者/Author : CYNO朔 日期/Date(YYYYMMDD) : 20200703 程序目的/Purpose : 本程序旨在演示如何使用计数器来控制ESP8266定时执行较复杂的函数。Ticker定时调用的函数必须要“短小精悍”。 而不能是复杂且占用时间较长的函数。对于较为复杂的函数,我们可以使用计数器的方法来实现。 本程序将会定时让ESP8266向example网络服务器发送请求,并且将服务器响应信息显示在屏幕中。 如需了解本程序的详细说明,请参考以下函数: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-tips/tinker/ ----------------------------------------------------------------------- 其它说明 / Other Description: 本程序为太极创客团队制作的免费视频教程《零基础入门学用物联网 》中一部分。该教程系统的 向您讲述ESP8266的物联网应用相关的软件和硬件知识。以下是该教程目录页: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/ ***********************************************************************/
#include <Ticker.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#define URL "http://www.example.com"
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "FAST_153C80";
const char* password = "123456798";
Ticker ticker;
int count;
void setup() {
Serial.begin(9600);
//设置ESP8266工作模式为无线终端模式
WiFi.mode(WIFI_STA);
//连接WiFi
connectWifi();
ticker.attach(1, tickerCount);
}
void loop() {
if (count >= 5){
httpRequest();
count = 0;
}
}
void tickerCount(){
count++;
Serial.print("count = ");
Serial.println(count);
}
// 发送HTTP请求并且将服务器响应通过串口输出
void httpRequest(){
WiFiClient client;
HTTPClient httpClient;
httpClient.begin(client, URL);
Serial.print("URL: "); Serial.println(URL);
int httpCode = httpClient.GET();
Serial.print("Send GET request to URL: ");
Serial.println(URL);
if (httpCode == HTTP_CODE_OK) {
// 使用getString函数获取服务器响应体内容
String responsePayload = httpClient.getString();
Serial.println("Server Response Payload: ");
Serial.println(responsePayload);
} else {
Serial.println("Server Respose Code:");
Serial.println(httpCode);
}
httpClient.end();
}
void connectWifi(){
//开始连接wifi
WiFi.begin(ssid, password);
//等待WiFi连接,连接成功打印IP
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.print("WiFi Connected!");
}
这个程序运行有问题,总是会导致异常而自动重启。 报 Exception (9) ,(查相关手册说导致的原因有两个,一个是野指针,一个是读/写 Cache 地址不对齐)。 查了半天也没有查出个所以然。
这个程序与视频中所使用的库的版本不一样,我这里使用的版本是3.0.2, 视频中所使用的是 2.6.3 版本, 3.0.0版本是一个分水岭。因为多了这句代码
HTTPClient httpClient;
WiFiClient client;
httpClient.begin(client, URL);
所以要想让程序正常运行,其中一个的解决方法就是重新安装 2.6.3 版本的库,然后不加上 WiFiClient client; 这个对象。