PlatformIO编译通过的库版本
- Blynk:0.6.1
- ArduinoJson:5.13.4
- WifiManager:0.14
- ESP8266:2.0.4、2.1.1、2.2.0
ArduinoIDE编译通过的库版本
- Blynk:0.6.1
- ArduinoJson:5.13.5
- WifiManager:0.14.0
- ESP8266:2.5.1
文中实测的开发板
- WeMos D1 mini
- NodeMCU V2/V3
实现功能
- 可选SSID和输入TOKEN
- 支持OTA
- 不需要每次做一个设备就在代码里输入一次key
需要的材料
- ESP8266
- 按钮开关
APP端先要设置的插件
- V0-文本框插件
- V1-文本框插件
- V2-文本框插件
- V3-虚拟LED插件
附注
- 操作流程
- 重置(刚上传完代码的设备最好先重置一遍):按住按钮 > 按一下RST(第一次操作最好留意串口信息我都写了的) > 设备会重启 > 出现设备热点
- 配置:进入设备WIFI热点 > 输入SSID/密码/KEY > 点击SAVE > 等待连接成功(留意串口是否已经连接到BLYNK)
示例代码(点击代码框内左上角三个点显示全屏模式)
#define BLYNK_PRINT Serial //必须放到第一行 | |
#define BLYNK_DEBUG | |
#include <Arduino.h> //在PlatformIO需要 | |
#include <FS.h> //如果不正常就放到第二位 | |
#include <BlynkSimpleEsp8266.h> | |
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino | |
#include <ESP8266mDNS.h> | |
#include <ESP8266WebServer.h> | |
#include <DNSServer.h> | |
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager | |
#include <WiFiUdp.h> | |
#include <ArduinoOTA.h> | |
#include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson | |
const int ResetButton = D1; //用于重置的按钮引脚,因应高低电平自行修好下面的代码 | |
const int LEDButton = D2; //用于点亮虚拟LED的按钮引脚,因应高低电平自行修好下面的代码 | |
WidgetLED led3(V3); //虚拟LED插件 | |
int ResetButtonState = digitalRead(ResetButton); | |
//这里声明"参数"的预设值, 如果和值不同,则会将他们覆盖,这里可以预先把KEY填好,每次重置后都会预先输入KEY,按需要改 | |
char blynk_token[34] = ""; | |
//用于保存数据的标志 | |
bool shouldSaveConfig = false; | |
boolean LEDbtnState = false; | |
BlynkTimer timer; | |
void buttonLedWidget() | |
{ | |
// 读取按钮引脚 | |
boolean isPressed = (digitalRead(LEDButton) == HIGH); | |
// 如果值有变化 | |
if (isPressed != LEDbtnState) { | |
if (isPressed) { | |
led3.on(); | |
} else { | |
led3.off(); | |
} | |
LEDbtnState = isPressed; | |
} | |
} | |
//回调通知我们需要保存配置 | |
void saveConfigCallback () | |
{ | |
Serial.println("Should save config"); | |
shouldSaveConfig = true; | |
} | |
void setup() { | |
Serial.begin(115200); | |
pinMode(ResetButton,INPUT); | |
pinMode(LEDButton,INPUT); | |
//读取FS json的配置 | |
Serial.println("mounting FS..."); | |
if (SPIFFS.begin()) { | |
Serial.println("mounted file system"); | |
if (SPIFFS.exists("/config.json")) { | |
//文件存在,读取和加载 | |
Serial.println("reading config file"); | |
File configFile = SPIFFS.open("/config.json", "r"); | |
if (configFile) { | |
Serial.println("opened config file"); | |
size_t size = configFile.size(); | |
// 分配缓冲区以存储文件的内容。 | |
std::unique_ptr<char[]> buf(new char[size]); | |
configFile.readBytes(buf.get(), size); | |
DynamicJsonBuffer jsonBuffer; | |
JsonObject& json = jsonBuffer.parseObject(buf.get()); | |
json.printTo(Serial); | |
if (json.success()) { | |
Serial.println("\nparsed json"); | |
strcpy(blynk_token, json["blynk_token"]); | |
} else { | |
Serial.println("failed to load json config"); | |
} | |
configFile.close(); | |
} | |
} | |
} else { | |
Serial.println("failed to mount FS"); | |
} | |
// 要配置的额外参数(可以是全局的,也可以只是在设置中) | |
// 连接后,parameter.getValue()将获得配置的值//After connecting, parameter.getValue() will get you the configured value | |
// id/name placeholder/prompt 的默认长度 | |
WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 32); | |
//WiFiManager | |
//本地初始化。一旦业务完成,就没有必要保留它 | |
WiFiManager wifiManager; | |
//设置配置保存通知回调 | |
wifiManager.setSaveConfigCallback(saveConfigCallback); | |
//在这里添加所有参数 | |
wifiManager.addParameter(&custom_blynk_token); | |
//设置重置按钮的功能 | |
if (ResetButtonState == HIGH) | |
{ | |
Serial.println("Getting Reset ESP Wifi-Setting......."); | |
delay(1000); | |
wifiManager.resetSettings(); | |
delay(5000); | |
Serial.println("Formatting FS......"); | |
delay(1000); | |
SPIFFS.format(); | |
delay(5000); | |
Serial.println("Done Reboot In 5 seconds"); | |
delay(5000); | |
ESP.restart(); | |
} | |
//获取ssid并传递并尝试连接 | |
//如果它没有连接,它将启动具有指定名称的访问点,"AutoConnectAP",并进入等待配置的阻塞循环 | |
//若写成wifiManager.autoConnect("abc", "12345678"),则设备的AP热点名称为"abc",密码为"12345678",留空则热点名字为ESP_#后四位MAC,无密码.热点名可以输入中文,视乎手机而定,有的手机会显示乱码 | |
if (!wifiManager.autoConnect("AutoConnectAP", "")) { | |
Serial.println("failed to connect and hit timeout"); | |
delay(3000); | |
//重置并重试,或者让它深入睡眠 | |
ESP.reset(); | |
delay(5000); | |
} | |
//如果已经连接 | |
Serial.println("connected...yeey :)"); | |
//读取更新的参数 | |
strcpy(blynk_token, custom_blynk_token.getValue()); | |
//将自定义参数保存到FS | |
if (shouldSaveConfig) { | |
Serial.println("saving config"); | |
DynamicJsonBuffer jsonBuffer; | |
JsonObject& json = jsonBuffer.createObject(); | |
json["blynk_token"] = blynk_token; | |
File configFile = SPIFFS.open("/config.json", "w"); | |
if (!configFile) { | |
Serial.println("failed to open config file for writing"); | |
} | |
json.printTo(Serial); | |
json.printTo(configFile); | |
configFile.close(); | |
//end save | |
} | |
Serial.println("local ip"); | |
Serial.println(WiFi.localIP()); | |
//OTA部分 | |
// 默认主机名为:esp8266-[ChipID]可以改中文 | |
ArduinoOTA.setHostname(""); | |
ArduinoOTA.onStart([]() { | |
String type; | |
if (ArduinoOTA.getCommand() == U_FLASH) { | |
type = "sketch"; | |
} else { // U_SPIFFS | |
type = "filesystem"; | |
} | |
//注意:如果更新SPIFFS,这将是使用SPIFFS.end()卸载SPIFFS的地方 | |
Serial.println("Start updating " + type); | |
}); | |
ArduinoOTA.onEnd([]() { | |
Serial.println("\nEnd"); | |
}); | |
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { | |
Serial.printf("Progress: %u%%\r", (progress / (total / 100))); | |
}); | |
ArduinoOTA.onError([](ota_error_t error) { | |
Serial.printf("Error[%u]: ", error); | |
if (error == OTA_AUTH_ERROR) { | |
Serial.println("Auth Failed"); | |
} else if (error == OTA_BEGIN_ERROR) { | |
Serial.println("Begin Failed"); | |
} else if (error == OTA_CONNECT_ERROR) { | |
Serial.println("Connect Failed"); | |
} else if (error == OTA_RECEIVE_ERROR) { | |
Serial.println("Receive Failed"); | |
} else if (error == OTA_END_ERROR) { | |
Serial.println("End Failed"); | |
} | |
}); | |
ArduinoOTA.begin(); | |
Serial.println("Ready"); | |
Serial.print("IP address: "); | |
Serial.println(WiFi.localIP()); | |
Blynk.config(blynk_token,"yourdomainname",8080); | |
timer.setInterval(500L, buttonLedWidget); | |
} | |
void loop() { | |
ArduinoOTA.handle(); | |
Blynk.run(); | |
timer.run(); | |
//用于显示网络信息的模块插件,不需要可省略 | |
Blynk.virtualWrite(V0,WiFi.localIP().toString()); | |
Blynk.virtualWrite(V1,WiFi.macAddress()); | |
Blynk.virtualWrite(V2,"RSSI:",WiFi.RSSI()," ","SSID: ",WiFi.SSID()); | |
} |
C++
正文完
发表至: 技术
2020-02-09