[企画・制作] ZEPエンジニアリング
高精度!超定番センサ SCD30で作るCO2&温湿度計
新型コロナウイルス感染防止対策や良好な空気環境の維持を目的に、CO2濃度を基準とする密状態の把握や換気の実施などが呼びかけられています。CO2濃度を測定するためのCO2センサには、NDIR方式や光音響方式がありますが、その他にH2(水素)をベースとして、二酸化炭素量を算出するCO2eq(等価二酸化炭素)センサがあります。それらの代表的なセンサデバイスとして、Sensirion社SCD30、SCD41、SGP30があり、それらをモジュール化した製品が販売されています。
今回から3回に分けて、それぞれのモジュールの基本的な仕様と使い方、M5Stackで制御する方法についてご紹介します。 今回はNDIR(Non-Dispersive InfraRed:非分散型赤外線吸収)方式のSCD30モジュールを取り上げます。動作させるためのプログラムの開発環境として、Arduino IDEを使用しましたので、M5Stackだけでなく、少しの変更で各種ArduinoボードやRaspberry Pi Pico等でも同様に使用することができます。
SCD30の測定方式
SCD30は、赤外線の吸収量を基にCO2濃度を算出するNDIR(Non-Dispersive InfraRed:非分散型赤外線吸収)方式のCO2センサです。NDIRの基本原理(シングルチャンネルまたは、シングルビーム方式)を以下に示します。

赤外線LED光源から発せられた赤外線は、光学フィルタを通して、赤外線センサに到達しますが、CO2分子は特定の波長(4.26μm)の赤外線を吸収するためCO2濃度によって赤外線センサに到達する赤外線量が変化します。その変化量からCO2濃度を測定します。光学フィルタは、CO2関連した赤外線のみ透過するのに用いられます。この付近の波長には、CO2以外にCO(一酸化炭素)やNOx(窒素酸化物)など環境モニターに用いられるものがあります。(関連参考文献:WIKIPEDIA Nondispersive infrared sensor)
上で述べたシングルチャンネル方式のNDIRは、光源等の経年変化が、測定結果に直接影響するため、比較的短い期間でのキャリブレーションが必要となります。一方、SCD30は、デュアルチャンネル(あるいはダブルビーム)方式のNDIRを採用しています。

上の図のように2つの空気室があり、ひとつはシングルチャンネル方式のNDIRと同様のCO2測定用のセンサ(光学フィルタを含む)が、もう一方の空気室には、CO2、その他のガスの影響を受けないリファレンス用のセンサがあります。それぞれのセンサ出力を比較して、CO2量を算出することにより、光源等の経年変化の影響を少なくすることができます。これにより、シングルチャンネル方式に比べて長期的に安定した測定が可能となります。
また、海抜の高低の変化(大気圧に影響)は、CO2濃度の測定に影響を与えますが、SCD30は、外部よりその値を設定することにより、測定値を補正する機能もあり、より高精度の測定が可能です。
SCD30の外観図とピンアサイン、基本仕様
SCD30の外形図とピンアサインを示します。外観寸法図、その他詳細については、データシートをご参照ください。



SCD30の基本仕様は以下のとおりです。CO2センサの他に温度、湿度センサ機能もあり、環境モニターセンサに最適です。

SCD30をM5Stackに接続して使用する
M5Stackには、Groveと呼ばれる電源とI2Cのインターフェースがあるのでそこに接続します。接続図と接続例の写真を以下に示します。


制御ソフトウェア
(1)開発環境構築
今回はArduino IDE環境で制御プログラムを作成します。M5StackのArduino IDE開発環境の構築については、別記事「いろいろなマイコンボードに使えるArduino IDE。環境構築メモ」の「M5StackをArduino IDEで使う」の章を参考にしてください。
M5Stack用のArduino IDE環境が構築できたら、今回のSCD30用のI/Oライブラリを以下の手順でインストールします。
・Arduino IDEメニューで ツール ⇒ ライブラリを管理 を選択。
・検索欄に「SCD30」と入力し検索されたものの中から「SparkFun SCD30 Arduino Library」をインストールする。
以上でSCD30を使用する開発環境が整いました。続いてサンプルプログラムを入力し、動かしてみます。
(2)サンプルプログラム
SCD30で取得したデータをM5StackのLCDに表示するとともにArduino IDEのシリアルモニタ、シリアルプロッタで表示できるようにシリアル出力をするものです。また後述するSCD30を強制リキャリブレーション(FRC: Forced Re-Calibration)するためのプログラムコードも含まれており、SCD30の校正も可能です。
サンプルプログラムリスト
- #include <M5Stack.h>
- #include <SparkFun_SCD30_Arduino_Library.h> //Click here to get the library: http://librarymanager/All#SparkFun_SCD30
- SCD30 airSensor;
- void setup() {
- M5.begin(true, false, true, true);
- if (airSensor.begin() == false) //SCD30の初期化
- {
- Serial.println("Air sensor not detected. Please check wiring. Freezing...");
- while (1);
- }
- M5.Lcd.fillScreen(TFT_BLACK); //M5Stackの画面初期化
- M5.Lcd.setTextFont(4);
- M5.Lcd.setTextSize(1);
- M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
- M5.Lcd.setTextDatum(TL_DATUM);
- if(M5.BtnA.isPressed()){ //左のボタンが押下されているか判定
- Serial.println("FRC started... PLS wait 3 min."); //押下されていればFRCを実行
- M5.Lcd.setCursor(20, 20);
- M5.Lcd.printf("FRC started...");
- delay(3*60*1000); //3分間通常動作させる
- //if(airSensor.StopMeasurement() == false) while(1); //計測停止
- if(airSensor.setForcedRecalibrationFactor(413) == false) while(1); //FRCを実行
- delay(1000); //FRC後1秒待つ
- if(airSensor.beginMeasuring() == false) while(1); //通常モードでの測定開始
- Serial.println("Completed."); //FRC完了表示
- M5.Lcd.setCursor(20, 40);
- M5.Lcd.printf("Completed.");
- }
- }
- void loop() {
- if (airSensor.dataAvailable()) //測定データがあるか判定
- {
- M5.Lcd.setCursor(0, 160); //あれば画面表示
- M5.Lcd.printf("SCD30:CO2 : %4d ppm ", airSensor.getCO2());
- M5.Lcd.setCursor(0, 200);
- M5.Lcd.printf("Temp: %2.1f 'C %2.1f %c ", airSensor.getTemperature(), airSensor.getHumidity(), '%');
- }
- Serial.print("SCD30 "); Serial.print(airSensor.getCO2()); Serial.print("\n"); //測定データをシリアル出力
- delay(1000); //1秒ウェイト
- }
- 6~16行目は、M5StackとSCD30の初期化です。
- 17~29行目は、M5Stack電源投入時にM5Stackの3つのボタンのうち、左のボタンが押下されているか否かを判定し、押下されていればFRC(強制リキャリブレーション)を行います。
- 32~42行目が、メインルーチンで、1秒ごとにSCD30の測定データ(CO2、温度、湿度)があるか否かを調べ、あれば、M5StackのLCDに表示します。SCD30では数秒ごとにデータが上がってきます。シリアル出力は1秒ごとにデータ送信しますが、SCD30からのデータがないときは、前回SCD30から取得したデータを送信します。※シリアル出力はCO2データのみ送信しています。温度、湿度データは送信していませんので、必要に応じて追加してください。
※サンプルプログラムで使用したSCD30用のライブラリの詳細については、GitHub上のドキュメントを参照してください。
(3)サンプルプログラムの実行例
サンプルプログラムを実行したときのM5StackのLCD表示とシリアルモニタ表示を以下に示します。

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

この例は、6畳程の部屋で換気を行ったときの様子です。はじめCO2濃度は約1,040ppmでしたが、数分間、窓を20cmほど開けると、すぐに約760ppmまで下がりました。その後、窓を閉じると再び上昇し、約980ppmに戻りました。もう少し長い時間の換気が必要そうです。
キャリブレーション(校正)
SCD30には、自動でキャリブレーションを行う、ASC(Automatic Self Calibration:自動自己キャリブレーション)と強制的にキャリブレーションを行うFRC (Forced Re-Calibration:強制リキャリブレーション)機能があります。
ASCは、外気のCO2濃度が約400ppmであることを利用して、SCD30が、ある期間(1週間程度)に測定したデータのうち一番低い値を外気同等とみなし400ppmに補正する機能です。したがって、一度も外気が入らない密閉空間では、実際には高いCO2濃度も低く400ppmと補正されてしまい、正しく校正されないため注意が必要です。この機能はプログラムで以下関数を用いることによって、無効/有効化することができます。
airSensor.setAutoSelfCalibration(引数)
引数:ASC機能 0:無効 1:有効
必要に応じて、setupルーチンの中に組込んで設定してください。
FRCを実行するには、既知のCO2環境下で、既知のCO2濃度を引数として、
airSensor.setForcedRecalibrationFactor(引数)
を実行することによって、SCD30をその値に補正することができます。補正した値は、NVRAMに記録され次回の電源オン時から使用されます。
既知のCO2濃度環境を構築できないときは、外気を400ppmと見なして、SCD30を外気中に置き補正します。サンプルプログラムでは、気象庁の最近の観測データを見ると413ppm前後なので413を引数としてみましたが、あまり気にせず400で良いでしょう。※ASCがオンの場合は400ppmに補正されるので、整合性を取って400にするのが良いと思われます。
FRCを実行するには、既知のCO2濃度環境で少なくとも2分間SCD30を通常モードで動作させておく必要があり、サンプルプログラムでは、3分間動作させた後にFRC関数を呼んでいます。このときセンサに風が当たっていたり、直射日光下では、正しい値が設定されない可能性があるので注意が必要です。
CO2センサを使用する上での注意点
センサは、人間の呼気や振動にも敏感に反応します。実験する際には、それらの影響が無いようにセンサと十分に距離をとるなどの配慮が必要です。特にSCD30に強く息を吹き掛けるなどすると高いCO2濃度を示し、しばらく正常値を出力しなくなったり、FRCを実行しない限り、測定値が異常のままになったりします。機能確認ができたら、正式な筐体などに入れて実験することをおすすめします。
マルツで購入できるCO2センサ
マルツで購入できるCO2センサは、こちらのリンクをクリックしてください。多数表示されますが、今回紹介したSCD30をはじめ、様々な製品があります。データシートを参照の上、選択してください。
c2022ー Takami.K, @logic_star All rights reserved.