查看: 379|回复: 0

[分享] 让家里的空调也能远程控制

[复制链接]
  • TA的每日心情
    无聊
    2019-12-6 10:02
  • 签到天数: 13 天

    [LV.3]偶尔看看II

    发表于 2019-12-4 15:55 | 显示全部楼层 |阅读模式
    让家里的空调也能远程控制
    我们这里借用点灯科技的bliker平台(平台地址https://diandeng.tech/home)(侵删)
    使用到的硬件有:  
    • 智能音箱(小爱同学,天猫精灵,小度等)
    • 8266(nodemcu)
    • 红外发射模块
    • 空调(我这里使用的格力)
    (本帖主自己使用的是小爱同学)

    使用到的软件有:
    arduinoIDE
    8266开发版,
    8266IRremote库(库地址:https://github.com/crankyoldgit/IRremoteESP8266)
    如有基础不会的请到arduino中文社区学习:https://www.arduino.cn/thread-1066-1-1.html

    好了,废话不多说,直接进入主题
    连线指南  8266(nodemcu)         模块
                    GPIO16                          S(数据)
                    VCC                                VCC
                    GND                              GND

    由于品牌红外协议不一致我们使用通用协议来测试家里的空调具体是用的什么协议

    8266IRremote库中给我提供了一个测试通用协议的示例CommonAcControl(作用是测试协议是否可以控制你所想的空调,如果他能控制你会看到空调打开5秒后关闭
    方便我们了解我们自己的空调是什么协议,我们查看使用的协议
    这里我们只需要协议在库中的具体序号就行
    然后将CommonAcControl示例上载到我们的8266
    完成之后打开串口调试信息,并将连接好的模块对着空调
    帖主经过测试
    格力控制协议序号为18
    aux控制协议序号为44




    拿到序号更改红外引脚

    kittenblock中小学创客名师推荐的图形化编程软件

    //设置空调厂商(18格力,48aux)
    int firm = 18;

    在blinker客户端添加一个设备
    然后添加如图所示的组件

    所有组件的key如下图所示

    并且更改你的设备auth,WiFi名称,WiFi密码

    kittenblock中小学创客名师推荐的图形化编程软件

    //WIFI基础信息
    
    char auth[] = "864123441048";//将改为你自己的设备auth
    char ssid[] = "WiFi";//你的WiFi名称
    char pswd[] = "12345678";//你的WiFi密码



    程序完整代码

    kittenblock中小学创客名师推荐的图形化编程软件

    
    #define BLINKER_MIOT_OUTLET
    #define BLINKER_WIFI
    
    #include <Blinker.h>
    //红外使用库
    #include <Arduino.h>
    #include <IRremoteESP8266.h>
    #include <IRsend.h>
    #include <IRac.h>
    #include <IRutils.h>
    
    int ledPin=2;
    
    //WIFI基础信息
    
    char auth[] = "864123441048";//将改为你自己的设备auth
    char ssid[] = "WiFi";//你的WiFi名称
    char pswd[] = "12345678";//你的WiFi密码
    
    
    
    //设置空调厂商(18格力,48aux)
    int firm = 18;
    
    //红外模块连接引脚D0
    const uint16_t kIrLed = 16;  // ESP8266 GPIO pin to use. Recommended: 16 (D0).
    IRac ac(kIrLed);  // Create a A/C object using GPIO to sending messages with.
    stdAc::state_t state;  // Where we will store the desired state of the A/C.
    stdAc::state_t prev;  // Where we will store the previous state of the A/C.
    
    
    //#define powerac "ButtonKey"
    //#define healthac "ButtonKey"
    //#define sethump "SliderKey"
    
    int countSetMode = 0;
    int countFan = 0;
    uint8_t lastSetMode;
    uint8_t lastSetFan;
    uint8_t twoLastSetMode;
    uint8_t twoLastSetFan;
    
    bool tab[5] = { false };
    bool tab1[5] = { false };
    bool tabSetMode[5] = { false };
    bool tabSetFan[5] = { false };
    
    BlinkerButton ButtonPower("powerac");
    BlinkerButton ButtonHealth("healthac");
    BlinkerSlider SliderHump("sethump");
    
    BlinkerTab setModeTab("setmode");
    BlinkerTab setSpeedTab("setspeed");
    
    
    bool oState = false;
    
    void miotPowerState(const String & state)
    {
        BLINKER_LOG("need set power state: ", state);
    
        if (state == BLINKER_CMD_ON) {
            digitalWrite(LED_BUILTIN, HIGH);
             powerOn();
            BlinkerMIOT.powerState("on");
            BlinkerMIOT.print();
    
            oState = true;
        }
        else if (state == BLINKER_CMD_OFF) {
            digitalWrite(LED_BUILTIN, LOW);
             powerOff();
            BlinkerMIOT.powerState("off");
            BlinkerMIOT.print();
    
            oState = false;
        }
    }
    
    void miotQuery(int32_t queryCode)
    {
        BLINKER_LOG("MIOT Query codes: ", queryCode);
    
        switch (queryCode)
        {
            case BLINKER_CMD_QUERY_ALL_NUMBER :
                BLINKER_LOG("MIOT Query All");
                BlinkerMIOT.powerState(oState ? "on" : "off");
                BlinkerMIOT.print();
                break;
            case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
                BLINKER_LOG("MIOT Query Power State");
                BlinkerMIOT.powerState(oState ? "on" : "off");
                BlinkerMIOT.print();
                break;
            default :
                BlinkerMIOT.powerState(oState ? "on" : "off");
                BlinkerMIOT.print();
                break;
        }
    }
    
    
    
    
    
    void buttonPower_callback(const String & state)
    {
      ledState();
      BLINKER_LOG("get buttonPower state: ", state);
    
      if (state == BLINKER_CMD_ON) {
        BLINKER_LOG("power on!");
        powerOn();
        //    ButtonPower.icon("icon_1");
        ButtonPower.color("#008000");
        ButtonPower.text("on  power");
        // ButtonPower.text("Your button name", "describe");
        ButtonPower.print("on");
      }
      else if (state == BLINKER_CMD_OFF) {
        BLINKER_LOG("power off!");
        powerOff();
        //    ButtonPower.icon("icon_1");
        ButtonPower.color("#FF0000");
        ButtonPower.text("off power");
        // ButtonPower.text("Your button name", "describe");
        ButtonPower.print("off");
      }
      else {
        BLINKER_LOG("Get user setting  buttonPower: ", state);
    
        //    ButtonPower.icon("icon_1");
        ButtonPower.color("#FFFFFF");
        ButtonPower.text("Your button name or describe");
        // ButtonPower.text("Your button name", "describe");
        ButtonPower.print();
      }
    }
    
    void buttonHealth_callback(const String & state)
    {
      ledState();
      BLINKER_LOG("get buttonHealth state: ", state);
    
      if (state == BLINKER_CMD_ON) {
        BLINKER_LOG("buttonHealth on!");
        healthOn();
        //    ButtonHealth.icon("icon_1");
        ButtonHealth.color("#008000");
        ButtonHealth.text("on Health");
        // ButtonHealth.text("Your button name", "describe");
        ButtonHealth.print("on");
      }
      else if (state == BLINKER_CMD_OFF) {
        BLINKER_LOG("buttonHealth off!");
        healthOff();
        //    ButtonHealth.icon("icon_1");
        ButtonHealth.color("#FF0000");
        ButtonHealth.text("off health");
        // ButtonHealth.text("Your button name", "describe");
        ButtonHealth.print("off");
      }
      else {
        BLINKER_LOG("Get user setting buttonHealth: ", state);
    
        //    ButtonHealth.icon("icon_1");
        ButtonHealth.color("#FFFFFF");
        ButtonHealth.text("Your button name or describe");
        //ButtonHealth.text("Your button name", "describe");
        ButtonHealth.print();
      }
    }
    
    void setHump_callback(int32_t value)
    {
      ledState();
      BLINKER_LOG("get slider setHump value: ", value);
      setDegrees(value);
    
    
    }
    
    //模式按键触发
    void setMode_callback(uint8_t tab_set)
    {
      BLINKER_LOG("get setMode tab set: ", tab_set);
      
    
      switch (tab_set)
      {
        case BLINKER_CMD_TAB_0 :
          tab[0] = true;
          BLINKER_LOG("tab 0 set");
          tab[1] = false;
          tab[2] = false;
          tab[3] = false;
          tab[4] = false;
    //      setModeAuto();
          BLINKER_LOG("");
          break;
        case BLINKER_CMD_TAB_1 :
          tab[1] = true;
          BLINKER_LOG("tab 1 set");
          tab[0] = false;
          tab[2] = false;
          tab[3] = false;
          tab[4] = false;
    //      setModeCool();
          break;
        case BLINKER_CMD_TAB_2 :
          tab[2] = true;
          BLINKER_LOG("tab 2 set");
          tab[0] = false;
          tab[1] = false;
          tab[3] = false;
          tab[4] = false;
    //      setModeDry();
          break;
        case BLINKER_CMD_TAB_3 :
          tab[3] = true;
          BLINKER_LOG("tab 3 set");
          tab[0] = false;
          tab[1] = false;
          tab[2] = false;
          tab[4] = false;
    //      setModeHeat();
          break;
        case BLINKER_CMD_TAB_4 :
          tab[4] = true;
          BLINKER_LOG("tab 4 set");
          tab[0] = false;
          tab[1] = false;
          tab[2] = false;
          tab[3] = false;
    //      setModeFan();
          break;
        default:
          break;
      }
      countSetMode++;
      //Serial.print("接收指令次数:");
      //Serial.println(countSetMode);
      tabCountMode();
     
    }
    //判断多次开关触发
    
    void tabCountMode() {
    
      if (countSetMode == 1) {
        for (uint8_t one = 0; one < 5; one++) {
          tabSetMode[one] = tab[one];
    
        }
    
      } else {
        for (uint8_t num = 0; num < 5; num++)
        {
          if (tab[num])
          {
            if (lastSetMode ==num) {
            for (uint8_t one = 0; one < 5; one++) {
                 tab[one] = tabSetMode[one];
                 tabSetMode[one]=false;
    
          }
           }
          }
        }
        
      }
    
    }
    
    
    //模式按键反馈
    void setMode_feedback()
    {
      for (uint8_t num = 0; num < 5; num++)
      {
        if (tab[num])
        {
          sendMode(num);
          setModeTab.tab(num);
          lastSetMode = num;
          tab[num] = false; 
        }
    
    
      }
      setModeTab.print();
      countSetMode=0;
    }
    
    
    //设置风速
    void setSpeed_callback(uint8_t tab_set)
    {
      BLINKER_LOG("get setMode tab set: ", tab_set);
    
      switch (tab_set)
      {
        case BLINKER_CMD_TAB_0 :
          tab1[0] = true;
          BLINKER_LOG("setFanAuto");
          tab1[1] =false;    
          tab1[2] =false;
          tab1[3] =false;
          tab1[4] =false;
    //      setFanAuto();
          break;
        case BLINKER_CMD_TAB_1 :
          tab1[1] = true;
          BLINKER_LOG(" setFanMin");
          tab1[0] = false;     
          tab1[2] =false;
          tab1[3] =false;
          tab1[4] =false;
    //      setFanMin();
          break;
        case BLINKER_CMD_TAB_2 :
          tab1[2] = true;
          BLINKER_LOG("setFanLow");
           tab1[0] = false;
           tab1[1] =false;
           tab1[3] =false;
           tab1[4] =false;
    //      setFanLow();
          break;
        case BLINKER_CMD_TAB_3 :
          tab1[3] = true;
          BLINKER_LOG(" setFanMedium");
           tab1[0] = false;
           tab1[1] =false;
           tab1[2] =false;
           tab1[4] =false;
    //      setFanMedium();
          break;
        case BLINKER_CMD_TAB_4 :
          tab1[4] = true;
          BLINKER_LOG(" setFanHigh");
          tab1[0] = false;
           tab1[1] =false;
           tab1[2] =false;
           tab1[3] =false;
    //      setFanHigh();
          break;
        default:
          break;
          
      }
      
      countFan++;
      //Serial.print("接收指令次数:");
      //Serial.println(countFan);
      tabCountFan();
    }
    
    
    void tabCountFan() {
    
      if (countFan == 1) {
        for (uint8_t one = 0; one < 5; one++) {
          tabSetFan[one] = tab1[one];
    
        }
    
      } else {
        for (uint8_t num = 0; num < 5; num++)
        {
          if (tab1[num])
          {
           if(lastSetFan==num){
            for (uint8_t one = 0; one < 5; one++) {
                     tab1[one]=tabSetFan[one];
                     tabSetFan[one]=false;
                    }
            }
          }
        }
       
      }
    
    }
    
    
    void setSpeed_feedback()
    {
      for (uint8_t num = 0; num < 5; num++)
      {
        if (tab1[num])
        {    
          
              sendFan(num);
              setSpeedTab.tab(num);
              lastSetFan = num; 
              tab1[num]=false;         
              }
      }
      setSpeedTab.print();
      countFan=0;
    }
    
    
    
    
    
    void dataRead(const String & data)
    {
      BLINKER_LOG("Blinker readString: ", data);
    
      Blinker.vibrate();
    
      uint32_t BlinkerTime = millis();
    
      Blinker.print("millis", BlinkerTime);
       BLINKER_LOG("Now second: ", Blinker.second());
        BLINKER_LOG("Now minute: ", Blinker.minute());
        BLINKER_LOG("Now hour: ", Blinker.hour());
        BLINKER_LOG("Now wday: ", Blinker.wday());
        BLINKER_LOG("Now month: ", Blinker.month());
        BLINKER_LOG("Now mday: ", Blinker.mday());
        BLINKER_LOG("Now year: ", Blinker.year());
        BLINKER_LOG("Now yday: ", Blinker.yday());
        BLINKER_LOG("Now ntp time: ", Blinker.time());
    }
    
    
    
    
    void setup()
    {
      Serial.begin(115200);
      BLINKER_DEBUG.stream(Serial);
    
      pinMode(ledPin, OUTPUT);
      digitalWrite(ledPin, HIGH);
      // digitalWrite(ledPin, LOW);
      setIntIr();
    
      Blinker.begin(auth, ssid, pswd);
      Blinker.attachData(dataRead);
      ButtonPower.attach(buttonPower_callback);
      ButtonHealth.attach(buttonHealth_callback);
      SliderHump.attach(setHump_callback);
      setModeTab.attach(setMode_callback, setMode_feedback);
      setSpeedTab.attach(setSpeed_callback, setSpeed_feedback);
      BlinkerMIOT.attachPowerState(miotPowerState);
      
    
    
    }
    
    void loop()
    {
      Blinker.run();
    }
    
    void  setFirm() {
      decode_type_t protocol = (decode_type_t)firm;
      state.protocol = protocol;  // Change the protocol used.
    }
    
    void sendIR() {
      ac.sendAc(state, &prev);  // Construct and send the message.
      ledState();
      
    }
    
    
    void ledState(){
    //  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
    //    // 输出PWM
    //    analogWrite(LED_BUILTIN, fadeValue);         
    //    // 等待30ms,以便观察到渐变效果
    //    delay(30);                            
    //  } 
    //
    //  // 从亮到暗,以每次减5的形式逐渐暗下来
    //  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
    //    // 输出PWM
    //    analogWrite(LED_BUILTIN, fadeValue);         
    //    // 等待30ms,以便观察到渐变效果
    //    delay(30);                            
    //  } 
    //  
    for(int i=0;i<6;i++){
    digitalWrite(ledPin, !analogRead(ledPin));
    delay(100);
      }
    
    
      }
    
    void powerOn() {
      setFirm();
      state.power = true;  // We want to turn on the A/C unit.
      sendIR();
    
    }
    
    
    
    void powerOff() {
      setFirm();
      state.power = false;  // We want to turn on the A/C unit.
      sendIR();
    }
    
    void healthOn() {
       setFirm();
      state.mode = stdAc::opmode_t::kAuto;
     sendIR();
    
    }
    
    
    
    void healthOff() {
       setFirm();
      state.mode = stdAc::opmode_t::kHeat;;
      sendIR();
    }
    
    void setDegrees(int32_t value) {
       setFirm();
      state.degrees = value;  // We want to turn on the A/C unit.
      sendIR();
    }
    
    void setTicker(int32_t value)
    {
      int8_t hour = Blinker.hour();
      int8_t min = Blinker.minute();
    
    
    }
    
    void setIntIr() {
    //  state.protocol = decode_type_t::KELVINATOR;  // Set a protocol to use.格力
      state.protocol = decode_type_t::ELECTRA_AC;  // Set a protocol to use.aux
      state.model = 1;  // Some A/C's have different models. Let's try using just 1.
      state.mode = stdAc::opmode_t::kCool;  // Run in cool mode initially.
      state.celsius = true;  // Use Celsius for units of temp. False = Fahrenheit
      state.degrees = 25;  // 25 degrees.
      state.fanspeed = stdAc::fanspeed_t::kMedium;  // Start with the fan at medium.
      state.swingv = stdAc::swingv_t::kOff;  // Don't swing the fan up or down.
      state.swingh = stdAc::swingh_t::kOff;  // Don't swing the fan left or right.
      state.light = true;  // Turn off any LED/Lights/Display that we can.
      state.beep = false;  // Turn off any beep from the A/C if we can.
      state.econo = false;  // Turn off any economy modes if we can.
      state.filter = false;  // Turn off any Ion/Mold/Health filters if we can.
      state.turbo = false;  // Don't use any turbo/powerful/etc modes.
      state.quiet = false;  // Don't use any quiet/silent/etc modes.
      state.sleep = -1;  // Don't set any sleep time or modes.
      state.clean = false;  // Turn off any Cleaning options if we can.
      state.clock = -1;  // Don't set any current time if we can avoid it.
      state.power = false;  // Initially start with the unit off.
      prev = state;  // Make sure we have a valid previous state.
    }
    void setModeAuto() {
      setFirm();
      state.power = true;
      state.mode = stdAc::opmode_t::kAuto;
     sendIR();
    }
    void setModeCool() {
      setFirm();
      state.power = true;
      state.mode = stdAc::opmode_t::kCool;
      sendIR();
    }
    void setModeDry() {
       setFirm();
      state.power = true;
      state.mode = stdAc::opmode_t::kDry;
     sendIR();
    }
    
    void setModeHeat() {
      setFirm();
      state.power = true;
      state.mode = stdAc::opmode_t::kHeat;
     sendIR();
    }
    
    
    void setModeFan() {
      setFirm();
      state.mode = stdAc::opmode_t::kFan;
      sendIR();
    }
    //发射红外
    void sendMode(int a){
      switch(a){
        case 0:setModeAuto();
        break;
        case 1:setModeCool();
        break;
        case 2:setModeDry();
        break;
        case 3:setModeHeat();
        break;
        case 4:setModeFan();
        break;
        default:
        break;        
        }
      
      }
    
    
    void setFanAuto() {
      setFirm();
      state.fanspeed = stdAc::fanspeed_t::kAuto;
      sendIR();
    }
    void setFanMin() {
      setFirm();
      state.fanspeed = stdAc::fanspeed_t::kMin;
      sendIR();
    }
    
    void setFanLow() {
      setFirm();
      state.fanspeed = stdAc::fanspeed_t::kLow;
      sendIR();
    }
    
    void setFanMedium() {
      setFirm();
      state.fanspeed = stdAc::fanspeed_t::kMedium;
      sendIR();
    }
    void setFanHigh() {
      setFirm();
      state.fanspeed = stdAc::fanspeed_t::kHigh;
      sendIR();
    }
    void setFanMax() {
      setFirm();
      state.fanspeed = stdAc::fanspeed_t::kMax;
      sendIR();
    }
    
    void sendFan(int a){
      switch(a){
        case 0:setFanAuto();    
        break;
        case 1:setFanLow();
        break;
        case 2:setFanMedium();
        break;
        case 3:setFanHigh();
        break;
        case 4:setFanMax();
        break;
        default:
        break;        
        }
      
      }
      
    


    最后更改好的完整代码上载到8266上,就可以实现控制你家的空调啦

    协议结果

    协议结果

    组件示意图

    组件示意图

    组件key

    组件key
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    热门推荐

    [限时福利]5分钟带你快速了解新一代开发板:M5STACK
    [限时福利]5分钟带你快速
    一、什么是M5Stack M5Stack是一种模块化、可堆叠扩展的开发板,每个模块
    哪位高手帮帮忙呀用UNO主板控制垃圾分类
    哪位高手帮帮忙呀用UNO主
    因为综合实践课给学生讲垃圾分类所以想用Arduino UNO主板制作一个智能分类的设
    中文 字库 的8针 OLED 12864模块 arduino
    中文 字库 的8针 OLED 128
    屏幕电路SPI连线: 中文字库OLED Arduino UNO GND GND
    【原创】全球最小口袋3D打印机mini one直播教程贴
    【原创】全球最小口袋3D打
    最近闲得蛋疼,没事搞个掌上3D打印机,先放效果图吧。 搞了半天,终于能正常打印,
    【Arduino】108种传感器系列实验(03)---微波雷达感应开关...
    【Arduino】108种传感器系
    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
    快速回复 返回顶部 返回列表