|
一.項(xiàng)目背景
最近為了完成交付的任務(wù),遂重制了一下小項(xiàng)目用STM32做一個小型的環(huán)境監(jiān)測系統(tǒng)。
項(xiàng)目整體示意框圖如下:
圖片1.png (9.67 KB, 下載次數(shù): 0)
下載附件
2024-12-16 12:42 上傳
二.器件選擇- 單片機(jī)(STM32F103)
- 數(shù)字溫濕度模塊(DHT11)
- 液晶顯示模塊(0.8寸OLED)
- 粉塵傳感器模塊(GP2Y10)
- 報警模塊(蜂鳴器)
- 按鍵控制模塊(獨(dú)立按鍵)
由于筆者覺得時鐘模塊沒什么必要性,就沒再加DS1302上去了。
三.PCB繪制
PCB推薦使用嘉立創(chuàng)專業(yè)版繪制,對于初學(xué)者來說簡單易上手,而且這種DIY的小玩意繪制的PCB大小控制在10*10以內(nèi)還可以免費(fèi)打樣。
嘉立創(chuàng)很方便的一點(diǎn)是可以使用它內(nèi)部自帶的在線庫,省去了自己畫封裝畫元件的步驟,非常簡單,但是注意要辨別這里的元件封裝的正確性,因?yàn)橛行┰庋b是用戶貢獻(xiàn)的,所以有些地方不一定正確,各位讀者如果是小白的話一定要注意辨別是否符合自己的需求�。。�
51hei圖片_20241122173050.png (155.64 KB, 下載次數(shù): 0)
下載附件
2024-12-16 12:42 上傳
51hei圖片_20241122173524.png (73.41 KB, 下載次數(shù): 0)
下載附件
2024-12-16 12:42 上傳
6319660e2ee25d12fde8f9d1568409a1.png (392 KB, 下載次數(shù): 0)
下載附件
2024-12-16 12:42 上傳
四.核心代碼
以下只對部分核心代碼做展示。
Snipaste_2024-12-16_12-41-38.png (67.06 KB, 下載次數(shù): 0)
下載附件
2024-12-16 12:42 上傳
Task.c
- #include "Task.h"
- uint8_t Prime_Mode = 0;
- uint8_t Start_Mode = 0;
- uint8_t Threshold_Mode = 0;//溫度調(diào)節(jié)模式
- 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;//數(shù)據(jù)采集計(jì)次
- uint8_t Blink_Count = 0;//閃爍
- uint16_t Timer_2000ms = 0;//數(shù)據(jù)采集間隔
- 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;
- }
- }
-
- //設(shè)置報警閾值
- 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();//采集粉塵濃度數(shù)據(jù)
- // 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:
- {
- //控制啟動關(guān)機(jī)
- if(Start_Mode == 1)//開機(jī)
- {
- LCD_PrintString(0,0,"Welcome to:");
- LCD_PrintString(5,2,"System");
- }
- else//關(guān)機(jī)
- 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://設(shè)置報警閾值
- {
- 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;
- }
- }
- }
復(fù)制代碼
五.最終效果
Snipaste_2024-12-16_12-41-58.png (313.92 KB, 下載次數(shù): 0)
下載附件
2024-12-16 12:42 上傳
六.總結(jié)
通過本項(xiàng)目的實(shí)踐,不僅實(shí)現(xiàn)了基礎(chǔ)功能監(jiān)測,還為未來更復(fù)雜的項(xiàng)目打下了堅(jiān)實(shí)的基礎(chǔ)。希望讀者通過該項(xiàng)目,也能夠掌握模塊化開發(fā)的思路,逐步進(jìn)階!
原理圖pcb: 無
仿真: 無
項(xiàng)目源碼如下:
PM2.5_Monitor_NoRTOS.7z
(5.92 MB, 下載次數(shù): 0)
2024-12-16 12:46 上傳
點(diǎn)擊文件名下載附件
項(xiàng)目源碼文件 下載積分: 黑幣 -5
|
評分
-
查看全部評分
|