一.项目背景
最近为了完成交付的任务,遂重制了一下小项目用STM32做一个小型的环境监测系统。
项目整体示意框图如下:
二.器件选择- 单片机(STM32F103)
- 数字温湿度模块(DHT11)
- 液晶显示模块(0.8寸OLED)
- 粉尘传感器模块(GP2Y10)
- 报警模块(蜂鸣器)
- 按键控制模块(独立按键)
由于笔者觉得时钟模块没什么必要性,就没再加DS1302上去了。
三.PCB绘制
PCB推荐使用嘉立创专业版绘制,对于初学者来说简单易上手,而且这种DIY的小玩意绘制的PCB大小控制在10*10以内还可以免费打样。
嘉立创很方便的一点是可以使用它内部自带的在线库,省去了自己画封装画元件的步骤,非常简单,但是注意要辨别这里的元件封装的正确性,因为有些元件封装是用户贡献的,所以有些地方不一定正确,各位读者如果是小白的话一定要注意辨别是否符合自己的需求!!!
四.核心代码
以下只对部分核心代码做展示。
Task.c
- #include "Task.h"
- uint8_t Prime_Mode = 0;
- uint8_t Start_Mode = 0;
- uint8_t Threshold_Mode = 0;//温度调节模式
- bool isCollecting = false;
- int Humidity = 0,Temperature = 0;
- float Dust_Concentration = 0;
- uint8_t TemperatureMax = 30;
- uint8_t TemperatureMin = 10;
- uint8_t DataRead_Count = 0;//数据采集计次
- uint8_t Blink_Count = 0;//闪烁
- uint16_t Timer_2000ms = 0;//数据采集间隔
- uint16_t Timer_Blink = 0;//
- void Task_Test(void)
- {
- //LCD_Test();
- //Key_Test();
- }
- void Device_Init(void)
- {
- LCD_Init();
- Buzzer_Init();
- DHT11_Init();
- GP2Y10_Init();
- Key_Init();
- }
- void Task_Key(void)
- {
- uint8_t Key_Number = Key_Scan();
-
- if(Prime_Mode == 2)
- {
- if(Key_Number == 1)
- {
- LCD_Clear();
- Start_Mode = 1;
- Prime_Mode = 0;
- isCollecting = false;
- }
- }
- else
- {
- if(Key_Number == 1)
- {
- LCD_Clear();
- Start_Mode ^= 1;
- Prime_Mode = 0;
- isCollecting = false;
- }
- }
- if(Prime_Mode == 2)
- {
- if(Key_Number == 2)
- {
- LCD_Clear();
- Threshold_Mode ^= 1;
- }
-
- }
- else
- {
- if(Key_Number == 2)
- {
- LCD_Clear();
- Prime_Mode = 1;
- isCollecting = false;
- }
- }
-
- //设置报警阈值
- if(Key_Number == 3)
- {
- LCD_Clear();
- Prime_Mode = 2;
- isCollecting = false;
-
- if(Threshold_Mode == 0)//高温阈值++
- {
- ++TemperatureMax;
- }
- if(Threshold_Mode == 1)//低温阈值++
- {
- ++TemperatureMin;
- }
- }
- if(Key_Number == 4)
- {
- LCD_Clear();
- Prime_Mode = 2;
- isCollecting = false;
-
- if(Threshold_Mode == 0)//高温阈值++
- {
- --TemperatureMax;
- }
- if(Threshold_Mode == 1)//低温阈值++
- {
- --TemperatureMin;
- }
- }
- }
- void filter_and_smooth(float *data, int size, float *smoothed_data) {
- // 滤除0
- int count = 0;
- for (int i = 0; i < size; i++) {
- if (data[i] != 0) {
- smoothed_data[count++] = data[i];
- }
- }
- // 平滑曲线
- for (int i = 0; i < count - 2; i++) {
- smoothed_data[i] = (smoothed_data[i] + smoothed_data[i + 1] + smoothed_data[i + 2]) / 3.0;
- }
- }
- void Task_DataCollect(void)
- {
- //DHT11_Read(&Humidity,&Temperature);
- if ( DHT11_Read(&Humidity,&Temperature) !=0 )
- {
- DHT11_Init();
- }
- Dust_Concentration = Get_PM25_Average_Data();//采集粉尘浓度数据
- // printf("Humidity:%d\n",Humidity);
- // printf("Temperature:%d\n",Temperature);
- // printf("PM2.5:%f\n",Dust_Concentration);
- printf("%f\n",Dust_Concentration/10);
- }
- void Task_Alarm(void)
- {
- if(Temperature > TemperatureMax || Temperature < TemperatureMin)
- {
- Buzzer_Control(ON);
- mdelay(20);
- Buzzer_Control(OFF);
- mdelay(20);
- }
- }
- void Task_OLED(void)
- {
- switch(Prime_Mode)
- {
- case 0:
- {
- //控制启动关机
- if(Start_Mode == 1)//开机
- {
- LCD_PrintString(0,0,"Welcome to:");
- LCD_PrintString(5,2,"System");
- }
- else//关机
- LCD_Clear();
- break;
- }
- case 1://温湿度,PM2.5浓度
- {
- if(Start_Mode == 1)
- {
- if(!isCollecting)
- {
- LCD_PrintString(2,3,"Collecting...");
- mdelay(3000);
- LCD_Clear();
- isCollecting = true;
- }
- LCD_PrintString(0,0,"Data=>");
- LCD_PrintString(0,2,"Humidity:");
- LCD_PrintSignedVal(9, 2, Humidity);
- LCD_PrintString(0,4,"Temperature:");
- LCD_PrintSignedVal(12, 4, Temperature);
- LCD_PrintString(0,6,"PM2.5:");
- LCD_PrintSignedVal(6, 6, (int)Dust_Concentration);
- }
- break;
- }
- case 2://设置报警阈值
- {
- if(Start_Mode == 1)
- {
- LCD_PrintString(0,2,"High:");
-
- LCD_PrintString(0,4,"Low:");
-
- if(Threshold_Mode == 0)
- {
- if(Blink_Count == 0)
- LCD_PrintSignedVal(6, 2, TemperatureMax);
- else
- LCD_PrintString(6,2," ");
- LCD_PrintSignedVal(6, 4, TemperatureMin);
- }
- if(Threshold_Mode == 1)
- {
- LCD_PrintSignedVal(6, 2, TemperatureMax);
- if(Blink_Count == 0)
- LCD_PrintSignedVal(6, 4, TemperatureMin);
- else
- LCD_PrintString(6,4," ");
- }
- }
- break;
- }
- // case 3://出行建议
- // {
- // if(Start_Mode == 1)
- // {
- // if(Humidity > HUM_MAX)
- // LCD_PrintString(0,0,"The humidity is too high!!!");
- // else if(Humidity < HUM_MIN)
- // LCD_PrintString(0,0,"The humidity is too low!!!");
- // }
- // break;
- // }
- }
- }
- void Task_Prime(void)
- {
- Task_Key();
- if(DataRead_Count == 1)
- {
- Task_DataCollect();
- DataRead_Count = 0;
- }
- Task_Alarm();
- Task_OLED();
- }
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- if(htim->Instance == TIM2)
- {
- ++Timer_2000ms;
- ++Timer_Blink;
- if(Timer_2000ms >= 2000)
- {
- DataRead_Count++;
- Timer_2000ms = 0;
- }
- if(Timer_Blink >= 650)
- {
- Blink_Count ^= 1;
- Timer_Blink = 0;
- }
- }
- }
复制代码
五.最终效果
六.总结
通过本项目的实践,不仅实现了基础功能监测,还为未来更复杂的项目打下了坚实的基础。希望读者通过该项目,也能够掌握模块化开发的思路,逐步进阶!
原理图pcb: 无
仿真: 无
项目源码如下:
PM2.5_Monitor_NoRTOS.7z
(5.92 MB, 下载次数: 0)
|