零知开源——基于ESP8266(ESP-12F)驱动YS-IR05F红外控制空调

在智能家居快速发展的今天,传统家电的智能化改造成为许多技术爱好者关注的焦点。空调作为家庭能耗主要设备之一,其智能化控制不仅能够提升生活便利性,还能实现能源的有效节约。

目录

一、硬件设计

1.1 硬件清单与选型

1.2 接线方案

1.3 详细接线图

1.4 接线实物图 

二、软件设计

2.1 所需库依赖

2.2 初始化框架

2.3 温度设置及展示

2.4 Web服务器实现

2.5 编码库详解

三、操作过程及展示

3.1 红外编码录制与处理

3.2 系统搭建与调试

3.3 效果展示

3.4 视频操作展示

四、YS-IR05F红外模块通信协议

4.1 数据包格式

4.2 指令集说明

4.3 工作原理

五、常见问题解答

Q1:红外编码录制不成功怎么办?

Q2:网页控制无响应?

Q3:红外控制距离短?


(1)项目概述

        本项目基于零知ESP8266开发板(ESP-12F模组) 和YS-IR05F红外编解码模块,构建了一套完整的智能空调遥控系统。系统不仅支持通过Web界面远程控制TCL空调的开关和温度调节,还集成了OLED显示屏用于实时状态显示。本项目深入讲解了红外编码的获取方法、ESP8266与红外模块的通信协议、Web服务器搭建以及多外设驱动整合。

(2)项目亮点

        >同时提供Web网页控制和OLED本地显示,支持移动端和PC端访问
        >详细讲解如何捕获、解析和重发红外编码
        >使用串口通信协议与YS-IR05F模块进行数据交互
        >采用现代化CSS设计,适配各种屏幕尺寸

(3)项目难点及解决方案

问题分析:不同空调品牌/型号的红外编码需要正确解析才能有效重发

解决方案:使用USB转TTL模块 + STC-ISP软件录制原始红外数据,替换operation.h中的数组。

一、硬件设计

1.1 硬件清单与选型

组件型号数量选型理由
主控制器零知ESP8266(ESP-12F)1集成WiFi功能,GPIO丰富,成本低廉
红外模块YS-IR05F1支持学习和发射,兼容多种红外协议
OLED显示屏SSD1306 0.96寸1I2C接口,低功耗,高对比度
USB转TTLCH340G1用于红外编码录制和调试
杜邦线母对母若干方便连接和调试

1.2 接线方案

零知ESP8266(ESP-12F)SSD1306 OLED显示屏YS-IR05F红外模块
3V3VCC3.3V
GNDGNDGND
D4(软串口RX)/TXD
D5(软串口TX)/RXD
SCLSCL/
SDASDA/

    🔌 注意:YS-IR05F的KEY引脚可不接,我们使用串口指令进入学习模式。

1.3 详细接线图

1.4 接线实物图 

        ESP8266与YS-IR05F通过杜邦线连接,OLED显示屏通过I2C连接。

二、软件设计

2.1 所需库依赖

        Adafruit SSD1306:用于OLED显示
        Adafruit GFX Library:图形库依赖
        ESPAsyncWebServer:异步Web服务器库
        SoftwareSerial:软件模拟串口依赖

2.2 初始化框架

#include "operation.h"
#include "ESP8266WiFi.h"
#include "SoftwareSerial.h"
#include <ESPAsyncWebServer.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// 创建软件串口对象,假设使用GPIO4(RX)和GPIO5(TX)
SoftwareSerial mySerial(D4, D5); // RX, TX

WiFiServer wifi_server(80);
String status = "空调关闭";  //默认状态
String statu = "Pausing";  //默认状态
int temperature = 20;
String header;

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

//配置自己的WIFI名称和密码
const char* ssid = "";
const char* password = "";

//读取JSON
String val = "";

void setup() {
  Serial.begin(115200);
  mySerial.begin(9600); // 初始化软件串口,波特率9600
  Wire.begin(); // SDA, SCL
  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  oled.clearDisplay();
  oled.setTextSize(1);
  oled.setTextColor(WHITE);
  oled.setCursor(0, 0);
  oled.println("Starting...");
  oled.display();
  
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
    oled.print(".");
    oled.display();
  }
  Serial.println(WiFi.localIP());
  oled.clearDisplay();
  oled.setCursor(0, 0);
  oled.println("IP: " + WiFi.localIP().toString());
  oled.display();
  wifi_server.begin();
  
  Serial.println("红外控制就绪,使用软件串口通信");
}

        库文件引用、变量参数及设备初始化

2.3 温度设置及展示

void set_TCL(int temperature) {
  switch (temperature) {
    case 16: mySerial.write(cold_16, 236); break;
    case 17: mySerial.write(cold_17, 236); break;
    case 18: mySerial.write(cold_18, 236); break;
    case 19: mySerial.write(cold_19, 236); break;
    case 20: mySerial.write(cold_20, 236); break;
    case 21: mySerial.write(cold_21, 236); break;
    case 22: mySerial.write(cold_22, 236); break;
    case 23: mySerial.write(cold_23, 236); break;
    case 24: mySerial.write(cold_24, 236); break;
    case 25: mySerial.write(cold_25, 236); break;
    case 26: mySerial.write(cold_26, 236); break;
    case 27: mySerial.write(cold_27, 236); break;
    case 28: mySerial.write(cold_28, 236); break;
    case 29: mySerial.write(cold_29, 236); break;
    case 30: mySerial.write(cold_30, 236); break;
    default:;
  }
  // 更新OLED显示
  oled.clearDisplay();
  oled.setCursor(0, 3);
  oled.println("TCL AC Control");
  oled.println(" ");
  oled.println("Status: " + statu);
  oled.println("Temp  : " + String(temperature) + " C");
  oled.display();
}

2.4 Web服务器实现

void loop() {
  WiFiClient client = wifi_server.available();
  if (client) {
    String currentLine = "";
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        header += c;
        if (c == '\n') {
          if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            
            if (header.indexOf("GET /TCL/on") >= 0) {
              Serial.println("空调开启");
              mySerial.write(on, 238);
              status = "空调开启";
              statu = "Running";
              delay(1000);
              temperature = 20;
              mySerial.write(cold_20, 236);

              // 更新OLED显示
              oled.clearDisplay();
              oled.setCursor(0, 3);
              oled.println("TCL AC Control");
              oled.println(" ");
              oled.println("Status: " + statu);
              oled.println("Temp  : " + String(temperature) + " C");
              oled.display();
            }
            if (header.indexOf("GET /TCL/off") >= 0) {
              Serial.println("空调关闭");
              mySerial.write(off, 236);
              status = "空调关闭";
              statu = "Pausing";
              oled.clearDisplay();
            }
            if (header.indexOf("GET /TCL/descend") >= 0) {
              if (temperature > 16) temperature -= 1;
              Serial.print("设置空调温度为:");
              Serial.println(temperature);
              set_TCL(temperature);
            }
            if (header.indexOf("GET /TCL/ascend") >= 0) {
              if (temperature < 30) temperature += 1;
              Serial.print("设置空调温度为:");
              Serial.println(temperature);
              set_TCL(temperature);
            }
            
            // 网页界面代码保持不变
            client.println("<!DOCTYPE html><html lang='zh-CN'>");
            client.println("<head>");
            client.println("<meta charset='UTF-8'>");
            client.println("<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'>");
            client.println("<title>TCL空调控制</title>");
            client.println("<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css'>");
            client.println("<style>");
            client.println("* { margin: 0; padding: 0; box-sizing: border-box; }");
            client.println("body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d); height: 100vh; display: flex; justify-content: center; align-items: center; color: #fff; }");
            client.println(".container { background: rgba(0, 0, 0, 0.7); border-radius: 20px; padding: 30px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); max-width: 400px; width: 90%; text-align: center; }");
            client.println(".header { margin-bottom: 20px; }");
            client.println(".header h1 { font-size: 28px; margin-bottom: 5px; }");
            client.println(".status { font-size: 18px; margin: 10px 0; }");
            client.println(".status span { color: #4ECDC4; font-weight: bold; }");
            client.println(".temp-display { background: rgba(255, 255, 255, 0.1); border-radius: 50%; width: 180px; height: 180px; margin: 20px auto; display: flex; flex-direction: column; justify-content: center; align-items: center; border: 5px solid #4ECDC4; }");
            client.println(".temperature { font-size: 48px; font-weight: bold; }");
            client.println(".unit { font-size: 24px; margin-top: 5px; }");
            client.println(".controls { display: flex; justify-content: space-between; margin: 20px 0; }");
            client.println(".btn { background: #4ECDC4; border: none; border-radius: 50%; width: 60px; height: 60px; color: white; font-size: 24px; cursor: pointer; transition: all 0.3s; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); display: flex; justify-content: center; align-items: center; }");
            client.println(".btn:hover { background: #2a8c85; transform: translateY(-3px); }");
            client.println(".btn:active { transform: translateY(1px); }");
            client.println(".power-btns { display: flex; justify-content: space-around; margin-top: 20px; }");
            client.println(".power-btn { padding: 12px 25px; border: none; border-radius: 30px; font-size: 16px; font-weight: bold; cursor: pointer; transition: all 0.3s; }");
            client.println(".power-on { background: linear-gradient(to right, #00b09b, #96c93d); color: white; }");
            client.println(".power-off { background: linear-gradient(to right, #ff416c, #ff4b2b); color: white; }");
            client.println(".power-btn:hover { opacity: 0.9; transform: translateY(-2px); }");
            client.println("@media (max-width: 480px) { .container { padding: 20px; } .temp-display { width: 150px; height: 150px; } .temperature { font-size: 40px; } }");
            client.println("</style>");
            client.println("</head>");
            client.println("<body>");
            client.println("<div class='container'>");
            client.println("<div class='header'>");
            client.println("<h1><i class='fas fa-wind'></i> TCL空调控制</h1>");
            client.println("<div class='status'>状态: <span>" + status + "</span></div>");
            client.println("</div>");
            client.println("<div class='temp-display'>");
            client.println("<div class='temperature'>" + String(temperature) + "</div>");
            client.println("<div class='unit'>°C</div>");
            client.println("</div>");
            client.println("<div class='controls'>");
            client.println("<a href='/TCL/descend' class='btn'><i class='fas fa-minus'></i></a>");
            client.println("<a href='/TCL/ascend' class='btn'><i class='fas fa-plus'></i></a>");
            client.println("</div>");
            client.println("<div class='power-btns'>");
            client.println("<a href='/TCL/on' class='power-btn power-on'><i class='fas fa-power-off'></i> 开启</a>");
            client.println("<a href='/TCL/off' class='power-btn power-off'><i class='fas fa-power-off'></i> 关闭</a>");
            client.println("</div>");
            client.println("</div>");
            client.println("</body>");
            client.println("</html>");
            client.println();
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }
    }
    header = "";
    client.stop();
    // Serial.println("");
  }
}

        发送ESP8266红外控制空调的静态网页页面

2.5 编码库详解

#ifndef OPERATION_H
#define OPERATION_H

#include <Arduino.h>

// TCL空调红外编码数据
// 注意:这些编码需要根据您的具体空调型号进行录制和替换

const uint8_t on[] = { 0xFD, 0xFD, 0x30, 0x03, 0x79, 0xE3, 0x00, 0x34, 0x5F, 0x00, 0xC1, 0x00, 0x3F, 0x00, 0x20, 0x00, 0x0B, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x12, 0x22, 0x12, 0x21, 0x12, 0x12, 0x21, 0x12, 0x11, 0x22, 0x12, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x12, 0x21, 0x12, 0x22, 0x22, 0x21, 0x11, 0x12, 0x22, 0x21, 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x12, 0x12, 0x21, 0x23, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x76, 0x3E, 0x15, 0xDF, 0xDF};

const uint8_t off[] = { 0xFD, 0xFD, 0x30, 0x03, 0x79, 0xE3, ... , 0xDF, 0xDF};

//制冷模式温度设置(16-30度)
const uint8_t cold_16[] = { 0xFD, 0xFD, 0x30, 0x03, 0x79, 0xE3, ... , 0xDF, 0xDF};

//其他设置编码省略


#endif

        🔧 如何获取这些数据?
        使用USB转TTL连接YS-IR05F,按下KEY键进入学习模式,用遥控器对准发射头按下按键,STC-ISP串口助手会显示236字节的16进制数据,复制并替换相应数组即可。

数据格式转换示例

(1)原始串口数据:

        FD FD 30 03 79 E3 ... DF DF

(2)转换为C数组:

const uint8_t cool_24[] PROGMEM = {
        0xFD, 0xFD, 0x30, 0x03, 0x79, 0xE3, ... , 0xDF, 0xDF };

三、操作过程及展示

3.1 红外编码录制与处理

(1)硬件连接

        使用USB转TTL模块连接YS-IR05F
        VCC接3.3V,GND接GND,TXD接RXD,RXD接TXD
        连接红外接收头到YS-IR05F的IR_IN接口

(2)软件配置

        >打开STC-ISP软件或其他串口调试工具
        >选择正确的COM口,设置波特率为9600,数据位8,停止位1,无校验位
        >选择"十六进制显示"模式

        接收缓冲区接收236个字节红外编码,将原始串口数据转换为C数组格式后,替换operation.h库文件中相关操作的对应数组

3.2 系统搭建与调试

(1)软件烧录

        修改代码中的WiFi配置,选择正确的开发板和端口,编译并上传代码

(2)系统测试

        观察OLED显示的系统状态,打开浏览器访问ESP8266的IP地址,测试各项控制功能

3.3 效果展示

(1) Web控制界面

        网页控制空调开启后设置初始温度为20℃的页面


 

(2) OLED显示效果

        TCL AC Control

        Status: Running

        Temp : 20℃

3.4 视频操作展示

ESP8266驱动YS-IR05F红外控制空调

网页控制ESP8266红外发送开启空调、调节温度和关闭空调等操作指令

四、YS-IR05F红外模块通信协议

4.1 数据包格式

模块使用固定的串口通信协议:

        波特率:9600bps、数据位:8位、停止位:1位、校验位:无

数据包格式:

[起始码] [起始码] [命令码] [数据段] [结束码][结束码]
  0xFD     0xFD    0x30   228字节    0xDF   0xDF

4.2 指令集说明

        >学习指令:0xFD 0xFD 0x30 0x03 + 228字节任意数据 + 0xDF 0xDF
        >发射指令:直接发送236字节红外数据

4.3 工作原理

YS-IR05F采用高性能红外处理芯片,能够接收、解析和发射红外信号。其工作流程如下:

(1)接收模式:红外接收头将38KHz的调制信号转换为电信号,经过放大、滤波和解调后,得到原始数字信号

(2)学习模式:模块记录原始波形的时序信息,转换为236字节的数据包

(3)发射模式:将数据包还原为红外波形,通过发射管发出

五、常见问题解答

Q1:红外编码录制不成功怎么办?

A:可能原因及解决方案:

        距离太近或太远,保持50cm左右距离
        环境光干扰,避免在强光环境下录制
        遥控器电池电量不足,更换电池
        串口设置错误,确认波特率为9600,十六进制显示

Q2:网页控制无响应?

A:排查步骤:

        重启ESP8266,检查OLED显示的IP地址是否正确
        确认设备与手机/电脑在同一局域网
        检查防火墙设置,是否阻止了局域网访问

Q3:红外控制距离短?

A:增强方法:

        使用多个红外发射管并联,增加发射功率
        调整发射管角度,对准空调接收器
        检查电源供电能力,确保工作电压稳定

项目资源:

        YS-IR05F使用手册、串口助手、源码下载链接: ESP8266红外控制

        本项目成功实现了一套基于ESP8266和YS-IR05F的智能空调控制系统。如有疑问或建议,欢迎在评论区留言讨论!

✔零知IDE 是一个真正属于国人自己的开源软件平台,在开发效率上超越了Arduino平台并且更加容易上手,大大降低了开发难度。零知开源在软件方面提供了完整的学习教程和丰富示例代码,让不懂程序的工程师也能非常轻而易举的搭建电路来创作产品,测试产品。快来动手试试吧!

✔访问零知实验室,获取更多实战项目和教程资源吧!

www.lingzhilab.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值