天天看點

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

一、傳感器的概述

   GP2Y1010AUOF是日本夏普公司開發的一款光學灰塵濃度檢測傳感器。此傳感器内部成對角分布的紅外發光二極管和光電半導體,利用光敏原理來工作。用于檢測特别細微的顆粒,如香煙顆粒、細微灰塵。依靠輸出脈沖的高度來判斷顆粒濃度。

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

二、傳感器的一些參數 

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

三、傳感器的工作原理

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

                                                         圖(1)

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

                                                            圖(2)

       夏普GP2Y1010AU0F灰塵傳感器價格較便宜,隻能檢測出室内空氣中的灰塵和煙塵含量.并不能測出所謂的PM2.5濃度,然而現在市面上有好多紅外發光二極管的傳感器都稱自己是PM2.5傳感器,能測PM2.5的值,其實并不是,真正能測PM2.5濃度的是那種上百的雷射傳感器,這種紅外的連PM10都測不了,隻能用來玩玩,或者大概描述空氣品質的等級而已,經我多次實驗,發現這傳感器顯示的灰塵濃度與網上公布的AQI空氣品質指數比較接近,跟真實的PM2.5濃度有很大的差別,這測出的灰塵濃度其實就是所有不同直徑的顆粒物總和,裡面包含了PM1.0,PM2.5,PM10

     其原理如上圖(2)所示,傳感器中心有個洞可以讓空氣自由流過,定向發射LED光,通過檢測經過空氣中灰塵折射過後的光線來判斷灰塵的含量。

四、傳感器與STM32的連接配接

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

  (注:把圖中的430單片機直接換成STM32就行,接線順序跟電阻、電容的大小都不變)

     在這裡簡單地說一下,為什麼要這樣接? 

1. 電阻R1和電容C1:因為V-LED和LED-GND是給紅外發光二極管供電的,是以不能直接接上5V,需要串一個150歐的電阻來限流,另外為了穩定供電,還需要在給發光二極管供電的正極和負極上并一個220uf的電容。

2. 三極管:可以增加LED的驅動能力(建議加上,加上後比較穩定)

3. 電阻R2:起到限流作用,因為該傳感器的最大工作電流為20mA

4. 電阻R3和R4:起分壓作用(因為該傳感器是5V供電,而32單片機的AD采樣最大電壓為3.3V)

5. 上圖中的P1.2為脈沖輸入腳,為傳感器提供輸入信号(該PWM的占空比規定為0.032)

6. 上圖中的P6.5為單片機的ADC模拟輸入腳,用來輸出信号的

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

                        (圖1)                                                                (圖2)

  圖1為脈沖輸入波形,周期為10ms,高電平為0.32ms

  圖2為AD采樣時序,由圖可知,在輸入上升沿到輸出的峰值,時間為280us左右,就在此時進行采樣,因為整個高電平持續的時間為320us,是以在打開紅外發光二極管280us後采樣,然後延時40us後關閉紅外發光二極管,最後再延時9680us(輸入波形的周期為10ms),這就實作了一次完整的工作

                  資料手冊上面有關電壓值與灰塵濃度的關系比例圖

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

    由圖可知,該曲線在前半部分是有一定的斜率的,大約到0.6mg/m3左右,該曲線不再增長,此時輸出的電壓最大為3.6V左右,但是在曲線的前半部分,是可以得出電壓值與灰塵濃度的關系:Dust density = 0.17 * Output Voltage  

  根據技術手冊可知,當空氣潔淨的時候,Vo的範圍是0~1.5V,典型值是0.9V

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

     當空氣灰塵濃度很高的時候,Vo的數值大于3.6V。但是該傳感器輸出的最大電壓為3.6V,是以當灰塵濃度再增加時,我們這款傳感器已經測不出了

    0.9V表示空氣潔淨,3.6V表示空氣灰塵很多。由于空氣中不可能一點灰塵都沒有,是以取個正常值0.9V,換成灰塵濃度就是0.053mg/m3

當達到最大電壓值3.6V時,此時的灰塵濃度為0.512mg/m3

是以我們這個傳感器的範圍就是0~512ug/m3(這個512隻是一個估算大約的值,實際情況中還是有可能超出這值的)

五、主要的程式代碼

Main.c

#include "stm32f10x.h"

#include "bsp_SysTick.h"

#include "bsp_usart1.h"

#include "bsp_GP2Y.h"

#include "bsp_pwm_output.h"

#include "bsp_TiMbase.h" 

#define FILTER_N 7

int  A[32];

volatile u32 time = 0; // ms 計時變量

void Delay(__IO uint32_t nCount)

{

  for(; nCount != 0; nCount--);

}

voidTIM3_Configuration(void);

void  TIM3_NVIC_Configuration(void);

int main(void)

{

float  calcVoltage ;

int  filter_sum, i ,j ,dust;

int filter_max, filter_min;

int filter_buf[FILTER_N];

SysTick_Init();

USART1_Config();

TIM3_Configuration();

TIM3_NVIC_Configuration();

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 , ENABLE);

Adc_Init();

TIM3_PWM_Init();

Delay_ms(200);  //等待傳感器穩定工作//

 while(1)

 {

   if(time==200)    //10ms發生一次中斷,等到中斷200次後,即2s//

     {

      time=0;

      for(i = 0; i < FILTER_N; i++)

    {

      GP2Y_Low;                //打開紅外二極管//

      Delay_us(280);            //延時280us//  

     filter_buf[i]=Get_Adc(ADC_Channel_10);    //采樣,讀取AD值//  

     Delay_us(19);           //延時19us,因為這裡我設了AD采樣的周     期為239.5,是以AD轉換一次需耗時21us,19加21再加280剛好是320us,這跟上面說的高電平持續的時間為0.32ms//

     GP2Y_High;             //關閉紅外二極管//

    Delay_us(9680);         //延時9680us//

   }

          filter_max = filter_buf[0];

          filter_min = filter_buf[0];

          filter_sum = filter_buf[0];

     for(i = FILTER_N - 1; i > 0; i--)

  {

    if(filter_buf[i] > filter_max)

      filter_max=filter_buf[i];

     else if(filter_buf[i] < filter_min)

      filter_min=filter_buf[i];

      filter_sum = filter_sum + filter_buf[i];

      filter_buf[i] = filter_buf[i - 1];

     }

       i = FILTER_N - 2;

      filter_sum = filter_sum - filter_max - filter_min + i/2;          //加上i/2是為了四舍五入//

      filter_sum = filter_sum / i;

      calcVoltage=filter_sum*(3.3/ 4096)*2;   /因為上面采集到的是AD值,這裡要把它轉換為電壓值//

  (注:為什麼我在公式的最後要乘以2呢?這個2是一定不能少的,因為我們将它與32單片機連接配接的時候,加了兩個10K的電阻分壓,讀取到的電壓值已減小了一半,但這不是實際采取到的電壓,是以要在最後乘以2傳回原來的電壓值)

     dust=(0.17*calcVoltage-0.1)*1000;  //乘以1000機關換成ug/m3//

     if (dust<0)

      dust=0;            //限位//

     if (dust>500)        

      dust=500;

      printf("\r\n電壓值:%fV\n",calcVoltage);

     printf("\r\n灰塵濃度:%dug/m3\n",dust);

 }

 }

}

以上就是主要的一些程式,由于該傳感器不太穩定,輸出波形抖動較大,是以在程式裡我加上了數字濾波算法,我采用那種去極值取平均的中位值濾波法,在傳感器工作一次時,取輸出波形的連續幾個波峰的峰值,存到數組裡,然後進行去掉最大值,最小值的操作,剩下的取平均

 六、實際操作

 實物連接配接圖如下:

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

 把程式燒進單片機,觀察其輸出的值

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

   對比右圖可知,一般室内的灰塵濃度所對應的電壓值都是0.9V左右

 再對比一下網上公布的空氣指數

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

對比可知,該傳感器測出的值與網上公布的AQI指數比較接近

  我們再來看看這輸入波形和輸出波形

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用
夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

     黃色的是輸入波形,藍色的是輸出波形

  (注:這圖像上顯示的電壓值是分壓後的)

   當我往傳感器的中心孔裡放根杜邦線時,可以看到其輸出波形立馬飙升,說明這傳感器還是挺靈敏的

夏普GP2Y1010AU0F灰塵傳感器在STM32平台上的使用

    當往孔裡插根杜邦線或者一支筆時,測出的值立馬到達最大值3.6V左右,這是對顆粒物的靈敏度,對于煙霧類型的也很敏感,我利用電烙鐵焊錫時産生的煙霧,經傳感器測量也能到達最大值,顯示的灰塵濃度達530ug/m3.

    由于這傳感器的内部存有空隙,是以當你外加煙霧給它時,會有少量的煙霧殘留在内部的空隙裡,才會出現為什麼我把煙霧撤去之後,顯示的濃度依然很大,這時你需往孔裡吹口氣,将裡面殘留的煙霧吹走,這時才恢複你室内正常的濃度,否則的話,你得等待一段時間,待裡面的煙霧慢慢散去.

繼續閱讀