qidao123.com技术社区-IT企服评测·应用市场
标题:
基于STM32(Freertos)&ESP01S的红外空调网络控制器 -ESP01S 软件部分
[打印本页]
作者:
羊蹓狼
时间:
2025-4-6 10:06
标题:
基于STM32(Freertos)&ESP01S的红外空调网络控制器 -ESP01S 软件部分
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企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/)
Powered by Discuz! X3.4