DN7C3CA001是夏普新發布的PM2.5傳感器,次傳感器能夠切割濾除粒徑大于2.5微米的粒子通過光傳感器元件,從而真正實現對粒徑小于等于2.5微米的顆粒物的監測,具體介紹請參考。
165458ovswl5nfxnn8wjwj.png (41.94 KB, 下載次數: 159)
下載附件
2016-4-11 02:55 上傳
圖1. 粒徑切割原理圖
拿到手的型號是DN7C3CA002改進版。根據傳感器手冊中的接線方法可以發現,除了物理排線線序相反以及需要接風扇的供電電路外,其它引腳接線方法與GP2Y1010AU0F相同。
170312utghqsbtq27ssg2o.png (27.53 KB, 下載次數: 176)
下載附件
2016-4-11 02:55 上傳
圖2. 接線原理圖
DN7C3CA002與GP2Y1010AU0F的脈沖采樣參數和采樣時長都是一樣的,猜測兩者采用的是類似的光學器件。
171544e9ka6apariecu8ek.png (2.65 KB, 下載次數: 153)
下載附件
2016-4-11 02:55 上傳
圖3. 采樣脈沖
171544k3lab3zaa553ky8d.png (10.15 KB, 下載次數: 174)
下載附件
2016-4-11 02:55 上傳
圖4. 采樣時間
傳感器采用電壓輸出方式,手冊中給出了輸出電壓與PM2.5質量濃度之間的關系:
172016ocz71dckd4wt7t79.png (12.24 KB, 下載次數: 168)
下載附件
2016-4-11 02:55 上傳
圖5. 輸出電壓與質量濃度關系
其中Vo是輸出電壓(電壓單位都是mV),Vs是基準電壓,Vs基準電壓的獲取有兩種方式,一種方式是從傳感器的序列號中讀出,由于我拿到的這顆傳感器無序列號,所以只有采用第二種方式,通過不接風扇電源將傳感器垂直放置幾分鐘后讀出的輸出電壓。
同時傳感器需要對Vs基準電壓進行溫度補償,修正參考值同樣除了可以從傳感器序列號中讀出外也可以通過測量得到。
173119ycfpldd3k7fyhdc3.png (22.2 KB, 下載次數: 148)
下載附件
2016-4-11 02:55 上傳
圖6. 溫度修正曲線
在-10~40℃約6mV/℃,40~60℃約1.5mV/℃。測量拿到的這顆傳感器的Vs基準電壓非常低,遠遠達不到圖6中兩條曲線的電壓值,不知道是電路問題還是傳感器自身的問題。
為了能夠根據實時溫度修正Vs基準電壓,使用sht10獲取溫度和濕度數據。同時使用lcd1602作為顯示輸出,基于Arduino UNO組成主控電路。
174945ynwftnj5sn5wut2h.jpg (186.9 KB, 下載次數: 139)
下載附件
2016-4-11 02:55 上傳
圖7. 裝置運行
175128fqq5653j5zoz26jq.jpg (172.44 KB, 下載次數: 181)
下載附件
2016-4-11 02:55 上傳
圖8. 內部結構
程序代碼在arduino IDE 0023上通過:
pmkit.rar
(1.47 KB, 下載次數: 9)
2016-4-11 01:40 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
,需要sht1x庫的支持。
- #include
- #include
- #define LCD_led 9
- #define clockPin A0
- #define dataPin A1
- #define DUSTOUTpin A2 //read dust value from this pin
- #define DUSTLEDpin A3 //control dust led through this pin
- LiquidCrystal lcd(2, 4, 5, 6, 7, 8);
- SHT1x sht1x(dataPin, clockPin);
- const int delayTime=280;
- const int delayTime2=40;
- const float offTime=9680;
- float temp_c=0.0;
- float humidity=0.0;
- double dustVal=0.0;
- double voteChange = 5000.0 /1024.0; //mV
- #define FREEPMVALUE 3
- #define FREEPMTEMP 31.0
- #define BASERATIO40 6 //mV
- #define BASERATIO60 1.5 //mV
- #define PMFIX 0 // 25 ug/m3
- #define PMRATIO 0.6
- #define DOBASEFIX false
- #define NSAMPLES 100
- uint8_t sampleCount = 0;
- int sampleSumPm = 0;
- int dustLevel=0;
- //moving average filter
- #define NULLVALUE -1.0
- #define MOVINGAVERAGECOUT 10
- double pm2_5[MOVINGAVERAGECOUT];
- uint8_t arrNewPoint = 0;
- static void initFilterArray()
- {
- for(int i=0;i<movingaveragecout;i++)
- {
- pm2_5[i]=NULLVALUE;
- }
- }
- int readPM(){
- // ledPower is any digital pin on the arduino connected to Pin 3 on the sensor
- digitalWrite(DUSTLEDpin,LOW);// power on the LED
- delayMicroseconds(delayTime);
- int Val = analogRead(DUSTOUTpin); // read the dust value via pin 5 on the sensor
- delayMicroseconds(delayTime2);
- digitalWrite(DUSTLEDpin,HIGH); // turn the LED off
- delayMicroseconds(offTime);
- return Val;
- }
- void setup() {
- pinMode(LCD_led, OUTPUT);
- digitalWrite(LCD_led, HIGH);
- pinMode(DUSTLEDpin,OUTPUT);
- digitalWrite(DUSTLEDpin,HIGH);// turn the LED off
- initFilterArray();
- lcd.begin(16, 2);
- lcd.print("System Warming!");
- //Serial.begin(9600);
- delay(5000);
- lcd.clear();
- lcd.setCursor(0, 0);
- lcd.print("PM2.5:");
- lcd.setCursor(11, 0);
- lcd.print("ug/m3");
- lcd.setCursor(5, 1);
- lcd.print("C");
- lcd.setCursor(15, 1);
- lcd.print("%");
- }
- void loop() {
- dustLevel =readPM();
- sampleCount++;
- sampleSumPm = sampleSumPm + dustLevel;
- if(sampleCount==NSAMPLES)
- {
- showTempHumiData();
- getPMdata(sampleSumPm / sampleCount);
- sampleCount=0;
- sampleSumPm=0;
- }
- }
- void getPMdata(int avgPm) {
- double dustVolt = avgPm * voteChange; //mV
- if(DOBASEFIX)
- {
- double baseVot = FREEPMVALUE * voteChange; //mV
- double baseChg = 0.0;
- if(temp_c <= 40.0 && temp_c>= -10.0)
- {
- baseChg=BASERATIO40;
- }
- else if(temp_c > 40.0 && temp_c <= 60.0)
- {
- baseChg=BASERATIO60;
- }
- baseVot=baseVot + baseChg*(temp_c - FREEPMTEMP);
- dustVolt=dustVolt-baseVot;
- if(dustVolt<0)
- {
- dustVolt=0;
- }
- }
- dustVal = dustVolt * PMRATIO;
- dustVal = dustVal + PMFIX;
- // moving average
- getMovingAverage(pm2_5,&dustVal);
- lcd.setCursor(6, 0);
- lcd.print(" ");
- lcd.setCursor(6, 0);
- lcd.print(dustVal,0);
- }
- void showTempHumiData() {
- temp_c = sht1x.readTemperatureC();
- humidity = sht1x.readHumidity();
- lcd.setCursor(0, 1);
- lcd.print(" ");
- lcd.setCursor(0, 1);
- lcd.print(temp_c,1);
- lcd.setCursor(12, 1);
- lcd.print(" ");
- lcd.setCursor(12, 1);
- lcd.print(humidity,0);
- }
- static float getAverage(double vals[])
- {
- double sum=0.0;
- uint8_t cout=0;
- for(int i=0;i<movingaveragecout;i++)
- {
- if(vals[i] != NULLVALUE)
- {
- sum=sum+vals[i];
- cout++;
- }
- }
- if(cout>0)
- {
- return sum/cout;
- }
- else
- {
- return 0.0;
- }
- }
- static void getMovingAverage(double pms[],double* pm)
- {
- pms[arrNewPoint] = *pm;
- arrNewPoint++;
- if(arrNewPoint>=MOVINGAVERAGECOUT)
- {
- arrNewPoint=0;
- }
- *pm=getAverage(pms);
- }
復制代碼
儀器未經標定,應用還需謹慎!
</movingaveragecout;i++)
</movingaveragecout;i++)
|