工具

  • esp8266 开发板
  • 继电器模块
  • 杜邦线
  • 用电器

实验连线

将 ESP8266 核心板的“VV”与继电器模块的“VCC”相连,“G”与“GND”相连,“D1”与“IN1”相连,“D4”与“IN2”相连。用电器电源线串入继电器模块的常开触点

程序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
/* *****************************************************************  
blinker+小爱同学控制2路开关(程序预留4路)
* *****************************************************************/

#define BLINKER_WIFI //以wifi方式连接
#define BLINKER_MIOT_MULTI_OUTLET //支持多路开关
#define BLINKER_PRINT Serial //定义串口方式打印信息
#define BLINKER_WITHOUT_SSL //以不加密方式进行远程通信,减少RAM占用

#include <Blinker.h> //调用Blinker库

char auth[] = "46e64f4684b9"; //Blinker APP中的设备Secret Key(密钥)
//网络配置
char ssid[] = "@Hyatt_WiFi"; //wifi名称
char pswd[] = ""; //wifi密码

//定义继电器信号引脚
#define Relay_1 D1 //定义继电器1信号接入D1
#define Relay_2 D2 //定义继电器2信号接入D2
#define Relay_3 D3 //定义继电器3信号接入D3
#define Relay_4 D4 //定义继电器4信号接入D4


// 新建Blinker软件组件对象
BlinkerButton Button("MainSwitch"); //组件对象,要和APP组件中的“数据键名”一致,总开关
BlinkerButton Button1("Switch1"); //组件对象,要和APP组件中的“数据键名”一致,开关1
BlinkerButton Button2("Switch2"); //组件对象,要和APP组件中的“数据键名”一致,开关2
BlinkerButton Button3("Switch3"); //组件对象,要和APP组件中的“数据键名”一致,开关3
BlinkerButton Button4("Switch4"); //组件对象,要和APP组件中的“数据键名”一致,开关4
BlinkerButton Button5("Refresh"); //APP端按钮状态刷新

//定义插座状态,用于小爱同学状态反馈
bool oState[5] = { false };
#define OUTLET_ALL 0 //所有插孔
#define OUTLET_NO_1 1 //插座插孔一
#define OUTLET_NO_2 2 //插座插孔二
#define OUTLET_NO_3 3 //插座插孔三
#define OUTLET_NO_4 4 //插座插孔四

//反馈继电器状态函数
void RelayState(int num)
{
switch(num)
{
case 1: //插座插孔一状态
if(digitalRead(Relay_1)==LOW)
{
Button1.color("#FF0000"); //app按键按下后变为红色
Button1.text("插座1开"); //app按键文本显示“开”
Button1.print("on");
oState[1] = true;
}
else if(digitalRead(Relay_1==HIGH))
{
Button1.color("#808080"); //app按键弹起,恢复灰色
Button1.text("插座1关"); //app按键文本显示“关”
Button1.print("off");
oState[1] = false;
}
break;
case 2:
if(digitalRead(Relay_2)==LOW)
{
Button2.color("#FF0000"); //app按键按下后变为红色
Button2.text("插座2开"); //app按键文本显示“开”
Button2.print("on");
oState[2] = true;
}
else if(digitalRead(Relay_2==HIGH))
{
Button2.color("#808080"); //app按键弹起,恢复灰色
Button2.text("插座2关"); //app按键文本显示“关”
Button2.print("off");
oState[2] = false;
}
break;
case 3:
if(digitalRead(Relay_3)==LOW)
{
Button3.color("#FF0000"); //app按键按下后变为红色
Button3.text("插座3开"); //app按键文本显示“开”
Button3.print("on");
oState[3] = true;
}
else if(digitalRead(Relay_3==HIGH))
{
Button3.color("#808080"); //app按键弹起,恢复灰色
Button3.text("插座3关"); //app按键文本显示“关”
Button3.print("off");
oState[3] = false;
}
break;
case 4:
if(digitalRead(Relay_4)==LOW)
{
Button4.color("#FF0000"); //app按键按下后变为红色
Button4.text("插座4开"); //app按键文本显示“开”
Button4.print("on");
oState[4] = true;
}
else if(digitalRead(Relay_4==HIGH))
{
Button4.color("#808080"); //app按键弹起,恢复灰色
Button4.text("插座4关"); //app按键文本显示“关”
Button4.print("off");
oState[4] = false;
}
break;
default:
break;
}
}

//小爱同学控制插座多个插孔
void ctrl_multi_outlet(uint8_t num, uint8_t io_level)
{
switch (num)
{
case 0: //所有插孔
digitalWrite(Relay_1, io_level);//控制继电器1
digitalWrite(Relay_2, io_level);//控制继电器2
digitalWrite(Relay_3, io_level);//控制继电器3
digitalWrite(Relay_4, io_level);//控制继电器4
break;
case 1: //插座插孔一
digitalWrite(Relay_1, io_level);//控制继电器1
break;
case 2: //插座插孔二
digitalWrite(Relay_2, io_level);//控制继电器2
break;
case 3: //插座插孔三
digitalWrite(Relay_3, io_level);//控制继电器3
break;
case 4: //插座插孔四
digitalWrite(Relay_4, io_level);//控制继电器4
break;
default:
break;
}
}

//小爱电源类回调,例如:“打开插座”、“打开插座插孔一”、“打开插座插孔二”
void miotPowerState(const String & state, uint8_t num)
{
BLINKER_LOG("need set outlet: ", num, ", power state: ", state);

if (state == BLINKER_CMD_ON)
{
ctrl_multi_outlet(num, LOW);//打开继电器,num表示是多少路(继电器低电平触发)
BlinkerMIOT.powerState("on", num);
BlinkerMIOT.print();
RelayState(num);

oState[num] = true;
}
else if (state == BLINKER_CMD_OFF)
{
ctrl_multi_outlet(num, HIGH);//关闭继电器,num表示是多少路

BlinkerMIOT.powerState("off", num);
BlinkerMIOT.print();
RelayState(num);

oState[num] = false;
}
}

//小爱设备查询的回调函数,查询设备状态,例如:“插座插孔一状态”
void miotQuery(int32_t queryCode,uint8_t num)
{
BLINKER_LOG("插孔",num,"状态",",codes:", queryCode);

switch (num)
{
case 0 :
BLINKER_LOG("状态:");
BlinkerMIOT.powerState(oState[1] ? "on" : "off");
BlinkerMIOT.powerState(oState[2] ? "on" : "off");
BlinkerMIOT.powerState(oState[3] ? "on" : "off");
BlinkerMIOT.powerState(oState[4] ? "on" : "off");
BlinkerMIOT.print();
break;
case 1 :
BLINKER_LOG("插孔1状态:");
BlinkerMIOT.powerState(oState[1] ? "on" : "off");
BlinkerMIOT.print();
break;
case 2 :
BLINKER_LOG("插孔2状态:");
BlinkerMIOT.powerState(oState[2] ? "on" : "off");
BlinkerMIOT.print();
break;
case 3 :
BLINKER_LOG("插孔3状态:");
BlinkerMIOT.powerState(oState[3] ? "on" : "off");
BlinkerMIOT.print();
break;
case 4 :
BLINKER_LOG("插孔4状态:");
BlinkerMIOT.powerState(oState[4] ? "on" : "off");
BlinkerMIOT.print();
break;
default :
BlinkerMIOT.powerState(oState[1] ? "on" : "off");
BlinkerMIOT.powerState(oState[2] ? "on" : "off");
BlinkerMIOT.powerState(oState[3] ? "on" : "off");
BlinkerMIOT.powerState(oState[4] ? "on" : "off");
BlinkerMIOT.print();
break;
}
}

// 在APP控制,按下MainSwitch按键即会执行该函数
void button_callback(const String & state)
{
BLINKER_LOG("操作了MainSwitch: ", state);//APP中的Monitor控件打印的信息
if (state=="on")
{
ctrl_multi_outlet(OUTLET_ALL, LOW);//打开继电器--所有
// 反馈继电器状态
Button.color("#FF0000"); //设置app按键是红色
Button.text("开"); //设置app按键注释“开”
Button.print("on");
} else if(state=="off")
{
ctrl_multi_outlet(OUTLET_ALL, HIGH);//关闭继电器--所有
// 反馈继电器状态
Button.color("#808080"); //设置app按键是纯黄色,16进制颜色码
Button.text("关"); //设置app按键注释“开”
Button.print("off");
}
}

// 在APP控制,按下Switch1按键即会执行该函数--第1路开关
void button1_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);//APP中的Monitor控件打印的信息
if (state=="on")
{
ctrl_multi_outlet(OUTLET_NO_1, LOW);//打开继电器--第1路
// 反馈继电器1状态
RelayState(1); //调用继电器反馈程序
} else if(state=="off")
{
ctrl_multi_outlet(OUTLET_NO_1, HIGH);//关闭继电器--第1路
// 反馈继电器状态
RelayState(1); //调用继电器反馈程序
}
}

// 在APP控制,按下Switch2按键即会执行该函数--第2路开关
void button2_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);//APP中的Monitor控件打印的信息
if (state=="on")
{
ctrl_multi_outlet(OUTLET_NO_2, LOW);//打开继电器--第2路
// 反馈继电器状态
RelayState(2); //调用继电器反馈程序
} else if(state=="off")
{
ctrl_multi_outlet(OUTLET_NO_2, HIGH);//关闭继电器--第2路
// 反馈继电器状态
RelayState(2); //调用继电器反馈程序
}
}

// 在APP控制,按下Switch3按键即会执行该函数--第3路开关
void button3_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);//APP中的Monitor控件打印的信息
if (state=="on")
{
ctrl_multi_outlet(OUTLET_NO_3, LOW);//打开继电器--第3路
// 反馈继电器状态
RelayState(3); //调用继电器反馈程序
} else if(state=="off")
{
ctrl_multi_outlet(OUTLET_NO_3, HIGH);//关闭继电器--第3路
// 反馈继电器状态
RelayState(3); //调用继电器反馈程序
}
}

// 在APP控制,按下Switch4按键即会执行该函数--第4路开关
void button4_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);//APP中的Monitor控件打印的信息
if (state=="on")
{
ctrl_multi_outlet(OUTLET_NO_4, LOW);//打开继电器--第4路
// 反馈继电器状态
RelayState(4); //调用继电器反馈程序
} else if(state=="off")
{
ctrl_multi_outlet(OUTLET_NO_4, HIGH);//关闭继电器--第4路
// 反馈继电器状态
RelayState(4); //调用继电器反馈程序
}
}

//APP端状态手动刷新按钮
void button5_callback(const String & state)
{
for(int i=0;i<5;i++)
{
RelayState(i);
}
}

//心跳包刷新状态
void heartbeat()
{
for(int i=0;i<5;i++)
{
RelayState(i);
}
}



void setup()
{
// 初始化串口,用于调试,后期可删除
Serial.begin(115200);
BLINKER_DEBUG.stream(Serial);
BLINKER_DEBUG.debugAll();

// 初始化有继电器的IO
pinMode(Relay_1, OUTPUT);
pinMode(Relay_2, OUTPUT);
pinMode(Relay_3, OUTPUT);
pinMode(Relay_4, OUTPUT);
//初始化继电器初始状态
digitalWrite(Relay_1, HIGH); //继电器为低电平触发,初始化为HIGH
digitalWrite(Relay_2, HIGH);
digitalWrite(Relay_3, HIGH);
digitalWrite(Relay_4, HIGH);


//初始化blinker
Blinker.begin(auth, ssid, pswd);//代码配网
Button.attach(button_callback); //绑定按键回调
Button1.attach(button1_callback); //绑定按键回调
Button2.attach(button2_callback); //绑定按键回调

Button3.attach(button3_callback); //绑定按键回调
Button4.attach(button4_callback); //绑定按键回调
Button5.attach(button5_callback);

//小爱同学注册回调
BlinkerMIOT.attachPowerState(miotPowerState); //注册小爱电源回调
BlinkerMIOT.attachQuery(miotQuery); //小爱设备查询的回调函数

//心跳包,初始化
Blinker.attachHeartbeat(heartbeat); //app定时向设备发送心跳包, 设备收到心跳包后会返回设备当前状态
}

void loop()
{

Blinker.run();
}