Co2センサーを自作してみよう!Arduinoで作ってみた!

AQI、TVOC、CO2測定センサーの自作(二酸化炭素測定器)

マニアック記事です。

Co2センサー、数年前から急にネットで様々な種類が出回りましたね。

アウトドアなんかでも活躍してくれそうなのはSwitchBotのCo2センサーです。

ただ、今回は自作してみたくてチャレンジしてみることにしました。

自作Co2センサー

空気汚染自作!おしゃれなケースに入れてみた

完成品がこちら。

100均の木のケースに収納した自作Co2センサーです。

空気汚染メーター

小さいモニターにAQI(空気質指数)、TVOC(総揮発性有機化合物)、eCO2(二酸化炭素濃度)、温度、湿度を表示するようにしてみました。

また、以下のレベルに到達するとメロディー(アラーム)でお知らせしてくれる機能を追加しました。

種類閾値アラーム音
AQI4 以上こいぬのマーチ
TVOC660 ppb 以上茶色の小瓶
eCO21,000 ppm 以上きらきら星

AQI、TVOCの閾値チェックは外す or 閾値をあげてしまっても良いと思います。

(すぐピーピーなって煩いです)

1度閾値を超えると1分待機するようにしています。

私用したもの

あとは100均の木箱、ELEGOOのキットに入っていたケーブルです。

二酸化炭素チェック器を作成するのにかかった費用はこちら。

パーツ費用
マイコン\ 998
モニター\ 500
センサー\ 982
ブザー\ 35
ブレッドボード\ 125
木箱\ 110
合計\ 2,739

センサー代が高い。。

お勉強用とはいえ結構かかってしまいました。

作成したコード

以下、作成したコードです。

#include <Wire.h>
#include <Adafruit_GFX.h>         //SSD1306 画像描画用
#include <Adafruit_SSD1306.h>     //SSD1306 モニタ用
#include <SparkFun_ENS160.h>      //ENS160 ガスセンサ用
#include <AHTxx.h>                //AHT21 温湿度用

#define TEMPERATURE_CORRECTION -4 // ENS160 温度補正 -4 ℃

SparkFun_ENS160 myENS;            //ENS160

const int SCREEN_WIDTH = 128;     //ディスプレイのサイズ指定
const int SCREEN_HEIGHT = 64;     //ディスプレイのサイズ指定
const int SCREEN_ADDRESS = 0x3C;  //I2Cのアドレス指定

// ENS160
int ensStatus;

int alertlevelAqi = 5;
int alertlevelTvoc = 660;
int alertlevelCo2 = 1001;

int pinBuzzer = 8;
int do2 = 262;
int re2 = 294;
int mi2 = 330;
int fa2 = 349;
int so2 = 392;
int ra2 = 440;
int si2 = 494;
int do3 = 523;
int re3 = 587;
int mi3 = 659;

int cooltime = 0;
bool flag = false;

// AHT21
AHTxx AHT21(AHTXX_ADDRESS_X38, AHT2x_SENSOR);

// ディスプレイ制御用のインスタンスを作成。この時にサイズを渡す
Adafruit_SSD1306 display( SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);

float calcMaxVaperPressure(float temp)
{
  // 飽和水蒸気圧
  return 6.1078 * pow(10, 7.5 * temp / (temp + 237.3));
}

float recalculateHumidity(float temp, float rh)
{
  // 温度を補正して湿度を再計算
  float temp2 = temp + TEMPERATURE_CORRECTION;
  return rh * calcMaxVaperPressure(temp) * (temp2 + 273.15) / ((temp + 273.15) * calcMaxVaperPressure(temp2));
}

void setup() {
  // BUILTIN LEDの消灯
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  Wire.begin();
  Serial.begin(115200);

  // 起動音
  buzzer(do2, 200);
  buzzer(re2, 200);
  buzzer(mi2, 200);

  // SSD1306
  //ディスプレイを初期化。この時にI2Cアドレスを渡す
  display.begin( SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS );
  display.clearDisplay(); //画面描写エリアを削除。
  display.display();      //画面描写エリアをディスプレイに転送。ここで全画面を削除。
  delay(1000);            //1秒待機

  // ENS160
  if( !myENS.begin() )
  {
    display.setCursor( 0, 22 );
    display.setTextColor( SSD1306_WHITE, SSD1306_BLACK );
    display.setTextSize( 1 );
    display.println("Did not begin.");
    display.display();
    while(1);
  }
  // Reset the indoor air quality sensor's settings.
  if( myENS.setOperatingMode(SFE_ENS160_RESET) )
  {
    display.setCursor( 0, 22 );
    display.setTextColor( SSD1306_WHITE, SSD1306_BLACK );
    display.setTextSize( 1 );
    display.println("Ready.");
    display.display();
  }
  delay(1000);
  myENS.setOperatingMode(SFE_ENS160_STANDARD);
 
  // There are four values here: 
  // 0 - Operating ok: Standard Operation
  // 1 - Warm-up: occurs for 3 minutes after power-on.
  // 2 - Initial Start-up: Occurs for the first hour of operation.
  // and only once in sensor's lifetime.
  // 3 - No Valid Output
  ensStatus = myENS.getFlags();
  
  display.setCursor( 0, 22 );
  display.setTextColor( SSD1306_WHITE, SSD1306_BLACK );
  display.setTextSize( 1 );
  display.println(" Gas Sensor ");
  display.print(" Status Flag: ");
  display.println(ensStatus);
  display.display();
}

void loop() {
  //ENS
  if( myENS.checkDataStatus() )
  {
    // AHT21センサーから温度と湿度を取得
    float rawTemperature = AHT21.readTemperature();
    float rawHumidity = AHT21.readHumidity();
    // 温湿度補正
    float temperature = rawTemperature + TEMPERATURE_CORRECTION;
    float humidity = recalculateHumidity(rawTemperature, rawHumidity);

    // SSD
    display.clearDisplay();
    display.setTextSize( 1 );     //フォントサイズ指定。
    display.setTextColor( SSD1306_BLACK, SSD1306_WHITE ); //display.setTextColor( 文字本体の色, 背景の色)
    display.setCursor( 15, 10 );  //描写開始座標(X.Y)
    if (flag == false) {
      display.print( " Air Check " );
    } else {
      display.print( " Cool Time : " );
      display.print( cooltime );
    }

    display.setCursor( 0, 22 );
    display.setTextColor( SSD1306_WHITE, SSD1306_BLACK );
    display.setTextSize( 1 );
    display.print( " AQI  : " );
    display.println(myENS.getAQI());

    display.print( " TVOC : " );
    display.print(myENS.getTVOC());
    display.println(" ppb ");

    display.print( " eCO2 : " );
    display.print(myENS.getECO2());
    display.println(" ppm ");

    display.print( " Temp : " );
    //display.print(rawTemperature);
    display.print(temperature);
    display.println(" C ");

    display.print( " Humi : " );
    //display.print(humidity);
    display.print(rawHumidity);
    display.println(" % ");

    // 5min wait
    if (flag == true && cooltime < 300) {
      cooltime = cooltime + 1;
      delay(1000); // 1 sec
    } else {
      flag = false;
      cooltime = 0;

      //checkAqi(myENS.getAQI());   // AQI チェック
      //checkTvoc(myENS.getTVOC()); // TVOC チェック
      checkCo2(myENS.getECO2());  // Co2 チェック
    }

    display.display();
	}
}

void buzzer (int oto, int time) {
    tone(pinBuzzer, oto, time);
    delay(time);
}

int checkAqi (int x) {
  if (x >= alertlevelAqi) {
    buzzer(mi2, 500);
    buzzer(do2, 500);
    buzzer(mi2, 500);
    buzzer(do2, 500);
    buzzer(mi2, 500);
    buzzer(so2, 500);
    buzzer(so2, 1000);
    buzzer(fa2, 500);
    buzzer(re2, 500);
    buzzer(re2, 1000);
    buzzer(mi2, 500);
    buzzer(do2, 500);
    buzzer(do2, 1000);
    
    flag = true;
  }
}

int checkTvoc (int x) {
  if (x >= alertlevelTvoc) {
      buzzer(mi2, 500);
      buzzer(so2, 500);
      buzzer(so2, 500);
      buzzer(so2, 500);
      buzzer(fa2, 500);
      buzzer(ra2, 500);
      buzzer(ra2, 500);
      buzzer(ra2, 500);
      buzzer(si2, 500);
      buzzer(si2, 500);
      buzzer(ra2, 500);
      buzzer(si2, 500);
      buzzer(do3, 500);
      buzzer(re3, 500);
      buzzer(mi3, 500);
      
      flag = true;
  }
}

int checkCo2 (int x) {
  if (x >= alertlevelCo2) {
    buzzer(do2, 500);
    buzzer(do2, 500);
    buzzer(so2, 500);
    buzzer(so2, 500);
    buzzer(ra2, 500);
    buzzer(ra2, 500);
    buzzer(so2, 1000);
    buzzer(fa2, 500);
    buzzer(fa2, 500);
    buzzer(mi2, 500);
    buzzer(mi2, 500);
    buzzer(re2, 500);
    buzzer(re2, 500);
    buzzer(do2, 1000);

    flag = true;
  }
}

以上、自作してみたCo2(二酸化炭素)測定器のお話でした。

応援してもらえると幸いです。

PVアクセスランキング にほんブログ村

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA