STM32毕设项目分享:基于STM32的办公环境与健康监控系统

发布时间:2026/9/6 4:07:46
STM32毕设项目分享:基于STM32的办公环境与健康监控系统 一、成品简介1.实物成品成品展示2.物联网成品手机物联网APP展示二、项目简介1.具体设计内容办公环境与健康监控系统可以实现对办公环境中温湿度、甲醛浓度、CO₂浓度、光照强度等核心参数的实时采集当监测到温湿度、甲醛浓度、CO₂浓度超出预设阈值时系统自动开窗通风或关闭窗户当光照强度过暗或过亮时自动控制开灯或关灯。如果监测到久坐时长、用眼疲劳等用户办公状态自动触发语音播报提醒并支持在电脑端同步查看数据为用户提供个性化健康办公方案。2.核心任务1.可以监测办公环境的温湿度、甲醛、CO2浓度、光照强度等;2.当温湿度、甲醛浓度、CO2浓度超出预设阈值时系统自动控制开窗或关窗设备进行通风或封闭3.当光照强度过暗或过亮时自动控制照明设备开启或关闭实现环境参数的自适应调节;4.实现对用户久坐时长、用眼疲劳状态的实时检测当检测到用户久坐超过预设时间或用眼过度时系统触发语音播报模块发出起身活动、远眺休息等健康提醒5.为用户提供个性化健康办公方案支持电脑端同步查看。3.系统框图4.系统流程5.课题研究目的及意义据统计现代职场人群日均办公时长普遍超过8小时办公环境质量不佳与不良办公习惯已成为引发颈椎病、干眼症、呼吸系统不适等各类职业疾病的主要诱因。如何改善办公环境、引导健康办公习惯、降低职业疾病发生风险就显得尤为重要。对职业疾病诱因的分析表明绝大多数的职场健康问题都是由于长期处于温湿度失衡、空气质量差的办公环境以及久坐不动、用眼过度等不良习惯所引起的而传统办公场景中超过九成的环境监测依赖人工检测或单一设备报警健康提醒也缺乏针对性无法实现全时段、全方位的健康管理。目前智能办公健康管理系统的研发成为改善职场办公环境、保障职场人群健康的主要研究对象之一。国内外现有的办公环境监测设备与健康管理工具多数功能单一、集成化程度低要么只能监测单一环境指标要么仅能提供笼统的健康提醒不利于全面推广与应用。因此研发一套功能集成、成本可控、精准智能的办公环境与健康监控系统具有重要的现实意义与应用价值。为了尽可能减少由于办公环境与办公习惯引发的职业健康问题迫切需要对智能办公健康管理技术进行研究研制出一套行之有效的办公环境与健康监控系统。其中多技术融合的实时监测与智能响应技术是当今智能办公健康管理领域研究的关键着眼点。6.国内研究现状国内在办公环境监测与健康管理领域已形成多类产品与研究成果环境监测端出现了温湿度计、甲醛检测仪等单一功能设备可实现特定参数的实时采集与报警健康管理端的智能台灯、人体工学椅等设备也集成了用眼时长、坐姿等基础健康提醒功能。学者们围绕办公环境健康优化展开多维度研究焦典等以新奥尔良The Shop办公空间为案例从空间感知视角梳理出“空间动势激活身体行为、空间构件界定活动边界” 等规律构建了情感化设计引导的健康办公环境范式 [1]董丽等聚焦后疫情时代需求从环境织补化、空间弹性化、心理舒适化维度提出了办公环境健康设计策略[2]刘慧慧等结合夏热冬冷地区工业建筑改造实践通过被动式设计与主动技术集成形成了工业楼宇健康性能提升技术体系[3]张静以远洋地产WELL铂金级项目为对象总结出自然光利用、眩光控制等健康光环境设计路径[4]罗彩姿等针对光环境动态特征构建了“混合光源混合视色温”的健康光环境控制模型实现了照度均匀性与色温可调性的协同优化[5]闫海燕等对比分体式空调办公建筑不同温度模式发现26℃以上高设定温度更利于降低污染物浓度与提升人体热调节能力[6]李华亮等通过企业办公空间监测验证了通风、吸附等措施对降低甲醛、苯健康风险的有效性[7]刘慧慧等以烟台某科技园为案例从污染控制、噪声治理等维度探索了健康环境技术在绿色园区的应用[8]。单片机凭借低成本、高稳定性成为小型监测系统的核心控制单元支撑数据采集与设备联动传感器技术实现了温湿度、人体状态等参数的精准采集物联网技术则推动了数据的端侧同步共享支持远程查看。但国内研究与应用仍存不足产品功能碎片化缺乏多参数与健康状态的综合联动监测理论研究多聚焦单一领域未与智能监测技术深度融合形成一体化方案系统智能化水平有限难以生成个性化健康管理方案部分集成系统成本高、兼容性差不利于大规模推广。7.国外研究现状国外在智能办公与健康监测领域起步较早部分发达国家已形成成熟技术体系其系统可实现温湿度、空气质量等多参数全覆盖监测同时通过人体传感器、动作捕捉技术采集用户办公行为数据。学者研究聚焦办公环境与人体状态的关Xi Lin等通过荟萃分析发现21-25℃是办公最佳温度范围25℃环境会降低工作精度、延长响应时间且高认知任务或长时间暴露下温度升高的负面影响更显著同时指出采暖季降至 17℃节能具有可行性[9]Biswas等针对空调办公环境中的寒冷体质人群研究表明女性、低BMI个体更易出现该体质其代谢率低、热感觉差且调整性别与BMI影响后热感觉的关联性仍显著强调了热环境评估需结合个体特质[10]。国外成果与产品也存在短板产品成本高终端售价偏高难以在国内普通办公场景普及适配性不足基于本土办公模式设计缺乏对国内场景的定制化适配操作逻辑与交互方式不符合国内用户习惯用户体验较差这为国内本土系统的研发提供了市场空间。8.主要器件STM32F103C8T6 单片机ESP8266物联网模块ASR01语音模块AMS1117稳压模块DHT11温湿度模块LED模块0.96寸OLED模块独立按键甲醛二氧化碳检测模块光敏电阻模块舵机模块四节干电池9.原理图设计供电由四节干电池提供之后经过AMS117模块降压为5V输入到STM32最小系统板的5V引脚给系统供电。三、主要模块1.STM32单片机STM32F103C8T6 是意法半导体推出的 32 位 ARM Cortex‑M3 内核低成本的单片机工作主频 72MHz片内自带 64KB Flash 程序存储、20KB SRAM 运行内存具备多路 GPIO、ADC、I2C、SPI、USART 外设接口。2. ASR01 语音识别模块ASR01 是款离线语音识别控制模块内置语音识别算法通过串口与主控芯片通信识别成功后向 STM32 发送信息实现语音交互控制功能。3. AMS1117 稳压模块AMS1117 低压差线性稳压芯片为单片机、传感器提供安全稳定的供电。4. DHT11 温湿度模块DHT11 是款数字式温湿度复合传感器单总线通信方式能够采集环境温度与相对湿度输。5. 甲醛二氧化碳检测模块模块集成电化学 气体传感单元可以对空气中甲醛、二氧化碳浓度进行检测使用串口输出浓度信息。6 舵机模块舵机模块是PWM 控制的伺服执行器件单片机输出 PWM 信号控制舵机旋转指定角度完成机械执行动作。7 .物联网模块ESP8266物联网通信模块串口与 STM32 通信实现 WiFi 联网。可上传环境数据到云平台实现远程查看也可接收远程指令控制设备。五、项目主要源码5.1.单片机源码5.1.1主程序/* 可监测办公环境如温湿度、甲醛、CO2 浓度、光照强度等 当室内温湿度、甲醛浓度、CO2 浓度异常时系统自动开窗通风或关闭窗户当室内光线过暗或过亮时系统自动控制开灯或关灯 可检测监测久坐时长、用眼疲劳等用户办公状态久坐、用眼过度时触语音播报提醒建议起身活动、远眺休息 TVOC 三合一: CO2\ 甲醛 UART1 PA10-RX PA9-TX DHT11: 温湿度 PB0 0.96oled: 显示 IIC1 SDA-PB7 SCL-PB6 光敏电阻亮度 PA5 LED: 灯 PA7 舵机窗户 TIME2-PA0 asr01 - 语音模块 UART2 PA2-TX PA3-RX esp8266-app UART3 PB10-TX PB11-RX 按键 PB12 13 14 15 // 温度偏离设定 5℃极为异常 // 湿度偏离设定 10 极为异常 // 甲醛以及二氧化碳超浓度为异常 // 模式 甲醛 温度 // 手 / 自动 xxxppm xx // 湿度 时长 提醒 //xxx xxx 是 / 否 //CO2 甲醛 温度 //XXXppm xxxppm xx // 湿度 窗户 时长 //xx% 开 / 关 xxx // 发送 0xaa 您当前使用时长过长建议您起身活动、远眺休息 // 发送 0xbb 当前甲醛浓度超标 // 发送 0xcc 当前二氧化碳浓度超标 // 发送 0xdd 当前温度异常 // 发送 0xee 当前湿度异常 // 接收到 0x11 开启久坐提醒 // 接收到 0x22 关闭久坐提醒 // 接收到 0x55 切换自动模式 // 接收到 0x66 切换手动模式 wifileo 123456789 设置界面修改参数之后切换到参数显示界面才会进行一些控制以及播报 手动模式下不会天黑天亮开关灯以及甲醛二氧化碳异常开关窗户 自动模式下天黑开灯 天亮关灯 二氧化碳以及甲醛异常自动开窗户 当温度设定-5 提醒:温度异常 当湿度设定-10提醒湿度异常 当二氧化碳和甲醛高于预定提醒二氧化碳超标以及甲醛浓度超标 当开启提醒之后且时间超过设定时间提醒您当前使用时长过长建议您起身活动、远眺休息 也可以通过语音去 ①开启久坐提醒 ②关闭久坐提醒 ③切换手动模式 ④切换自动模式 */ #include bsp.h char oled_buffers[25]; extern uint8_t rx1; extern uint8_t rx2; extern uint8_t rx3; uint8_t mode;//0-手动 1-自动 uint8_t set_mode;//需要设置的模式 uint8_t set_inter;//0-设置界面 1-显示界面 uint16_t jiaquan_thre200; uint16_t co2_thre800; uint16_t temp_thre20; uint16_t humi_thre50; uint16_t tixing;//是否开启提醒到时间 uint16_t times_thre10;//计时的时间阈值 uint16_t times_jishi;//当前计时时间 uint16_t co2_dat; uint16_t jiaquan_dat; uint16_t temp_dat; uint16_t humi_dat; uint8_t windows_state; extern uint16_t formaldehyde_concentration; // 甲醛浓度 (ug/m³) extern uint16_t eco2_concentration ; // 等效eCO2浓度 (PPM) uint32_t tim_dly; void bsp_init() { MG90_Init();MG90_Set_Angle(0); OLED_Init(); co2_init(); esp8266_rx_init(); HAL_UART_Receive_IT(huart2, rx2, 1);//asr-2 co2_init();//uart1 //ESP8266 未调试 OLED_NewFrame(); OLED_PrintString(0, 0, (char *) OneNetConnect..., font16x16, OLED_COLOR_NORMAL); OLED_ShowFrame(); wifi_init(); OLED_PrintString(0, 16,(char *) WIFI_OK!, font16x16, OLED_COLOR_NORMAL); OLED_ShowFrame(); mqtt_init(); OLED_PrintString(0, 32,(char *) MQTT_OK!, font16x16, OLED_COLOR_NORMAL); OLED_ShowFrame(); HAL_Delay(500); } uint8_t key; DHT11_Data_TypeDef DH11; static uint16_t oled_rest0; void loop() { if(oled_rest50) {oled_rest0; OLED_Init();} //OLED OLED_NewFrame(); if(set_inter0) { sprintf((char *)oled_buffers,模式);//OLED_COLOR_REVERSED OLED_PrintString(0,0,oled_buffers,font16x16, set_mode0?OLED_COLOR_REVERSED:OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,甲醛); OLED_PrintString(42,0,oled_buffers,font16x16,set_mode1?OLED_COLOR_REVERSED:OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,温度); OLED_PrintString(84,0,oled_buffers,font16x16, set_mode2?OLED_COLOR_REVERSED:OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,湿度); OLED_PrintString(0,32,oled_buffers,font16x16, set_mode3?OLED_COLOR_REVERSED:OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,时长); OLED_PrintString(42,32,oled_buffers,font16x16, set_mode4?OLED_COLOR_REVERSED:OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,提醒); OLED_PrintString(84,32,oled_buffers,font16x16, set_mode5?OLED_COLOR_REVERSED:OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,%s,mode0?手动:自动); OLED_PrintString(0,16,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,%03dppm,jiaquan_thre); OLED_PrintString(38,16,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,%02d,temp_thre); OLED_PrintString(90,16,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,%02d,humi_thre); OLED_PrintString(5,48,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,%03d,times_thre); OLED_PrintString(42,48,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,%s,tixing0?否:是); OLED_PrintString(90,48,oled_buffers,font16x16, OLED_COLOR_NORMAL); } if(set_inter1) { sprintf((char *)oled_buffers,CO2); OLED_PrintString(0,0,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,甲醛); OLED_PrintString(42,0,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,温度); OLED_PrintString(84,0,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,%3d,co2_dat); OLED_PrintString(0,16,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,%3d,jiaquan_dat); OLED_PrintString(38,16,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,%2d,temp_dat); OLED_PrintString(90,16,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,湿度); OLED_PrintString(0,32,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,窗户); OLED_PrintString(42,32,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,时长); OLED_PrintString(84,32,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,%2d,humi_dat); OLED_PrintString(0,48,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,%s,windows_state0?关:开); OLED_PrintString(50,48,oled_buffers,font16x16, OLED_COLOR_NORMAL); sprintf((char *)oled_buffers,%3d,times_jishi); OLED_PrintString(84,48,oled_buffers,font16x16, OLED_COLOR_NORMAL); } OLED_ShowFrame(); //DH11 DHT11_ReadData(DH11); humi_datDH11.humi_int; temp_datDH11.temp_int; //co2 jiaquan_datformaldehyde_concentration; co2_dateco2_concentration ; //判断逻辑 // 温度偏离设定 5℃极为异常 // 湿度偏离设定 10 极为异常 // 甲醛以及二氧化碳超浓度为异常 // 发送 0xaa 您当前使用时长过长建议您起身活动、远眺休息 // 发送 0xbb 当前甲醛浓度超标 // 发送 0xcc 当前二氧化碳浓度超标 // 发送 0xdd 当前温度异常 // 发送 0xee 当前湿度异常 static uint8_t times_alarm; if(set_inter1)//语音提醒 { times_alarm;if(times_alarm%300) { if(temp_dattemp_thre5 ||temp_dattemp_thre-5) {uint8_t dat10xdd; HAL_UART_Transmit(huart2,dat1,1, 100);} if(humi_dathumi_thre10 ||humi_dathumi_thre-10) {uint8_t dat20xee; HAL_UART_Transmit(huart2,dat2,1, 100);} if(jiaquan_datjiaquan_thre ) {uint8_t dat30xbb; HAL_UART_Transmit(huart2,dat3,1, 100);} if(co2_datco2_thre) {uint8_t dat40xcc; HAL_UART_Transmit(huart2,dat4,1, 100);} } } if(set_inter0){times_alarm0;} //时间超过 提醒活动 static uint8_t times_dly; if(times_jishitimes_thre tixing1){times_dly;if(times_dly4){ uint8_t dat50xaa; HAL_UART_Transmit(huart2,dat5,1, 100);}} else{times_dly0;} //天黑开灯 天亮关灯 甲醛 二氧化碳异常自动开窗户 MG90_Set_Angle(uint8_t angle); if(mode1set_inter1) { if(jiaquan_datjiaquan_thre ){windows_state1;MG90_Set_Angle(60);}// if(co2_datco2_thre ){windows_state1;MG90_Set_Angle(60);} if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5)) {HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);} else {HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);} } //asr01 - 语音模块 UART2 PA2-TX PA3-RX //esp8266-app UART3 PB10-TX PB11-RX //ESP8266 Humi Temp JiaQuan CO2 static uint8_t send_times0; send_times; if(send_times1){esp8266_connect_send(Humi, humi_dat,100) ;} if(send_times45){esp8266_connect_send(Temp, temp_dat,100) ;} if(send_times80){ esp8266_connect_send(JiaQuan, jiaquan_dat,100) ;} if(send_times110){send_times0;esp8266_connect_send(CO2, co2_dat,100) ;} //计时 HAL_Delay(7);tim_dly; if(tim_dly60){tim_dly0;times_jishitimes_jishi1;} //KEY keykey_scan(); switch(key) { case 1:if(set_inter0){set_mode(set_mode1)%6;} break;//参数修改 case 2:if(set_inter0set_mode0){mode(mode1)%2;} if(set_inter0set_mode1){jiaquan_threjiaquan_thre5;if(jiaquan_thre800)jiaquan_thre0;} if(set_inter0set_mode2){temp_thretemp_thre1;if(temp_thre35)temp_thre5;} if(set_inter0set_mode3){humi_threhumi_thre1;if(humi_thre80)humi_thre10;} if(set_inter0set_mode4){times_thretimes_thre2;if(times_thre60)times_thre2;} if(set_inter0set_mode5){tixing(tixing1)%2;}break;//- case 3:if(set_inter0set_mode0){mode(mode1)%2;} if(set_inter0set_mode1){jiaquan_threjiaquan_thre-5;if(jiaquan_thre50)jiaquan_thre500;} if(set_inter0set_mode2){temp_thretemp_thre-1;if(temp_thre5)temp_thre35;} if(set_inter0set_mode3){humi_threhumi_thre-1;if(humi_thre10)humi_thre80;} if(set_inter0set_mode4){times_thretimes_thre-2;if(times_thre2)times_thre60;} if(set_inter0set_mode5){tixing(tixing1)%2;} break;// case 4: set_inter(set_inter1)%2;break;//界面修改 } } void asr_rx(uint8_t data ) { if(data0x11){ tixing1; } if(data0x22){ tixing0;} // if(data0x33){ windows_state1;MG90_Set_Angle(30); } // if(data0x44){windows_state0;MG90_Set_Angle(0); } if(data0x55){ mode 0;} if(data0x66){ mode 1;} HAL_UART_Receive_IT(huart2, rx2, 1); }5.1.2 二氧化碳甲醛检测模块#include co2.h uint8_t co2_rx; // 存储每次中断接收的字节 uint16_t tvoc_concentration 0; // TVOC浓度 (ug/m³) uint16_t formaldehyde_concentration 0; // 甲醛浓度 (ug/m³) uint16_t eco2_concentration 0; // 等效eCO2浓度 (PPM) uint8_t co2_data_ready 0; // 数据解析完成标志 void co2_init(void) { HAL_UART_Receive_IT(huart1, co2_rx, 1); } void co2_it_get(void) { static uint8_t co2_state 0; static uint8_t tvoc_temp[2]; // TVOC高低字节 static uint8_t formaldehyde_temp[2]; // 甲醛高低字节 static uint8_t eco2_temp[2]; // eCO2高低字节 static uint8_t sum 0; // 校验和只保留低8位 switch (co2_state) { case 0: // 等待帧头 0x2C if (co2_rx 0x2C) { sum 0x2C; co2_state 1; } break; case 1: // 等待 0xE4 if (co2_rx 0xE4) { sum 0xE4; co2_state 2; } else { co2_state 0; // 帧头错误重置 } break; case 2: // TVOC 高字节 tvoc_temp[0] co2_rx; sum co2_rx; co2_state 3; break; case 3: // TVOC 低字节 tvoc_temp[1] co2_rx; sum co2_rx; co2_state 4; break; case 4: // 甲醛 高字节 formaldehyde_temp[0] co2_rx; sum co2_rx; co2_state 5; break; case 5: // 甲醛 低字节 formaldehyde_temp[1] co2_rx; sum co2_rx; co2_state 6; break; case 6: // eCO2 高字节 eco2_temp[0] co2_rx; sum co2_rx; co2_state 7; break; case 7: // eCO2 低字节 eco2_temp[1] co2_rx; sum co2_rx; co2_state 8; break; case 8: // 校验和第9字节 sum 0xFF; // 只保留低8位重要 if (sum co2_rx) { // 解析成功 tvoc_concentration (tvoc_temp[0] 8) | tvoc_temp[1]; formaldehyde_concentration (formaldehyde_temp[0] 8) | formaldehyde_temp[1]; eco2_concentration (eco2_temp[0] 8) | eco2_temp[1]; co2_data_ready 1; } else { co2_data_ready 0; // 校验失败 } // 重置状态准备下一帧 co2_state 0; sum 0; break; default: co2_state 0; sum 0; break; } // debug_send(%c,co2_rx); HAL_UART_Receive_IT(huart1, co2_rx, 1); // 启动下一次中断接收 }5.1.3温湿度读取代码#include dh11.h static void DHT11_PP_OUT(void) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin DHT11_PIN; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(DHT11_PORT, GPIO_InitStruct); } /** * ************************************************************************ * brief 将DHT11配置为上拉输入模式 * ************************************************************************ */ static void DHT11_UP_IN(void) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin DHT11_PIN; GPIO_InitStruct.Mode GPIO_MODE_INPUT; GPIO_InitStruct.Pull GPIO_PULLUP; //上拉 HAL_GPIO_Init(DHT11_PORT, GPIO_InitStruct); } /** * ************************************************************************ * brief 读取字节 * return temp * ************************************************************************ */ uint8_t DHT11_ReadByte(void) { uint8_t i, temp 0; for (i 0; i 8; i) { while (DHT11_ReadPin 0); // 等待低电平结束 delay_us(40); // 延时 40 微秒 if (DHT11_ReadPin 1) { while (DHT11_ReadPin 1); // 等待高电平结束 temp | (uint8_t)(0X01 (7 - i)); // 先发送高位 } else { temp (uint8_t)~(0X01 (7 - i)); } } return temp; } /** * ************************************************************************ * brief 读取一次数据 * param[in] DHT11_Data 定义的结构体变量 * return 0或1数据校验是否成功 * note 它首先向DHT11发送启动信号然后等待DHT11的应答。如果DHT11正确应答 * 则继续读取湿度整数、湿度小数、温度整数、温度小数和校验和数据 * 并计算校验和以进行数据校验 * ************************************************************************ */ uint8_t DHT11_ReadData(DHT11_Data_TypeDef *DHT11_Data) { DHT11_PP_OUT(); // 主机输出主机拉低 DHT11_PULL_0; HAL_Delay(18); // 延时 18 ms DHT11_PULL_1; // 主机拉高延时 30 us delay_us(30); DHT11_UP_IN(); // 主机输入获取 DHT11 数据 if (DHT11_ReadPin 0) // 收到从机应答 { while (DHT11_ReadPin 0); // 等待从机应答的低电平结束 while (DHT11_ReadPin 1); // 等待从机应答的高电平结束 /*开始接收数据*/ DHT11_Data-humi_int DHT11_ReadByte(); DHT11_Data-humi_dec DHT11_ReadByte(); DHT11_Data-temp_int DHT11_ReadByte(); DHT11_Data-temp_dec DHT11_ReadByte(); DHT11_Data-check_sum DHT11_ReadByte(); DHT11_PP_OUT(); // 读取结束主机拉高 DHT11_PULL_1; // 数据校验 if (DHT11_Data-check_sum DHT11_Data-humi_int DHT11_Data-humi_dec DHT11_Data-temp_int DHT11_Data-temp_dec) { return 1; } else { return 0; } } else // 未收到从机应答 { return 0; } } //任务 //extern uint16_t dt11_update_add; //DHT11_Data_TypeDef DHT11_Data; //void dt11_task() //{ // if(dt11_update_add500) return; // dt11_update_add0; // DHT11_ReadData(DHT11_Data); //} //////if (DHT11_ReadData(DHT11_Data)) ////// { ////// printf(湿度%d RH 温度%d ℃ \n, DHT11_Data.humi_int, DHT11_Data.temp_int); ////// }5.1.4ESP8266物联网模块#include esp8266.h /* */ #define TX_SIZE 245 char at_txbuffer[TX_SIZE]{0}; #define RX_SIZE 245 char at_rxbuffer[RX_SIZE]{0}; uint8_t at_rxindex; uint8_t at_rx; #define WIFI_SSID leo #define WIFI_PASSWORD 123456789 #define WIFI_ONENET_PRODUCT_ID h1pDm19B6T #define WIFI_ONENET_DEVICE_NAME XX #define WIFI_ONENET_TOKEN version2018-10-31resproducts%XX%XXXet1851106542methodmd5signXX%3D%3D #define MQTT_HOST_URL mqtts.heclouds.com #define MQTT_HOST_PORT 1883 const char* topic1 $sys/ WIFI_ONENET_PRODUCT_ID / WIFI_ONENET_DEVICE_NAME /thing/property/post/reply; const char* topic2 $sys/ WIFI_ONENET_PRODUCT_ID / WIFI_ONENET_DEVICE_NAME /thing/property/set; // 串口接收中断处理增加缓冲区溢出保护 void uart_rx_esp8266() { if(at_rxindex RX_SIZE - 1) // 留1个位置给结束符 { at_rxbuffer[at_rxindex] at_rx; at_rxbuffer[at_rxindex] \0; // 实时添加结束符确保strstr正常工作 } else { at_rxindex 0; // 溢出则重置 memset(at_rxbuffer, 0, RX_SIZE); } HAL_UART_Receive_IT(huart3, at_rx, 1); } void esp8266_printf(char* fmt, ...) { memset(at_txbuffer, 0, TX_SIZE); va_list ap; va_start(ap, fmt); vsprintf(at_txbuffer, fmt, ap); va_end(ap); uint16_t length strlen(at_txbuffer); HAL_UART_Transmit(huart3, (uint8_t*)at_txbuffer, length, 2000); } void esp8266_rx_init() { at_rxindex 0; memset(at_rxbuffer, 0, RX_SIZE); HAL_UART_Receive_IT(huart3, at_rx, 1); } // 发送AT指令通用函数确保指令以\r\n结尾 char esp8266_send_cmd(char *cmd, int timeout) { at_rxindex 0; memset(at_rxbuffer, 0, RX_SIZE); esp8266_printf(%s\r\n, cmd); // 所有指令必须加\r\n HAL_UART_Transmit(huart1, (uint8_t*)cmd, strlen(cmd), 2000); while(timeout--) { HAL_Delay(1); // 每次等待10ms if(strstr(at_rxbuffer, OK) ! NULL) // 找到OK表示成功 { return 0; // 成功 } else if(strstr(at_rxbuffer, ready) ! NULL)//ready { return 0; // 成功 } else if(strstr(at_rxbuffer, ) ! NULL) { return 0; // 成功 }//MQTTCONNECTED // 增加错误判断如出现ERROR也返回失败 else if(strstr(at_rxbuffer, ERROR) ! NULL) { } } return -1; // 超时失败 } char wifi_init() { HAL_Delay(2500); esp8266_printf(ATRESTORE\r\n ); HAL_Delay(2500); while(1) { int8_t connect; connectesp8266_send_cmd(ATCWMODE1,1500); if(connect!-1){break;} } while(1) { int8_t connect; connectesp8266_send_cmd(ATCWJAP\leo\,\123456789\,5000); if(connect!-1){break;} } return 0; } char mqtt_init() { while(1) { int8_t connect; connectesp8266_send_cmd(ATMQTTUSERCFG0,1,\XX\,\XXX\,\version2018-10-31resproducts%2Fh1pDm19B6T%2Fdevices%XXXet1821354075XXXmd5signXXX%2BA%3D%3D\,0,0,\\,4000); if(connect!-1){break;} } while(1) { int8_t connect; connectesp8266_send_cmd(ATMQTTCONN0,\mqtts.heclouds.com\,1883,1,4000);// if(connect!-1){break;} } while(1) { int8_t connect; connectesp8266_send_cmd(ATMQTTSUB0,\$sys/XX//XX/thing/property/post/reply\,0,4000); if(connect!-1){break;} } while(1) { int8_t connect; connectesp8266_send_cmd(ATMQTTSUB0,\$sys/XX//XX/thing/property/set\,0,1500); if(connect!-1){break;} } return 0; } char esp8266_connect_send(const char* paramName, int value, int timeout) { char cmd[256]; // 在逗号前添加反斜杠转义符用\\\\\,\\\ 生成 \,\ 的效果 sprintf(cmd, ATMQTTPUB0,\$sys/%s/%s/thing/property/post\,\{\\\id\\\:\\\123\\\\\,\\\params\\\:{\\\%s\\\:{\\\value\\\:%d}}}\,0,0, WIFI_ONENET_PRODUCT_ID, WIFI_ONENET_DEVICE_NAME, paramName, value); return esp8266_send_cmd(cmd, timeout); }5.1.5 按键检测代码#include key.h //KEY1-5:PA6 PA7 PB0 PB1 pb10 #define KEY1 HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) #define KEY2 HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) #define KEY3 HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) #define KEY4 HAL_GPIO_ReadPin(KEY4_GPIO_Port, KEY4_Pin) uint8_t key_scan() { static uint8_t key_up1; if(key_up1(KEY10||KEY20||KEY30||KEY40)) { key_up0; if(KEY10) return 1; if(KEY20) return 2; if(KEY30) return 3; if(KEY40) return 4; } else if(KEY11KEY21KEY31KEY41) { key_up1; } return 0; }六、工程主要内容工程的具体内容包括但不限于原理图、程序代码、流程图等等。完整工程、原理图、APP 源码我已经开源到 Gitee需要的同学可以评论区留言或者私信A01-基于STM32的办公环境与健康监控系统

相关新闻