查看: 168|回复: 2

[分享] esp01s web配网、秘钥、OTA,eeprom,汉字wifi名称,断网重启

[复制链接]

该用户从未签到

发表于 2021-11-25 16:20 | 显示全部楼层 |阅读模式
实现的功能
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界面

APP界面

web配网前wifi

web配网前wifi

进入web配网

进入web配网

选择报讯的wifi

选择报讯的wifi

以下主程序,记着改wifi信息 和 秘钥
  1. #define BLINKER_WIFI                    //接入方式:wifi
  2. #define BLINKER_ALIGENIE_OUTLET         //接入天猫插座库
  3. #define BLINKER_PRINT Serial            //串口协议库
  4. #include <WiFiManager.h>                //wifimanager库
  5. #include <Blinker.h>                    //官方库
  6. #define BLINKER_WITHOUT_SSL //非SSL加密通信接入,省堆栈,不是必要的

  7. #include <ESP8266WebServer.h>
  8. #include <ESP8266HTTPUpdateServer.h>
  9. ESP8266WebServer httpServer(80);     //webota
  10. ESP8266HTTPUpdateServer httpUpdater;  //webota

  11. String devname = "DT";   //定义WIFI名称和主机名,只能非汉字,显示"智能_"+devname
  12. char auth[] = "0b436cf***";  //换成你的,也可配网时再填
  13. int led= 2;        //板载led。不做为指示灯时,随可便定义
  14. int relay = 0; //继电器连接在8266的GPIO0上,LOW时打开  
  15. bool zt = LOW ; //继电器连接在8266的GPIO0上,LOW时打开;

  16. void(*resetFunc) (void) = 0;//据说软复位  resetFunc();
  17. int key = 1; //本地开关,与gnd接通时动作
  18. BlinkerMQTT  BlinkerMQTT2;

  19. struct storeStruct_t {
  20.   char myVersion[4];
  21.   char name[13];
  22. };
  23. char  version2[4] = "186"  ; // 保存数据用验证码

  24. char api_key[26] = ""; //增加网页设置页面参数,网页保存秘钥
  25. char mqtt_server[40]; //增加网页设置页面参数,预留传值

  26. char cxpw[] = "cxpw";  //搜到这个wifi重新配网,手机开热点尽量靠近
  27. char ssid[] = "xxxx";            //默认wifi-1,改成你的
  28. char pswd[] = "123123123";      
  29. char ssid2[] = "CMCC-2dvu";    //默认wifi-2,改成你的
  30. char pswd2[] = "ms8888";     

  31. //*******新建组件对象
  32. BlinkerButton Button1("btn-abc");    //设置app按键的键名
  33. BlinkerText Text1("tex-zh4");       //绑定文字组件
  34. BlinkerText Text2("tex-vkh");

  35. //*******天猫精灵
  36. void aligeniePowerState(const String & state)
  37. {
  38.   BLINKER_LOG("天猫精灵语音操作!");              //串口打印
  39.   show(state);          //没测试,不知道 state 内容
  40.   if (state == BLINKER_CMD_ON) {
  41.     BlinkerAliGenie.powerState("on");
  42.     BlinkerAliGenie.print();
  43.   }
  44.   else if (state == BLINKER_CMD_OFF) {
  45.     BlinkerAliGenie.powerState("off");
  46.     BlinkerAliGenie.print();
  47.   }
  48.   Text2.print("天猫");
  49. }

  50. void aligenieQuery(int32_t queryCode)      //天猫设备查询的回调函数
  51. {
  52.   BLINKER_LOG("AliGenie Query codes: ", queryCode);
  53.   switch (queryCode)
  54.   {
  55.     case BLINKER_CMD_QUERY_ALL_NUMBER :
  56.       BLINKER_LOG("AliGenie Query All");

  57.       BlinkerAliGenie.powerState(relay ? "on" : "off");
  58.       BlinkerAliGenie.print();
  59.       break;
  60.     case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
  61.       BLINKER_LOG("AliGenie Query Power State");
  62.       BlinkerAliGenie.powerState(relay ? "on" : "off");
  63.       BlinkerAliGenie.print();
  64.     default :
  65.       BlinkerAliGenie.powerState(relay ? "on" : "off");
  66.       BlinkerAliGenie.print();
  67.       break;
  68.   }
  69. }

  70. //APP未绑定的组件被触发,或者输入框发送内容,执行其中内容
  71. void dataRead(const String & data)
  72. {
  73.   show(data);
  74. }
  75. //App 按键
  76. void button1_callback(const String & state)        //app里按键有2种模式3钟不同样式用state来存储组键的值按键 : "tap"(点按); "pre"(长按); "pup"(释放)开关 : "on"(打开); "off"(关闭)
  77. {
  78.   show(state);
  79. }
  80. //App定时向设备发送心跳包, 收到心跳包后执行
  81. void heartbeat()
  82. {
  83.   show("chaxun");   
  84. }
  85. //APP“所有设备”页显示开关按钮
  86. void switch_callback(const String & state)
  87. {
  88.   show(state);
  89. }
  90. //本地开关控制2
  91. int jilu = 0 ;
  92. int startPressed = 0 ;
  93. void sdms() {
  94.   if (digitalRead(key) == LOW)
  95.   { jilu = millis() - startPressed; //计算按下的时间
  96.   }
  97.   else
  98.   { startPressed = millis();

  99.     if (jilu > 30 && jilu < 1300)
  100.     {
  101.       digitalWrite(relay, !digitalRead(relay));
  102.       show("tongbu");   //同步
  103.       Text2.print("本地开关");
  104.     }
  105.     else if (jilu > 4000)
  106.     {
  107.       show("press");
  108.     }

  109.     jilu = 0;
  110.   }
  111. }

  112. void setup()
  113. {
  114.   delay(3000);
  115.   Serial.begin(115200);   // 初始化串口
  116.   delay(200);
  117.   pinMode(relay, OUTPUT);
  118.   pinMode(led, OUTPUT);       //设为输出,闪灯
  119.   show("off");        //初始上电关
  120.   delay(200);
  121.   BLINKER_DEBUG.stream(Serial);  //查看设备端调试信息
  122.   BLINKER_DEBUG.debugAll();          //查看设备端调试信息
  123.   delay(100);
  124.   lianwang();       //进入联网程序
  125.   Blinker.delay(300);
  126.   Button1.attach(button1_callback);        //app按键回调
  127.   Blinker.attachData(dataRead);             //没有绑定的控件 函数注册
  128.   Blinker.attachHeartbeat(heartbeat);         //app定时向设备发送心跳包, 设备收到心跳包后会返回设备当前状态进行语音操作和app操作同步。
  129.   BUILTIN_SWITCH.attach(switch_callback);    //注册APP设备外面的图标上显示这一个开关按键
  130.   BlinkerAliGenie.attachPowerState(aligeniePowerState);      //天猫语音操作注册函数
  131.   BlinkerAliGenie.attachQuery(aligenieQuery);//天猫设备查询的回调函数
  132.   httpUpdater.setup(&httpServer);  //OTA
  133.   httpServer.begin();      //OTA
  134.   httpServer.on("/", homepage);//访问主页

  135.   // 初始化IO
  136.     digitalWrite(led, HIGH);
  137.   pinMode(key, INPUT_PULLUP);       //设输入上拉,按钮控制
  138. }

  139. void loop() {
  140.   Blinker.run();
  141.   sdms();//本地开关
  142.   cq();//无网重启
  143.   httpServer.handleClient();//OTA
  144. }

  145. const char PAGE_INDEX[] PROGMEM = R"(
  146.   <!DOCTYPE html ">
  147. <html">
  148. <head>
  149. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  150. <title>ESP8266物联网</title>
  151. </head>

  152. <body>
  153.   <h1>ESP8266物联网</h1>
  154.   <p>你正在浏览ESP8266提供的信息</p>
  155.   <p>
  156.     <a href="/update" target="_self" title="升级">升级</a><br/>
  157. </p>
  158. <p>
  159.     <a href="/?pw=abc" target="_self" title="重新设置">重新设置</a><br/>
  160. </p>
  161. <p>
  162.     <a href="/?cq=abc" target="_self" title="重新启动">重新启动</a><br/>
  163. </p>
  164. </body>
  165. </html>
  166. )";
  167. // 设置主页请求处理函数
  168. void homepage() {
  169.   httpServer.send(200,"text/html",PAGE_INDEX);
  170.   Blinker.println("用户访问了主页");
  171.   
  172.     if (httpServer.hasArg("pw")) {
  173.     Serial.print("请求中pw参数的值:");
  174.     //Serial.println(httpServer.arg("token"));
  175.   show("press");
  176.   }
  177.       if (httpServer.hasArg("cq")) {
  178.   show("cq");
  179.   }
  180.   else {
  181.     Serial.println("当前请求中无法找到指定请求体内容");
  182.   }
  183. }


  184. //使用web配置网络
  185. void WebConfig() {
  186.   httpServer.stop();
  187.   WiFiManager wifiManager;


  188.   for (int counter = 1; counter <= 4; counter++) { //闪灯提示进入配网
  189.      digitalWrite(led, HIGH);
  190.     Blinker.delay(300);
  191.     digitalWrite(led, LOW);
  192.     Blinker.delay(300);
  193.   }

  194. wifiManager.resetSettings();
  195.       
  196.   //设置配置页增加两个参数
  197.   WiFiManagerParameter custom_apikey("apikey", "apikey", api_key, 32);
  198.   WiFiManagerParameter custom_mqtt_server("server", "server", mqtt_server, 40);
  199.   wifiManager.addParameter(&custom_apikey);
  200.   wifiManager.addParameter(&custom_mqtt_server);
  201.   /*************************************/
  202.   /*** 步骤三:尝试连接网络,失败去到配置页面 **/
  203.   Serial.println("Entered config mode...");

  204. // wifiManager.setConfigPortalTimeout(60);  //设置连接超时时间60s  
  205. wifiManager.setMinimumSignalQuality(40);   //过滤信号质量  

  206. char buf[]="";
  207. devname="智能_"+devname ;
  208. strcpy(buf,devname.c_str());
  209. wifiManager.startConfigPortal(buf, NULL);  //直接进入配网管理,不会尝试保存的wifi
  210. //  wifiManager.autoConnect(buf, NULL);
  211.   Serial.print("ESP8266 Connected to ");
  212.   /*************************************/
  213.   // 读取配置页面配置好的信息
  214.   strcpy(mqtt_server, custom_mqtt_server.getValue());
  215.   strcpy(api_key,custom_apikey.getValue() );
  216.   saveinf1(api_key);
  217. delay(100);
  218. //ESP.restart();
  219. resetFunc();
  220. }

  221. void show(const String & state) {
  222.     if (state.endsWith("on") == 1 )  {
  223.     digitalWrite(relay, zt);     
  224.   }
  225.   if (state.endsWith("off") == 1 )  {
  226.     digitalWrite(relay, !zt);  
  227.   }
  228.     if (state.endsWith("tap") == 1 )  {
  229.       digitalWrite(relay, zt);
  230.       Blinker.delay(3000);
  231.     digitalWrite(relay, !zt);
  232.      Text2.print("电梯");
  233.   }
  234. if(state == "press") {
  235. Text2.print("重新配网");
  236.   WebConfig();
  237.   return;
  238. }
  239.   if(state.endsWith("cq") == 1 ) {
  240. Text2.print("重新启动");
  241. Blinker.delay(200);
  242. ESP.restart();
  243. }
  244.       Blinker.delay(200);
  245.       if (digitalRead(relay) == zt)
  246.       {
  247.          digitalWrite(led, LOW);
  248.         BUILTIN_SWITCH.print("on");
  249.         Button1.color("red");              //设置app按键是红色
  250.         Button1.text("继电器打开");
  251.         Button1.print("on");   
  252.     }
  253.       else
  254.       {
  255.             digitalWrite(led, HIGH);
  256.         BUILTIN_SWITCH.print("off");
  257.         Button1.color("gray");              //设置app按键是灰色
  258.         Button1.text("继电器关闭");
  259.         Button1.print("off");        
  260.       }
  261.       Text1.print(WiFi.localIP().toString().c_str(),WiFi.SSID().c_str());  //上传IP地址和wifi名称
  262. }

  263. void saveinf1( String api_key1) {        //  保存api
  264. Serial.print("saved:");
  265. storeStruct_t saved;

  266. strcpy(saved.name,api_key1.c_str());  
  267. strcpy(saved.myVersion,version2);  //验证码赋值

  268.   EEPROM.begin(4095);
  269.   EEPROM.put( 1, saved );
  270.    Blinker.delay(300);
  271.   EEPROM.commit();                      // Only needed for ESP8266 to get data written
  272.   EEPROM.end();                         // Free RAM copy of structure
  273. }

  274. void loadConfig() {
  275.   // Loads configuration from EEPROM into RAM
  276.   Serial.println("Loading config");
  277.   storeStruct_t load;
  278.   EEPROM.begin(4095);
  279.   EEPROM.get( 1, load);
  280.   EEPROM.end();

  281.   if (load.myVersion[0] != version2[0] ||
  282.       load.myVersion[1] != version2[1] ||
  283.      load.myVersion[2] != version2[2])   //比较验证码
  284. {
  285.     Serial.println("验证码没通过");   
  286.     return;
  287.   }
  288.   else {
  289.     strcpy(auth, load.name);
  290.   //给auth,重新赋值
  291.   Serial.println(auth); }
  292. }

  293. void lianwang(){

  294.   BlinkerMQTT2.hostname2(devname);  //BlinkerMQTT文件修改后才能用
  295.   digitalWrite(led, LOW); //常亮联网
  296.   //配网保存的信息
  297. loadConfig(); //读auth的值
  298.        Blinker.delay(300);      
  299. int n = WiFi.scanNetworks();    //开始同步扫描,存放在变量n中
  300.     for (int i = 0; i < n; ++i){  //开始逐个打印扫描到的wifi
  301.       Serial.print(WiFi.SSID(i));
  302.       if (WiFi.SSID(i)==cxpw )  //扫描到进入网页配网
  303.       {
  304.          Serial.println("重新配网");
  305.       WebConfig();
  306.       }
  307.      if(WiFi.SSID(i)==ssid )
  308.      {
  309.        Blinker.begin(auth, ssid, pswd);
  310.      return;
  311.       }
  312.            if(WiFi.SSID(i)==ssid2 )
  313.      {
  314.        Blinker.begin(auth, ssid2, pswd2);
  315.      return;
  316.       }
  317.            if(WiFi.SSID(i)==WiFi.SSID().c_str() )
  318.      {
  319.         Blinker.begin(auth, WiFi.SSID().c_str(), WiFi.psk().c_str());
  320.      return;
  321.       }
  322.     }   
  323.        Serial.println("没找到网络3s后重试!");   
  324.     delay(3000);     
  325. lianwang();
  326. }
  327. int detect_os_time=60;
  328.   void cq(){    //设定断网重新启动
  329.          bool result = Blinker.connected();         //获取连接服务器的状态  0失败 1成功
  330.        if (result == 1  || detect_os_time-millis()/60000 >60) {   //   或语句是防止millis()溢出时不能进入倒计时
  331.       detect_os_time =60+ millis()/60000;}  //倒计时60分钟
  332.         else
  333.         {       if (millis()%60000==0) {  //每分钟提醒一次
  334.                          Serial.print("断网重启倒计时(分钟):");  
  335.                         Serial.println(detect_os_time-millis()/60000 );
  336.                        Blinker.delay(300);
  337.                           }

  338.   if (detect_os_time-millis()/60000 <=0 && digitalRead(relay) != zt) {     //超时且开关关闭时 重启
  339.                          //ESP.restart();
  340.                          resetFunc();
  341.                               }
  342.        }
  343.         }
复制代码

以下是ota程序,我已经尽量减小了,但是水平有限。
  1. #include <ESP8266WiFi.h>
  2. #include <WiFiClient.h>
  3. #include <ESP8266WebServer.h>
  4. #include <ESP8266HTTPUpdateServer.h>

  5. ESP8266WebServer httpServer(80);
  6. ESP8266HTTPUpdateServer httpUpdater;

  7. void setup(void) {

  8.   Serial.begin(115200);
  9.   WiFi.mode(WIFI_STA);
  10.   WiFi.begin("xxxx", "123123123");

  11.   while (WiFi.status() != WL_CONNECTED) {
  12.       Serial.print("Connecting...");
  13.     delay(400);
  14.   }

  15.   httpUpdater.setup(&httpServer);
  16.   httpServer.begin();
  17. httpServer.on("/", homepage);//访问主页,不用记IP地址+/update 的升级方式

  18.   Serial.print("Open http://");
  19.   Serial.print(WiFi.localIP());
  20.   Serial.println("/update in your browser");
  21. }

  22. void loop(void)
  23. {
  24.   httpServer.handleClient();
  25. }
  26. const char PAGE_INDEX[] PROGMEM = R"(
  27.   <!DOCTYPE html ">
  28. <html">
  29. <head>
  30. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  31. <title>ESP8266物联网</title>
  32. </head>

  33. <body>
  34.   <h1>ESP8266物联网</h1>
  35.   <p>你正在浏览ESP8266提供的信息</p>
  36.   <p>
  37.     <a href="/update" target="_self" title="升级">升级</a><br/>
  38. </p>

  39. </body>
  40. </html>
  41. )";
  42. // 设置主页请求处理函数
  43. void homepage() {
  44.   httpServer.send(200,"text/html",PAGE_INDEX);
  45. Serial.println("用户访问了主页");
  46. }
复制代码

APP界面配置
  1. {¨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


该用户从未签到

发表于 2021-11-26 16:03 来自手机 | 显示全部楼层
学习了,谢谢分享

该用户从未签到

发表于 2021-11-26 16:57 | 显示全部楼层
感谢分享代码。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

热门推荐

Arduino数字与字母字体应该如何设置?
Arduino数字与字母字体应
尝试用Arduino uno 做了个小工具,用来控制电脑水冷的运行。 洞洞板已经测试成功,完
WEMOS LOLIN32Lite(ESP32v1.0.0Rev1)入手+引脚图
WEMOS LOLIN32Lite(ESP32v
突发奇想做个精致的蓝牙遥控平衡小车(大学时做过一次,比较笨,用洞洞板焊电路做的比
【Arduino】168种传感器模块系列实验(129)---BH1750光照传感器
【Arduino】168种传感器模
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
16度双足机器人舵机驱动板pca9685连接舵机,舵机没反应
16度双足机器人舵机驱动板
各位同为arduino爱好者的大佬们大家好!想请教一下大家有关舵机驱动板pca9685
pca9685+arduino驱动舵机失败
pca9685+arduino驱动舵机
我网上别人的代码,编译通过且上传,但舵机不转,怎么解决?Arduino uno使用PCA9685模
Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
快速回复 返回顶部 返回列表