前段时间看了ESP8266点灯的视频,想着自己也DIY一个。
上网搜了资料,买来ESP-8266-12F和继电器模块,开始动手制作。
制作过程省略,要是有不太明白的地方可以找度娘,一搜一大把,我这就偷个懒。
……制作的过程中遇到的问题与大家分享一下。
1.最先遇到的就是每次下载程序都得插在电脑上下载,因为我用的免费版的,blinker一旦更新库文件或者与小爱的接口,咱们的灯就控制不了。 这就很麻烦了,不可能每次更新都去拆装一下灯吧。于是又找度娘商量了一下,度娘给了我一个http_update的例程,把这个例程加入进去,程序更新是解决了,可是电脑得开web服务器,不过总算是不用拆装灯具了。
2.第二个问题就是设备ID是固化在程序里的,如果我做好2个或5个设备(blinker免费版最多5个独立设备),更新的时候岂不是得生成5个更新包,万一更新的时候弄错了,后续使用就很麻烦。这个问题得解决掉,查看8266 库的时候发现8266是可以将FLASH当作EEPROM来操作的,于是把设备ID在下载程序后第一次运行就存在EEPROM里,后面就只要读出来就可以了。这样不管几个设备,更新程序都可以通用了。
3.第三个问题就是WIFI配置。与设备ID一样,网上例程都是将WIFI SSID和PASSWORD固化在程序里的。如果只是测试用是没问题的,只要不改WIFI密码,或者改WIFI密码的时候先给灯的程序更新一下.......咱这个不是得装灯里面吗?这就又是个麻烦。好在blinker app里面就带有WIFI配网
操作路径:打开blinker app => 点左上角的几条横线 => 点开发者 => 点开发工具 =>ApConfig,输入你的WIFI名称和密码,然后打开你要配置的设备,就可以愉快的点开始配置了。
代码我和电路图我放附件里了,需要的朋友可以下载参考一下。
- #define BLINKER_PRINT Serial
- #define BLINKER_MIOT_LIGHT
- #define BLINKER_WIFI
- #define BLINKER_APCONFIG
- #include <Blinker.h>
- #include <Arduino.h>
- #include <ESP8266WiFi.h>
- #include <ESP8266WiFiMulti.h>
- #include <ESP8266HTTPClient.h>
- #include <ESP8266httpUpdate.h>
- #include <EEPROM.h> ";
- char eep1=0;
- char eep2=5;
- int addr = 3900;//避开blinker使用的eeprom地址
- char tmp = 0;
- bool oState = false;
- bool switch_state = true;
- int counter = 0;
- float pai =0;
- bool UpDate = false; //系统升级标志
- char auth[] = "xxxxxxxxxx";//上一步中在blinker app中获取到的Secret Key
- char up_date_path["http://xxxxxxxxxxxx/file.bin"];//更新固件的具体http地址,只试过http,没试过https不知道可不可行
- // 新建组件对象
- BlinkerButton Button1("btn-put");//灯开关组件
- BlinkerButton Button2("btn-upd");//升级用的开关组件
- BlinkerNumber Number1("num-abc");
- ESP8266WiFiMulti WiFiMulti;
- void read_skey()
- {
- EEPROM.begin(4096);
- for(tmp=0;tmp<12;tmp++)
- {
- auth[tmp]=EEPROM.read(addr+tmp);
- }
- EEPROM.end();
- Serial.println("EEPROM_read OK:");
- Serial.println(auth);
- }
- void write_skey()
- {
- EEPROM.begin(4096);
- EEPROM.write(addr+14,0x42);//auth码存储标志
- EEPROM.write(addr+15,0xbd);//auth码存储标志反码
- for(tmp=0;tmp<12;tmp++)
- {
- EEPROM.write(addr+tmp,auth[tmp]);
-
- }
- if (EEPROM.commit())
- {
- Serial.println(auth);
- Serial.println("EEPROM successfully committed");
- }
- else
- {
- Serial.println("ERROR! EEPROM commit failed");
- }
- EEPROM.end();
- }
- /* 小米设备状态查询回调函数 */
- void miotQuery(int32_t queryCode)
- {
- BLINKER_LOG("MIOT Query codes: ", queryCode);
- switch (queryCode)
- {
- case BLINKER_CMD_QUERY_ALL_NUMBER :
- BLINKER_LOG("MIOT Query All");
- BlinkerMIOT.powerState(oState ? "on" : "off");
- BlinkerMIOT.print();
- break;
- case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
- BLINKER_LOG("MIOT Query Power State");
- BlinkerMIOT.powerState(oState ? "on" : "off");
- BlinkerMIOT.print();
- break;
- default :
- BlinkerMIOT.powerState(oState ? "on" : "off");
- BlinkerMIOT.print();
- break;
- }
- }
- // 按下按键即会执行该函数
- void button1_callback(const String & state)
- {
- if (state=="on")
- {
- BLINKER_LOG("get button state: ", state);
- digitalWrite(LED_BUILTIN, LOW);
- Button1.print("on");
- switch_state = true;
- }else if (state=="off")
- {
- BLINKER_LOG("get button state: ", state);
- digitalWrite(LED_BUILTIN, HIGH);
- Button1.print("off");
- switch_state = false;
- }
- }
- void heartbeat()//自定义心跳包的返回
- {
- if (switch_state)
- {
- //BUILTIN_SWITCH.print("on");
- Button1.print("on");
- }
- else
- {
- //BUILTIN_SWITCH.print("off");
- Button1.print("off");
- }
- }
- //按下此键改变升级状态,进行http升级
- void button2_callback(const String & stage)
- {
- UpDate = true;
- }
- // 如果未绑定的组件被触发,则会执行其中内容
- void dataRead(const String & data)
- {
- BLINKER_LOG("Blinker readString: ", data);
- counter++;
- Number1.print(counter);
- if (counter>0xfff0)counter=0;
- }
- void miotPowerState(const String & state) //小爱语音控制函数
- {
-
- if (state == BLINKER_CMD_ON) {
- digitalWrite(LED_BUILTIN, LOW);
- BlinkerMIOT.powerState("on");
- BlinkerMIOT.print();
- Button1.print("on");
- switch_state = true;
- }
- else if (state == BLINKER_CMD_OFF) {
- digitalWrite(LED_BUILTIN, HIGH);
- BlinkerMIOT.powerState("off");
- BlinkerMIOT.print();
- Button1.print("off");
- switch_state = false;
- }
- BLINKER_LOG("need set power state: ", state);
- }
- void setup() {
- Serial.begin(115200);
- Serial.println();
- Serial.println();
- Serial.println();
- #if defined(BLINKER_PRINT)
- BLINKER_DEBUG.stream(BLINKER_PRINT);
- #endif
- EEPROM.begin(4096);
- eep1=EEPROM.read(addr+14); //ID存储标志
- eep2=255-EEPROM.read(addr+15);//ID存储标志反码
- EEPROM.end();
- if (eep1==eep2)
- {
- read_skey();
- Serial.println("EEPROM read OK.");
- }
- else
- {
- write_skey();
- }
- Serial.print("WiFi Connected!");
- // 初始化有LED的IO
- pinMode(LED_BUILTIN, OUTPUT);
- digitalWrite(LED_BUILTIN, LOW);
- // Blinker.begin(auth, ssid, pswd); //初始化blinker
- Blinker.begin(auth); //使用blinker app配网,这里只需要ID就行,如果预置WIFI配置就用上面一行代码
- //注册回调函数
- Blinker.attachHeartbeat(heartbeat);
- Blinker.attachData(dataRead);
- BlinkerMIOT.attachPowerState(miotPowerState);
- Button1.attach(button1_callback);
- Button2.attach(button2_callback);
- BlinkerMIOT.attachQuery(miotQuery);
- ESPhttpUpdate.onStart(update_started);
- ESPhttpUpdate.onEnd(update_finished);
- ESPhttpUpdate.onProgress(update_progress);
- ESPhttpUpdate.onError(update_error);
- }
- void update_started() {
- Serial.println("CALLBACK: HTTP update process started");
- }
- void update_finished() {
- Serial.println("CALLBACK: HTTP update process finished");
- UpDate = false;
- digitalWrite(LED_BUILTIN, HIGH);
- }
- void update_progress(int cur, int total) {
- Serial.printf("CALLBACK: HTTP update process at %d bytes of %3.1f %%total\n", cur, (float)cur/(float)total*100.0);
- }
- void update_error(int err) {
- Serial.printf("CALLBACK: HTTP update fatal error code %d\n", err);
- UpDate = false;
- if (switch_state) //更新失败则恢复灯的开关状态。
- {
- digitalWrite(LED_BUILTIN, LOW);
- Button1.print("on");
- }
- else
- {
- digitalWrite(LED_BUILTIN, HIGH);
- Button1.print("off");
- }
- Button2.print("update error");
- }
- void loop() {
- // wait for WiFi connection
- Blinker.run();
- if (UpDate) { //接收到更新指令,进入更新程序
- if (switch_state){
- digitalWrite(LED_BUILTIN, HIGH);
- }
- else{
- digitalWrite(LED_BUILTIN, LOW); //灯状态取反表示进入更新模式
- }
- WiFiClient client;
- t_httpUpdate_return ret = ESPhttpUpdate.update(client, up_date_path);//更新固件
- switch (ret) {
- case HTTP_UPDATE_FAILED:
- Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
- break;
- case HTTP_UPDATE_NO_UPDATES:
- Serial.println("HTTP_UPDATE_NO_UPDATES");
- break;
- case HTTP_UPDATE_OK:
- Serial.println("HTTP_UPDATE_OK");
- break;
- }
- }
- }
复制代码
blinker_esp_8266_httpUpdate.rar
(735.03 KB, 下载次数: 28)
2个文件一起解压才能成功:
8266_标准库.part1.rar
(18 MB, 下载次数: 17)
8266_标准库.part2.rar
(14.39 MB, 下载次数: 26)
|