一. Ticker 定时库
Ticker 是ESP32自带库
注意: 不建议使用Ticker回调函数来阻塞IO操作(网络、串口、文件);可以在Ticker回调函数中设置一个标记,在loop函数中检测这个标记;
对于arg,必须是 char, short, int, float, void, char 之一;
1. 定时状态获取 .active();
/**
* Ticker是否激活状态
* @return bool true表示ticker启用
*/
bool active();
2. 终止定时器 .detach()
/**
* 停止Ticker
*/
void detach();
3. once() —— xx秒后只执行一次
/**
* xx秒后只执行一次
* @param seconds 秒数
* @param callback 回调函数
*/
void once(float seconds, callback_function_t callback);
/**
* xx秒后只执行一次
* @param seconds 秒数
* @param callback 回调函数
* @param arg 回调函数的参数
*/
void once(float seconds, void (*callback)(TArg), TArg arg)
示例: 一个传参,一个不传参
#include "Arduino.h"
#include "Ticker.h"
Ticker t1;
Ticker t2;
void func1()
{
Serial.println("我是t1的回调,我没参数");
}
void func1(int a)
{
Serial.print("我是t2的回调,我的参数是:");
Serial.println(a);
}
void setup()
{
Serial.begin(115200);
if (1)
{
t1.once(10, func1);
t2.once(20, func1, 8);
//t1 t2 方法名都叫func1, 但其实是不同的方法, 这涉及到一个方法重载的概念
}
}
void loop()
{
Serial.println("我来证明我没被阻塞,也没法阻塞Ticker");
delay(2700);
}
4. once_ms() —— xx毫秒后只执行一次
用法同上
/**
* xx毫秒后只执行一次
* @param seconds 秒数
* @param callback 回调函数
*/
void once_ms(float seconds, callback_function_t callback)
/**
* xx毫秒后只执行一次
* @param seconds 秒数
* @param callback 回调函数
* @param arg 回调函数的参数
*/
void once_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg);
5. attach() —— 每隔xx秒周期性执行
和上面一样,只是周期性执行, 需要.detach()结束运行
/**
* 每隔xx秒周期性执行
* @param seconds 秒数
* @param callback 回调函数
*/
void attach(float seconds, callback_function_t callback);
/**
* 每隔xx秒周期性执行
* @param seconds 秒数
* @param callback 回调函数
* @param arg 回调函数的参数
*/
void attach(float seconds, void (*callback)(TArg), TArg arg)
6. attach_ms() —— 每隔xx毫秒周期性执行
/**
* 每隔xx毫秒周期性执行
* @param seconds 秒数
* @param callback 回调函数
*/
void attach_ms(float seconds, callback_function_t callback);
/**
* 每隔xx毫秒周期性执行
* @param seconds 秒数
* @param callback 回调函数
* @param arg 回调函数的参数
*/
void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
二. 转换为base64
1. 什么是base64
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。
标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符。
为解决此问题,可采用一种用于URL的改进Base64编码,它在末尾填充'='号,并将标准Base64中的“+”和“/”分别改成了“-”和“_”,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。
ESP32就是采用这种编码方式来将数据转换未base64的
2. ESP32转换base64码
base64 是ESP32自带库
用法非常简单. 只有一个静态方法:
static String base64::encode(const String &text)
还有 1 个重载
convert input data to base64
参数:
text – const String&
返回:
String
因为是静态方法, 所以我们访问此方法要用如下方法:
base64::encode(testBase64);
完整的举例:
#include <Arduino.h>
#include "base64.h"
String testBase64 = "this is a test to base64!";
String revBase64Reslut;
void setup()
{
Serial.begin(115200);
delay(5000);
Serial.println("begin encode the string!");
revBase64Reslut = base64::encode(testBase64);
Serial.println(revBase64Reslut);
}
void loop() {}
我们使用https://base64.us/来验证一下:
三. OTA空中升级
OTA(空中)更新是使用 WiFi 连接而不是串行端口将固件加载到 ESP 模块的过程。
- Arduino IDE:主要用于软件开发阶段,实现不接线固件烧写
- Web Browser:通过 Web 浏览器手动提供应用程序更新模块
- HTTP Server:自动使用http服务器 - 针对产品应用
在三种升级情况下,必须通过串行端口完成第一个固件上传。
OTA 进程没有强加的安全性,需要确保开发人员只能从合法/受信任的来源获得更新。更新完成后,模块将重新启动,并执行新的代码。开发人员应确保在模块上运行的应用程序以安全的方式关闭并重新启动。
1. ESP32 OTA升级原理
ESP32 连接 HTTP 服务器(可以使本地也可以是云,OTA demo使用本地服务器),发送请求 Get 升级固件;每次读取1KB固件数据,写入Flash。
ESP32 SPI Flash 内有与升级相关的(至少)四个分区:
OTA data区:决定运行哪个区的App
Factory App区:有出厂时的默认App
OTA_0区:OTA_0 App
OTA_1区:OTA_1 App
首次进行 OTA 升级时,OTA Demo 向 OTA_0 分区烧录目标App,并在烧录完成后,更新 OTA data 分区数据并重启。
系统重启时获取 OTA data 分区数据进行计算,决定此后加载 OTA_0 分区的App执行(而不是默认的 Factory App 分区内的App),从而实现升级。
同理,若某次升级后 ESP32 已经在执行 OTA_0 内的App,此时再升级时,OTA Demo 就会向 OTA_1 分区写入目标App。再次启动后,执行 OTA_1 分区实现升级。以此类推,升级的目标App始终在 OTA_0、OTA_1 两个分区之间交互烧录,不会影响到出厂时的 Factory App 固件,如下图状态。
2. OTA升级的安全性
模块必须以无线方式联网获取新的固件, 这使得模块被强行入侵并加载了其他代码。 为了减少被黑客入侵的可能性,请考虑使用密码保护您的上传,选择某些OTA端口,也可以给bin文件加密等。
3. ESP32 OTA升级流程和说明(服务器是本地PC)
升级流程
- 电脑连上路由器(AP)
- 电脑运行HTTP服务器(本地)
- 下载OTA Demo到ESP32开发板
- ESP32连上路由器(AP)后就会访问HTTP下载新的APP到OTA区
升级逻辑
这里要补一个 局域网OTA升级的程序
4. ESP32 OTA升级(真正网络环境,真正云服务器)
这里要补充一个真正的OTA升级程序
4. ESP32无线代码上传(ESP32搭建服务器进行OTA升级)
流程:
- ESP32通过STA模式连接至WIFI
- ESP32建立局域网WEB服务器, 提供WEB更新界面, 需要使用库 ESP32HTTPUpdateServer
- 用IDE编译好 .bin文件
- 通过mDNS功能在浏览器中访问ESP32的服务器页面 ,服务器默认地址: http://esp32.local
- 通过web界面将本地编译好的程序使用HTTP的POST方法上传到ESP32中
- 上传完成后, ESP32将固件写入flash
这里要补充一个esp32作为局域网服务器的 OTA程序
四. SSD1306显示二维码
这里我们要用到一个库 : ESP8266 QRcode
这个库依赖于库: ESP8266_SSD1306
这个SSD1306驱动库非常好用,可以了解一下
#include <Arduino.h>
#include "SSD1306.h"
#include "qrcode.h"
SSD1306 display(0x3c, 21, 22);
QRcode qrcode(&display);
void setup()
{
Serial.begin(115200);
delay(5000);
Serial.println("");
Serial.println("Starting...");
display.init();
display.clear();
display.display();
qrcode.init();
// create qrcode
qrcode.create("helloworld!.");
}
void loop()
{
}