Arduino UNO R4 Minimaでセンサ・インターフェーシング ㉗ 空気質センサENS160
Adafruitから入手した空気質センサ ENS160(ScioSense)を利用します。
複数のIAQ(Indoor Air Quality;室内空気品質)指標のうち、eCO2、TVOC、AQIの3種類を検出できます。
前回の空気質センサSGP40 第25回で掲載したCO2センサのSCD41、第18回で掲載したボッシュBME688の気圧センサとの比較を次に示します。
型名 | 電源電圧 [V] |
気圧測定範囲 [hPa] |
温度[℃] | 湿度[%] | 空気測定の機能 |
ENS160 | 1.71~3.6 | - | - | - |
eCO2;二酸化炭素相当物レベル |
---|---|---|---|---|---|
SGP40 | 1.7~3.6 | - | - | - | 屋内に存在する一般的なVOCガスをもとにディジタル値を出力 |
SCD41 | 2.4~5.5 | - | -10~+60 確度;± 0.8℃ |
0~100 |
CO2 |
BME688 | 1.7~3.6 | 300~1100 | -40~+85℃ 確度;±0.5℃ |
0~100% 確度;±3% |
MOX (金属酸化物)センサで、各種空気のにおいを検知 |
- eCO2;equivalent CO2 values for compatibility with HVAC ventilation standards
- TVOC;Total Volatile Organic Compounds
- AQI;Air Quality Index
eCO2/CO2濃度の目安
eCO2/CO2 | レベル | 提案 |
---|---|---|
21500 | ひどい | 室内空気汚染が深刻で換気が必要 |
1000-1500 | 悪い | 室内の空気が汚れているので換気を推奨 |
800-1000 | 一般的に | 換気できる |
600-800 | 良い | 普通 |
400-600 | 素晴らしい | 提案なし |
TVOC 濃度の基準
TOVC(ppb) | 人間の健康への影響 |
---|---|
>6000 | 頭痛と神経の問題 |
750-6000 | 落ち着きがなく頭痛がする |
50-750 | 落ち着きがなく不快感がある |
<50 | 無効 |
AQI リファレンス
レベル | 説明 | 提案 | 推奨滞在時間 |
---|---|---|---|
5 | 非常に悪い | やむを得ない場合は換気を強化してください | 滞在は非推奨 |
4 | 悪い | 換気を強化し、汚染源を特定する | 1か月未満 |
3 | 一般的に | 水源に近い、換気を強化する | 12か月未満 |
2 | 良い | 適切な換気を維持する | 長期居住にも適している |
1 | 素晴らしい | 提案なし | 長期居住にも適している |
●AdafruitのStemma QT/Qwiicボード
Stemma QT/Qwiic(JST SH 4ピン)コネクタは2か所に装着されていて、どちらにつないでもかまいません。このコネクタを使ってI2Cで制御する場合、特に、ジャンパ線をつなぐなどは不要です。
コネクタは、表と裏のどちらも差し込めそうですが、ピンが内部の上部に並んでいるので、差し込める方向は一意です。ロック機構はないですが、すぐに抜けるということはありません。
●空気質センサENS160のおもなスペック
- 電源電圧 1.71~3.6V
- 動作時消費電流 29mA
- 動作条件 温度;-40~+85℃、湿度;5~95%RH
- eCO2測定範囲;400~65000ppm
- TVOC測定範囲;0~65000ppb
- AQI-UBA指標範囲;1~5
- インターフェース I2C(0~1MHz)、SPI
- スレーブ・アドレス 0x53、裏面のAddrジャンパで0x52に変更できる
●使用環境
- Arduino UNO R4 Minima
- Arduino IDE 2.2.1
- Windows10 22H2
●接続
Arduino UNO R4 MinimaのI2C信号とセンサ・ボードをJSTコネクタでつなぎます(Stemma QT/Qwiicボードの写真の比率は異なる)。
●スレーブ・アドレスを確認
従来からよく使われているi2cScanner.inoを動かしてスレーブ・アドレスを確認します。電源は3.5Vです。
0x53を見つけてきました。
●ライブラリの用意
ENS160で検索して、見つかったENS160-Adafruit Forkライブラリをインストールします。
●サンプル・スケッチ
メニューのファイル->スケッチ例、ENS160-Adafruit forkからsnd160basic_std.inoを選択し、1か所変更して、コンパイル、実行します。
13行目をコメントアウトし、14行目の先頭の//を削除してこちらの行を有効にします。ENS160_I2CADDR_1がここで利用するI2Cのスレーブ・アドレス0x53です。
//ScioSense_ENS160 ens160(ENS160_I2CADDR_0);
ScioSense_ENS160 ens160(ENS160_I2CADDR_1);
●グラフィック・ディスプレイに測定結果を表示
次の記事を参考に、グラフィック・ディスプレイに測定したTVOC、eCO2、AQIの値を表示します。
Arduino UNO R4 Minimaでセンサ・インターフェーシング ⑤ 温湿度センサSi7021の測定結果をグラフィック・ディスプレイに表示
スケッチです。
// ENS160 - Digital Air Quality Sensor. Updated by Sciosense / 25-Nov-2021
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
int ArduinoLED = 13;
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#include "ScioSense_ENS160.h" // ENS160 library
ScioSense_ENS160 ens160(ENS160_I2CADDR_1);
void setup() {
Serial.begin(115200);
while (!Serial) {}
//Switch on LED for init
pinMode(ArduinoLED, OUTPUT);
digitalWrite(ArduinoLED, LOW);
Serial.println("------------------------------------------------------------");
Serial.println("ENS160 - Digital air quality sensor");
Serial.println();
Serial.println("Sensor readout in standard mode");
Serial.println();
Serial.println("------------------------------------------------------------");
delay(1000);
Serial.print("ENS160...");
ens160.begin();
Serial.println(ens160.available() ? "done." : "failed!");
if (ens160.available()) {
// Print ENS160 versions
Serial.print("\tRev: "); Serial.print(ens160.getMajorRev());
Serial.print("."); Serial.print(ens160.getMinorRev());
Serial.print("."); Serial.println(ens160.getBuild());
Serial.print("\tStandard mode ");
Serial.println(ens160.setMode(ENS160_OPMODE_STD) ? "done." : "failed!");
}
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
display.clearDisplay();
display.drawRect(0, 0, display.width(), display.height(), SSD1306_WHITE);
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(3,3);
display.println("AQI:");
display.setCursor(30,3);
display.println("TVOC:");
display.setCursor(72,3);
display.println("eCO2:");
display.setCursor(3,34);
display.println("HP0:");
display.setCursor(34,34);
display.println("HP1:");
display.setCursor(60,34);
display.println("HP2:");
display.setCursor(88,34);
display.println("HP3:");
display.display();
delay(200);
}
void loop() {
if (ens160.available()) {
ens160.measure(true);
ens160.measureRaw(true);
Serial.print("AQI: ");Serial.print(ens160.getAQI());Serial.print("\t");
Serial.print("TVOC: ");Serial.print(ens160.getTVOC());Serial.print("ppb\t");
Serial.print("eCO2: ");Serial.print(ens160.geteCO2());Serial.print("ppm\t");
Serial.print("R HP0: ");Serial.print(ens160.getHP0());Serial.print("Ohm\t");
Serial.print("R HP1: ");Serial.print(ens160.getHP1());Serial.print("Ohm\t");
Serial.print("R HP2: ");Serial.print(ens160.getHP2());Serial.print("Ohm\t");
Serial.print("R HP3: ");Serial.print(ens160.getHP3());Serial.println("Ohm");
}
display.setTextSize(2); // Draw 2X-scale text
display.setCursor(10,17);
display.fillRect(10, 17, 110, 16, SSD1306_BLACK);
display.println(ens160.getAQI());
display.setCursor(30,17);
display.println(ens160.getTVOC());
display.setCursor(72,17);
display.println(ens160.geteCO2());
display.setTextSize(1); // Draw 1X-scale text
display.setCursor(8, 44);
display.fillRect(6, 44, 114, 19, SSD1306_BLACK);
display.println(ens160.getHP0());
display.setCursor(32, 52);
display.println(ens160.getHP1());
display.setCursor(60, 44);
display.println(ens160.getHP2());
display.setCursor(90, 52);
display.println(ens160.getHP3());
display.display();
delay(1000);
}
実行例です。