项目预想
- 改造自家设备,投入控制在50 – 100元左右
- 至少让以下设备(数据)联网并实现语音控制 三盏灯 关门提醒 温湿度
- 先用低压电实验,全部完成并测试无误后再接入220V,小命要紧
当前进度
先把卧室灯接入小爱同学和手机
- 由于是普通灯泡,不能调光,很省事,控制开关就可以
使用硬件
- ESP8266 (12元)
- 10A继电器(4.5元)
前言
- 之前计划用一块板控制多路设备,实际上一块主板小爱只支持接入一个设备
- 代码上可以绕开一些限制,但操作上走线也是个大问题,不经济,现在计划改变了
- 现在的计划: 一块板控制三个灯 温湿度传感器信息不接入小爱 控制方式:遥控器、语音、手机 本来打算用双控开关,但现在用的旧开关还好着,暂时不换……
- 实验已经完成,线路已经复杂到看不清了,附上个原理图,温湿度传感器和红外接收太简单就不画了
- 下一步就是接220V,这个步骤会比较危险,一不小心你和设备都会被带走的哟
- 原则上所有弱电设备要共地,强电由弱电继电器驱动,二者不能有交接
所需硬件(30元)
1 2 3 4 |
1. ESP8266 * 1(12元) 2. 旧电视遥控器 * 1(0元) 3. 温湿度传感器 * 1(4.5元) 4. 10A继电器 * 3(13.5元) |
原理图
实验图
前言
- 卧室开关是双控的,这样开关也能参与控制了
- 此场景理想的开关是触摸或按键,但得跑2根线,还需要盾板(一块ESP8266的前提下),这次不搞那么复杂了
- 用双控开关加小爱控制有个问题,双控开关在L2档时小爱开关指令是反的
- 布的一条20米的网线
- 小爱同学手机app和音箱(电视)上的小爱同学训练结果不同步,使用小爱app训练的还需要用小爱音箱app再训练一次
双控原理图
接线及引脚
双绞线供3个并联的继电器电
- 橙色,5V正极
- 橙白,5V负极
- 绿色,卧室一控制线
- 绿白,卧室二控制线
- 棕色,客厅控制线
- 蓝色,红外接收器正极(ESP8266供电)
- 棕白,外红接收器负极(ESP8266供电)
- 蓝白,红外接收器控制线
ESP8266引脚接线
- D1,客厅控制
- D2,卧室二控制
- D5,卧室一控制
- D6,温度传感器数据
- D7,红外接收器数据
红外接收器和温湿度传感器由ESP8266供电,所有模块共地
最终代码
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 |
<em>// 此案例实现一块ESP8266控制三路电灯,一个温湿度传感器,一个红外接收器</em> <em>// 由于小爱只可以一块板接入一样设备,所以温湿度信息只能在手机端显示,不能通过小爱查询</em> #define BLINKER_WIFI #define BLINKER_MIOT_LIGHT #include <Blinker.h> #include <IRremote.h> // 红外控制库 #include <DHT.h> // 温湿度传感器库 <em>// MQTT操作库</em> #include <ESP8266WiFi.h> #include <PubSubClient.h> long lastMsg = 0; <em>// 记录最后发送的时间</em> <em>// 定义联网参数</em> char auth[] = "4d4318f43000"; char ssid[] = "gzhx"; char pswd[] = "12345678"; const char* mqttServer = "mqtts.heclouds.com"; WiFiClient wifiClient; PubSubClient mqttClient(wifiClient); const char* client_ID = "esp8266_2"; const char* mqttUserName = "465328"; <em>// 服务端连接用户名</em> const char* mqttPassword = "version=2018-10-31&res=products%2F465328%2Fdevices%2Fesp8266_2&et=1667311968&method=md5&sign=U7hjNC0WKq%2FeR5XSTXjm2A%3D%3D"; <em>// 服务端连接密码</em> char dataTemplate[] = "{\"id\": %d, \"dp\": {\"temp\": [{\"v\": %.2f}], \"humi\": [{\"v\": %.2f}]}}"; <em>// 信息模板</em> char postData[100]; <em>// 信息</em> int id_num = 0; <em>// ID</em> <em>// 主题</em> char topic[] = "$sys/465328/esp8266_2/dp/post/json"; <em>// 设备上传数据点</em> <em>// 定义组件</em> BlinkerButton lamp1_button("lamp1_button"); <em>// 客厅灯</em> BlinkerButton lamp2_button("lamp2_button"); <em>// 卧室一灯</em> BlinkerButton lamp3_button("lamp3_button"); <em>// 卧室二灯</em> BlinkerNumber HUMI("humi"); <em>// 湿度</em> BlinkerNumber TEMP("temp"); <em>// 温度</em> #define lamp1_relay D1 <em>// 灯泡1继电器</em> #define lamp2_relay D2 <em>// 灯泡2继电器</em> #define lamp3_relay D5 <em>// 灯泡3继电器</em> int lamp1_state = 0; <em>// 灯泡1状态</em> int lamp2_state = 0; <em>// 灯泡2状态</em> int lamp3_state = 0; <em>// 灯泡3状态</em> #define DHTPIN D6 <em>// 温湿度传感器引脚</em> #define DHTTYPE DHT11 <em>// 温湿度传感器型号DHT11</em> DHT dht(DHTPIN, DHTTYPE); <em>// 预加载温湿度传感器</em> float humi_read = 0, temp_read = 0; <em>// 温度湿度的值</em> #define RECV_PIN D7 <em>// 红外模块引脚</em> IRrecv irrecv(RECV_PIN); <em>// 红外遥控初始化</em> decode_results results; <em>// 储存接收到的红外遥控信息</em> <em>// 连接wifi的函数</em> void connectWifi(){ WiFi.begin(ssid, pswd); <em>//等待WiFi连接,成功连接后输出成功信息</em> while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } Serial.println(""); Serial.println("WiFi Connected!"); Serial.println(""); } <em>// 连接MQTT服务器</em> void connectMQTTserver(){ if (mqttClient.connect(client_ID, mqttUserName, mqttPassword)) { Serial.print("MQTT Server Connected. ClientId: "); Serial.println(id_num); Serial.print("MQTT Server: "); Serial.println(mqttServer); } else { Serial.print("MQTT Server Connect Failed. Client State:"); Serial.println(mqttClient.state()); } } void setup(){ pinMode(lamp1_relay, OUTPUT); <em>// 灯1引脚</em> pinMode(lamp2_relay, OUTPUT); <em>// 灯2引脚</em> pinMode(lamp3_relay, OUTPUT); <em>// 灯3引脚</em> BLINKER_DEBUG.stream(Serial); <em>// 串口输出调试信息</em> BLINKER_DEBUG.debugAll(); <em>// 显示更多调试信息</em> Blinker.begin(auth, ssid, pswd); <em>// 设备上线</em> irrecv.enableIRIn(); <em>// 启动红外接收</em> Blinker.attachData(dataRead); <em>// 注册未知指令回调函数</em> <em>// 可不可以传参???三个函数功能是一样的,但需要传参控制不同的灯</em> lamp1_button.attach(lamp1_switch); <em>// 注册灯1组件回调函数</em> lamp2_button.attach(lamp2_switch); <em>// 注册灯1组件回调函数</em> lamp3_button.attach(lamp3_switch); <em>// 注册灯1组件回调函数</em> BlinkerMIOT.attachMode(miotMode); <em>// 绑定模式函数,通过模式来控制三盏灯</em> Blinker.attachHeartbeat(heartbeat); <em>// 绑定心跳包函数</em> dht.begin(); <em>// 执行DHT库</em> <em>//设置为无线终端模式</em> WiFi.mode(WIFI_STA); <em>// 连接WiFi</em> connectWifi(); <em>// 设置MQTT服务器和端口号</em> mqttClient.setServer(mqttServer, 1883); <em>// 明文模式</em> Serial.begin(9600); } void loop(){ Blinker.run(); float h = dht.readHumidity(); <em>// 用dht库读取湿度数据</em> float t = dht.readTemperature(); <em>// 用dht库读取温度数据</em> if (isnan(h) || isnan(t)) <em>// 如果数据有缺失</em> { BLINKER_LOG("Failed to read from DHT sensor!"); <em>// 输出调试信息</em> } else { BLINKER_LOG("Humidity: ", h, " %"); <em>// 串口输出湿度</em> BLINKER_LOG("Temperature: ", t, " *C"); <em>// 串口输出温度</em> humi_read = h; <em>// 心跳包发送湿度</em> temp_read = t; <em>// 心跳包发送温度</em> } if (irrecv.decode()){ <em>// 如果接收到遥控信号</em> if (irrecv.decodedIRData.command == 0x92){ <em>// 接收到的数据command为 0x92</em> lamp1_switch("tap"); <em>// 调用按钮组件函数</em> }else if(irrecv.decodedIRData.command == 0x93){ lamp2_switch("tap"); }else if(irrecv.decodedIRData.command == 0xCC) lamp3_switch("tap"); } irrecv.resume(); <em>// 恢复接收下一个红外遥控信号</em> delay(200); <em>// 如果MQTT未连接,则尝试连接服务器</em> if (!mqttClient.connected()) { connectMQTTserver(); } <em>// 处理信息以及心跳</em> mqttClient.loop(); snprintf(postData, 100, dataTemplate, id_num, temp_read, humi_read); <em>// 1分钟发送一次数据</em> long now = millis(); if (now - lastMsg > 60000) { id_num++; lastMsg = now; Serial.print("Publish message: "); Serial.println(postData); mqttClient.publish(topic, (uint8_t *)postData, strlen(postData)); } } void heartbeat() <em>// 心跳包函数,发送数据给app</em> { HUMI.print(humi_read); <em>// 发送数据给湿度组件</em> TEMP.print(temp_read); <em>// 发送数据给温度组件</em> } <em>// 切换模式的函数,用来控制多路设备</em> void miotMode(uint8_t mode) { BLINKER_LOG("need set mode: ", mode); if (mode == BLINKER_CMD_MIOT_DAY) { <em>// 日光模式,训练小爱“打开客厅的灯”执行“灯设置为日光模式”</em> digitalWrite(lamp1_relay, HIGH); <em>// 执行打开灯1</em> lamp1_button.print(); <em>// 反馈状态给手机app</em> BlinkerMIOT.powerState("on"); <em>// 发反馈状态给小爱</em> BlinkerMIOT.print(); } else if (mode == BLINKER_CMD_MIOT_NIGHT) { <em>// 月光模式,训练小爱“关闭客厅的灯”执行“灯设置为月光模式”</em> digitalWrite(lamp1_relay, LOW); <em>// 执行关闭灯1</em> lamp1_button.print(); <em>// 反馈状态给手机app</em> BlinkerMIOT.powerState("off"); <em>// 发反馈状态给小爱</em> BlinkerMIOT.print(); } else if (mode == BLINKER_CMD_MIOT_COLOR) { <em>// 彩光模式,训练小爱“打开昊熙的灯”执行“灯设置为彩光模式”</em> digitalWrite(lamp2_relay, HIGH); <em>// 执行打开灯2</em> lamp2_button.print(); <em>// 反馈状态给手机app</em> BlinkerMIOT.powerState("on"); <em>// 发反馈状态给小爱</em> BlinkerMIOT.print(); } else if (mode == BLINKER_CMD_MIOT_WARMTH) { <em>// 温馨模式,训练小爱“关闭昊熙的灯”执行“灯设置为温馨模式”</em> digitalWrite(lamp2_relay, LOW); <em>// 执行关闭灯2</em> lamp2_button.print(); <em>// 反馈状态给手机app</em> BlinkerMIOT.powerState("off"); <em>// 发反馈状态给小爱</em> BlinkerMIOT.print(); } else if (mode == BLINKER_CMD_MIOT_TV) { <em>// 电视模式,训练小爱“打开卧室的灯”执行“灯设置为电视模式”</em> digitalWrite(lamp3_relay, HIGH); <em>// 执行打开灯3</em> lamp3_button.print(); <em>// 反馈状态给手机app</em> BlinkerMIOT.powerState("on"); <em>// 发反馈状态给小爱</em> BlinkerMIOT.print(); } else if (mode == BLINKER_CMD_MIOT_READING) { <em>// 阅读模式,训练小爱“关闭卧室的灯”执行“灯设置为阅读模式”</em> digitalWrite(lamp3_relay, LOW); <em>// 执行关闭灯3</em> lamp3_button.print(); <em>// 反馈状态给手机app</em> BlinkerMIOT.powerState("off"); <em>// 发反馈状态给小爱</em> BlinkerMIOT.print(); } else if (mode == BLINKER_CMD_MIOT_COMPUTER) { <em>// Your mode function</em> } } <em>// 灯1组件函数</em> void lamp1_switch(const String & state){ digitalWrite(lamp1_relay, !digitalRead(lamp1_relay)); lamp1_state = !lamp1_state; <em>// 状态取反</em> BLINKER_LOG("灯1指令: ", state); lamp1_button.print(); <em>// 反馈状态给手机app</em> BlinkerMIOT.powerState(lamp1_state ? "on" : "off"); <em>// 发反馈状态给小爱</em> BlinkerMIOT.print(); } <em>// 灯2组件函数</em> void lamp2_switch(const String & state){ digitalWrite(lamp2_relay, !digitalRead(lamp2_relay)); lamp2_state = !lamp2_state; <em>// 状态取反</em> BLINKER_LOG("灯2指令: ", state); lamp2_button.print(); <em>// 反馈状态给手机app</em> BlinkerMIOT.powerState(lamp2_state ? "on" : "off"); <em>// 发反馈状态给小爱</em> BlinkerMIOT.print(); } <em>// 灯3组件函数</em> void lamp3_switch(const String & state){ digitalWrite(lamp3_relay, !digitalRead(lamp3_relay)); lamp3_state = !lamp3_state; <em>// 状态取反</em> BLINKER_LOG("灯1指令: ", state); lamp3_button.print(); <em>// 反馈状态给手机app</em> BlinkerMIOT.powerState(lamp3_state ? "on" : "off"); <em>// 发反馈状态给小爱</em> BlinkerMIOT.print(); } <em>// 无绑定函数时执行</em> void dataRead(const String & data) { BLINKER_LOG("接收到未知指令: ", data); Blinker.vibrate(); uint32_t BlinkerTime = millis(); Blinker.print("运行时间", BlinkerTime); } |
近期评论