怎么同步开关状态 顺便分享小爱同学+app控制继电器代码-Arduino中文社区 - Powered by Discuz! Archiver

asker 发表于 2020-2-24 19:51

怎么同步开关状态 顺便分享小爱同学+app控制继电器代码

本帖最后由 asker 于 2020-2-24 19:52 编辑

WIFI模块 ESP 01
https://www.arduino.cn/forum.php?mod=image&aid=61465&size=300x300&key=160910ce94d3e391&nocache=yes&type=fixnone
物联网继电器模块 GPIO0 低电平控制

https://www.arduino.cn/forum.php?mod=image&aid=61464&size=300x300&key=fb711cdfe87bd0c1&nocache=yes&type=fixnone

代码改自官方”MIOT_OUTLET“例程

如下:

#define BLINKER_WIFI
#define BLINKER_MIOT_OUTLET

#include <Blinker.h>

char auth[] = "**************";   
char ssid[] = "***************";
char pswd[] = "*************";

#define LED 0    //0对应GPIO02对应GPIO2

bool oState = false;

BlinkerButton Button1("btn-abc");

//按下按键即会执行该函数
void button1_callback(const String & state) {
digitalWrite(LED, !digitalRead(LED));
BLINKER_LOG("get button state: ", state);
Button1.print(state);
}

void miotPowerState(const String & state)
{
BLINKER_LOG("need set power state: ", state);

if (state == BLINKER_CMD_ON) {
    digitalWrite(LED, LOW);
    BlinkerMIOT.powerState("on");   
    BlinkerMIOT.print();   
    oState = true;
} else if (state == BLINKER_CMD_OFF) {
    digitalWrite(LED, HIGH);
    BlinkerMIOT.powerState("off");
    BlinkerMIOT.print();   
    oState = false;
}
}

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 dataRead(const String & data)
{
BLINKER_LOG("Blinker readString: ", data);
Blinker.vibrate();
uint32_t BlinkerTime = millis();
Blinker.print("millis", BlinkerTime);
}

void setup()
{
Serial.begin(115200);
BLINKER_DEBUG.stream(Serial);
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);
Blinker.begin(auth, ssid, pswd);
Blinker.attachData(dataRead);
Button1.attach(button1_callback);
BlinkerMIOT.attachPowerState(miotPowerState);
BlinkerMIOT.attachQuery(miotQuery);
}

void loop()
{
Blinker.run();
}

(安装编程环境折腾了半天时间,编译老是出问题,最后把''blinker-library-master''放到程序安装目录下的''libraries''里后竟然好了。。。不知道有没有人和我一样- -)

烧写完程序,把小爱同学设置好,并在点灯app里添加一个开关型按钮,就可以同时用小爱同学和点灯app控制继电器动作。

然后我就发现了一个问题,比如继电器控制一盏灯,用小爱控制继电器闭合后,灯打开了,但是app里的开关组件显示灯还是在关闭状态。

请教大佬们,怎么才能让小爱同学和App里的开关组件状态同步,也就是说用小爱打开或关闭这盏灯,app里的开关组件也能同步显示为开启或关闭状态?




Creeper666 发表于 2020-2-24 23:48

本帖最后由 Creeper666 于 2020-2-24 23:57 编辑

app中使用开关按键,在button1的回调函数中使用如下代码
```
if (state == BLINKER_CMD_ON) {
Button1.text("已开启")
Button1.print("on");
}
else if (state == BLINKER_CMD_OFF) {
Button1.text("已开启");
Button1.print("off");
}
```

13943006062 发表于 2020-2-25 06:18

我想io0和io2一起单独控制,应该怎么写代码?

asker 发表于 2020-2-25 19:45

本帖最后由 asker 于 2020-2-25 20:18 编辑

13943006062 发表于 2020-2-25 06:18
我想io0和io2一起单独控制,应该怎么写代码?
#define LED 0
#define LED1 1         //0对应GPIO02对应GPIO2

BlinkerButton Button1("btn-abc");
BlinkerButton Button2("第二个开关的键值");

//按下按键即会执行该函数
void button1_callback(const String & state) {
//按下第一个按钮执行的动作
}
void button2_callback(const String & state) {
//按下第二个按钮执行的动作
}


在void button1_callback(const String & state) {};void button2_callback(const String & state) {};里面写两个按钮触发后的响应程序 程序格式跟控制一个按钮是一样的


Button1.attach(button1_callback);
Button2.attach(button2_callback);
这里需要绑定两个回调函数
控制小爱的话估计要用“MIOT_MULTI_OUTLET”这个例子改 我还没研究过






asker 发表于 2020-2-25 20:11

Creeper666 发表于 2020-2-24 23:48
app中使用开关按键,在button1的回调函数中使用如下代码
```
if (state == BLINKER_CMD_ON) {


多谢大佬 这样是点击按键后同步开关状态吗? 今天我尝试在小爱的电源状态反馈函数中添加给按钮同步状态的函数,然后在按钮回调函数中加入给小爱同步状态的函数

//按下按键即会执行该函数
void button1_callback(const String & state) {
BLINKER_LOG("get button state: ", state);
if (state == "on") {
    digitalWrite(LED, LOW);
    oState = true;
} else if (state == "off") {
    digitalWrite(LED, HIGH);
    oState = false;
}
Button1.print(state);
BlinkerMIOT.powerState(oState ? "on" : "off");
BlinkerMIOT.print();
}


void miotPowerState(const String & state)
{
BLINKER_LOG("need set power state: ", state);
if (state == BLINKER_CMD_ON) {
    digitalWrite(LED, LOW);
    BlinkerMIOT.powerState("on");   //反馈电源状态
    BlinkerMIOT.print();
    Button1.print("on");
    oState = true;
} else if (state == BLINKER_CMD_OFF) {
    digitalWrite(LED, HIGH);
    BlinkerMIOT.powerState("off");
    BlinkerMIOT.print();
    Button1.print("off");
    oState = false;
}
}
试验了一下,状态成功同步了,但有时不稳定,失败的时候串口监视报错“ERROR: MQTT NOT ALIVE OR MSG” 这种情况下开关是可以动作,但是状态就没有办法同步了,大佬能否解答一下

Creeper666 发表于 2020-2-25 20:47

本帖最后由 Creeper666 于 2020-2-25 20:51 编辑

不是if (state == "on")是if (state == BLINKER_CMD_ON)
关闭同理

随缘7906 发表于 2020-2-25 21:24

感谢楼上的几位,我已经改好了。不过只有用小爱控制才显示开启关闭,用按钮,状态不会变化。

asker 发表于 2020-2-25 22:45

本帖最后由 asker 于 2020-2-25 22:48 编辑

Creeper666 发表于 2020-2-25 20:47
不是if (state == "on")是
这个我明白,不过你第一次给的代码只是用按键查询开关的状态,我把它改了一下,在执行app按键发出的指令前先查询小爱里开关的状态,如果状态一样就只改变app按键显示状态,否则既改变状态同时执行按键指令。我一开始想让8266在执行小爱指令的时候发送一个开关状态值返回给app按键,按键根据这个值改变自身的显示状态,只是用8266反馈开关状态值不太稳定,加上你这些代码就保险了,最差的情况就是多按一次按键。

asker 发表于 2020-2-25 22:47

随缘7906 发表于 2020-2-25 21:24
感谢楼上的几位,我已经改好了。不过只有用小爱控制才显示开启关闭,用按钮,状态不会变化。 ...

//按下按键即会执行该函数
void button1_callback(const String & state) {
BLINKER_LOG("get button state: ", state);
if (state == BLINKER_CMD_ON) {
    digitalWrite(LED, LOW);
    oState = true;
} else if (state == BLINKER_CMD_OFF) {
    digitalWrite(LED, HIGH);
    oState = false;
}
Button1.print(state);
BlinkerMIOT.powerState(oState ? "on" : "off");
BlinkerMIOT.print();
}


把你写的代码里的void button1_callback(const String & state) {}替换成这个试试

Creeper666 发表于 2020-2-26 09:06

asker 发表于 2020-2-25 22:45
这个我明白,不过你第一次给的代码只是用按键查询开关的状态,我把它改了一下,在执行app按键发出的指令前 ...

根据小爱的值返回状态需要使用心跳包才可以,否则状态只会在按下按钮后才返回
页: [1] 2 3
查看完整版本: 怎么同步开关状态 顺便分享小爱同学+app控制继电器代码