点灯科技app+小爱同学控制美的空调(esp8266)-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1049|回复: 2

[分享] 点灯科技app+小爱同学控制美的空调(esp8266)

[复制链接]
发表于 2022-5-18 14:51 | 显示全部楼层 |阅读模式
本帖最后由 weixuezi 于 2022-5-19 10:26 编辑

1、硬件准备:
esp8266开发板、红外发射二极管、三极管(我用的S9013)、电阻(100~200Ω)等。

自己手绘一个简单电路图。

电路图

电路图



2、软件部分:

使用Arduino软件编程,参考了太极创客的代码和点灯科技技术文档。
用到的库:“IRremoteESP8266”、“Blinker”、“WiFiManager”等。

3、实现功能:
  • 设备自动配网(参考太极创客程序)
  • 点灯科技app开启空调后模式和风速按钮变蓝,关闭空调按钮按下所有按钮变灰
  • 点灯科技app模式按钮按下后根据不同的模式变换图标
  • 点灯科技app通过滑动条调节空调温度
  • 点灯科技app模式按钮按下反馈当前模式,风速按钮按下反馈当前风速
  • 可控制空调功能:开关、模式(制热、制冷、送风、除湿、自动)、风速、温度、舒睡模式
  • 小爱同学由于没有制热、制冷等模式接口,使用其他模式代替,利用小爱训练控制空调模式

点灯科技app按钮配置图,直男审美

点灯科技app按钮配置图,直男审美

小爱同学训练

小爱同学训练




4、代码部分:



[pre]#define BLINKER_WIFI
#define BLINKER_MIOT_AIRCONDITION  //定义小爱同学空调设备

#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <ir_Coolix.h>
#include <Blinker.h>
#include <WiFiManager.h>

char auth[] = "**********";  //点灯科技设备密钥

// ESP8266 GPIO pin to use. Recommended: 14 (D5).接信号发射,三极管B极
const uint16_t kIrLed = 14;  
IRCoolixAC ac(kIrLed);  //实例化空调对象

//遥控器当前状态存储
bool power = false;
uint8_t tempread = 26;
uint8_t fanread = kCoolixFanAuto;
uint8_t moderead = kCoolixAuto;
bool sleepmode = false;
uint8_t setLevel = 0;
bool x_auto = 0;
bool x_heat = 0;
bool x_cool = 0;
bool x_dry = 0;
bool x_fan = 0;

//定义按键
BlinkerButton btn_on("btn-on");
BlinkerButton btn_mode("btn-mode");
BlinkerButton btn_fan("btn-fan");
BlinkerButton btn_sleep("btn-sleep");
BlinkerSlider slide_temp("ran-wd");

//按下开关按钮后获取按钮状态
void ac_con(){
  if(power==false){  //关机后按钮变灰色
    btn_on.color("#000000");
    btn_on.print("off");
    btn_mode.color("#000000");
    btn_mode.print("off");
    btn_fan.color("#000000");
    btn_fan.print("off");
    btn_sleep.color("#000000");
    btn_sleep.print("off");
  }else {              //开机后按钮变蓝色
    btn_on.color("#4169E1");
    btn_on.print("on");
    btn_mode.color("#4169E1");
    btn_mode.print("on");
    btn_fan.color("#4169E1");  
    btn_fan.print("on");
    if (sleepmode==true){
      btn_sleep.color("#4169E1");
      btn_sleep.print("on");
    }   
  }
}

// 开关按键回调函数
void onoff_callback(const String & state)
{
  BLINKER_LOG("开/关按钮被按下:",state);
  if (state=="tap" && power==false) {
    ac.setTemp(tempread);
    ac.setMode(moderead);
    ac.setFan(fanread);  
    ac.on();
    ac.send();
    power = true;
    BLINKER_LOG("打开空调",tempread,moderead,fanread);
  } else if(state=="tap" && power==true){
    ac.off();
    ac.send();
    power = false;
    BLINKER_LOG("关闭空调");
  }
  ac_con();
  Blinker.vibrate();    //手机震动
}

//模式按键回调函数
void mode_callback(const String & state)
{
  BLINKER_LOG("模式按钮被按下:",moderead);
  if (state=="tap") {
    switch (moderead) {
      case kCoolixAuto:
        ac.setMode(kCoolixCool);
        btn_mode.text("模式:制冷");
        btn_mode.icon("fad fa-snowflakes");
        moderead = kCoolixCool;
        x_auto = 0;
        x_heat = 0;
        x_cool = 1;
        x_dry = 0;
        x_fan = 0;
        break;
      case kCoolixCool:
        ac.setMode(kCoolixHeat);
        btn_mode.text("模式:制热");
        btn_mode.icon("fad fa-sun");
        moderead = kCoolixHeat;
        x_auto = 0;
        x_heat = 1;
        x_cool = 0;
        x_dry = 0;
        x_fan = 0;
        break;
      case kCoolixHeat:
        ac.setMode(kCoolixDry);
        btn_mode.text("模式:除湿");
        btn_mode.icon("fad fa-raindrops");
        moderead = kCoolixDry;
        x_auto = 0;
        x_heat = 0;
        x_cool = 0;
        x_dry = 1;
        x_fan = 0;
        break;
      case kCoolixDry:
        ac.setMode(kCoolixFan);
        ac.send();
        btn_mode.text("模式:送风");
        btn_mode.icon("fas fa-fan");
        moderead = kCoolixFan;
        x_auto = 0;
        x_heat = 0;
        x_cool = 0;
        x_dry = 0;
        x_fan = 1;         
        break;
      case kCoolixFan:
        ac.setMode(kCoolixAuto);
        btn_mode.text("模式:自动");
        btn_mode.icon("fas fa-toggle-on");
        moderead = kCoolixAuto;
        x_auto = 1;
        x_heat = 0;
        x_cool = 0;
        x_dry = 0;
        x_fan = 0;
        break;
      default:
        ac.setMode(kCoolixAuto);
        btn_mode.text("模式:自动");
        btn_mode.icon("fas fa-toggle-on");
        moderead = kCoolixAuto;
        x_auto = 1;
        x_heat = 0;
        x_cool = 0;
        x_dry = 0;
        x_fan = 0;   

        break;        
    }
  }     
  ac.send();
  btn_mode.color("#4169E1");
  btn_mode.print("on");
  Blinker.vibrate();    //手机震动
}

//风速按键回调函数
void fan_callback(const String & state)
{
  BLINKER_LOG("风速按钮被按下:",fanread);
  if (state=="tap") {
    switch (fanread) {
      case kCoolixFanAuto:
        ac.setFan(kCoolixFanMin);
        btn_fan.text("风速:慢");
        setLevel = 1;
        fanread=kCoolixFanMin;
        break;
      case kCoolixFanMin:
        ac.setFan(kCoolixFanMed);
        btn_fan.text("风速:中");
        setLevel = 2;
        fanread=kCoolixFanMed;
        break;
      case kCoolixFanMed:
        ac.setFan(kCoolixFanMax);
        btn_fan.text("风速:大");
        setLevel = 3;
        fanread=kCoolixFanMax;
        break;
      case kCoolixFanMax:
        ac.setFan(kCoolixFanAuto);
        btn_fan.text("风速:自动");
        setLevel = 0;
        fanread=kCoolixFanAuto;
        break;
      default:
        ac.setFan(kCoolixFanAuto);
        btn_fan.text("风速:自动");  
        setLevel = 0;
        fanread=kCoolixFanAuto;
        break;
    }
  }     
  ac.send();
  btn_fan.color("#4169E1");
  btn_fan.print("on");
  Blinker.vibrate();    //手机震动
}

void sleep_callback(const String & state)
{
  BLINKER_LOG("睡眠按钮被按下:",sleepmode);
  if (state=="tap") {
    ac.setSleep();
    ac.send();
    sleepmode = ac.getSleep();
  }
  if (sleepmode==true){
    btn_sleep.color("#4169E1");
    btn_sleep.print("on");
  }else {
    btn_sleep.color("#000000");
    btn_sleep.print("off");
  }
  Blinker.vibrate();    //手机震动
}

//滑动温度滑动条时 执行的函数
void tempset_callback(int32_t value)
{
  BLINKER_LOG("温度设定:", value);
  tempread = value;
  ac.setTemp(value);
  ac.send();
}

// 如果未绑定的组件被触发,则会执行其中内容
void dataRead(const String & data)
{
  BLINKER_LOG("未绑定的组件被触发 :", data);
}

void miotPowerState(const String & state)
{
  BLINKER_LOG("小爱同学开关空调 ", state);
  if (state == BLINKER_CMD_ON) {
    ac.setTemp(tempread);
    ac.setMode(moderead);
    ac.setFan(fanread);  
    ac.on();
    ac.send();
    BlinkerMIOT.powerState("on");
    BlinkerMIOT.print();
    power = true;
  }
  else if (state == BLINKER_CMD_OFF) {
    ac.off();
    ac.send();
    power = false;
    BlinkerMIOT.powerState("off");
    BlinkerMIOT.print();
  }
}

void miotLevel(uint8_t level)
{
  BLINKER_LOG("小爱控制风速: ", level);
  // 0:AUTO MODE, 1-3 LEVEL
  switch (level) {
    case 1:
      ac.setFan(kCoolixFanMin);
      break;
    case 2:
      ac.setFan(kCoolixFanMed);
      break;
    case 3:
      ac.setFan(kCoolixFanMax);
      break;
    case 0:
      ac.setFan(kCoolixFanAuto);
      break;
    default:
      ac.setFan(kCoolixFanAuto);
      break;
  }
  ac.send();
  fanread=ac.getFan();
  setLevel = level;
  BlinkerMIOT.level(level);
  BlinkerMIOT.print();
}

//小爱同学模式设置,此处用节能替换为自动,辅热替换为制热,柔风替换为送风,UV杀菌替换为制冷
void miotMode(const String & mode, const String & state)
{
  BLINKER_LOG("小爱模式设置: ", mode);
  BLINKER_LOG("小爱模式状态: ", state);
  if (mode == "eco" && state == "on") {       // eco 此处用作自动模式
    ac.setMode(kCoolixAuto);
    x_auto = 1;
    x_heat = 0;
    x_cool = 0;
    x_dry = 0;
    x_fan = 0;
  }
  else if (mode == "heater" && state == "on") { // heater  此处用作制热模式
    ac.setMode(kCoolixHeat);
    moderead = kCoolixHeat;
    x_auto = 0;
    x_heat = 1;
    x_cool = 0;
    x_dry = 0;
    x_fan = 0;        
  }
  else if (mode == "dryer" && state == "on") {  // dryer 此处用作除湿模式
    ac.setMode(kCoolixDry);
    moderead = kCoolixDry;
    x_auto = 0;
    x_heat = 0;
    x_cool = 0;
    x_dry = 1;
    x_fan = 0;        
  }
  else if (mode == "sleep" && state == "on" && sleepmode == false) {
    ac.setSleep();
    sleepmode = true;
  }
  else if (mode == "sleep" && state == "off" && sleepmode == true) {
    ac.setSleep();
    sleepmode = false;
  }   
  else if (mode == "soft"&& state == "on") {    // soft 此处用作送风模式
    ac.setMode(kCoolixFan);
    moderead = kCoolixFan;
    x_auto = 0;
    x_heat = 0;
    x_cool = 0;
    x_dry = 0;
    x_fan = 1;        
  }
  else if (mode == "uv"&& state == "on") {     // uv 此处用作制冷模式
    ac.setMode(kCoolixCool);
    moderead = kCoolixCool;
    x_auto = 0;
    x_heat = 0;
    x_cool = 1;
    x_dry = 0;
    x_fan = 0;
  }
  ac.send();
  BlinkerMIOT.mode(mode, state);
  BlinkerMIOT.print();
}

//小爱温度设置
void miotTemp(uint8_t temp)
{
  BLINKER_LOG("小爱温度设置: ", temp);
  ac.setTemp(temp);
  ac.send();
  tempread = temp;
  BlinkerMIOT.temp(temp);
  BlinkerMIOT.print();
}

//小爱同学设备查询接口
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(power ? "on" : "off");
      BlinkerMIOT.level(setLevel);
      BlinkerMIOT.temp(tempread);
      BlinkerMIOT.eco(x_auto ? "on" : "off");
      BlinkerMIOT.heater(x_heat ? "on" : "off");
      BlinkerMIOT.dryer(x_dry ? "on" : "off");
      BlinkerMIOT.sleep(sleepmode ? "on" : "off");
      BlinkerMIOT.soft(x_fan ? "on" : "off");
      BlinkerMIOT.uv(x_cool ? "on" : "off");
      BlinkerMIOT.print();
      break;
    case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
      BLINKER_LOG("MIOT Query Power State");
      BlinkerMIOT.powerState(power ? "on" : "off");
      BlinkerMIOT.print();
      break;
    case BLINKER_CMD_QUERY_TEMP_NUMBER :
      BlinkerMIOT.temp(tempread);
      BlinkerMIOT.print();
    default :
      BlinkerMIOT.powerState(power ? "on" : "off");
      BlinkerMIOT.level(setLevel);
      BlinkerMIOT.temp(tempread);
      BlinkerMIOT.eco(x_auto ? "on" : "off");
      BlinkerMIOT.heater(x_heat ? "on" : "off");
      BlinkerMIOT.dryer(x_dry ? "on" : "off");
      BlinkerMIOT.sleep(sleepmode ? "on" : "off");
      BlinkerMIOT.soft(x_fan ? "on" : "off");
      BlinkerMIOT.uv(x_cool ? "on" : "off");
      BlinkerMIOT.print();
      break;
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  BLINKER_DEBUG.stream(Serial);

  // 建立WiFiManager对象
  WiFi.mode(WIFI_STA);
  WiFiManager wifiManager;
  // 自动连接WiFi。以下语句的参数是连接ESP8266时的WiFi名称
  wifiManager.autoConnect("AutoConnectAP");
  // WiFi连接成功后将通过串口监视器输出连接成功信息
  Serial.println("");
  Serial.print("ESP8266 Connected to ");
  Serial.println(WiFi.SSID());              // WiFi名称
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());           // IP

  ac.begin();
  
  // 初始化blinker
  Blinker.begin(auth, WiFi.SSID().c_str(), WiFi.psk().c_str());
  Blinker.attachData(dataRead);
  btn_on.attach(onoff_callback);  //注册点灯软件回调函数
  btn_mode.attach(mode_callback);  //注册点灯软件回调函数
  btn_fan.attach(fan_callback);  //注册点灯软件回调函数
  btn_sleep.attach(sleep_callback);  //注册点灯软件回调函数
  slide_temp.attach(tempset_callback);//注册点灯软件回调函数
  BlinkerMIOT.attachPowerState(miotPowerState);//小爱同学回调函数
  BlinkerMIOT.attachLevel(miotLevel);
  BlinkerMIOT.attachMode(miotMode);
  BlinkerMIOT.attachTemp(miotTemp);
  BlinkerMIOT.attachQuery(miotQuery);
}

void loop() {
  // put your main code here, to run repeatedly:
  Blinker.run();
}[/pre]


 楼主| 发表于 2022-5-18 14:52 | 显示全部楼层
缺点:睡眠模式可能存在状态不对应的错误
 楼主| 发表于 2022-5-18 15:20 | 显示全部楼层
补充下:我用示例程序“IRremoteESP8266: IRrecvDumpV2”红外接收管接收过美的空调遥控器的数据,显示结果如下:
Protocol  : COOLIX
Code      : 0xB2BFD0 (24 Bits)
Mesg Desc.: Power: On, Mode: 0 (Cool), Fan: 5 (Auto), Temp: 26C, Zone Follow: Off, Sensor Temp: Off
uint16_t rawData[199] = {*****此处省略原生数据*******};  // COOLIX B2BFD0
uint64_t data = 0xB2BFD0;
因为此遥控器正好匹配COOLIX库的控制代码,我就引用了此库作为控制空调的源
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 09:29 , Processed in 0.083020 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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