点灯科技app+小爱同学控制美的空调(esp8266)
本帖最后由 weixuezi 于 2022-5-19 10:26 编辑1、硬件准备:
esp8266开发板、红外发射二极管、三极管(我用的S9013)、电阻(100~200Ω)等。
自己手绘一个简单电路图。
2、软件部分:
使用Arduino软件编程,参考了太极创客的代码和点灯科技技术文档。
用到的库:“IRremoteESP8266”、“Blinker”、“WiFiManager”等。
3、实现功能:
[*]设备自动配网(参考太极创客程序)
[*]点灯科技app开启空调后模式和风速按钮变蓝,关闭空调按钮按下所有按钮变灰
[*]点灯科技app模式按钮按下后根据不同的模式变换图标
[*]点灯科技app通过滑动条调节空调温度
[*]点灯科技app模式按钮按下反馈当前模式,风速按钮按下反馈当前风速
[*]可控制空调功能:开关、模式(制热、制冷、送风、除湿、自动)、风速、温度、舒睡模式
[*]小爱同学由于没有制热、制冷等模式接口,使用其他模式代替,利用小爱训练控制空调模式
4、代码部分:
#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();
}
缺点:睡眠模式可能存在状态不对应的错误 补充下:我用示例程序“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 = {*****此处省略原生数据*******};// COOLIX B2BFD0
uint64_t data = 0xB2BFD0;
因为此遥控器正好匹配COOLIX库的控制代码,我就引用了此库作为控制空调的源
页:
[1]