实现的功能
web配网,web配秘钥。利用wifimanager 库,可以搜索想用的wifi,自己填密码
用EEPROM储存通过网页设置的秘钥,这个貌似是blinker 专属设备的功能
webOTA
同步不同方式对开关操作后,开关状态
汉字wifi名称,即,在路由器中显示的汉字名称
长时间断网重启,因为设置了多个wifi,且wifi名称也能引导程序配网
注意:ide务必使用我的附件,因为有些库被我进行了改动
安装
1.打开8266_package_3.0.1_arduino.cn
2.打开Arduino IDE菜单 > 文件 >首选项,在 附加开发板管理器网址 输入框中,填入以下网址:
https://www.arduino.cn/package_esp8266com_index.json
使用ide串口监视器方式:插入usb,然后打开ide串口监视器,如很快出现窗口,关闭重新打开
使用说明 1. 重新配网方式: 实体按钮长按4s以上,进入配网 搜索到这个wifi热点"cxpw" app按钮长按 浏览器访问8266的IP地址 进入网页选择 2. 更改路由器显示的名称 就是增加一个传值的函数,把自定义名称传给BlinkerMQTT 找到 libraries\blinker-library-dev_3.0\src\Adapters\BlinkerMQTT.h ①在 class BlinkerMQTT 外部 增加全局变量 String _hostname2 ; ②在 class BlinkerMQTT 内部 public 中增加函数 void hostname2(const String _name2); ③在void BlinkerMQTT::connectWiFi(const char* _ssid, const char* _pswd) 上部增加 void BlinkerMQTT::hostname2(const String _name2){ _hostname2 = BLINKER_F("智能_"); _hostname2 +=_name2; } ④在内部改为 String _hostname = _hostname2; 其他_hostname = 注释掉 如果不用传值函数,可只改④ 如汉字显示乱码,.h文件另存 编码必须选择ANSI格式 3.所有指令统一进入控制函数 4.程序预设多个wifi账号信息,利用wifiscan,方便调试查看及日常使用。 5.webOTA 如内存太小,如01s只有1M,编译或上传时 把flah size 设置成 no spiffs 或者fs:none OTA:502k 。此设置带来问题:程序不能用spiff 先进入ota上传一个最小的bin(只有webota功能),再进入webota,上传准备使用的bin。 进入ip地址也可以选择升级,不必记住IP地址后面加/update的方式。经常忘记 6.重启方式 APP 发送cq 访问IP地址 选择重启 二,问题 1.不确定WiFiManager.h 或blinker 调用了json库,用过一次json没成功 2.pulseIn();取按钮按下时间的函数,不能用 01s 引脚 TX=1 RX=3 GPIO0通电时接地为烧录模式
APP界面
web配网前wifi
进入web配网
选择报讯的wifi
以下主程序,记着改wifi信息 和 秘钥 - #define BLINKER_WIFI //接入方式:wifi
- #define BLINKER_ALIGENIE_OUTLET //接入天猫插座库
- #define BLINKER_PRINT Serial //串口协议库
- #include <WiFiManager.h> //wifimanager库
- #include <Blinker.h> //官方库
- #define BLINKER_WITHOUT_SSL //非SSL加密通信接入,省堆栈,不是必要的
- #include <ESP8266WebServer.h>
- #include <ESP8266HTTPUpdateServer.h>
- ESP8266WebServer httpServer(80); //webota
- ESP8266HTTPUpdateServer httpUpdater; //webota
- String devname = "DT"; //定义WIFI名称和主机名,只能非汉字,显示"智能_"+devname
- char auth[] = "0b436cf***"; //换成你的,也可配网时再填
- int led= 2; //板载led。不做为指示灯时,随可便定义
- int relay = 0; //继电器连接在8266的GPIO0上,LOW时打开
- bool zt = LOW ; //继电器连接在8266的GPIO0上,LOW时打开;
- void(*resetFunc) (void) = 0;//据说软复位 resetFunc();
- int key = 1; //本地开关,与gnd接通时动作
- BlinkerMQTT BlinkerMQTT2;
- struct storeStruct_t {
- char myVersion[4];
- char name[13];
- };
- char version2[4] = "186" ; // 保存数据用验证码
- char api_key[26] = ""; //增加网页设置页面参数,网页保存秘钥
- char mqtt_server[40]; //增加网页设置页面参数,预留传值
- char cxpw[] = "cxpw"; //搜到这个wifi重新配网,手机开热点尽量靠近
- char ssid[] = "xxxx"; //默认wifi-1,改成你的
- char pswd[] = "123123123";
- char ssid2[] = "CMCC-2dvu"; //默认wifi-2,改成你的
- char pswd2[] = "ms8888";
- //*******新建组件对象
- BlinkerButton Button1("btn-abc"); //设置app按键的键名
- BlinkerText Text1("tex-zh4"); //绑定文字组件
- BlinkerText Text2("tex-vkh");
- //*******天猫精灵
- void aligeniePowerState(const String & state)
- {
- BLINKER_LOG("天猫精灵语音操作!"); //串口打印
- show(state); //没测试,不知道 state 内容
- if (state == BLINKER_CMD_ON) {
- BlinkerAliGenie.powerState("on");
- BlinkerAliGenie.print();
- }
- else if (state == BLINKER_CMD_OFF) {
- BlinkerAliGenie.powerState("off");
- BlinkerAliGenie.print();
- }
- Text2.print("天猫");
- }
- void aligenieQuery(int32_t queryCode) //天猫设备查询的回调函数
- {
- BLINKER_LOG("AliGenie Query codes: ", queryCode);
- switch (queryCode)
- {
- case BLINKER_CMD_QUERY_ALL_NUMBER :
- BLINKER_LOG("AliGenie Query All");
- BlinkerAliGenie.powerState(relay ? "on" : "off");
- BlinkerAliGenie.print();
- break;
- case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
- BLINKER_LOG("AliGenie Query Power State");
- BlinkerAliGenie.powerState(relay ? "on" : "off");
- BlinkerAliGenie.print();
- default :
- BlinkerAliGenie.powerState(relay ? "on" : "off");
- BlinkerAliGenie.print();
- break;
- }
- }
- //APP未绑定的组件被触发,或者输入框发送内容,执行其中内容
- void dataRead(const String & data)
- {
- show(data);
- }
- //App 按键
- void button1_callback(const String & state) //app里按键有2种模式3钟不同样式用state来存储组键的值按键 : "tap"(点按); "pre"(长按); "pup"(释放)开关 : "on"(打开); "off"(关闭)
- {
- show(state);
- }
- //App定时向设备发送心跳包, 收到心跳包后执行
- void heartbeat()
- {
- show("chaxun");
- }
- //APP“所有设备”页显示开关按钮
- void switch_callback(const String & state)
- {
- show(state);
- }
- //本地开关控制2
- int jilu = 0 ;
- int startPressed = 0 ;
- void sdms() {
- if (digitalRead(key) == LOW)
- { jilu = millis() - startPressed; //计算按下的时间
- }
- else
- { startPressed = millis();
- if (jilu > 30 && jilu < 1300)
- {
- digitalWrite(relay, !digitalRead(relay));
- show("tongbu"); //同步
- Text2.print("本地开关");
- }
- else if (jilu > 4000)
- {
- show("press");
- }
- jilu = 0;
- }
- }
- void setup()
- {
- delay(3000);
- Serial.begin(115200); // 初始化串口
- delay(200);
- pinMode(relay, OUTPUT);
- pinMode(led, OUTPUT); //设为输出,闪灯
- show("off"); //初始上电关
- delay(200);
- BLINKER_DEBUG.stream(Serial); //查看设备端调试信息
- BLINKER_DEBUG.debugAll(); //查看设备端调试信息
- delay(100);
- lianwang(); //进入联网程序
- Blinker.delay(300);
- Button1.attach(button1_callback); //app按键回调
- Blinker.attachData(dataRead); //没有绑定的控件 函数注册
- Blinker.attachHeartbeat(heartbeat); //app定时向设备发送心跳包, 设备收到心跳包后会返回设备当前状态进行语音操作和app操作同步。
- BUILTIN_SWITCH.attach(switch_callback); //注册APP设备外面的图标上显示这一个开关按键
- BlinkerAliGenie.attachPowerState(aligeniePowerState); //天猫语音操作注册函数
- BlinkerAliGenie.attachQuery(aligenieQuery);//天猫设备查询的回调函数
- httpUpdater.setup(&httpServer); //OTA
- httpServer.begin(); //OTA
- httpServer.on("/", homepage);//访问主页
- // 初始化IO
- digitalWrite(led, HIGH);
- pinMode(key, INPUT_PULLUP); //设输入上拉,按钮控制
- }
- void loop() {
- Blinker.run();
- sdms();//本地开关
- cq();//无网重启
- httpServer.handleClient();//OTA
- }
- const char PAGE_INDEX[] PROGMEM = R"(
- <!DOCTYPE html ">
- <html">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>ESP8266物联网</title>
- </head>
- <body>
- <h1>ESP8266物联网</h1>
- <p>你正在浏览ESP8266提供的信息</p>
- <p>
- <a href="/update" target="_self" title="升级">升级</a><br/>
- </p>
- <p>
- <a href="/?pw=abc" target="_self" title="重新设置">重新设置</a><br/>
- </p>
- <p>
- <a href="/?cq=abc" target="_self" title="重新启动">重新启动</a><br/>
- </p>
- </body>
- </html>
- )";
- // 设置主页请求处理函数
- void homepage() {
- httpServer.send(200,"text/html",PAGE_INDEX);
- Blinker.println("用户访问了主页");
-
- if (httpServer.hasArg("pw")) {
- Serial.print("请求中pw参数的值:");
- //Serial.println(httpServer.arg("token"));
- show("press");
- }
- if (httpServer.hasArg("cq")) {
- show("cq");
- }
- else {
- Serial.println("当前请求中无法找到指定请求体内容");
- }
- }
- //使用web配置网络
- void WebConfig() {
- httpServer.stop();
- WiFiManager wifiManager;
- for (int counter = 1; counter <= 4; counter++) { //闪灯提示进入配网
- digitalWrite(led, HIGH);
- Blinker.delay(300);
- digitalWrite(led, LOW);
- Blinker.delay(300);
- }
- wifiManager.resetSettings();
-
- //设置配置页增加两个参数
- WiFiManagerParameter custom_apikey("apikey", "apikey", api_key, 32);
- WiFiManagerParameter custom_mqtt_server("server", "server", mqtt_server, 40);
- wifiManager.addParameter(&custom_apikey);
- wifiManager.addParameter(&custom_mqtt_server);
- /*************************************/
- /*** 步骤三:尝试连接网络,失败去到配置页面 **/
- Serial.println("Entered config mode...");
- // wifiManager.setConfigPortalTimeout(60); //设置连接超时时间60s
- wifiManager.setMinimumSignalQuality(40); //过滤信号质量
- char buf[]="";
- devname="智能_"+devname ;
- strcpy(buf,devname.c_str());
- wifiManager.startConfigPortal(buf, NULL); //直接进入配网管理,不会尝试保存的wifi
- // wifiManager.autoConnect(buf, NULL);
- Serial.print("ESP8266 Connected to ");
- /*************************************/
- // 读取配置页面配置好的信息
- strcpy(mqtt_server, custom_mqtt_server.getValue());
- strcpy(api_key,custom_apikey.getValue() );
- saveinf1(api_key);
- delay(100);
- //ESP.restart();
- resetFunc();
- }
- void show(const String & state) {
- if (state.endsWith("on") == 1 ) {
- digitalWrite(relay, zt);
- }
- if (state.endsWith("off") == 1 ) {
- digitalWrite(relay, !zt);
- }
- if (state.endsWith("tap") == 1 ) {
- digitalWrite(relay, zt);
- Blinker.delay(3000);
- digitalWrite(relay, !zt);
- Text2.print("电梯");
- }
- if(state == "press") {
- Text2.print("重新配网");
- WebConfig();
- return;
- }
- if(state.endsWith("cq") == 1 ) {
- Text2.print("重新启动");
- Blinker.delay(200);
- ESP.restart();
- }
- Blinker.delay(200);
- if (digitalRead(relay) == zt)
- {
- digitalWrite(led, LOW);
- BUILTIN_SWITCH.print("on");
- Button1.color("red"); //设置app按键是红色
- Button1.text("继电器打开");
- Button1.print("on");
- }
- else
- {
- digitalWrite(led, HIGH);
- BUILTIN_SWITCH.print("off");
- Button1.color("gray"); //设置app按键是灰色
- Button1.text("继电器关闭");
- Button1.print("off");
- }
- Text1.print(WiFi.localIP().toString().c_str(),WiFi.SSID().c_str()); //上传IP地址和wifi名称
- }
- void saveinf1( String api_key1) { // 保存api
- Serial.print("saved:");
- storeStruct_t saved;
-
- strcpy(saved.name,api_key1.c_str());
- strcpy(saved.myVersion,version2); //验证码赋值
- EEPROM.begin(4095);
- EEPROM.put( 1, saved );
- Blinker.delay(300);
- EEPROM.commit(); // Only needed for ESP8266 to get data written
- EEPROM.end(); // Free RAM copy of structure
- }
- void loadConfig() {
- // Loads configuration from EEPROM into RAM
- Serial.println("Loading config");
- storeStruct_t load;
- EEPROM.begin(4095);
- EEPROM.get( 1, load);
- EEPROM.end();
- if (load.myVersion[0] != version2[0] ||
- load.myVersion[1] != version2[1] ||
- load.myVersion[2] != version2[2]) //比较验证码
- {
- Serial.println("验证码没通过");
- return;
- }
- else {
- strcpy(auth, load.name);
- //给auth,重新赋值
- Serial.println(auth); }
- }
- void lianwang(){
- BlinkerMQTT2.hostname2(devname); //BlinkerMQTT文件修改后才能用
- digitalWrite(led, LOW); //常亮联网
- //配网保存的信息
- loadConfig(); //读auth的值
- Blinker.delay(300);
- int n = WiFi.scanNetworks(); //开始同步扫描,存放在变量n中
- for (int i = 0; i < n; ++i){ //开始逐个打印扫描到的wifi
- Serial.print(WiFi.SSID(i));
- if (WiFi.SSID(i)==cxpw ) //扫描到进入网页配网
- {
- Serial.println("重新配网");
- WebConfig();
- }
- if(WiFi.SSID(i)==ssid )
- {
- Blinker.begin(auth, ssid, pswd);
- return;
- }
- if(WiFi.SSID(i)==ssid2 )
- {
- Blinker.begin(auth, ssid2, pswd2);
- return;
- }
- if(WiFi.SSID(i)==WiFi.SSID().c_str() )
- {
- Blinker.begin(auth, WiFi.SSID().c_str(), WiFi.psk().c_str());
- return;
- }
- }
- Serial.println("没找到网络3s后重试!");
- delay(3000);
- lianwang();
- }
- int detect_os_time=60;
- void cq(){ //设定断网重新启动
- bool result = Blinker.connected(); //获取连接服务器的状态 0失败 1成功
- if (result == 1 || detect_os_time-millis()/60000 >60) { // 或语句是防止millis()溢出时不能进入倒计时
- detect_os_time =60+ millis()/60000;} //倒计时60分钟
- else
- { if (millis()%60000==0) { //每分钟提醒一次
- Serial.print("断网重启倒计时(分钟):");
- Serial.println(detect_os_time-millis()/60000 );
- Blinker.delay(300);
- }
- if (detect_os_time-millis()/60000 <=0 && digitalRead(relay) != zt) { //超时且开关关闭时 重启
- //ESP.restart();
- resetFunc();
- }
- }
- }
复制代码
以下是ota程序,我已经尽量减小了,但是水平有限。 - #include <ESP8266WiFi.h>
- #include <WiFiClient.h>
- #include <ESP8266WebServer.h>
- #include <ESP8266HTTPUpdateServer.h>
- ESP8266WebServer httpServer(80);
- ESP8266HTTPUpdateServer httpUpdater;
- void setup(void) {
- Serial.begin(115200);
- WiFi.mode(WIFI_STA);
- WiFi.begin("xxxx", "123123123");
- while (WiFi.status() != WL_CONNECTED) {
- Serial.print("Connecting...");
- delay(400);
- }
- httpUpdater.setup(&httpServer);
- httpServer.begin();
- httpServer.on("/", homepage);//访问主页,不用记IP地址+/update 的升级方式
- Serial.print("Open http://");
- Serial.print(WiFi.localIP());
- Serial.println("/update in your browser");
- }
- void loop(void)
- {
- httpServer.handleClient();
- }
- const char PAGE_INDEX[] PROGMEM = R"(
- <!DOCTYPE html ">
- <html">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>ESP8266物联网</title>
- </head>
- <body>
- <h1>ESP8266物联网</h1>
- <p>你正在浏览ESP8266提供的信息</p>
- <p>
- <a href="/update" target="_self" title="升级">升级</a><br/>
- </p>
- </body>
- </html>
- )";
- // 设置主页请求处理函数
- void homepage() {
- httpServer.send(200,"text/html",PAGE_INDEX);
- Serial.println("用户访问了主页");
- }
复制代码
APP界面配置 - {¨config¨{¨headerColor¨¨transparent¨¨headerStyle¨¨dark¨¨background¨{¨img¨¨assets/img/bg/f3.jpg¨¨isFull¨»}}¨dashboard¨|{¨type¨¨btn¨¨ico¨¨fad fa-siren-on¨¨mode¨Ê¨t0¨¨点我开关灯¨¨clr¨¨#389BEE¨¨t1¨¨文本2¨¨bg¨É¨cols¨Ë¨rows¨Ë¨key¨¨btn-abc¨´x´Ï´y´Ë¨speech¨|÷¨lstyle¨Ê}{ßA¨deb¨ßEÉßLÉßMÑßNÍßO¨debug¨´x´É´y´ÏßQ|÷ßRÊ}{ßA¨tex¨ßF¨文本1¨ßJßKßLÊßC¨fad fa-arrow-alt-up¨ßMÍßNËßO¨tex-zh4¨´x´É´y´ËßQ|÷ßRÌ}{ßAßUßF¨1234¨ßJßKßLÉßC´´ßMËßNÊßO¨tex-vkh¨´x´Ï´y´ÍßQ|÷ßRÉ}{ßA¨inp¨ßLÉßMÑßNËßO¨inp-27v¨´x´É´y´¤AßQ|÷}÷¨actions¨|¦¨cmd¨¦¨switch¨‡¨text¨‡¨on¨¨打开?name¨¨off¨¨关闭?name¨—÷¨triggers¨|{¨source¨ße¨source_zh¨¨开关状态¨¨state¨|ßgßi÷¨state_zh¨|¨打开¨¨关闭¨÷}÷}
复制代码
arduino及8266_package 下载链接:https://pan.baidu.com/s/1tNotiyqCPmEZ2og3a5v0FQ 提取码:1234
|