基于STM32(Freertos)&ESP01S的红外空调网络控制器 -ESP01S 软件部分 ...

打印 上一主题 下一主题

主题 1721|帖子 1721|积分 5163

1.概述
本文基于ESP01S 硬件,Arduino 开辟情况,Blinker库及手机控制APP,完成与STM32的通信,为手机APP提供按键笔墨数据接口。
2.ESO01S 驱动代码
  1. #define BLINKER_WIFI
  2. #include <Blinker.h>
  3. #include <NTPClient.h>//用于获取网络时间
  4. #include <WiFiUdp.h>
  5. // 定义时区(东八区)
  6. #define TIME_ZONE 8 * 3600
  7. WiFiUDP ntpUDP;
  8. NTPClient timeClient(ntpUDP, "pool.ntp.org", TIME_ZONE);
  9. char auth[] = "1d7475c3d0df";
  10. char ssid[] = "ziroom605";
  11. char pswd[] = "4001001111";
  12. #define Temp_add "temp-add"
  13. #define temp_sub "temp-sub"
  14. #define IR_mode "IR-mode"
  15. #define sysdebug "sysdebug"
  16. #define Humi_mode "Humi-mode"
  17. #define SYS_ONOFF "onoff"
  18. BlinkerButton Button1(Temp_add);/*定义按键类型的一个按键对象Button1 初始化BUTTON_1*/
  19. BlinkerButton Button2(temp_sub);/*定义按键类型的一个按键对象Button2 初始化BUTTON_2*/
  20. BlinkerButton Button3(IR_mode);/*定义按键类型的一个按键对象Button3 初始化BUTTON_3*/
  21. BlinkerButton Button4(sysdebug);/*定义按键类型的一个按键对象Button4 初始化BUTTON_4*/
  22. BlinkerButton Button5(Humi_mode);/*定义按键类型的一个按键对象Button5 初始化BUTTON_5*/
  23. BlinkerButton Button6(SYS_ONOFF);/*定义按键类型的一个按键对象Button6 初始化BUTTON_6*/
  24. BlinkerNumber Number1("num-temp"); /*空调温度显示数字初始化*/
  25. BlinkerNumber Number2("num-irmode");/*空调模式显示数字初始化*/
  26. BlinkerNumber Number3("num-Humimode");/*加湿器模式显示数字初始化*/
  27. BlinkerNumber Number4("s-temp"); /*传感器温度数字初始化*/
  28. BlinkerNumber Number5("s-humi");/*传感器湿度数字初始化*/
  29. BlinkerText   IRstate("IR-state"); /*空调模式字符接口初始化*/
  30. BlinkerText   Humistate("Humi-state");/*加湿器模式字符接口初始化*/
  31. //用以接收数据的结构体定义
  32. #pragma pack(push, 1) // 确保结构体紧凑排列
  33. typedef struct {
  34.     uint8_t start_flag;  // 起始字节 0xB3
  35.     uint8_t temp_IR;       // 第二个字节 IR
  36.     uint8_t mode_IR;       // 第三个字节 Humi
  37.     uint8_t mode_Humi;       // 第4个字节 Humi
  38.     float   data1;       // 5-8字节 float temp
  39.     float   data2;       // 9-12字节 float humi
  40. } SerialData;
  41. #pragma pack(pop)
  42. //用以发送数据结构体
  43. #pragma pack(push, 1)
  44. typedef struct {
  45.     uint8_t start_flag;  // 固定0x47
  46.     uint8_t hour;        // 网络时间小时(24制)
  47.     uint8_t minute;      // 分钟
  48.     uint8_t second;      // 秒
  49.     uint8_t cmd0;        // 命令字节温度
  50.     uint8_t cmd1;        // 命令字节模式
  51.     uint8_t cmd2;        // 加湿器模式
  52.     uint8_t cmd3;        // 总开关标志 0 为关 高4为F时自动
  53. } SendPacket;
  54. #pragma pack(pop)
  55. //接收数据的结构体变量初始化
  56. SerialData sensorData={0xB3,26,0,2,0,0};
  57. //发送数据的结构体变量初始化
  58. SendPacket SendData={0x47,0,0,0,26,0,2,0x00};//初始化发送数据,26度,自动模式,关闭加湿器
  59. //定义接收数据的函数状态机
  60. enum ParserState { WAIT_HEADER, PARSE_DATA };
  61. //初始化接收数据的状态机
  62. ParserState state = WAIT_HEADER;
  63. //定义缓冲区以接收数据
  64. uint8_t buffer[12];
  65. uint8_t dataIndex = 0;
  66. uint8_t i=0;
  67. static uint8_t curtemp=sensorData.temp_IR;//初始化控制状态
  68. static uint8_t curHumimode=sensorData.mode_Humi;//初始化控制状态
  69. /*
  70. 功能:用以在手机APP上显示空调状态字符
  71. 参数:模式,从0-4
  72. */
  73. void IRmode_show(uint8_t text_num)
  74. {
  75.   switch(text_num)
  76.   {
  77.     case 0: IRstate.print("自动");break;
  78.     case 1: IRstate.print("制冷");break;
  79.     case 2: IRstate.print("除湿");break;
  80.     case 3: IRstate.print("加热");break;
  81.     case 4: IRstate.print("送风");break;
  82.     default:IRstate.print("Error");break;
  83.   }
  84. }
  85. /*
  86. 功能:用以在手机APP上显示加湿器状态字符
  87. 参数:模式,从0-4
  88. */
  89. void Humimode_show(uint8_t text_num)
  90. {
  91.   switch(text_num)
  92.   {
  93.     case 0: Humistate.print("OFF");break;
  94.     case 1: Humistate.print("Low");break;
  95.     case 2: Humistate.print("High");break;
  96.     default:Humistate.print("Error");break;
  97.   }
  98. }
  99. /*
  100. 功能:空调温度加
  101. 参数:无
  102. */
  103. void button1_callback(const String & state)//控制加空调温度,低5位温度
  104. {
  105.     if(SendData.cmd3==0x00)
  106.     {
  107.     if (state == BLINKER_CMD_BUTTON_TAP)
  108.     {
  109.         BLINKER_LOG("CurIRTemp %d\n",curtemp);
  110.         Button1.icon("fas fa-plus");
  111.         Button1.color("#FFB71D");
  112.         Button1.text("ADD TEMP");
  113.         if(curtemp<=16||curtemp>=31)
  114.         {curtemp=26;}
  115.         SendData.cmd0=++curtemp;
  116.         Number1.print(curtemp); // 直接支持数值类型
  117.         Number1.unit("°C");
  118.         sendTimeCommand();   
  119.     }
  120.     }
  121. }
  122. /*
  123. 功能:空调温度减
  124. 参数:无
  125. */
  126. void button2_callback(const String & state)//控制减空调温度,低5位温度
  127. {
  128.       if(SendData.cmd3==0x00)
  129.     {
  130.     if (state == BLINKER_CMD_BUTTON_TAP)
  131.     {
  132.         BLINKER_LOG("CurIRTemp %d\n",curtemp);
  133.         Button2.icon("fas fa-window-minimize");
  134.         Button2.color("#4CC7FF");
  135.         Button2.text("SUB TEMP");
  136.         if(curtemp<=16||curtemp>=31)
  137.         {curtemp=26;}
  138.         SendData.cmd0=--curtemp;
  139.         Number1.print(curtemp); // 直接支持数值类型
  140.         Number1.unit("°C");
  141.         sendTimeCommand();   
  142.     }
  143.     }
  144. }
  145. /*
  146. 功能:空调模式切换
  147. 参数:无
  148. */
  149. void button3_callback(const String & state)
  150. {
  151.     uint8_t static curtempmode=sensorData.mode_IR;
  152.     if(SendData.cmd3==0x00)
  153.     {
  154.     if (state == BLINKER_CMD_BUTTON_TAP)
  155.     {
  156.         BLINKER_LOG("CurIRmode %d\n",curtempmode);
  157.         Button3.icon("fas fa-spinner");
  158.         Button3.color("#B0DC58");
  159.         Button3.text("IR Mode");
  160.         curtempmode=curtempmode+1;
  161.         if(curtempmode==5)
  162.         curtempmode=0;
  163.         IRmode_show(curtempmode);
  164.         SendData.cmd1=curtempmode;
  165.         Number2.print(curtempmode);
  166.         sendTimeCommand();   
  167.     }
  168.     }
  169. }
  170. /*
  171. 功能:debug 按键,实际不使用
  172. 参数:无
  173. */
  174. void button4_callback(const String & state)//DEBUG KEY
  175. {
  176.     if (state == BLINKER_CMD_BUTTON_TAP)
  177.     {
  178.         BLINKER_LOG("i=",i);
  179.         BLINKER_LOG("value=",buffer[i]);
  180.         //BLINKER_LOG("TEMP=",sensorData.data1);
  181.         //BLINKER_LOG("Humi=",sensorData.data2);
  182.         Button4.icon("fa fa-minus");
  183.         Button4.color("#05FFF");
  184.         Button4.text("debug++");
  185.         i++;
  186.         if(i==12)
  187.         {
  188.         BLINKER_LOG("TEMP=",sensorData.data1);
  189.         BLINKER_LOG("Humi=",sensorData.data2);
  190.         i=0;
  191.         }
  192.     }
  193. }
  194. /*
  195. 功能:加湿器模式切换
  196. 参数:无
  197. */
  198. void button5_callback(const String & state)
  199. {   
  200.       if(SendData.cmd3==0x00)
  201.     {
  202.     if (state == BLINKER_CMD_BUTTON_TAP)
  203.     {
  204.         BLINKER_LOG("CurHumimode %d\n",curHumimode);
  205.         Button5.icon("fab fa-gg-circle");
  206.         Button5.color("#B0DC58");
  207.         Button5.text("HUMI Mode");
  208.         curHumimode++;
  209.         if(curHumimode==3)
  210.         curHumimode=0;
  211.         Humimode_show(curHumimode);
  212.         SendData.cmd2=curHumimode;
  213.         Number3.print(curHumimode);
  214.         sendTimeCommand();   
  215.     }
  216.     }
  217. }
  218. /*
  219. 功能:控制器总开关
  220. 参数:无
  221. */
  222. void button6_callback(const String & state)
  223. {   
  224.         BLINKER_LOG("ON_OFF_Sta\n",state);
  225.         if (state=="on")
  226.         {
  227.         Button6.print("on");
  228.         Button6.icon("fas fa-power-on");
  229.         Button6.color("#98F5FF");
  230.         SendData.cmd3=0x00;
  231.         }
  232.         else if(state=="off")
  233.         {
  234.         Button6.print("off");
  235.         Button6.icon("fas fa-power-off");
  236.         Button6.color("#F5F5F5");
  237.         SendData.cmd3=0x0F;
  238.         }
  239.         sendTimeCommand();   
  240. }
  241. // 发送数据函数
  242. void sendTimeCommand(void)
  243. {
  244.     SendData.start_flag = 0x47;
  245.     SendData.hour = timeClient.getHours();
  246.     SendData.minute =timeClient.getMinutes();
  247.     SendData.second =timeClient.getSeconds();
  248.     SendData.cmd0 = SendData.cmd0;//温度17-31
  249.     SendData.cmd1 = SendData.cmd1;//模式0-4 自动,制冷,除湿,加热,送风
  250.     SendData.cmd2 = SendData.cmd2;//加湿器模式 0-2  关 低 高  
  251.     SendData.cmd3 = SendData.cmd3;//总开关
  252.     // 通过串口发送二进制数据
  253.     Serial.write((uint8_t*)&SendData, sizeof(SendPacket));
  254. }
  255. /*
  256. 功能:解析4字节的float数据
  257. 参数:无
  258. */
  259. float parse_float(const uint8_t* bytes)
  260. {
  261.     union {
  262.         float value;
  263.         uint8_t bytes[4];
  264.     } converter;
  265.     if (1)
  266.     {
  267.         // 接收端为小端,直接复制字节
  268.         memcpy(converter.bytes, bytes, 4);
  269.     } else {
  270.         // 接收端为大端,反转字节顺序
  271.         converter.bytes[0] = bytes[3];
  272.         converter.bytes[1] = bytes[2];
  273.         converter.bytes[2] = bytes[1];
  274.         converter.bytes[3] = bytes[0];
  275.     }
  276.     return converter.value;
  277. }
  278. /*
  279. 功能:处理串口接收程序接收到的数据,进行校验
  280. 参数:无
  281. */
  282. void processData(void)
  283. {
  284.   uint32_t temp0=0;
  285.   uint32_t humi0=0;
  286.   sensorData.start_flag=buffer[0];
  287.   sensorData.temp_IR=buffer[1];
  288.   sensorData.mode_IR=buffer[2];
  289.   sensorData.mode_Humi=buffer[3];
  290.   // 解析第一个float(buffer[4]到buffer[7])
  291.   sensorData.data1=parse_float(&buffer[4]);
  292.   sensorData.data2=parse_float(&buffer[8]);
  293. }
  294. /*
  295. 功能:串口数据接收程序
  296. 参数:无
  297. */
  298. void Uart_Data_Recesive(void)
  299. {
  300.   while (Serial.available() > 0) {
  301.         uint8_t incomingByte = Serial.read();
  302.         
  303.         switch (state)
  304.         {
  305.             case WAIT_HEADER:
  306.                 if (incomingByte == 0xB3)
  307.                 {
  308.                     buffer[0] = incomingByte;
  309.                     dataIndex = 1;
  310.                     state = PARSE_DATA;
  311.                 }
  312.                 break;
  313.                
  314.             case PARSE_DATA:
  315.                 if (dataIndex < 12)
  316.                 {
  317.                     buffer[dataIndex] = incomingByte;
  318.                     dataIndex++;
  319.                     
  320.                     if (dataIndex == 12) {
  321.                         // 完整数据包接收完成
  322.                         memcpy(&sensorData, buffer, sizeof(SerialData));
  323.                         
  324.                         // 验证起始字节
  325.                         if (sensorData.start_flag == 0xB3)
  326.                         {
  327.                             // 数据解析成功,这里添加处理逻辑
  328.                             processData();
  329.                         }
  330.                         
  331.                         // 重置状态机
  332.                         state = WAIT_HEADER;
  333.                         dataIndex = 0;
  334.                     }
  335.                 }
  336.                 break;
  337.         }
  338.     }
  339. }
  340. /*
  341. 功能:ESP01S 初始化
  342. 参数:无
  343. */
  344. void setup()
  345. {
  346.     Serial.begin(9600);
  347.     Serial1.begin(9600);
  348.     Blinker.begin(auth, ssid, pswd);
  349.     timeClient.begin();  // 初始化NTP客户端
  350.     timeClient.update(); // 首次时间同步
  351.     BLINKER_DEBUG.stream(Serial1);
  352.     Blinker.println("System initialized");
  353.     Number1.unit("°C"); // 设置单位
  354.     Button1.attach(button1_callback);
  355.     Button2.attach(button2_callback);
  356.     Button3.attach(button3_callback);
  357.     Button4.attach(button4_callback);
  358.     Button5.attach(button5_callback);
  359.     Button6.attach(button6_callback);
  360. }
  361. /*
  362. 功能:ESP01S 循环执行函数
  363. 参数:无
  364. */
  365. void loop()
  366. {
  367.     timeClient.update();
  368.     Uart_Data_Recesive();
  369.     Blinker.run(); // 保持Blinker连接
  370. }
复制代码
3.手机APP界面

项目软硬件源文件:
通过网盘分享的文件:基于STM32(Freertos)&ESP01S的红外空调网络控制器
链接: https://pan.baidu.com/s/1v1wjqlfK64kvp4HNg9b2ew 提取码: vzx5

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

羊蹓狼

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表