看到最近智能家居的討論挺火,我也來分享下在智能家居這塊的體會。我主要改造了我租的房子的室燈。主要實現功能有:監控室內環境,改裝了室燈,光線暗的時候有人時自動開燈,光線亮自動滅燈,可紅外用遙控器、手機客戶端改變閾值。
材料
主控板:Arduino UNO/Mega2560(IO口多)
傳感器:光敏電阻、DHT11溫濕度傳感器、串口WIFI模塊、紅外遙控探頭、紅外人體探測器、5V繼電器(220V)
布線
室燈控制還是很簡單的,控制電源即可。
- 首先使用繼電器接管室燈的電線。
- 然后放置紅外人體探測器,我把它朝向房間門口。
- 溫濕度傳感器、光敏電阻、wifi模塊、紅外遙控探頭就比較隨意了,合理放置就行。
程序開發
Arduino開發工具官方有提供,代碼類似c語言,有很多第三方庫,開發非常容易。最讓我感到幸福的是VS也有相應的開發環境,有個插件叫做Visual Micro。
- 控制電路無非就是置數字IO口高電平或低電平。
- 光敏電阻測光很簡單,使用模擬口測電阻值,如果需要精度更高更專業的可以買專門的測光模塊。
- 通信方式多種多樣,紅外遙控、射頻、藍牙、wifi,坑爹的wp不支持藍牙串口,所以我選用的是串口wifi,使用簡單,模塊有自己的配置頁面,我配置成接入屋里的wifi網絡+模塊自建AP,并使用UDP模式發送廣播。
- 具體代碼附在下面。
原型
可以使用220v~5v變壓器,這樣就可以把主體放到燈罩里了,而且可以使用小點的板子。
擴展
Arduino這種類似積木的搭建方法非常適合咱們程序員自己DIY,不需要自己制作電路板。在這個室燈控制的基礎上咱們在擴展一下思維:
- 加上紅外發射頭就可以控制相應的紅外遙控設備,一個接收一個發射組合就是萬能遙控器,多個發射器可以防死角
- 加上常用的2.4G或者低頻段的無線模塊,就可以實現無線設備間通訊(模塊很便宜,有興趣可以嘗試鼠標、鍵盤、遙控車、航模通訊)
- 加個舵機,拉窗簾不在話下。
- 再大膽點,拆開電器找到電路板,接上線,使用Arduino的數字IO直接監控/控制電器電路板。
- 加上語音識別模塊(目前的貌似都不太理想,相對Arduino有些重,這活交給家庭網關或者手機比較好)語音控制電器。
Arduino可以方便的實現控制電源、控制/監控帶電路控制的電器的電路板。
憧憬一下當WP的Cortana成熟的時候,這些設備控制,Cortana都能根據我的習慣自動搞定,并支持語音控制,全時待命,未來生活啊~
最后附上我的Arduino代碼:
- #include <EEPROM.h>
- #include <IRremote.h>
- #include <dht11.h>
- //UNO
- //#define GM_dpin A5 //光敏電阻
- //#define dht_dpin 2 //溫濕度傳感器
- //#define wifiRx_dpin 5 //WIFI接收Rx
- //#define wifiTx_dpin 6 //WIFI發送Tx
- //#define HW_dpin 8 //紅外遙控探頭
- //#define RSensor_dpin 10 //紅外探測器人
- //#define jdq_dpin 11 //繼電器
- //#define light_dpin 13 //指示燈
- //2560
- #define GM_dpin A15 //光敏電阻
- //#define wifiTx_dpin 10 //WIFI發送Rx
- //#define wifiRx_dpin 11 //WIFI接收Tx
- #define dht_dpin 21 //溫濕度傳感器
- #define HW_dpin 22 //紅外遙控探頭
- #define RSensor_dpin 23 //紅外探測器人
- #define jdq_dpin 29 //繼電器
- #define light_dpin 13 //指示燈
- int ADZ = 45; //暗度閥值
- int LDZ = 175; //亮度閥值
- bool IsJDQOpend = false;
- bool IsAutoOpen = false;
- bool IsPause = false;
- IRrecv irrecv(HW_dpin);
- decode_results results;
- dht11 DHT;
- //SoftwareSerial WiFiPort(wifiRx_dpin, wifiTx_dpin);
- void InitController(){
- pinMode(jdq_dpin, OUTPUT);
- digitalWrite(jdq_dpin, LOW);
- pinMode(light_dpin, OUTPUT);
- digitalWrite(light_dpin, LOW);
- pinMode(RSensor_dpin, INPUT);
- pinMode(GM_dpin, INPUT);
- }
- void closeLight(){
- digitalWrite(light_dpin, LOW);
- digitalWrite(jdq_dpin, LOW);
- IsJDQOpend = false;
- IsAutoOpen = false;
- delay(2000);
- }
- void openLight(){
- digitalWrite(light_dpin, HIGH);
- digitalWrite(jdq_dpin, HIGH);
- IsJDQOpend = true;
- delay(2000);
- }
- void makePause(){
- IsPause = !IsPause;
- if (IsPause){
- for (int i = 0; i < 5; i++)
- {
- digitalWrite(light_dpin, HIGH);
- delay(100);
- digitalWrite(light_dpin, LOW);
- delay(100);
- }
- }
- else{
- digitalWrite(light_dpin, HIGH);
- delay(1000);
- digitalWrite(light_dpin, LOW);
- }
- }
- //室燈控制器
- void LightController(){
- //接收紅外遙控器信號
- if (irrecv.decode(&results)) {
- Serial.println(results.value, HEX);
- if (results.value == 0xFFA25D){
- //關燈
- closeLight();
- }
- if (results.value == 0xFFE21D){
- //開燈
- openLight();
- }
- if (results.value == 0xFFC23D){
- //暫停
- makePause();
- }
- irrecv.resume();
- }
- if (IsPause)return;
- //光敏電阻判斷室內亮度
- int valx = analogRead(GM_dpin);
- //Serial.println(valx);
- if (valx < ADZ){
- //繼電器如果是關的
- if (!IsJDQOpend){
- //紅外人體檢測
- int val = digitalRead(RSensor_dpin);
- if (val == 1)
- {
- //開燈
- openLight();
- IsAutoOpen = true;
- }
- else
- {
- return;
- }
- }
- }
- else{
- if (valx > LDZ && IsJDQOpend && IsAutoOpen){
- valx = analogRead(GM_dpin);
- if (valx <= LDZ)return;
- //環境亮,關燈
- closeLight();
- }
- }
- }
- void setup(){
- byte value = EEPROM.read(1);
- if (value != 255)ADZ = value;
- value = EEPROM.read(2);
- if (value != 255)LDZ = value;
- Serial.begin(115200);
- Serial3.begin(115200);
- InitController();
- irrecv.enableIRIn();
- delay(500);
- Serial.println();
- Serial.println("[---ZZY Hareware Startup---]");
- }
- void loop(){
- LightController();
- InfoQuery();
- GetCommand();
- }
- long timespan;
- void InfoQuery(){
- unsigned long t = (micros() - timespan) / 1000000;
- if (t < 1)return;
- timespan = micros();
- //信息查詢
- //光控信息
- int valx = analogRead(GM_dpin);
- //溫濕度傳感器
- DHT.read(dht_dpin);
- String msg = "VMZClub_Home HTP H";
- msg += DHT.humidity;
- msg += "T";
- msg += DHT.temperature;
- msg += "L";
- msg += valx;
- msg += "S";
- msg += IsJDQOpend;
- msg += "P";
- msg += IsPause;
- msg += "F";
- msg += ADZ;
- msg += "/";
- msg += LDZ;
- Serial3.print(msg);
- Serial.println(msg);
- }
- void GetCommand(){
- int cmd[10] = { -1 };
- for (int i = 0; i < 10; i++)
- {
- cmd[i] = Serial3.read();
- if (cmd[i] == -1)break;
- Serial.println((char) cmd[i]);
- }
- if (cmd[0] == -1)return;
- switch ((char) cmd[0])
- {
- case 'L':
- switch (cmd[1])
- {
- case '0':
- closeLight();
- break;
- case '1':
- openLight();
- break;
- }
- break;
- case 'P':
- switch (cmd[1])
- {
- case '0':
- IsPause = false;
- break;
- case '1':
- IsPause = true;
- break;
- }
- break;
- case 'F':
- switch (cmd[1])
- {
- case'A':
- if (cmd[2] != -1) {
- ADZ = cmd[2];
- EEPROM.write(1, ADZ);
- }
- break;
- case'L':
- if (cmd[2] != -1){
- LDZ = cmd[2];
- EEPROM.write(2, LDZ);
- }
- break;
- }
- break;
- }
- }
本文來自:http://www.cnblogs.com/zhang740/p/3785600.html