SHARPのほこりセンサー(GP2Y1010AU)をArduino unoで動かしてみた

last updated : 2023-02-06

家電などで使用されているほこりセンサーをArduinoを使って動作させてみました。その際の技術的な情報や Arduino のサンプルプログラムなどを記載しましたので、興味があれば参考にして下さい。


SHARP ほこりセンサー(GP2Y1010AU)

エアコンや空気清浄機などで使用するための空気中のほこりを検出するセンサです。赤外発行ダイオードとフォトトランジスタでほこりを検出します。出力電圧は質量濃度(μg/m3)換算できます。検出粒子径は0.8 mm以上。検出量範囲は~ 0.5 mg/m3(500 μg/m3)です。

ほこりセンサGP2Y1010AU

シャープ製品ラインナップ/ほこりセンサユニット


ほこりセンサユニット GP2Y1010AU 仕様書


Arduino Uno

Arduinoボードは電気やプログラミングの深い知識を持っていない電子工作初心者でも扱いやすい、オープンソースのマイコンボードです。プログラミングに使う統合開発環境(IDE)と呼ばれるソフトウェア Arduino IDEを使ってプログラミングすることができます。 デジタル入出力、アナログ入力、通信とデジタル制御に必要な最低限の機能が組み込まれています。機器の制御だけであれば Arduinoは機能的に十分です。使用したいIOの数や通信ポートの数を増やしたい場合は Arduiono Mega というボードも選択できます。

ELEGOO uno R3 スターターキット

今回は、Arduiono uno R3 の互換ボードで、3Dプリンタなどの販売もしている ELEGOO 社のボードを使いました。スタータきっとだと、色々なセンサー類などがパッケージされていて色々遊べます。そして、Amazonで入手可能です。



ほこりセンサを動かしてみる

Arduino uno R3 に ほこりセンサを接続して動作させてみました。

ほこりセンサ

無塵時の出力電圧の設定範囲が広い(0 ~ 1.5 V)のでどの値に設定するかで測定値が大きく変わってしまいます。これは、設定する条件をメーカーに問い合わせてみましたが個人には開示していただけないようです。しかたないので、ほこり検出穴をマスキングテープで塞いで放置して落ち着いた電圧をとりあえずの無塵時の出力電圧としました。※サンプルプログラムのVoc(0.17 V)が私が設定した無塵時出力電圧です。

出力電圧(V)を質量濃度(μg/m3)に変換する係数 K も 仕様書では 0.5 ± 0.15 (V/(0.1mg/m3)となっているので、自分のセンサーに合わせて設定する必要があります。これも基準になる測定器が無いのでセンター値の 0.5 を設定しています。

この設定で自室で動作させた時の質量濃度の表示値は 「10μg/m3」程度でした。環境省が設定している PM2.5の質量濃度の目安が「 1日平均値 35μg/m3以下 」ですので、大きくかけ離れた測定値ではないようです。センサの測定穴に何かLED光を遮るようなものを挿入してみると、測定値が大きく増えるように変化するのでセンサが動作していることは確認できました。

このセンサを紹介している別なブログなのですが、センサの上下を間違って使用しているのを見かけることがあります。仕様書にも注記がありますが、発光ダイオードとフォトトランジスタの組み合わせなので、検出穴から入る外光の影響でほこりを正常に検出できなくなるようです。センサのコネクタの配線が下側に出るような向きが正常なセンサの姿勢です。

実際のパルス波形をオシロスコープで観てみます。

出力電圧波形

プログラムの時間設定では仕様通り320 μsec.を狙っていますが、実測では 390 μsec.ほどになっています。これは、データ読み込みなどの処理の時間が約70 μsec.ほどあることになります。ですのでプログラムの読み取り処理のあとのWait時間(40 μsec.)を外しました。

配線(Arduinoとほこりセンサの接続)

GP2Y1010AU配線図

GP2Y1010AUの1番ピンに入力する電圧には図の通りR = 150 Ω、C = 220 μF を挿入することと仕様書に記載があります。


コネクター配線

ほこりセンサ動作フロー

センサの3番 LED 入力に 0.32 msのパルスを 10 ms間隔で入力します。

出力パルスタイミング

その入力パルスがONになってから 質量濃度に比例した出力電圧が出力されますが、出力パルスがONになってから 0.28 ms後の出力電圧を読み取ります。

出力電圧タイミング

読み取った出力電圧を、換算係数を使って 質量濃度(μg/m3)に換算します。

サンプルプログラムでは、10 ms間隔で100回 (1秒)測定して平均値を1秒間隔で出力するようにしています。

スケッチ(サンプルプログラム)

Arduino uno R3 で動作させたプログラムです。Arduinoではプログラムのことを、スケッチと呼ぶようです。ほこりの質量濃度出力先は Serial通信とLCD(16×2; ELEGOO uno R3 スターターキット 附属)になっています。

/////////////////////////////////////////////////////////////////////////////
// Sharp GP2Y1010AU Dust Sensor
//
// Board Connection:
//   GP2Y1010      Arduino
//   1.V-LED       Between R1 and C1
//   2.LED-GND     C1 and GND
//   3.LED         Pin 2
//   4.S-GND       GND
//   5.Vo          A5
//   6.Vcc         5V
//
// Serial monitor setting:  9,600 bps
/////////////////////////////////////////////////////////////////////////////

// Choose program options.
//#define PRINT_RAW_DATA
#define USE_AVG

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

// Arduino pin numbers.
const int sharpLEDPin = 2;   // Arduino digital pin 2 connect to sensor LED.
const int sharpVoPin = 5;   // Arduino analog pin A5 connect to sensor Vo.
const int Vccpin = 0;  // Arduino analog pin A0 connect to sensor Vcc.

// For averaging last N raw voltage readings.
#ifdef USE_AVG
#define N 100
static unsigned long VoRawTotal = 0;
static int VoRawCount = 0;
#endif // USE_AVG

// Set the typical output voltage in Volts when there is zero dust. 
static float Voc = 0.17;

// Set the Vcc voltage;
static float Vcc = 5.0;

// Use the typical sensitivity in units of V per 100ug/m3.
const float K = 0.5;
  
/////////////////////////////////////////////////////////////////////////////

// Helper functions to print a data value to the serial monitor.
void printValue(String text, unsigned int value, bool isLast = false) {
  Serial.print(text);
  Serial.print("=");
  Serial.print(value);
  
  if (!isLast) {
    Serial.print(", ");
  }
  
}
void printFValue(String text, float value, String units, bool isLast = false) {
  Serial.print(text);
  Serial.print("=");
  Serial.print(value);
  Serial.print(units);
  
  if (!isLast) {
    Serial.print(", ");
  }

}

/////////////////////////////////////////////////////////////////////////////

// Arduino setup function.
void setup() {
  
  // Set LED pin for output.
  pinMode(sharpLEDPin, OUTPUT);
  
// Start the hardware serial port for the serial monitor.
  Serial.begin(9600);
  
  // Wait two seconds for startup.
  delay(2000);
  Serial.println("");
  Serial.println("GP2Y1014AU0F");
  Serial.println("=================");

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  
  // Print a message to the LCD.
  lcd.print("DustDensity");
  
}

// Arduino main loop.
void loop() {
    
  // Turn on the dust sensor LED by setting digital pin LOW.
  digitalWrite(sharpLEDPin, HIGH);

  // Wait 0.28ms before taking a reading of the output voltage as per spec.
  delayMicroseconds(280);

  // Record the output voltage. This operation takes around 100 microseconds.
  int VoRaw = analogRead(sharpVoPin);
  
  // Turn the dust sensor LED off by setting digital pin HIGH.
  digitalWrite(sharpLEDPin, LOW);

  // Wait 0.04ms before taking a reading of the output voltage as per spec.
  delayMicroseconds(40);

  // Wait for remainder of the 10ms cycle = 10000 - 280 - 40 microseconds.
  delayMicroseconds(9680);
  
  // Print raw voltage value (number from 0 to 1023).
  #ifdef PRINT_RAW_DATA
  printValue("VoRaw", VoRaw, true);
  Serial.println("");
  #endif // PRINT_RAW_DATA
  
  // Use averaging if needed.
  float Vo = VoRaw;
  #ifdef USE_AVG
  VoRawTotal += VoRaw;
  VoRawCount++;
  
  if ( VoRawCount >= N ) {
    Vo = 1.0 * VoRawTotal / N;
    VoRawCount = 0;
    VoRawTotal = 0;
    
  } else {
    return;
    
  }
  
  #endif // USE_AVG

  //Vcc measured
  Vcc = analogRead(Vccpin);
  Vcc = Vcc/1024.0 * 5.0;
  printFValue("Vcc", Vcc*1000.0, "mV");
  
  // Compute the output voltage in Volts.
  Vo = Vcc / 1024.0 * Vo;
  printFValue("Vo", Vo*1000.0, "mV");

  // Convert to Dust Density in units of ug/m3.
  float dV = Vo - Voc;
  if ( dV < 0 ) {
    dV = 0;
    Voc = Vo;
  }
  
  float dustDensity = dV / K * 100.0;
  printFValue("DustDensity", dustDensity, "ug/m3", true);
  Serial.println("");

  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(2, 1);
  
  // print the number of seconds since reset:
  String myString = ("    " + String(dustDensity,2) + "ug/m3");
  int slength = myString.length()-12;
  myString = myString.substring(slength);
  lcd.print(myString);
  
} // END PROGRAM

PM2.5について

1.微小粒子状物質(PM2.5)とは

大気中に浮遊している2.5μm(1μmは1mmの千分の1)以下の小さな粒子のことで、従来から環境基準を定めて対策を進めてきた浮遊粒子状物質(SPM:10μm以下の粒子)よりも小さな粒子です。

PM2.5は非常に小さいため(髪の毛の太さの1/30程度)、肺の奥深くまで入りやすく、呼吸器系への影響に加え、循環器系への影響が心配されています。図:PMの大きさ(人髪や海岸細砂)との比較(概念図)
PMの大きさ(人髪や海岸細砂)との比較(概念図)(出典:USEPA資料)

図:人の呼吸器と粒子の沈着領域(概念図)
人の呼吸器と粒子の沈着領域(概念図)(出典:国立環境研究所)

粒子状物質には、物の燃焼などによって直接排出されるものと、硫黄酸化物(SOx)、窒素酸化物(NOx)、揮発性有機化合物(VOC)等のガス状大気汚染物質が、主として環境大気中での化学反応により粒子化したものとがあります。発生源としては、ボイラー、焼却炉などのばい煙を発生する施設、コークス炉、鉱物の堆積場等の粉じんを発生する施設、自動車、船舶、航空機等、人為起源のもの、さらには、土壌、海洋、火山等の自然起源のものもあります。

これまで取り組んできた大気汚染防止法に基づく工場・事業場等のばい煙発生施設の規制や自動車排出ガス規制などにより、SPMとPM2.5の年間の平均的な濃度は減少傾向にあります。図:PM2.5の生成メカニズム

PM2.5の生成メカニズム

図:PM2.5質量濃度の推移(平成13~22年度)
PM2.5質量濃度の推移(平成13~22年度)(出典:微小粒子状物質等曝露影響実測調査)

環境省サイトより(http://www.env.go.jp/air/osen/pm/info.html)

2.環境基準について(環境省サイトより)

  • 環境基本法第16条第1項に基づく人の健康の適切な保護を図るために維持されることが望ましい水準として以下のとおり環境基準を定めています。

1年平均値 15μg/m3以下 かつ 1日平均値 35μg/m3以下(平成21年9月設定)

Related posts

Leave a Comment