找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 7180|回復(fù): 2
收起左側(cè)

基于夏普DN7C3CA002及arduino UNO的PM2.5監(jiān)測(cè)裝置

[復(fù)制鏈接]
ID:113207 發(fā)表于 2016-4-11 01:41 | 顯示全部樓層 |閱讀模式
DN7C3CA001是夏普新發(fā)布的PM2.5傳感器,次傳感器能夠切割濾除粒徑大于2.5微米的粒子通過光傳感器元件,從而真正實(shí)現(xiàn)對(duì)粒徑小于等于2.5微米的顆粒物的監(jiān)測(cè),具體介紹請(qǐng)參考。

165458ovswl5nfxnn8wjwj.png

圖1. 粒徑切割原理圖


拿到手的型號(hào)是DN7C3CA002改進(jìn)版。根據(jù)傳感器手冊(cè)中的接線方法可以發(fā)現(xiàn),除了物理排線線序相反以及需要接風(fēng)扇的供電電路外,其它引腳接線方法與GP2Y1010AU0F相同。

170312utghqsbtq27ssg2o.png

圖2. 接線原理圖


DN7C3CA002與GP2Y1010AU0F的脈沖采樣參數(shù)和采樣時(shí)長(zhǎng)都是一樣的,猜測(cè)兩者采用的是類似的光學(xué)器件。

171544e9ka6apariecu8ek.png

圖3. 采樣脈沖


171544k3lab3zaa553ky8d.png

圖4. 采樣時(shí)間


傳感器采用電壓輸出方式,手冊(cè)中給出了輸出電壓與PM2.5質(zhì)量濃度之間的關(guān)系:

172016ocz71dckd4wt7t79.png

圖5. 輸出電壓與質(zhì)量濃度關(guān)系


其中Vo是輸出電壓(電壓?jiǎn)挝欢际莔V),Vs是基準(zhǔn)電壓,Vs基準(zhǔn)電壓的獲取有兩種方式,一種方式是從傳感器的序列號(hào)中讀出,由于我拿到的這顆傳感器無序列號(hào),所以只有采用第二種方式,通過不接風(fēng)扇電源將傳感器垂直放置幾分鐘后讀出的輸出電壓。

同時(shí)傳感器需要對(duì)Vs基準(zhǔn)電壓進(jìn)行溫度補(bǔ)償,修正參考值同樣除了可以從傳感器序列號(hào)中讀出外也可以通過測(cè)量得到。

173119ycfpldd3k7fyhdc3.png

圖6. 溫度修正曲線


在-10~40℃約6mV/℃,40~60℃約1.5mV/℃。測(cè)量拿到的這顆傳感器的Vs基準(zhǔn)電壓非常低,遠(yuǎn)遠(yuǎn)達(dá)不到圖6中兩條曲線的電壓值,不知道是電路問題還是傳感器自身的問題。

為了能夠根據(jù)實(shí)時(shí)溫度修正Vs基準(zhǔn)電壓,使用sht10獲取溫度和濕度數(shù)據(jù)。同時(shí)使用lcd1602作為顯示輸出,基于Arduino UNO組成主控電路。

174945ynwftnj5sn5wut2h.jpg

圖7. 裝置運(yùn)行


175128fqq5653j5zoz26jq.jpg

圖8. 內(nèi)部結(jié)構(gòu)


程序代碼在arduino IDE 0023上通過: pmkit.rar (1.47 KB, 下載次數(shù): 9) ,需要sht1x庫(kù)的支持。
  1. #include
  2. #include

  3. #define LCD_led 9
  4. #define clockPin A0
  5. #define dataPin  A1
  6. #define DUSTOUTpin A2         //read dust value from this pin
  7. #define DUSTLEDpin A3       //control dust led through this pin

  8. LiquidCrystal lcd(2, 4, 5, 6, 7, 8);
  9. SHT1x sht1x(dataPin, clockPin);

  10. const int delayTime=280;
  11. const int delayTime2=40;
  12. const float offTime=9680;

  13. float temp_c=0.0;
  14. float humidity=0.0;
  15. double dustVal=0.0;
  16. double voteChange = 5000.0 /1024.0;   //mV
  17. #define FREEPMVALUE 3
  18. #define FREEPMTEMP 31.0
  19. #define BASERATIO40 6   //mV
  20. #define BASERATIO60 1.5   //mV
  21. #define PMFIX 0 // 25 ug/m3
  22. #define PMRATIO 0.6
  23. #define DOBASEFIX false

  24. #define NSAMPLES 100
  25. uint8_t sampleCount = 0;
  26. int sampleSumPm = 0;
  27. int dustLevel=0;

  28. //moving average filter
  29. #define NULLVALUE -1.0
  30. #define MOVINGAVERAGECOUT 10
  31. double pm2_5[MOVINGAVERAGECOUT];
  32. uint8_t arrNewPoint = 0;

  33. static void initFilterArray()
  34. {
  35.   for(int i=0;i<movingaveragecout;i++)
  36.   {
  37.     pm2_5[i]=NULLVALUE;
  38.   }
  39. }

  40. int readPM(){
  41.   // ledPower is any digital pin on the arduino connected to Pin 3 on the sensor
  42.   digitalWrite(DUSTLEDpin,LOW);// power on the LED
  43.   delayMicroseconds(delayTime);
  44.   int Val = analogRead(DUSTOUTpin); // read the dust value via pin 5 on the sensor
  45.   delayMicroseconds(delayTime2);
  46.   digitalWrite(DUSTLEDpin,HIGH); // turn the LED off
  47.   delayMicroseconds(offTime);  
  48.   return Val;
  49. }

  50. void setup() {
  51.   pinMode(LCD_led, OUTPUT);
  52.   digitalWrite(LCD_led, HIGH);

  53.   pinMode(DUSTLEDpin,OUTPUT);
  54.   digitalWrite(DUSTLEDpin,HIGH);// turn the LED off

  55.   initFilterArray();

  56.   lcd.begin(16, 2);

  57.   lcd.print("System Warming!");
  58.   //Serial.begin(9600);
  59.   delay(5000);
  60.   lcd.clear();
  61.   lcd.setCursor(0, 0);
  62.   lcd.print("PM2.5:");
  63.   lcd.setCursor(11, 0);
  64.   lcd.print("ug/m3");

  65.   lcd.setCursor(5, 1);
  66.   lcd.print("C");
  67.   lcd.setCursor(15, 1);
  68.   lcd.print("%");
  69. }

  70. void loop() {
  71.   dustLevel =readPM();
  72.   sampleCount++;
  73.   sampleSumPm = sampleSumPm + dustLevel;
  74.   if(sampleCount==NSAMPLES)
  75.   {
  76.     showTempHumiData();

  77.     getPMdata(sampleSumPm / sampleCount);

  78.     sampleCount=0;
  79.     sampleSumPm=0;
  80.   }
  81. }

  82. void getPMdata(int avgPm) {
  83.   double dustVolt = avgPm * voteChange;  //mV

  84.   if(DOBASEFIX)
  85.   {
  86.     double baseVot = FREEPMVALUE * voteChange; //mV
  87.     double baseChg = 0.0;
  88.     if(temp_c <= 40.0 && temp_c>= -10.0)
  89.     {
  90.       baseChg=BASERATIO40;
  91.     }
  92.     else if(temp_c > 40.0 && temp_c <= 60.0)
  93.     {
  94.       baseChg=BASERATIO60;
  95.     }
  96.     baseVot=baseVot + baseChg*(temp_c - FREEPMTEMP);
  97.     dustVolt=dustVolt-baseVot;
  98.     if(dustVolt<0)
  99.     {
  100.       dustVolt=0;
  101.     }
  102.   }

  103.   dustVal = dustVolt * PMRATIO;
  104.   dustVal = dustVal + PMFIX;

  105.   // moving average
  106.   getMovingAverage(pm2_5,&dustVal);

  107.   lcd.setCursor(6, 0);
  108.   lcd.print("     ");
  109.   lcd.setCursor(6, 0);
  110.   lcd.print(dustVal,0);
  111. }

  112. void showTempHumiData() {
  113.   temp_c = sht1x.readTemperatureC();
  114.   humidity = sht1x.readHumidity();

  115.   lcd.setCursor(0, 1);
  116.   lcd.print("     ");
  117.   lcd.setCursor(0, 1);
  118.   lcd.print(temp_c,1);

  119.   lcd.setCursor(12, 1);
  120.   lcd.print("   ");
  121.   lcd.setCursor(12, 1);
  122.   lcd.print(humidity,0);
  123. }

  124. static float getAverage(double vals[])
  125. {
  126.   double sum=0.0;
  127.   uint8_t cout=0;
  128.   for(int i=0;i<movingaveragecout;i++)
  129.   {
  130.     if(vals[i] != NULLVALUE)
  131.     {
  132.       sum=sum+vals[i];
  133.       cout++;
  134.     }
  135.   }
  136.   if(cout>0)
  137.   {
  138.     return sum/cout;
  139.   }
  140.   else
  141.   {
  142.     return 0.0;
  143.   }
  144. }

  145. static void getMovingAverage(double pms[],double* pm)
  146. {
  147.   pms[arrNewPoint] = *pm;

  148.   arrNewPoint++;
  149.   if(arrNewPoint>=MOVINGAVERAGECOUT)
  150.   {
  151.     arrNewPoint=0;
  152.   }
  153.   *pm=getAverage(pms);
  154. }

復(fù)制代碼

儀器未經(jīng)標(biāo)定,應(yīng)用還需謹(jǐn)慎!
</movingaveragecout;i++)
</movingaveragecout;i++)
回復(fù)

使用道具 舉報(bào)

ID:111876 發(fā)表于 2016-6-17 10:22 | 顯示全部樓層
  這個(gè)代碼無法用!
回復(fù)

使用道具 舉報(bào)

ID:119421 發(fā)表于 2017-4-12 13:56 | 顯示全部樓層
感謝分享,不知道有沒有proteus的仿真
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表