1.概述
本文基于ESP01S 硬件,Arduino 开辟情况,Blinker库及手机控制APP,完成与STM32的通信,为手机APP提供按键笔墨数据接口。
2.ESO01S 驱动代码- #define BLINKER_WIFI
- #include <Blinker.h>
- #include <NTPClient.h>//用于获取网络时间
- #include <WiFiUdp.h>
- // 定义时区(东八区)
- #define TIME_ZONE 8 * 3600
- WiFiUDP ntpUDP;
- NTPClient timeClient(ntpUDP, "pool.ntp.org", TIME_ZONE);
- char auth[] = "1d7475c3d0df";
- char ssid[] = "ziroom605";
- char pswd[] = "4001001111";
- #define Temp_add "temp-add"
- #define temp_sub "temp-sub"
- #define IR_mode "IR-mode"
- #define sysdebug "sysdebug"
- #define Humi_mode "Humi-mode"
- #define SYS_ONOFF "onoff"
- BlinkerButton Button1(Temp_add);/*定义按键类型的一个按键对象Button1 初始化BUTTON_1*/
- BlinkerButton Button2(temp_sub);/*定义按键类型的一个按键对象Button2 初始化BUTTON_2*/
- BlinkerButton Button3(IR_mode);/*定义按键类型的一个按键对象Button3 初始化BUTTON_3*/
- BlinkerButton Button4(sysdebug);/*定义按键类型的一个按键对象Button4 初始化BUTTON_4*/
- BlinkerButton Button5(Humi_mode);/*定义按键类型的一个按键对象Button5 初始化BUTTON_5*/
- BlinkerButton Button6(SYS_ONOFF);/*定义按键类型的一个按键对象Button6 初始化BUTTON_6*/
- BlinkerNumber Number1("num-temp"); /*空调温度显示数字初始化*/
- BlinkerNumber Number2("num-irmode");/*空调模式显示数字初始化*/
- BlinkerNumber Number3("num-Humimode");/*加湿器模式显示数字初始化*/
- BlinkerNumber Number4("s-temp"); /*传感器温度数字初始化*/
- BlinkerNumber Number5("s-humi");/*传感器湿度数字初始化*/
- BlinkerText IRstate("IR-state"); /*空调模式字符接口初始化*/
- BlinkerText Humistate("Humi-state");/*加湿器模式字符接口初始化*/
- //用以接收数据的结构体定义
- #pragma pack(push, 1) // 确保结构体紧凑排列
- typedef struct {
- uint8_t start_flag; // 起始字节 0xB3
- uint8_t temp_IR; // 第二个字节 IR
- uint8_t mode_IR; // 第三个字节 Humi
- uint8_t mode_Humi; // 第4个字节 Humi
- float data1; // 5-8字节 float temp
- float data2; // 9-12字节 float humi
- } SerialData;
- #pragma pack(pop)
- //用以发送数据结构体
- #pragma pack(push, 1)
- typedef struct {
- uint8_t start_flag; // 固定0x47
- uint8_t hour; // 网络时间小时(24制)
- uint8_t minute; // 分钟
- uint8_t second; // 秒
- uint8_t cmd0; // 命令字节温度
- uint8_t cmd1; // 命令字节模式
- uint8_t cmd2; // 加湿器模式
- uint8_t cmd3; // 总开关标志 0 为关 高4为F时自动
- } SendPacket;
- #pragma pack(pop)
- //接收数据的结构体变量初始化
- SerialData sensorData={0xB3,26,0,2,0,0};
- //发送数据的结构体变量初始化
- SendPacket SendData={0x47,0,0,0,26,0,2,0x00};//初始化发送数据,26度,自动模式,关闭加湿器
- //定义接收数据的函数状态机
- enum ParserState { WAIT_HEADER, PARSE_DATA };
- //初始化接收数据的状态机
- ParserState state = WAIT_HEADER;
- //定义缓冲区以接收数据
- uint8_t buffer[12];
- uint8_t dataIndex = 0;
- uint8_t i=0;
- static uint8_t curtemp=sensorData.temp_IR;//初始化控制状态
- static uint8_t curHumimode=sensorData.mode_Humi;//初始化控制状态
- /*
- 功能:用以在手机APP上显示空调状态字符
- 参数:模式,从0-4
- */
- void IRmode_show(uint8_t text_num)
- {
- switch(text_num)
- {
- case 0: IRstate.print("自动");break;
- case 1: IRstate.print("制冷");break;
- case 2: IRstate.print("除湿");break;
- case 3: IRstate.print("加热");break;
- case 4: IRstate.print("送风");break;
- default:IRstate.print("Error");break;
- }
- }
- /*
- 功能:用以在手机APP上显示加湿器状态字符
- 参数:模式,从0-4
- */
- void Humimode_show(uint8_t text_num)
- {
- switch(text_num)
- {
- case 0: Humistate.print("OFF");break;
- case 1: Humistate.print("Low");break;
- case 2: Humistate.print("High");break;
- default:Humistate.print("Error");break;
- }
- }
- /*
- 功能:空调温度加
- 参数:无
- */
- void button1_callback(const String & state)//控制加空调温度,低5位温度
- {
- if(SendData.cmd3==0x00)
- {
- if (state == BLINKER_CMD_BUTTON_TAP)
- {
- BLINKER_LOG("CurIRTemp %d\n",curtemp);
- Button1.icon("fas fa-plus");
- Button1.color("#FFB71D");
- Button1.text("ADD TEMP");
- if(curtemp<=16||curtemp>=31)
- {curtemp=26;}
- SendData.cmd0=++curtemp;
- Number1.print(curtemp); // 直接支持数值类型
- Number1.unit("°C");
- sendTimeCommand();
- }
- }
- }
- /*
- 功能:空调温度减
- 参数:无
- */
- void button2_callback(const String & state)//控制减空调温度,低5位温度
- {
- if(SendData.cmd3==0x00)
- {
- if (state == BLINKER_CMD_BUTTON_TAP)
- {
- BLINKER_LOG("CurIRTemp %d\n",curtemp);
- Button2.icon("fas fa-window-minimize");
- Button2.color("#4CC7FF");
- Button2.text("SUB TEMP");
- if(curtemp<=16||curtemp>=31)
- {curtemp=26;}
- SendData.cmd0=--curtemp;
- Number1.print(curtemp); // 直接支持数值类型
- Number1.unit("°C");
- sendTimeCommand();
- }
- }
- }
- /*
- 功能:空调模式切换
- 参数:无
- */
- void button3_callback(const String & state)
- {
- uint8_t static curtempmode=sensorData.mode_IR;
- if(SendData.cmd3==0x00)
- {
- if (state == BLINKER_CMD_BUTTON_TAP)
- {
- BLINKER_LOG("CurIRmode %d\n",curtempmode);
- Button3.icon("fas fa-spinner");
- Button3.color("#B0DC58");
- Button3.text("IR Mode");
- curtempmode=curtempmode+1;
- if(curtempmode==5)
- curtempmode=0;
- IRmode_show(curtempmode);
- SendData.cmd1=curtempmode;
- Number2.print(curtempmode);
- sendTimeCommand();
- }
- }
- }
- /*
- 功能:debug 按键,实际不使用
- 参数:无
- */
- void button4_callback(const String & state)//DEBUG KEY
- {
- if (state == BLINKER_CMD_BUTTON_TAP)
- {
- BLINKER_LOG("i=",i);
- BLINKER_LOG("value=",buffer[i]);
- //BLINKER_LOG("TEMP=",sensorData.data1);
- //BLINKER_LOG("Humi=",sensorData.data2);
- Button4.icon("fa fa-minus");
- Button4.color("#05FFF");
- Button4.text("debug++");
- i++;
- if(i==12)
- {
- BLINKER_LOG("TEMP=",sensorData.data1);
- BLINKER_LOG("Humi=",sensorData.data2);
- i=0;
- }
- }
- }
- /*
- 功能:加湿器模式切换
- 参数:无
- */
- void button5_callback(const String & state)
- {
- if(SendData.cmd3==0x00)
- {
- if (state == BLINKER_CMD_BUTTON_TAP)
- {
- BLINKER_LOG("CurHumimode %d\n",curHumimode);
- Button5.icon("fab fa-gg-circle");
- Button5.color("#B0DC58");
- Button5.text("HUMI Mode");
- curHumimode++;
- if(curHumimode==3)
- curHumimode=0;
- Humimode_show(curHumimode);
- SendData.cmd2=curHumimode;
- Number3.print(curHumimode);
- sendTimeCommand();
- }
- }
- }
- /*
- 功能:控制器总开关
- 参数:无
- */
- void button6_callback(const String & state)
- {
- BLINKER_LOG("ON_OFF_Sta\n",state);
- if (state=="on")
- {
- Button6.print("on");
- Button6.icon("fas fa-power-on");
- Button6.color("#98F5FF");
- SendData.cmd3=0x00;
- }
- else if(state=="off")
- {
- Button6.print("off");
- Button6.icon("fas fa-power-off");
- Button6.color("#F5F5F5");
- SendData.cmd3=0x0F;
- }
- sendTimeCommand();
- }
- // 发送数据函数
- void sendTimeCommand(void)
- {
- SendData.start_flag = 0x47;
- SendData.hour = timeClient.getHours();
- SendData.minute =timeClient.getMinutes();
- SendData.second =timeClient.getSeconds();
- SendData.cmd0 = SendData.cmd0;//温度17-31
- SendData.cmd1 = SendData.cmd1;//模式0-4 自动,制冷,除湿,加热,送风
- SendData.cmd2 = SendData.cmd2;//加湿器模式 0-2 关 低 高
- SendData.cmd3 = SendData.cmd3;//总开关
- // 通过串口发送二进制数据
- Serial.write((uint8_t*)&SendData, sizeof(SendPacket));
- }
- /*
- 功能:解析4字节的float数据
- 参数:无
- */
- float parse_float(const uint8_t* bytes)
- {
- union {
- float value;
- uint8_t bytes[4];
- } converter;
- if (1)
- {
- // 接收端为小端,直接复制字节
- memcpy(converter.bytes, bytes, 4);
- } else {
- // 接收端为大端,反转字节顺序
- converter.bytes[0] = bytes[3];
- converter.bytes[1] = bytes[2];
- converter.bytes[2] = bytes[1];
- converter.bytes[3] = bytes[0];
- }
- return converter.value;
- }
- /*
- 功能:处理串口接收程序接收到的数据,进行校验
- 参数:无
- */
- void processData(void)
- {
- uint32_t temp0=0;
- uint32_t humi0=0;
- sensorData.start_flag=buffer[0];
- sensorData.temp_IR=buffer[1];
- sensorData.mode_IR=buffer[2];
- sensorData.mode_Humi=buffer[3];
- // 解析第一个float(buffer[4]到buffer[7])
- sensorData.data1=parse_float(&buffer[4]);
- sensorData.data2=parse_float(&buffer[8]);
- }
- /*
- 功能:串口数据接收程序
- 参数:无
- */
- void Uart_Data_Recesive(void)
- {
- while (Serial.available() > 0) {
- uint8_t incomingByte = Serial.read();
-
- switch (state)
- {
- case WAIT_HEADER:
- if (incomingByte == 0xB3)
- {
- buffer[0] = incomingByte;
- dataIndex = 1;
- state = PARSE_DATA;
- }
- break;
-
- case PARSE_DATA:
- if (dataIndex < 12)
- {
- buffer[dataIndex] = incomingByte;
- dataIndex++;
-
- if (dataIndex == 12) {
- // 完整数据包接收完成
- memcpy(&sensorData, buffer, sizeof(SerialData));
-
- // 验证起始字节
- if (sensorData.start_flag == 0xB3)
- {
- // 数据解析成功,这里添加处理逻辑
- processData();
- }
-
- // 重置状态机
- state = WAIT_HEADER;
- dataIndex = 0;
- }
- }
- break;
- }
- }
- }
- /*
- 功能:ESP01S 初始化
- 参数:无
- */
- void setup()
- {
- Serial.begin(9600);
- Serial1.begin(9600);
- Blinker.begin(auth, ssid, pswd);
- timeClient.begin(); // 初始化NTP客户端
- timeClient.update(); // 首次时间同步
- BLINKER_DEBUG.stream(Serial1);
- Blinker.println("System initialized");
- Number1.unit("°C"); // 设置单位
- Button1.attach(button1_callback);
- Button2.attach(button2_callback);
- Button3.attach(button3_callback);
- Button4.attach(button4_callback);
- Button5.attach(button5_callback);
- Button6.attach(button6_callback);
- }
- /*
- 功能:ESP01S 循环执行函数
- 参数:无
- */
- void loop()
- {
- timeClient.update();
- Uart_Data_Recesive();
- Blinker.run(); // 保持Blinker连接
- }
复制代码 3.手机APP界面

项目软硬件源文件:
通过网盘分享的文件:基于STM32(Freertos)&ESP01S的红外空调网络控制器
链接: https://pan.baidu.com/s/1v1wjqlfK64kvp4HNg9b2ew 提取码: vzx5
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |