• 适合程序员的智能家居


    前言

    看到最近智能家居的讨论挺火,我也来分享下在智能家居这块的体会。我主要改造了我租的房子的室灯。主要实现功能有:监控室内环境,改装了室灯,光线暗的时候有人时自动开灯,光线亮自动灭灯,可红外用遥控器、手机客户端改变阈值。

    材料

    主控板: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;
        }
    }

  • 相关阅读:
    第7.10节 Python类中的实例变量定义与使用
    第7.9节 案例详解:Python类封装
    第7.8节 Python中隐秘的类封装方法
    第7.7节 案例详解:Python类继承机制
    第7.6节 Python中类的继承机制详述
    第7.5节 揭开Python类中self的面纱
    第7.4节 Python中与众不同的类
    第7.3节 Python特色的面向对象设计:协议、多态及鸭子类型
    第7.2节 关于面向对象设计的一些思考
    (独孤九剑)--流程控制
  • 原文地址:https://www.cnblogs.com/zhang740/p/3785600.html
Copyright © 2020-2023  润新知