前段時間看了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)
2021-2-8 13:04 上傳
點擊文件名下載附件
源代碼以及相應庫文件與電路圖
2個文件一起解壓才能成功:
8266_標準庫.part1.rar
(18 MB, 下載次數: 17)
2021-2-8 13:50 上傳
點擊文件名下載附件
8266_標準庫.part2.rar
(14.39 MB, 下載次數: 26)
2021-2-8 13:50 上傳
點擊文件名下載附件
|