注目

Arduino Nano に CCS811(空気品質センサー) を接続し、部屋の二酸化炭素濃度を測定する #2/2

eCO2値の取得

利用するCCS811センサー用ライブラリ

今回購入したAliExpressで購入したCJMCU-811については、ライブラリーに関する情報が提供されていませんでした。そこで、Google検索をして、CCS811センサーを扱うライブラリーとしてMITライセンスで公開されているSparkFun CCS811 Arduino Library *5 を使用することにしました。

*5 参照URL https://github.com/sparkfun/SparkFun_CCS811_Arduino_Library

実装例を用いeCO2値が取得できるか確認する

同GitHubリポジトリにはArduinoでCCS811のセンサー値を読み取り、シリアル通信でその値を確認できる実装例:Example1_BasicReadings.ino が公開されています。そこで、まずこの実装例を利用し、今回利用するArduino Nano+CJMCU-811で動作するように変更しました。

尚、実装例のコメントに下記が記載されていました。

A new sensor requires at 48-burn in. - 新しいセンサーは48時間の「慣らし」が必要。

Once burned in a sensor requires 20 minutes of run in before readings are considered good. - 一度慣らしを終えたセンサーは、良好な値を得るため使用前に20分間の暖気が必要。

#include <wire.h>

#include "SparkFunCCS811.h" //Click here to get the library: http://librarymanager/All#SparkFun_CCS811

//#define CCS811_ADDR 0x5B //Default I2C Address
#define CCS811_ADDR 0x5A //Alternate I2C Address

CCS811 mySensor(CCS811_ADDR);

void setup()
{
  Serial.begin(115200);
  Serial.println("CCS811 Basic Example");

  Wire.begin(); //Inialize I2C Hardware

  if (mySensor.begin() == false)
  {
    Serial.print("CCS811 error. Please check wiring. Freezing...");
    while (1)
      ;
  }
}

void loop()
{
  //Check to see if data is ready with .dataAvailable()
  if (mySensor.dataAvailable())
  {
    //If so, have the sensor read and calculate the results.
    //Get them later
    mySensor.readAlgorithmResults();

    Serial.print("CO2[");
    //Returns calculated CO2 reading
    Serial.print(mySensor.getCO2());
    Serial.print("] tVOC[");
    //Returns calculated TVOC reading
    Serial.print(mySensor.getTVOC());
    Serial.print("] millis[");
    //Display the time since program start
    Serial.print(millis());
    Serial.print("]");
    Serial.println();
  }

  delay(10); //Don't spam the I2C bus
}

尚、実装例のコメントに下記が記載されていましたので、CCS811を使用するには注意が必要です。

  • A new sensor requires at 48-burn in. - 新しいセンサーは48時間の「慣らし」が必要。
  • Once burned in a sensor requires 20 minutes of run in before readings are considered good. - 一度慣らしを終えたセンサーは、良好な値を得るため使用前に20分間の暖気が必要。

実行結果

上記コードをArduino IDEに張り付け、コンパイルエラー等発生しないことを「検証・コンパイル」で確認し、「マイコンボードに書き込む」を実行しました。

その後、シリアルポートの出力を確認すると、下記のようになり、無事CCS811センサーよりeCO2値を取得できていることが確認できました。

12:26:56.013 -> CCS811 Basic Example
12:27:00.012 -> CO2[400] tVOC[0] millis[3997]
12:27:01.008 -> CO2[400] tVOC[0] millis[4994]
12:27:02.009 -> CO2[400] tVOC[0] millis[5989]
12:27:03.012 -> CO2[400] tVOC[0] millis[6975]
12:27:04.011 -> CO2[400] tVOC[0] millis[7970]
12:27:04.965 -> CO2[400] tVOC[0] millis[8967]
12:27:05.968 -> CO2[400] tVOC[0] millis[9962]
12:27:06.971 -> CO2[400] tVOC[0] millis[10958]
12:27:07.969 -> CO2[400] tVOC[0] millis[11943]
12:27:08.968 -> CO2[400] tVOC[0] millis[12940]
12:27:09.970 -> CO2[400] tVOC[0] millis[13936]

SH1106 OLEDへの表示

利用するSH1106ドライバー

今回購入したAliExpressで購入したSH1106 OLEDディスプレイについても、ライブラリーに関する情報が提供されていませんでした。そこで、こちらもGoogle検索したところ、Arduino-er の Hello World 1.3 inch IIC/SPI 128x64 OLED x Arduino, using u8glib library という記事 でu8glibライブラリを使用した解説がされていました。
u8glibBSDライセンスhttps://github.com/olikraus/u8glib にて公開されていますが、既に開発は止まっているようです。u8g2ライブラリの開発へ移行しているのでそちらを使うようにとの記載がありますが、今回はu8glibを使うことにしました。

u8glibのGitHubリポジトリには使い方の説明もドキュメント化されていますので、https://github.com/olikraus/u8glib/wiki/thelloworld を参考に、先ほどのCCS811のコードに実装を追加しました。

#include <wire.h>
#include <u8glib.h>         // https://github.com/olikraus/u8glib
#include <sparkfunccs811.h> //Click here to get the library: http://librarymanager/All#SparkFun_CCS811

// CCS811 sensor
//#define CCS811_ADDR 0x5B        //Default I2C Address
#define CCS811_ADDR 0x5A          //Alternate I2C Address
#define WARMUP_TIME 1200000ul   // センサーウォームアップ時間 20min*60s*1000msec
CCS811 mySensor(CCS811_ADDR);

//OLEDモニタ使用のワイヤ定義
U8GLIB_SH1106_128X64 u8g(13, 11, 10, 9, 8);
#define UPDATE_INTERVAL 1000ul    // 表示更新間隔 1s*1000msec
unsigned long previous_time = 0ul;

void setup()
{
  Serial.begin(115200);
  Serial.println("CCS811 Basic Example");

  Wire.begin(); //Inialize I2C Hardware

  if (mySensor.begin() == false)
  {
    Serial.print("CCS811 error. Please check wiring. Freezing...");
    while (1)
      ;
  }
}

//画面表示
void draw(void) {
 //1列目:CO2 Meter
  u8g.setFont(u8g_font_unifont);
  u8g.setPrintPos(2,14);
  if (millis() <= WARMUP_TIME) { // センサWARM UP中
    u8g.print("= CO2 Monitor *=");
  }
  else {
    u8g.print("= CO2 Monitor =");
  }
  
 //2列目:二酸化炭素PPM実数表示
  u8g.setPrintPos(2,28);
  u8g.print("CO2:");
  u8g.print(mySensor.getCO2());
  u8g.print(" ppm");
  
 //3列目:総揮発性有機化合物PPB実数表示
  u8g.setPrintPos(2,42);
  u8g.print("TVOC:");
  u8g.print(mySensor.getTVOC());
  u8g.print(" ppb");

}

void loop()
{ 
  //Check to see if data is ready with .dataAvailable()
  if (mySensor.dataAvailable())
  {
    //If so, have the sensor read and calculate the results.
    //Get them later
    mySensor.readAlgorithmResults();

    // 表示更新間隔を過ぎていたらOLEDの表示を更新する
    if (millis() - previous_time > UPDATE_INTERVAL) {
      Serial.print("eCO2[");
      //Returns calculated CO2 reading
      Serial.print(mySensor.getCO2());
      Serial.print("] tVOC[");
      //Returns calculated TVOC reading
      Serial.print(mySensor.getTVOC());
      Serial.print("] millis[");
      //Display the time since program start
      Serial.print(millis());
      Serial.print("]");
      Serial.println();
      
      u8g.firstPage();
      do {
        draw();
      } while( u8g.nextPage() );
    }
  }

  delay(10); //Don't spam the I2C bus
}

尚、20分間の暖気が必要ということで、起動後20分間はOLEDの1行目の表示を
= CO2 Monitor *=
としています。20分経過後すると、
= CO2 Monitor =
と表示されます。

実行結果

上記コードをArduino IDEに張り付け、コンパイルエラー等発生しないことを「検証・コンパイル」で確認し、「マイコンボードに書き込む」を実行しました。
その結果、下記のようにSH1106 OLEDディスプレイにeCO2値が表示されました。

CCS811センサー値をSH1106 OLEDディスプレイに表示

以上で今回の目標は達成です。

今後、MH-19BとCCS811のCO2センサー値の比較を実施しようと思います。

コメント