查看: 35309|回复: 10

[7月赛] 【开源盛世】智能家居之智慧寝室

[复制链接]

2

主题

6

帖子

34

积分

新手上路

Rank: 1

积分
34
发表于 2017-7-15 15:25:28 | 显示全部楼层 |阅读模式
本帖最后由 Fan_MingLei 于 2018-2-13 16:36 编辑

【个人简介】:物联网专业在校学生
【项目介绍】:整套装置能够实现远程监控室内各项数据,也能够远程操控室内的一些电器,还提供了一些语音报警的功能、防盗功能、天气预报等功能。
废话不多说直接进入正题

所需硬件材料:Arduino Mega 2560、ESP8266、语音模块、串口屏、DTH11传感器、MQ-2传感器、SR501传感器、火焰传感器、光敏传感器、红外发射模块、红外接收模块、继电器*2、红外遥控器、开关、杜邦线若干

下面分别对主要几个功能做简要的说明:

1:天气预报功能

主要是从网上获取天气信息,这里需要用到心知天气的API,通过WiFi模块发送请求,并接受返回数据加以解析就能得到所需天气信息

下面简单的介绍一下心知天气的API
这个链接是获取实时天气状况
https://api.seniverse.com/v3/weather/now.json?key=APIPASSWORD&location=地址&language=返回的数据语言格式&unit=温度单位
黑色加粗的部分是需要根据自己情况进行修改的。
当发送正确的请求后将会收到服务器返回的json数据
{"results":[{"location":{"id":"WX4FBXXFKE4F","name":"北京","country":"CN","path":"北京,北京,中国","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"now":{"text":"多云","code":"4","temperature":"25"},"last_update":"2017-04-14T12:20:00+08:00"}]}
黑色加粗就是我们需要解析的天气信息,然后使用ArduinoJson库进行解析
  1. while (!doCmdOk("AT+CIPMODE=1", "OK"));
  2. while (!doCmdOk("AT+CIPSTART=\"TCP\",\"116.62.81.138\",80", "CONNECT"));
  3. while (!doCmdOk("AT+CIPSEND", ">"));

  4. Serial1.println("GET /v3/weather/now.json?key=9l3kb1dgowaobqi4&location=zhengzhou&language=en&unit=c");
  5. String httpData = Serial1.readString();
  6. //Serial.println(httpData);
  7. data = httpData.substring((httpData.indexOf("\"now\":") + 6), httpData.indexOf(",\"last"));
  8. Dy**onBuffer jsonBuffer0;
  9. JsonObject& root0 = jsonBuffer0.parseObject(data);
  10. temperature = root0[String("temperature")];
  11. code = root0[String("code")];
  12. delay(100);
复制代码

然后就是获取未来三天的天气信息,原理都一样,有了上面的基础就简单多了这一次我们还需要从另外的地址获取更多的信息。
https://api.seniverse.com/v3/weather/daily.json?key=APIPASSWORD&location=地址&language=返回的数据语言格式&unit=温度单位&start=起始时间(0:当天、1明天···)&days=获取多少天的信息(从起始时间开始,免费的最多只有三天)

返回数据如下
{"results":[{"location":{"id":"WX4FBXXFKE4F","name":"Beijing","country":"CN","path":"Beijing,Beijing,China","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"daily":[{"date":"20170417","text_day":"Cloudy","code_day":"4","text_night":"Cloudy","code_night":"4","high":"27","low":"13","precip":"","wind_direction":"SW","wind_direction_degree":"225","wind_speed":"15","wind_scale":"3"}],"last_update":"2017-04-17T18:00:00+08:00"}]}这次还是需要用到json库,不过需要解析出更多的数据


  1. Dy**onBuffer jsonBuffer1;
  2.   JsonObject& root1 = jsonBuffer1.parseObject(data_day1);
  3.   date1 = root1[("date")].as<String>();
  4.   temperature_low_day1 = root1[String("low")];
  5.   temperature_high_day1 = root1[String("high")];
  6.   code_day1 = root1[String("code_day")];
  7.   code_night1 = root1[String("code_night")];
  8.   wind_direction_day1 = root1[("wind_direction")].as<String>();
  9.   wind_scale_day1 = root1[String("wind_scale")];
复制代码

当我们获取所有信息之后就需要往串口屏的组件发送相应的数据
9.png
当然屏幕的固件已经编写好了,在最后我会上传的
最终的效果图:

8.png
最后应该还有获取天气指数的,但是再说下去感觉太啰嗦了,你们还是看看代码了解一下吧,原理都一样。
天气功能的介绍到这也差不多了。。。。

2:语音播放模块

使用的是普通的串口模块,通过串口发送指令播放相应的语音即可,当然语音需要提前在电脑合成再存入SD卡中(PS:来来回回合成了将近2000个语音。。。贴心的我当然不会让你们一个个合成了
貌似这个功能没有什么好讲的了。。。。。。。。
简单介绍一下其中的一些函数吧,具体的命令还是看卖家给的资料吧[size=18**]http://pan.baidu.com/s/1geJNbMV
  1. void Voice_Class::playWeather()
  2. {
  3.   buf[3] = 3;
  4.   buf[4] = code;
  5.   if (digitalRead(13) == 1)
  6.   {
  7.     for (int i = 0 ; i < 7 ; i++)
  8.       Serial2.write(buf[i]);
  9.   }
  10.   buf[3] = 4;
  11.   if (temperature_high_day1 < 0)
  12.     buf[4] = (100 - temperature_high_day1);
  13.   else
  14.     buf[4] = temperature_high_day1;
  15.   if (digitalRead(13) == 1)
  16.   {
  17.     for (int i = 0 ; i < 7 ; i++)
  18.       Serial2.write(buf[i]);
  19.   }
  20.   buf[3] = 5;
  21.   if (temperature_low_day1 < 0)
  22.     buf[4] = (100 - temperature_low_day1);
  23.   else
  24.     buf[4] = temperature_low_day1;
  25.   if (digitalRead(13) == 1)
  26.   {
  27.     for (int i = 0 ; i < 7 ; i++)
  28.       Serial2.write(buf[i]);
  29.   }
  30.   buf[3] = 6;
  31.   if (wind_direction_day1.indexOf("CLM") == 0)
  32.     buf[4] = 0;
  33.   if (wind_direction_day1.indexOf("E") == 0)
  34.     buf[4] = 1;
  35.   if (wind_direction_day1.indexOf("S") == 0)
  36.     buf[4] = 2;
  37.   if (wind_direction_day1.indexOf("W") == 0)
  38.     buf[4] = 3;
  39.   if (wind_direction_day1.indexOf("N") == 0)
  40.     buf[4] = 4;
  41.   if (wind_direction_day1.indexOf("ES") == 0 || wind_direction_day1.indexOf("SE") == 0)
  42.     buf[4] = 5;
  43.   if (wind_direction_day1.indexOf("EN") == 0 || wind_direction_day1.indexOf("NE") == 0)
  44.     buf[4] = 6;
  45.   if (wind_direction_day1.indexOf("WS") == 0 || wind_direction_day1.indexOf("SW") == 0)
  46.     buf[4] = 7;
  47.   if (wind_direction_day1.indexOf("WN") == 0 || wind_direction_day1.indexOf("NW") == 0)
  48.     buf[4] = 8;
  49.   if (digitalRead(13) == 1)
  50.   {
  51.     for (int i = 0 ; i < 7 ; i++)
  52.       Serial2.write(buf[i]);
  53.   }
  54.   buf[3] = 7;
  55.   buf[4] = wind_scale_day1;
  56.   if (digitalRead(13) == 1)
  57.   {
  58.     for (int i = 0 ; i < 7 ; i++)
  59.       Serial2.write(buf[i]);
  60.   }
  61.   buf[3] = 11;
  62.   if (temperature < 0)
  63.     buf[4] = 100 - temperature;
  64.   else
  65.     buf[4] = temperature;
  66.   if (digitalRead(13) == 1)
  67.   {
  68.     for (int i = 0 ; i < 7 ; i++)
  69.       Serial2.write(buf[i]);
  70.   }
  71. }
复制代码

3:电器的远程遥控这部分包括三种:1通过屏幕点击、2通过红外遥控器、3通过OneNet平台远程遥控

1:屏幕点击遥控:通过点击屏幕返回相应的数值来实现的
  1. if (Serial3.available() > 0)
  2.         {
  3.           int Switch = Serial3.read();
  4.           Serial.println(Switch);
  5.           if (Switch == 10)
  6.             Switch3.Control(9, 0);      //关灯
  7.           if (Switch == 11)
  8.             Switch3.Control(9, 1);      //开灯
  9.           if (Switch == 20)
  10.             Switch3.Control(10, 0);     //关闭
  11.           if (Switch == 21)
  12.             Switch3.Control(10, 1);     //打开
  13.           if (Switch == 31)
  14.             **1 = 1;                   //打开离家模式
  15.           if (Switch == 30)
  16.           {
  17.             **1 = 0;                   //关闭离家模式
  18.             **2 = 1;
  19.             **3 = 1;
  20.             **4 = 0;
  21.             Voice3.play(10, 5);
  22.           }

  23.           if (Switch > 50)
  24.             break;
  25.         }
复制代码

2:红外遥控 :用到了Arduino的IRremote库,接收红外遥控器发出的信息作出相应的判断
  1. int Infrared_Class::Control()
  2. {
  3.   if (irrecv.decode(&results))
  4.   {
  5.     if (results.value == Key1 )
  6.       Switch1.Control(9, 1);
  7.     if (results.value == Key2)
  8.       Switch1.Control(9, 0);
  9.     if (results.value == Key3)
  10.     {
  11.       Voice1.playTemHum();
  12.       Display1.showTemHum();
  13.     }
  14.     if (results.value == Key4)
  15.     {
  16.       Display1.showWeather();
  17.       Voice1.playWeather();
  18.     }
  19.     if (results.value == Key5)
  20.     {
  21.       **1 = 1;
  22.     }
  23.     if (results.value == Key6)
  24.     {
  25.       **1 = 0;
  26.       Voice1.play(10, 5);
  27.       **2 = 1;                       //重置,让下一次开启时播放提示语音
  28.       **3 = 1;
  29.       **4 = 0;
  30.     }
  31.     if (results.value == Key7)
  32.       Switch1.Control(10, 1);
  33.     if (results.value == Key8)
  34.       Switch1.Control(10, 0);
  35.     if (results.value == Key9)
  36.     {
  37.       //Voice
  38.     }
  39.     if (results.value == UP)
  40.       Voice1.VolumeUP();
  41.     if (results.value == Reduce)
  42.       Voice1.VolumeReduce();
  43.     Serial.println(results.value);
  44.     irrecv.resume();                    // 接收下一次数值
  45.   }
复制代码
3 OneNet平台的远程遥控:使用的是EDP协议
  1. void WiFi_Class::Control()
  2. {
  3.   edp_pkt rcv_pkt;
  4.   while (Serial1.available())
  5.   {
  6.     readEdpPkt(&rcv_pkt);
  7.     if (isEdpPkt(&rcv_pkt))
  8.     {
  9.       pkt_type = rcv_pkt.data[0];
  10.       switch (pkt_type)
  11.       {
  12.         case CMDREQ:
  13.           char edp_command[50];
  14.           char edp_cmd_id[40];
  15.           long id_len, cmd_len, rm_len;
  16.           char datastr[20];
  17.           char val[10];
  18.           memset(edp_command, 0, sizeof(edp_command));
  19.           memset(edp_cmd_id, 0, sizeof(edp_cmd_id));
  20.           edpCommandReqParse(&rcv_pkt, edp_cmd_id, edp_command, &rm_len, &id_len, &cmd_len);  //解析数据
  21.           sscanf(edp_command, "%[^:]:%s", datastr, val);              //格式化读取
  22.           if (strcmp(datastr, "SwitchLED") == 0)                      //判断是哪个指令
  23.           {
  24.             if (atoi(val) == 1)
  25.             {
  26.               Switch2.Control(9, 1);                  // 打开LED
  27.               Voice2.play(10, 7);
  28.             }
  29.             if (atoi(val) == 0)
  30.             {
  31.               Switch2.Control(9, 0);                  // 关闭LED
  32.               Voice2.play(10, 8);
  33.             }
  34.           }
  35.           if (strcmp(datastr, "SwitchPIN") == 0)
  36.           {
  37.             if (atoi(val) == 1)
  38.             {
  39.               Switch2.Control(10, 1);                   // 打开
  40.               Voice2.play(10, 10);
  41.             }
  42.             if (atoi(val) == 0)
  43.             {
  44.               Switch2.Control(10, 0);                    // 关闭
  45.               Voice2.play(10, 9);
  46.             }
  47.           }
  48.           if (strcmp(datastr, "Conditioner") == 0)  //   远程控制空调
  49.           {
  50.             switch (atoi(val))
  51.             {
  52.               case 24:
  53.                 Infrared2.Send();
  54.             }
  55.           }
  56.           if (strcmp(datastr, "Control1") == 0)  //   回家模式
  57.           {
  58.             if (atoi(val) == 1)
  59.             {
  60.               **1 = 0;
  61.               Voice2.play(10, 5);
  62.               **2 = 1;                       //重置,让下一次开启时播放提示语音
  63.               **3 = 1;
  64.               **4 = 0;
  65.               //Infrared2.Send()               //这里可以选择是否自动开启空调
  66.             }
  67.           }
  68.           if (strcmp(datastr, "Control2") == 0)  //  离家模式
  69.           {
  70.             if (atoi(val) == 1)
  71.             {
  72.               **1 = 1;
  73.             }
  74.           }
  75.           Serial.print(datastr); Serial.println(val);
  76.           packetSend(packetDataSaveTrans(NULL, datastr, val)); //将新数据值上传至数据流
  77.           break;
  78.         default:
  79.           Serial.print("unknown type: ");
  80.           Serial.println(pkt_type, HEX);
  81.           break;
  82.       }
  83.     }
  84.   }
  85.   if (rcv_pkt.len > 0)
  86.     packetClear(&rcv_pkt);
  87.   delay(150);
  88. }
复制代码

4其他:
   除了上面几个主要的功能还有一些其他的小功能就不再一一详述了,简单的介绍一下,至于怎么实现的可以看看源码(注释应该还算详细)
  1、离家模式:首先需要通过屏幕、遥控器或者OneNet平台设置一下,开启这个功能,当开启的时候会有语音提醒的,并且会根据当时的天气提醒你携带雨伞、注意防晒等。功能开启后装置会检测有人是否外出,有人外出装置会自动开启防盗功能,并且关闭所有的开关。防盗功能开启后再检测到有人进入时是有语音报警的,并且会上传数据到OneNet平台通过触发器的方式远程通知用户。当然也可以通过上面的几种方式取消离家模式和防盗功能的。
  2、火情监控:系统会不断的扫描传感器的数据当火焰传感器、烟雾传感器到达阈值的时候会有相应的语音报警的,也会通过触发器远程的通知到用户的。
  3、传感器的数据会每隔3秒向OneNet平台上传,方便用户能够远程查看,当然系统也会根据这些数据做一些自己的操作,如光线过暗的时候会自己开启灯光的(PS:学生寝室没什么能控制的电器,只能做到这个地步了,预留了一个继电器接口方便以后的改进了)
  4、关于屏幕,除了显示上面哪些必要的信息还做了一些简单的界面:
菜单界面:
1.PNG

时钟界面(能够读取时钟模块的时间数据实时更新)
2.PNG

仿照OneNet平台做的温湿度显示界面
3.PNG

设置界面:
5.PNG

键盘:
6.PNG

操作界面可通过点击按钮实现一些简单的功能:
4.PNG

最后的成品图:
11.jpg

12.jpg 13.jpg

要说的就这么多了,这东西隔得时间太长了,很多细节部分也忘的差不多了,再者语言组织能力有限,很多东西也不知道怎么说清楚
本着开源精神所有的资料当然也是公开的(PS :所有的界面都是自己找图然后一张一张P出来的,语音文件来来回回合成了四五遍,真的发了很大的精力,虽然还是比较low)

具体的可以看看最后的演示视频 http://v.youku.com/v_show/id_XMj ... j.8428770.3416059.1
源码链接 喜欢的话赏个star
应用链接 https://open.iot.10086.cn/appvie ... 86ae389189ea80f69a5

报名表上不能选择【开源盛世】!!!!
希望能够在开源类评比!!!!






回复

举报

95

主题

575

帖子

2201

积分

金牌会员

Rank: 5Rank: 5

积分
2201
发表于 2018-1-10 17:04:41 | 显示全部楼层
帮贴一下作者QQ:1193589986,需要代码的可以联系作者       
1、OneNET交流群6:887624121
该群目前非常活跃,欢迎大家参与进来,交流,讨论,答疑,解惑~~

2

主题

6

帖子

34

积分

新手上路

Rank: 1

积分
34
 楼主| 发表于 2017-7-20 22:26:39 | 显示全部楼层

就以Arduino的那点性能不用串口屏能做出啥界面

1

主题

6

帖子

41

积分

新手上路

Rank: 1

积分
41
发表于 2017-10-30 19:40:20 | 显示全部楼层
想学着做一下,可是链接失效肿么办,楼主再发一下呗

26

主题

256

帖子

873

积分

高级会员

Rank: 4

积分
873
发表于 2017-7-28 10:16:13 | 显示全部楼层
Fan_MingLei 发表于 2017-7-27 22:47
对啊,总共的语音文件大概合成了450+吧

厉害了

2

主题

6

帖子

34

积分

新手上路

Rank: 1

积分
34
 楼主| 发表于 2017-7-27 22:47:43 | 显示全部楼层
chenguang3312 发表于 2017-7-26 16:51
那温度语音播报是把所有 数值都合成了一遍?

对啊,总共的语音文件大概合成了450+吧

26

主题

256

帖子

873

积分

高级会员

Rank: 4

积分
873
发表于 2017-7-26 16:51:10 | 显示全部楼层
Fan_MingLei 发表于 2017-7-20 22:26
就以Arduino的那点性能不用串口屏能做出啥界面

那温度语音播报是把所有 数值都合成了一遍?

95

主题

575

帖子

2201

积分

金牌会员

Rank: 5Rank: 5

积分
2201
发表于 2017-7-20 09:31:02 | 显示全部楼层
好的,开源盛事我们帮你记录一下
1、OneNET交流群6:887624121
该群目前非常活跃,欢迎大家参与进来,交流,讨论,答疑,解惑~~

2

主题

6

帖子

34

积分

新手上路

Rank: 1

积分
34
 楼主| 发表于 2017-7-20 22:27:22 | 显示全部楼层
cdd 发表于 2017-7-20 09:31
好的,开源盛事我们帮你记录一下

好的谢谢了

4

主题

44

帖子

101

积分

注册会员

Rank: 2

积分
101
发表于 2017-7-15 15:35:40 | 显示全部楼层
好棒好棒!!!

26

主题

256

帖子

873

积分

高级会员

Rank: 4

积分
873
发表于 2017-7-20 08:41:57 | 显示全部楼层
串口屏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表