零基础入门学用物联网(ESP8266) 第一部分 基础知识篇(六)

发布时间:2026/6/3 19:04:45

零基础入门学用物联网(ESP8266) 第一部分 基础知识篇(六) 参考教程https://www.bilibili.com/video/BV1L7411c7jw/?spm_id_from333.1387.favlist.content.click十、ESP8266应用技巧1、ESP8266自动配网——WiFiManager库使用说明1在开发物联网项目时经常需要为ESP8266设置Wi-Fi在以往的章节例程里设置Wi-Fi的方法是通过修改程序中的内容来实现的但是假如这是一个面向用户的产品用户拿到产品后不可能通过修改程序设置Wi-Fi因此需要有一个Wi-Fi配置流程即使是不懂编程的用户也能为产品设置Wi-Fi。2以下是理想的Wi-Fi配置流程为了实现该流程可借助ESP8266的一个第三方库——WiFiManager库。3Wi-Fi配置示例程序①预备程序清理ESP8266储存的Wi-Fi连接信息。ESP8266的Wi-Fi设置是储存在它的闪存系统中的因此在启动ESP8266并连接Wi-Fi时它都会尝试使用闪存系统中储存的信息来进行Wi-Fi连接在开始介绍如何使用WiFiManager库来配置ESP8266的Wi-Fi设置前首先需要清除ESP8266的Wi-Fi连接信息这样才能看到WiFiManager库的工作效果而WiFiManager类的resetSettings函数即可实现清除功能运行以下示例程序可以清除ESP8266的闪存中存储的Wi-Fi连接信息#include ESP8266WiFi.h #include DNSServer.h #include ESP8266WebServer.h #include WiFiManager.h void setup() { Serial.begin(9600); WiFiManager wifiManager; // 建立WiFiManager对象 wifiManager.resetSettings(); // 清除ESP8266所存储的WiFi连接信息 Serial.println(ESP8266 WiFi Settings Cleared); } void loop() {}②示例程序创建WiFiManager类后直接调用其成员函数autoConnect就能实现ESP8266理想的Wi-Fi配置流程autoConnect函数有两种重载形式如果希望启动AP模式构建的Wi-Fi网络无密码则函数参数只有一个为Wi-Fi网络名字符串如果希望启动AP模式构建的Wi-Fi网络有密码则函数参数有两个依次为Wi-Fi网络名字符串、Wi-Fi网络密码字符串#include ESP8266WiFi.h #include DNSServer.h #include ESP8266WebServer.h #include WiFiManager.h void setup() { Serial.begin(9600); WiFiManager wifiManager; // 建立WiFiManager对象 // 自动连接Wi-Fi如果连接不上启动AP模式Wi-Fi网络名为AutoConnectAP wifiManager.autoConnect(AutoConnectAP); // 如果希望启动AP模式构建的Wi-Fi网络带有密码则可使用以下语句 // wifiManager.autoConnect(AutoConnectAP, 00114514); // WiFi连接成功后将通过串口监视器输出连接成功信息 Serial.println(); Serial.print(ESP8266 Connected to ); Serial.println(WiFi.SSID()); Serial.print(IP address:\t); Serial.println(WiFi.localIP()); } void loop() {}2、ESP8266多任务处理——Ticker库使用说明1ESP8266在运行过程中只能一条线式的依次执行任务但是在开发物联网项目时可能需要ESP8266在执行某一任务的过程中还能处理其它任务比如使用ESP8266来控制电机运行的同时还需要定时检查某一个引脚上连接按钮有没有被用户按下。为了解决以上问题可以使用Ticker库如果有《操作系统》的前置知识储备以下介绍会更容易理解。2Ticker类提供了以下几个成员函数①attach函数该函数用于创建任务并设置其运行周期需要注意一个Ticker对象只能对应创建一个任务要想创建多个任务需要先创建多个Ticker对象。第一种重载形式有两个函数参数第一个参数指定调用函数的时间间隔单位为秒第二个参数指定调用函数无参函数的函数名第二种重载形式有三个函数参数第一个参数指定调用函数的时间间隔单位为秒第二个参数指定调用函数的函数名第三个参数是传递给调用函数的参数值最多有一个且数据类型局限于char、short、int、float、void*、char*②attach_ms函数该函数用于创建任务并设置其运行周期需要注意一个Ticker对象只能对应创建一个任务要想创建多个任务需要先创建多个Ticker对象。第一种重载形式有两个函数参数第一个参数指定调用函数的时间间隔单位为毫秒第二个参数指定调用函数无参函数的函数名第二种重载形式有三个函数参数第一个参数指定调用函数的时间间隔单位为毫秒第二个参数指定调用函数的函数名第三个参数是传递给调用函数的参数值最多有一个且数据类型局限于char、short、int、float、void*、char*③detach函数该函数用于停止其对应的任务被调度运行该函数无参数。3基本操作示例①示例1[1]任务调度示意图[2]程序代码#include Ticker.h Ticker ticker;// 建立Ticker用于实现定时功能 int count; // 计数用变量 void setup() { Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); 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[1]任务调度示意图[2]程序代码#include Ticker.h Ticker ticker;// 建立Ticker用于实现定时功能 int count; // 计数用变量 void setup() { Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); 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); // 当定时调用了6次后停止定时调用函数 if (count 6) { ticker.detach(); // 使用detach来停止ticker对象定时调用函数 Serial.print(ticker.detach()); } }③示例3[1]任务调度示意图[2]程序代码#include Ticker.h Ticker ticker; int count; void setup() { Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); ticker.attach(1, sayHi, 8); } void loop() { 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); } void sayHi(int hiTimes){ count; Serial.print(Hi ); Serial.println(count); if (count hiTimes) { ticker.detach(); Serial.print(ticker.detach();); } }④示例4[1]任务调度示意图[2]程序代码#include Ticker.h Ticker ticker; Ticker buttonTicker; int count; void setup() { Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); pinMode(D3, INPUT_PULLUP); ticker.attach(1, sayHi, 60); buttonTicker.attach_ms(100, buttonCheck); } void loop() { 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); } void sayHi(int hiTimes){ count; Serial.print(Hi ); Serial.println(count); if (count hiTimes) { ticker.detach(); Serial.print(ticker.detach();); } } void buttonCheck(){ if (digitalRead(D3) LOW){ Serial.println(D3 Button Pushed...); } }3Ticker定时调用的函数必须要“短小精悍”简单来说就是不能消耗过多CPU资源执行时间不能太长否则可能引发难以预料的问题那么假如需要ESP8266定时执行的操作较为复杂就不能直接将该操作封装为Ticker定时调用的函数了而是应该“另辟蹊径”可以在Ticker类定时调用的函数中增加计数逻辑当计数值达到一定值时意味着间隔时间到达一定值主程序可以根据这个计数值调用需要定时执行的复杂操作如下所示的示例程序正是运用了这种思想。#include Ticker.h #include ESP8266WiFi.h #include ESP8266HTTPClient.h #define URL http://www.example.com const char* ssid Zevalin_Computer; const char* password 00114514; Ticker ticker; int count; void setup() { Serial.begin(9600); WiFi.mode(WIFI_STA); connectWifi(); ticker.attach(1, tickerCount); //每隔1s执行一次tickerCount函数 } void loop() { if (count 5){ //计数值达到5说明已经间隔5s httpRequest(); //执行复杂的操作 count 0; //计数值清零准备下一次计时 } } void tickerCount(){ count; //执行一次tickerCount函数计数值加1 Serial.print(count ); Serial.println(count); } void httpRequest(){ HTTPClient httpClient; httpClient.begin(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) { 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.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(1000); Serial.print(.); } Serial.println(); Serial.print(WiFi Connected!); }

相关新闻