SGP30でつくる環境チェッカ

[企画・制作] ZEPエンジニアリング

化学物質にも反応!CO2eqセンサ SGP30で作る環境チェッカ

 新型コロナウイルス感染防止対策や良好な空気環境の維持を目的に、CO2濃度を基準とする密状態の把握や換気の実施などが呼びかけられています。CO2濃度を測定するためのCO2センサには、NDIR方式や光音響方式がありますが、その他にH2(水素)をベースとして、二酸化炭素量を算出するCO2eq(等価二酸化炭素)センサがあります。それらの代表的なセンサデバイスとして、Sensirion社SCD30、SCD41、SGP30があり、それらをモジュール化した製品が販売されています。


CO2センサ・モジュール例

SCD30センサモジュール
CO2センサモジュール【SCD30】

(二酸化炭素+温度/湿度センサ)
(NDIR方式)
SCD41センサモジュール
Grove-CO2/温/湿度センサ【SCD41】

(二酸化炭素+温度/湿度センサ)
(Photoacoustic:光音響方式)
SCP30センサモジュール
TVOC/eCO2 ガスセンサ【SGP30】

(TVOC/CO2eqセンサ)
(CO2eq:等価二酸化炭素算出方式)

 3回に分けて、それぞれのモジュールの基本的な仕様と使い方、M5Stackで制御する方法についてご紹介しています。 第3回の今回は室内の空気環境センサSGP30モジュールを取り上げます。動作させるためのプログラムの開発環境として、Arduino IDEを使用しましたので、M5Stackだけでなく、少しの変更で各種ArduinoボードやRaspberry Pi Pico等でも同様に使用することができます。

SGP30

 最初にお断りしておきますが、SGP30は、CO2そのものを測定するセンサではなく、室内のAir Quality(空気の質)を測定するために開発されたデバイスです。測定対象は、空気中のエタノールとH2(水素)ですが、そこからTVOC (Total Volatile Organic Compounds:総揮発性有機化合物量)とCO2eq(CO2 equivalent:等価二酸化炭素量)を算出*1し出力します。(CO2eqは、eCO2とも表現され、本記事では、両方の表現を使用しますが、同一のものと認識ください。)
 SGP30が示すTVOC/CO2eqそれぞれの値は、対象気体そのものの濃度を測定したものではないということに留意する必要があります。特にCO2eqについては、特定の環境下では実際のCO2と近似した値を示しますが、他のVOC(Volatile Organic Compounds:揮発性有機化合物)の影響も受けるためCO2濃度そのものを正確に測定したい用途には適しません。室内空気環境維持を目的とした、CO2だけでなく他のVOCを含めたAir Qualityを観測するセンサとして用いるのが最適です。
 CO2濃度そのものを測定したい場合は、第1回で紹介したSCD30、第2回で紹介したSCD41といったCO2測定専用のセンサを用いることを推奨します。

 *1:SGP30は、TVOC/CO2eqの算出に、SGP30特有のDynamic baseline(動的ベースライン)補正アルゴリズムとオンチップのキャリブレーションパラメータを使用します。(詳細は後述)

TVOC(Total Volatile Organic Compounds:総揮発性有機化合物量)とは

 最初にVOCについて説明します。VOC(Volatile Organic Compounds:揮発性有機化合物) は、常温常圧で大気中に容易に揮発する有機化学物質の総称のことです。これらの物質は、体内に吸気し続けると健康被害を及ぼす可能性があります。特に室内において、建材や家具、日用品から揮発されたVOCが「シックハウス症候群」の原因物質であるとされています。これを鑑み厚生労働省がVOCとその室内濃度指針値をガイドラインとして定めています。厚生労働省が定めたVOCは13種類だけですが、その他にもVOCは多く存在し、それぞれ個々に指針を示すことは困難なため、13種類のVOCを含め他のVOC濃度の合計の総量をTVOC(Total Volatile Organic Compounds:総揮発性有機化合物量)と表現し、その目標値として、400μg/m3と定めています。参考としてVOC13種とそれぞれの指針値を以下表に示します。
VOC13種とTVOC

厚生労働省ウェブページより引用

TVOC/eCO2 ガスセンサー【SGP30】の基本仕様

 今回はSGP30を用いた、M5Stack社製の TVOC/eCO2 ガスセンサー【SGP30】Groveモジュールを使用しました。SGP30デバイス単体の仕様については、Sensirion社のデータシートをご参照ください。

・SGP30の機能ブロックダイヤグラムは、以下のとおりです。(Sensirion社のデータシートより引用)
SGP30 block diagram
・TVOCとCO2eq は、測定したエタノールとH2の値からDynamic baseline補正アルゴリズムにより算出されます。
SGP30 block diagram
・SGP30には推奨動作条件と推奨保存条件があります。この条件外で使用または保存(保管)すると測定精度を保てなかったり、デバイスの劣化が加速される可能性があるため注意が必要です。
SGP30 Operating conditions

TVOC/eCO2 ガスセンサー【SGP30】をM5Stackに接続して使用する

 TVOC/eCO2ガスセンサー【SGP30】モジュールは、M5StackのGroveインターフェースに接続します。接続例の写真を以下に示します。
M5Stack and SGP30
 なお、SGP30には、絶対湿度による補正機能があり、その機能を活かすには、別途温湿度センサを用意する必要があります。今回はM5Stack社の「温湿度気圧センサユニットVer.3(ENV III)」を「M5Stack用拡張ハブユニット」を介してTVOC/eCO2 ガスセンサー【SGP30】と一緒に接続して使用してみました。 M5Stack, SGP30, ENV.III and HUB

ENV.III
M5Stack用温湿度気圧センサユニットVer.3(ENV III)

HUB
M5Stack用拡張ハブユニット

制御ソフトウェア

(1)開発環境構築

 今回はArduino IDE環境で制御プログラムを作成します。M5StackのArduino IDE開発環境の構築については、別記事「いろいろなマイコンボードに使えるArduino IDE。環境構築メモ」の「M5StackをArduino IDEで使う」の章を参考にしてください。

 M5Stack用のArduino IDE環境が構築できたら、今回のSGP30用のI/Oライブラリを以下の手順でインストールします。
 ・Arduino IDEメニューで ツール ⇒ ライブラリを管理 を選択。
 ・検索欄に「SGP30」と入力し検索されたものの中から「Adafruit SGP30 Sensor」をインストールする。
 以上でTVOC/eCO2 ガスセンサー【SGP30】を使用する開発環境が整いました。続いてサンプルプログラムを入力し、動かしてみます。

(2)サンプルプログラム

 TVOC/eCO2ガスセンサー【SGP30】で取得したデータをM5StackのLCDに表示するとともにArduino IDEのシリアルモニタ、シリアルプロッタで表示できるようにシリアル出力をするものです。また、温湿度気圧センサユニットVer.3(ENV III)の温度、相対湿度データから絶対湿度を算出し、TVOC/eCO2の補正をするコードも含まれています。

サンプルプログラムリスト

  1. #include <M5Stack.h>
  2. #include <Adafruit_SGP30.h>
  3. Adafruit_SGP30 sgp;
  4. uint16_t eco2_base = 37335; //eco2 baseline仮設定値
  5. uint16_t tvoc_base = 40910; //TVOC baseline仮設定値
  6. #define ENV_III //ENV_III使用しない場合はコメントアウト要
  7. #ifdef ENV_III
  8. #include "UNIT_ENV.h"
  9. SHT3X sht30;
  10. QMP6988 qmp6988;
  11. float tmp = 0.0;
  12. float hum = 0.0;
  13. float pressure = 0.0;
  14. uint32_t getAbsoluteHumidity(float temperature, float humidity) { //温度、相対湿度から絶対湿度を計算
  15.   // approximation formula from Sensirion SGP30 Driver Integration chapter 3.15
  16.   const float absoluteHumidity = 216.7f
  17.                                  * ((humidity / 100.0f) * 6.112f
  18.                                     * exp((17.62f * temperature) / (243.12f + temperature))
  19.                                     / (273.15f + temperature)); // [g/m^3]
  20.   const uint32_t absoluteHumidityScaled = static_cast<uint32_t>(1000.0f
  21.                                           * absoluteHumidity); // [mg/m^3]
  22.   return absoluteHumidityScaled;
  23. }
  24. #endif
  25. void setup() {
  26.   M5.begin(true, false, true, true);
  27.   if (! sgp.begin()){
  28.     Serial.println("Sensor not found :(");
  29.     while (1);
  30.   }
  31.   sgp.softReset();
  32.   sgp.IAQinit();
  33.   sgp.setIAQBaseline(eco2_base, tvoc_base); //仮のbaseline設定しない場合はコメントアウト要
  34. #ifdef ENV_III
  35.   qmp6988.init();
  36. #endif
  37.   M5.Lcd.fillScreen(TFT_BLACK); //M5Stackの画面初期化
  38.   M5.Lcd.setTextFont(4);
  39.   M5.Lcd.setTextSize(1);
  40.   M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
  41.   M5.Lcd.setTextDatum(TL_DATUM);
  42.   M5.Lcd.setCursor(20, 40);
  43.   for(int i = 0; i < 15; i++){ //SGP30が動作するまで15秒ウェイト
  44.     M5.Lcd.printf(".");
  45.     delay(1000);
  46.   }
  47. }
  48. void loop() {
  49. #ifdef ENV_III
  50.   pressure = qmp6988.calcPressure() / 100; //気圧を測定
  51.   if(sht30.get()==0){ //Obtain the data of shT30. //温湿度を測定
  52.     tmp = sht30.cTemp; //Store the temperature obtained from shT30.
  53.     hum = sht30.humidity; //Store the humidity obtained from the SHT30.
  54.   }
  55.   sgp.setHumidity(getAbsoluteHumidity(tmp, hum)); //絶対湿度をSGP30にセット
  56. #endif
  57.   if (! sgp.IAQmeasure()) { //eCo2 TVOC読込
  58.     Serial.println("Measurement failed");
  59.     while(1);
  60.   }
  61.   M5.Lcd.setCursor(0, 40);
  62.   M5.Lcd.printf("TVOC: %4d ppb ", sgp.TVOC);
  63.   M5.Lcd.setCursor(0, 80);
  64.   M5.Lcd.printf("eCO2: %4d ppm ", sgp.eCO2);
  65. #ifdef ENV_III
  66.   M5.Lcd.setCursor(0, 160);
  67.   M5.Lcd.printf("Pres.: %4.1f hPa", pressure);
  68.   M5.Lcd.setCursor(0, 200);
  69.   M5.Lcd.printf("Temp: %2.1f 'C %2.1f %c ", tmp, hum, '%');
  70. #endif
  71.   Serial.print("eCO2 "); Serial.print(sgp.eCO2); Serial.print("\t");
  72.   Serial.print("TVOC "); Serial.print(sgp.TVOC); Serial.print("\n");
  73.   delay(1000); //1秒ウェイト
  74. }

  • 7~26行目は、ENV.IIIを使用する場合の定義と相対湿度から絶対湿度に変換する関数です。 ENV.IIIを使用しない場合は、7行目をコメントアウトしてください。
  • 28~50行目は、M5Stackその他の初期化ルーチンです。
    46~49行目は、SGP30が動作開始するまでの15秒のウェイトです。
  • 52~78行目が、メインルーチンで、1秒ごとにSGP30の測定データをM5StackのLCDに表示します。シリアル出力にデータ送信もします。※シリアル出力はTVOC/CO2eqデータを送信しています。ENV.IIIの測定データ(温度、湿度、気圧)は送信していませんので、必要に応じて追加してください。

※サンプルプログラムで使用したSGP30用のライブラリの詳細については、GitHub上のドキュメントを参照してください。

(3)サンプルプログラムの実行例

 サンプルプログラムを実行したときのM5StackのLCD表示とシリアルモニタ表示を以下に示します。

Data display Serial output

 また、下のグラフは、シリアルプロッタで部屋の中のCO2eqとTVOCの変化をグラフ化したものです。シリアルプロッタは、Arduino IDEのメニューで ツール ⇒ シリアルプロッタ を選択することによって表示できます。
Data plot

Dynamic baseline補正アルゴリズム

 SGP30は、TVOC/CO2eqの算出にあたって、SGP30が持っているDynamic baseline(動的ベースライン)補正アルゴリズムとオンチップのキャリブレーションパラメータを使用します。
 電源投入、またはソフトリセット後にbaselineパラメータが与えられるとその値を用いて、SGP30は、TVOC/CO2eqを算出すると共にDynamic baseline補正アルゴリズムによって、baselineの値を更新し続けます。この機能が正しく動き続けるためには、1秒ごとに sgp30_measure_iaq コマンドを発行する必要があります。
 また、電源投入、またはソフトリセット後にbaselineパラメータが与えられなかった場合は、12時間 環境をセンシングしながらDynamic baseline補正アルゴリズムが実行され、内部でbaseline値が設定されます。その後、算出されたTVOC/CO2eqを出力し始めます。12時間の間は、TVOC/CO2eqそれぞれ実際の濃度に関わらず、0pbb/400ppmの値を出力します。

SCD30(NDIR方式)と測定データの比較

 第1回で紹介したNDIR方式のCO2センサSCD30で測定したCO2の値と今回のSGP30で測定したCO2eqの値を長時間観測し比較したグラフを以下に示します。

測定例1

SCD30 vs SGP30  SGP30(CO2eq)とSCD30(CO2)測定値を比較すると測定値の増減の様子(定性的な変化)は、似ていますが、baseline補正が誤動作または、学習途中のためか、測定値そのものは、同程度の値を示すときもあれば、500~800ppm程度のオフセットがある場合もあります。グラフの右方の12:00:00付近で換気をしていますが、その際、baselineがリセットされたのか、測定値の誤差は小さくなっております。SGP30のDynamic baseline補正アルゴリズムは、1週間程度の学習期間が必要なようなので、長期間動作させることにより、より最適化される可能性があります。(上記グラフは電源オン1日後の観測データです。)

測定例2

SCD30 vs SGP30  こちらは、リビングでの測定例です。時刻6:00:00~8:00:00の間でSGP30(CO2eq)の測定値が急上昇していますが、このとき朝食の用意など料理や家事を行っています。火気の使用、その他でVOCが上昇し、その影響を受けていると思われます。その後の9:00以降の時間帯は、測定値には差があるものの定性的には同じようなカーブを描いています。
 余談になりますが、SGP30は、VOCの変化に対して、とても敏感に反応します。例えば「おなら」にも反応します。 fart detection

CO2センサを使用する上での注意点

 今回使用したSGP30に関わらず、CO2センサは、人間の呼気やデバイスに伝わる機械的振動にも敏感に反応します。実験する際には、それらの影響が無いようにセンサと十分な距離をとるなどの配慮が必要です。特にSGP30は、VOCに敏感に反応し、CO2eqの測定値に影響するため、CO2eqを目的とした測定の場合は、その点を十分考慮する必要があります。

まとめ

 CO2測定シリーズとして、3回に分けて、SCD30、SCD41、SGP30を使用しました。CO2の測定については、CO2専用のセンサであるSCD30、SCD41の使用を推奨します。いずれのセンサも市販のCO2計にも使用されており、同等の値を示します。一方、SGP30は、空気環境を測定することを目的としたものです。CO2だけでなく多くのVOCに反応するため、空気環境を把握し、適切な換気を促すというようなアプリケーション(応用)に適しています。

関連記事

定番センサSCD30で作る CO2&温湿度計
Groveで直結!新定番センサ SCD41で作るCO2&温湿度計

マルツで購入できるCO2センサ

 マルツで購入できるCO2センサは、こちらのリンクをクリックしてください。多数表示されますが、今回紹介したSCD41をはじめ、様々な製品があります。データシートを参照の上、選択してください。

©2022ー @logic_star All rights reserved.



Page Top