一、任務目標
? ? ? ? 使用STM32F103C8T6單片機,使用單片機AD模塊采集MQ2煙霧傳感器的數據,在OLED屏顯示檢測到的AD值、電壓值和濃度值(ppm單位)。
二、實現過程
1、MQ2煙霧傳感器的濃度轉化方法
(1)實驗所用的MQ2的鏈接
商品詳情
(2)MQ2的技術參數
1、具有信號輸出指示。
2、雙路信號輸出(模擬量輸出及TTL電平輸出)
3、TTL輸出有效信號為低電平。(當輸出低電平時信號燈亮,可直接接單片機) ????????????????
4、模擬量輸出0~5V電壓,濃度越高電壓越高。
5、對液化氣,天然氣,城市煤氣有較好的靈敏度。
6、具有長期的使用壽命和可靠的穩定性
7、快速的響應恢復特性
傳感器模塊的原理圖為:
由技術參數可知,MQ2模塊輸出0-5V的模擬量電壓,而STM32單片機的AD電壓采集范圍為0-3.3V,所以需要使用分壓電路將0-5V轉化為0-3.3V的范圍,以下為參考電路
其中,MQ2_AD連接到單片機AD采集引腳。
(3)濃度轉化推算
由傳感器的靈敏度曲線可知,不同濃度的ppm對應不同的RS/R0值,其中RS為元件在不同氣體不同濃度下傳感器的電阻值,R0為元件在潔凈空氣中電阻值。
又由電路可知,Vrl/Rl = (Vc - Vrl)/Rs;
Vrl:即AO口輸出電壓
Vc:回路電壓5V
Rl:Rl為可調電阻,這里電路里面Rl為第一張電路里面的R2為1K歐姆固定值。
從而,已知Vrl、Vc、Rl可以算出RS,已知RS和R0就可以得出不同濃度的ppm值。
根據靈敏度特性曲線,可進一步得出RS/R0與ppm的方程:
選擇丙烷(propane)使用matlab進行提取曲線,
ppm=[200 500 800 1000 1562 2000 3000 5000 10000];
Rs/R0=[1.74 1.22 0.90 0.80 0.63 0.60 0.50 0.38 0.27];
根據Rs/R0=a*(ppm)^b,得到
? ? ? ? ? ? ? ? ? Rs/R0=21.72×(ppm)^(-0.4739)
也即
? ? ? ? ? ? ? ? ppm=(21.72×R0/RS)^(2.1101)
最后,我們將單片機AD引腳采集到的在潔凈空氣中的電壓為0.78V,算出R0=(Vc-Vrl)*Rl/vrl=(5-0.78)*1/0.78=5.41(正常空氣情況下的Vrl值)。(由于R0和RS電阻值單位為千歐,這里都約掉千歐單位)
由RS=(Vc-Vrl)*Rl/vrl=(5-Vrl)*1/vrl,ppm=pow(21.72*R0/Rs,2.1101);即可得出濃度值。
2、STM32單片機的實現過程
(1)建立cubemx工程,并添加ADC設置和IIC驅動的OLED屏設置,即ADC檢測接PA1引腳,OLED的IIC接PB6---SCL,PB7---SDA。
(2)添加程序實現代碼
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_ADC1_Init();MX_I2C1_Init();/* USER CODE BEGIN 2 */OLED_Init();OLED_Clear();// htim2.Instance->CNT=0; /* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */Get_Smoke_ADC_Value();//獲取MQ2煙霧模塊的ADC值
// key=KEY_Scan(0); //獲取按鍵值OLED_ShowString(8, 1, "Smoke Detect", 12);//OLED屏第一行顯示煙霧檢測字符串OLED_ShowString(0, 3, "ADC_Value:", 12);//OLED屏第三行顯示MQ2的ADC_Value采樣值字符串OLED_ShowNum(80, 3, MQ2_ADC_Value, 4, 12); //OLED屏第三行顯示ADC采集值OLED_ShowString(0, 4, "ADC_Volt:", 12);//OLED屏第四行顯示MQ2的ADC_Volt采樣電壓字符串MQ2_ADC_Volt100=MQ2_ADC_Volt*100;//將采樣電壓擴大100倍 sprintf((char*)str_buff, "%d.%d%dV", MQ2_ADC_Volt100/100, (MQ2_ADC_Volt100%100/10), MQ2_ADC_Volt100%10);//格式化輸出擴大100倍的采樣電壓OLED_ShowString(72, 4,(uint8_t *)str_buff,12);//OLED屏第四行顯示采集的電壓值RS=(5-MQ2_ADC_Volt)*1/MQ2_ADC_Volt; //濃度轉化算法R0=5.41;//R0為在潔凈空氣中的RS值Concent_Value=pow(21.72*R0/RS,2.1101); //利用濃度擬合曲線公式和指數運算函數,計算出來ppm單位的煙霧含量值Concent_Value100=Concent_Value*100; //將煙霧含量值擴大100倍 OLED_ShowString(0, 5, "smoke:", 12);//OLED屏第五行顯示煙霧字符串sprintf((char*)str_buff, "%d%d%d%d.%d%dppm", (Concent_Value100/100000), (Concent_Value100%100000/10000),(Concent_Value100%10000/1000),(Concent_Value100%1000/100),(Concent_Value100%100/10), (Concent_Value100%10));//格式化輸出擴大100倍的煙霧濃度OLED_ShowString(48, 5,(uint8_t *)str_buff,12);//OLED屏第五行顯示顯示煙霧ppm濃度值HAL_Delay(500);//每隔500ms刷新一次數據顯示}/* USER CODE END 3 */
}
3、成果展示
(1)潔凈空氣中的煙霧濃度值為513.79ppm
(2)點燃牙簽后MQ2探測到的煙霧濃度值,達到1401.13ppm
三、程序源碼下載鏈接
https://download.csdn.net/download/jacklood/90675879
四、參考文獻
1、MQ-2煙霧傳感器的電壓與濃度轉換_mq2煙霧濃度轉換公式-CSDN博客
2、關于MQ2煙霧模塊換算出的ppm太小的解決辦法_mq2煙霧濃度轉換公式-CSDN博客