找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1350|回复: 1
打印 上一主题 下一主题
收起左侧

基于STM32单片机的PM2.5环境监测系统设计

[复制链接]
跳转到指定楼层
楼主
一.项目背景
最近为了完成交付的任务,遂重制了一下小项目用STM32做一个小型的环境监测系统。
        项目整体示意框图如下:


二.器件选择
  • 单片机(STM32F103)
  • 数字温湿度模块(DHT11)
  • 液晶显示模块(0.8寸OLED)
  • 粉尘传感器模块(GP2Y10)
  • 报警模块(蜂鸣器)
  • 按键控制模块(独立按键)
        由于笔者觉得时钟模块没什么必要性,就没再加DS1302上去了。
三.PCB绘制
PCB推荐使用嘉立创专业版绘制,对于初学者来说简单易上手,而且这种DIY的小玩意绘制的PCB大小控制在10*10以内还可以免费打样。
        嘉立创很方便的一点是可以使用它内部自带的在线库,省去了自己画封装画元件的步骤,非常简单,但是注意要辨别这里的元件封装的正确性,因为有些元件封装是用户贡献的,所以有些地方不一定正确,各位读者如果是小白的话一定要注意辨别是否符合自己的需求!!!


四.核心代码
以下只对部分核心代码做展示。


Task.c

  1. #include "Task.h"

  2. uint8_t Prime_Mode = 0;
  3. uint8_t Start_Mode = 0;
  4. uint8_t Threshold_Mode = 0;//温度调节模式
  5. bool isCollecting = false;

  6. int Humidity = 0,Temperature = 0;
  7. float Dust_Concentration = 0;
  8. uint8_t TemperatureMax = 30;
  9. uint8_t TemperatureMin = 10;

  10. uint8_t DataRead_Count = 0;//数据采集计次
  11. uint8_t Blink_Count = 0;//闪烁
  12. uint16_t Timer_2000ms = 0;//数据采集间隔
  13. uint16_t Timer_Blink = 0;//

  14. void Task_Test(void)
  15. {
  16.         //LCD_Test();
  17.         //Key_Test();
  18. }

  19. void Device_Init(void)
  20. {
  21.         LCD_Init();
  22.         Buzzer_Init();
  23.         DHT11_Init();
  24.         GP2Y10_Init();
  25.         Key_Init();
  26. }

  27. void Task_Key(void)
  28. {
  29.         uint8_t Key_Number = Key_Scan();
  30.         
  31.         if(Prime_Mode == 2)
  32.         {
  33.                 if(Key_Number == 1)
  34.                 {
  35.                         LCD_Clear();
  36.                         Start_Mode = 1;
  37.                         Prime_Mode = 0;
  38.                         isCollecting = false;
  39.                 }
  40.         }
  41.         else
  42.         {
  43.                 if(Key_Number == 1)
  44.                 {
  45.                         LCD_Clear();
  46.                         Start_Mode ^= 1;
  47.                         Prime_Mode = 0;
  48.                         isCollecting = false;
  49.                 }
  50.         }

  51.         if(Prime_Mode == 2)
  52.         {
  53.                 if(Key_Number == 2)
  54.                 {
  55.                         LCD_Clear();
  56.                         Threshold_Mode ^= 1;
  57.                 }
  58.                
  59.         }
  60.         else
  61.         {
  62.                 if(Key_Number == 2)
  63.                 {
  64.                         LCD_Clear();
  65.                         Prime_Mode = 1;
  66.                         isCollecting = false;
  67.                 }
  68.         }
  69.                

  70.         //设置报警阈值
  71.         if(Key_Number == 3)
  72.         {
  73.                 LCD_Clear();
  74.                 Prime_Mode = 2;
  75.                 isCollecting = false;
  76.                
  77.                 if(Threshold_Mode == 0)//高温阈值++
  78.                 {
  79.                         ++TemperatureMax;
  80.                 }
  81.                 if(Threshold_Mode == 1)//低温阈值++
  82.                 {
  83.                         ++TemperatureMin;
  84.                 }
  85.         }
  86.         if(Key_Number == 4)
  87.         {
  88.                 LCD_Clear();
  89.                 Prime_Mode = 2;
  90.                 isCollecting = false;
  91.                
  92.                 if(Threshold_Mode == 0)//高温阈值++
  93.                 {
  94.                         --TemperatureMax;
  95.                 }
  96.                 if(Threshold_Mode == 1)//低温阈值++
  97.                 {
  98.                         --TemperatureMin;
  99.                 }
  100.         }
  101. }

  102. void filter_and_smooth(float *data, int size, float *smoothed_data) {
  103.     // 滤除0
  104.     int count = 0;
  105.     for (int i = 0; i < size; i++) {
  106.         if (data[i] != 0) {
  107.             smoothed_data[count++] = data[i];
  108.         }
  109.     }

  110.     // 平滑曲线
  111.     for (int i = 0; i < count - 2; i++) {
  112.         smoothed_data[i] = (smoothed_data[i] + smoothed_data[i + 1] + smoothed_data[i + 2]) / 3.0;
  113.     }
  114. }


  115. void Task_DataCollect(void)
  116. {
  117.         //DHT11_Read(&Humidity,&Temperature);
  118.         if ( DHT11_Read(&Humidity,&Temperature) !=0 )
  119.         {
  120.                 DHT11_Init();
  121.         }
  122.         Dust_Concentration = Get_PM25_Average_Data();//采集粉尘浓度数据
  123. //        printf("Humidity:%d\n",Humidity);
  124. //        printf("Temperature:%d\n",Temperature);
  125. //        printf("PM2.5:%f\n",Dust_Concentration);
  126.         printf("%f\n",Dust_Concentration/10);
  127. }

  128. void Task_Alarm(void)
  129. {
  130.         if(Temperature > TemperatureMax || Temperature < TemperatureMin)
  131.         {
  132.                 Buzzer_Control(ON);
  133.                 mdelay(20);
  134.                 Buzzer_Control(OFF);
  135.                 mdelay(20);
  136.         }        
  137. }


  138. void Task_OLED(void)
  139. {
  140.         switch(Prime_Mode)
  141.         {
  142.                 case 0:
  143.                 {
  144.                         //控制启动关机
  145.                         if(Start_Mode == 1)//开机
  146.                         {
  147.                                 LCD_PrintString(0,0,"Welcome to:");
  148.                                 LCD_PrintString(5,2,"System");
  149.                         }
  150.                         else//关机
  151.                                 LCD_Clear();
  152.                         break;
  153.                 }
  154.                 case 1://温湿度,PM2.5浓度
  155.                 {
  156.                         if(Start_Mode == 1)
  157.                         {
  158.                                 if(!isCollecting)
  159.                                 {
  160.                                         LCD_PrintString(2,3,"Collecting...");
  161.                                         mdelay(3000);
  162.                                         LCD_Clear();
  163.                                         isCollecting = true;
  164.                                 }
  165.                                 LCD_PrintString(0,0,"Data=>");
  166.                                 LCD_PrintString(0,2,"Humidity:");
  167.                                 LCD_PrintSignedVal(9, 2, Humidity);
  168.                                 LCD_PrintString(0,4,"Temperature:");
  169.                                 LCD_PrintSignedVal(12, 4, Temperature);
  170.                                 LCD_PrintString(0,6,"PM2.5:");
  171.                                 LCD_PrintSignedVal(6, 6, (int)Dust_Concentration);
  172.                         }
  173.                         break;
  174.                 }
  175.                 case 2://设置报警阈值
  176.                 {
  177.                         if(Start_Mode == 1)
  178.                         {
  179.                                 LCD_PrintString(0,2,"High:");
  180.                                 
  181.                                 LCD_PrintString(0,4,"Low:");
  182.                                 
  183.                                 if(Threshold_Mode == 0)
  184.                                 {
  185.                                         if(Blink_Count == 0)
  186.                                                 LCD_PrintSignedVal(6, 2, TemperatureMax);
  187.                                         else
  188.                                                 LCD_PrintString(6,2,"     ");
  189.                                         LCD_PrintSignedVal(6, 4, TemperatureMin);
  190.                                 }
  191.                                 if(Threshold_Mode == 1)
  192.                                 {
  193.                                         LCD_PrintSignedVal(6, 2, TemperatureMax);
  194.                                         if(Blink_Count == 0)
  195.                                                 LCD_PrintSignedVal(6, 4, TemperatureMin);
  196.                                         else
  197.                                                 LCD_PrintString(6,4,"     ");
  198.                                 }
  199.                         }
  200.                         break;
  201.                 }
  202. //                case 3://出行建议
  203. //                {
  204. //                        if(Start_Mode == 1)
  205. //                        {
  206. //                                if(Humidity > HUM_MAX)
  207. //                                        LCD_PrintString(0,0,"The humidity is too high!!!");
  208. //                                else if(Humidity < HUM_MIN)
  209. //                                        LCD_PrintString(0,0,"The humidity is too low!!!");
  210. //                        }
  211. //                        break;
  212. //                }               
  213.         }
  214. }

  215. void Task_Prime(void)
  216. {
  217.         Task_Key();
  218.         if(DataRead_Count == 1)
  219.         {
  220.                 Task_DataCollect();
  221.                 DataRead_Count = 0;
  222.         }
  223.         Task_Alarm();
  224.         Task_OLED();
  225. }

  226. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  227. {
  228.         if(htim->Instance == TIM2)
  229.         {
  230.                 ++Timer_2000ms;
  231.                 ++Timer_Blink;
  232.                 if(Timer_2000ms >= 2000)
  233.                 {
  234.                         DataRead_Count++;
  235.                         Timer_2000ms = 0;
  236.                 }
  237.                 if(Timer_Blink >= 650)
  238.                 {
  239.                         Blink_Count ^= 1;
  240.                         Timer_Blink = 0;
  241.                 }
  242.         }
  243. }
复制代码


五.最终效果

六.总结
通过本项目的实践,不仅实现了基础功能监测,还为未来更复杂的项目打下了坚实的基础。希望读者通过该项目,也能够掌握模块化开发的思路,逐步进阶!

原理图pcb: 无
仿真: 无
项目源码如下: PM2.5_Monitor_NoRTOS.7z (5.92 MB, 下载次数: 0)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:302495 发表于 2024-12-20 12:59 | 只看该作者
厉害啊大佬,学习了
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表