2017年1月10日 星期二

Arduino連接夏普GP2Y1010AU0F空氣品質感測器檢測PM2.5

Arduino連接夏普GP2Y1010AU0F空氣品質感測器檢測PM2.5


夏普GP2Y1010AU0F圖片



GP2Y1010AU0F接腳圖

序號
名稱
作用
1
V-LED
LED供電
2
LED-GND
LED GND
3
LED
LED控制
4
S-GND
感測器GND
5
VO
檢測結果電壓類比量輸出
6
VCC
供電




GP2Y1010AU0F接线图










程式碼

/*
   Arduino連接夏普GP2Y1010AU0F空氣品質感測器檢測PM2.5
   些程式也適用于用 Arduino IDE 開發 ESP8266
*/

/* 定義引腳 */

 #define PIN_DATA_OUT A0 //連接空氣品質感測器模擬量輸出的IO


 #define PIN_LED_VCC 2 //空氣品質感測器中為內部Led供電的引腳

 /* 定義時間 */
 const int DELAY_BEFORE_SAMPLING = 280; //採樣前等待時間
 const int DELAY_AFTER_SAMPLING = 40; //採樣後等待時間
 const int DELAY_LED_OFF = 9680; //間隔時間

/**
   讀取輸出電壓
*/
double getOutputV() {
  digitalWrite(PIN_LED_VCC, LOW);
  delayMicroseconds(DELAY_BEFORE_SAMPLING);
  double analogOutput = analogRead(PIN_DATA_OUT);
  delayMicroseconds(DELAY_AFTER_SAMPLING);
  digitalWrite(PIN_LED_VCC, HIGH);
  delayMicroseconds(DELAY_LED_OFF);
  //Arduino模擬量讀取值的範圍為0~1023,以下換算為0~5v
  double outputV = analogOutput / 1024 * 5;
  return outputV;
}

/**
   根據輸出電壓計算灰塵密度
*/
double getDustDensity(double outputV) {
  //輸出電壓和灰塵密度換算公式: ug/m3 = (V - 0.9) / 5 * 1000
  double ugm3 = (outputV - 0.9) / 5 * 1000;
  //去除檢測不到的範圍
  if (ugm3 < 0) {
    ugm3 = 0;
  }
  return ugm3;
}

/**
   根據灰塵密度計算AQI
   環境空氣品質指數(AQI)技術規定(試行)](http://kjs.mep.gov.cn/hjbhbz/bzwb/dqhjbh/jcgfffbz/201203/t20120302_224166.htm
*/
double getAQI(double ugm3) {
  double aqiL = 0;
  double aqiH = 0;
  double bpL = 0;
  double bpH = 0;
  double aqi = 0;
  //根據pm2.5aqi對應關係分別計算aqi
  if (ugm3 >= 0 && ugm3 <= 35) {
    aqiL = 0;
    aqiH = 50;
    bpL = 0;
    bpH = 35;
  } else if (ugm3 > 35 && ugm3 <= 75) {
    aqiL = 50;
    aqiH = 100;
    bpL = 35;
    bpH = 75;
  } else if (ugm3 > 75 && ugm3 <= 115) {
    aqiL = 100;
    aqiH = 150;
    bpL = 75;
    bpH = 115;
  } else if (ugm3 > 115 && ugm3 <= 150) {
    aqiL = 150;
    aqiH = 200;
    bpL = 115;
    bpH = 150;
  } else if (ugm3 > 150 && ugm3 <= 250) {
    aqiL = 200;
    aqiH = 300;
    bpL = 150;
    bpH = 250;
  } else if (ugm3 > 250 && ugm3 <= 350) {
    aqiL = 300;
    aqiH = 400;
    bpL = 250;
    bpH = 350;
  } else if (ugm3 > 350) {
    aqiL = 400;
    aqiH = 500;
    bpL = 350;
    bpH = 500;
  }
  //公式aqi = (aqiH - aqiL) / (bpH - bpL) * (desity - bpL) + aqiL;
  aqi = (aqiH - aqiL) / (bpH - bpL) * (ugm3 - bpL) + aqiL;
  return aqi;
}

/**
   根據aqi獲取級別描述
*/
String getGradeInfo(double aqi) {
  String gradeInfo;
  if (aqi >= 0 && aqi <= 50) {
    gradeInfo = String("Perfect");
  } else if (aqi > 50 && aqi <= 100) {
    gradeInfo = String("Good");
  } else if (aqi > 100 && aqi <= 150) {
    gradeInfo = String("Mild polluted");
  } else if (aqi > 150 && aqi <= 200) {
    gradeInfo = String("Medium polluted");
  } else if (aqi > 200 && aqi <= 300) {
    gradeInfo = String("Heavily polluted");
  } else if (aqi > 300 && aqi <= 500) {
    gradeInfo = String("Severely polluted");
  } else {
    gradeInfo = String("Broken roof!!!");
  }
  return gradeInfo;
}

void setup() {
  Serial.begin(115200);
  pinMode(PIN_DATA_OUT, INPUT); //定義為輸入(ADC讀取模擬量)
  pinMode(PIN_LED_VCC, OUTPUT); //定義為輸出
}

void loop() {
  double outputV = getOutputV(); //採樣獲取輸出電壓
  double ugm3 = getDustDensity(outputV); //計算灰塵濃度
  double aqi = getAQI(ugm3); //計算aqi
  String gradeInfo = getGradeInfo(aqi); //計算級別

  //列印到串口
  Serial.println(String("outputV=") + outputV + "\tug/m3=" + ugm3 + "\tAQI=" + aqi + "\tgradeInfo=" + gradeInfo);

  //間隔1秒執行下次檢測
  delay(1000);
}

輸出結果


outputV=1.05          ug/m3=29.96           AQI=42.80  gradeInfo=Perfect
outputV=1.36          ug/m3=92.46           AQI=121.83 gradeInfo=Mild polluted
outputV=1.29          ug/m3=77.81           AQI=103.52 gradeInfo=Mild polluted
outputV=1.16          ug/m3=51.45           AQI=70.56  gradeInfo=Good
outputV=1.12          ug/m3=43.63           AQI=60.79  gradeInfo=Good
outputV=1.26          ug/m3=72.93           AQI=97.41  gradeInfo=Good


沒有留言:

張貼留言

WOKWI DHT22 & LED , Node-Red + SQLite database

 WOKWI DHT22 & LED , Node-Red + SQLite database Node-Red程式 [{"id":"6f0240353e534bbd","type":"comment&...