标题:
带无线更新的基于esp8266和blinker的小爱语音控制智能灯
[打印本页]
作者:
udbfhq
时间:
2021-2-8 13:52
标题:
带无线更新的基于esp8266和blinker的小爱语音控制智能灯
前段时间看了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名称和密码,然后打开你要配置的设备,就可以愉快的点开始配置了。
代码我和电路图我放附件里了,需要的朋友可以下载参考一下。
51hei.png
(24 KB, 下载次数: 109)
下载附件
2021-2-9 01:13 上传
#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 上传
点击文件名下载附件
源代码以及相应库文件与电路图
下载积分: 黑币 -5
2个文件一起解压才能成功:
8266_标准库.part1.rar
(18 MB, 下载次数: 17)
2021-2-8 13:50 上传
点击文件名下载附件
下载积分: 黑币 -5
8266_标准库.part2.rar
(14.39 MB, 下载次数: 26)
2021-2-8 13:50 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1