Seeeduino XIAO と SGP30 でeCO2濃度測定器を作ってみた

小型マイコンボード**Seeeduino XIAO** と Sensirion エアクオリティセンサ**SGP30-2.5K**を使ってeCO2濃度測定器を作ってみました。

機器構成

| 名称 | 型名 | メーカー | データシート等 |
|:----|:----|:----|:----|
| マイコン | Seeeduino XIAO | Seeed |[Seeedウィキ](https://wiki.seeedstudio.com/jp/Seeeduino-XIAO/)
| センサー | SGP30-2.5K | Sensirion | [データシート](https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/9_Gas_Sensors/Datasheets/Sensirion_Gas_Sensors_SGP30_Datasheet.pdf)
| LEDアレイ | OSX10201-GYR1 | オプトサプライ | [データシート](https://akizukidenshi.com/download/ds/optosupply/OSX10201-XXXX%20_VER_A5.1_20190304.pdf)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99249/874eeab2-72a8-7fa8-48e1-4e88f26eea3b.png)

回路図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99249/66a4b527-32fb-b942-3ae5-a81668aed766.png)

プログラム
SparkFunのSPG30ライブラリを使っていますので
こちらから[ダウンロード](https://github.com/sparkfun/SparkFun_SGP30_Arduino_Library)してにライブラリに追加して下さい。

LEDとeCO2濃度の関係は次のようになっています。

| LED | 色 | CO2濃度範囲(単位 ppm) |
|:----|:----|:----|
|LED0|緑| 400 ～ 499|
|LED1|緑|500 ～ 599|
|LED2|緑|600 ～ 699|
|LED3|緑|700 ～ 799| 
|LED4|緑|800 ～ 999| 
|LED5|黃|1000 ～ 1149| 
|LED6|黃|1150 ～ 1299| 
|LED7|黃|1300 ～ 1499| 
|LED8|赤|1500 ～ 1999| 
|LED9|赤|2000 以上|
※LED0は電源モニターも兼ねています。


```
/*
  Library for the Sensirion SGP30 Indoor Air Quality Sensor
  By: Ciara Jekel
  SparkFun Electronics
  Date: June 28th, 2018
  License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).

  SGP30 Datasheet: https://cdn.sparkfun.com/assets/c/0/a/2/e/Sensirion_Gas_Sensors_SGP30_Datasheet.pdf

  Feel like supporting our work? Buy a board from SparkFun!
  https://www.sparkfun.com/products/14813

  This example reads the sensors calculated CO2 and TVOC values
*/

#include "SparkFun_SGP30_Arduino_Library.h" // Click here to get the library: https://github.com/sparkfun/SparkFun_SGP30_Arduino_Library
#include <Wire.h>
#define LED1 0
#define LED2 1
#define LED3 2
#define LED4 3
#define LED5 6
#define LED6 7
#define LED7 8
#define LED8 9
#define LED9 10

SGP30 mySensor; //create an object of the SGP30 class

void led_all_on(void);
void led_all_off(void);

void led_all_on(){
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);
  digitalWrite(LED4, LOW);
  digitalWrite(LED5, LOW);
  digitalWrite(LED6, LOW);
  digitalWrite(LED7, LOW);
  digitalWrite(LED8, LOW);
  digitalWrite(LED9, LOW);
}
void led_all_off(){
  digitalWrite(LED1, HIGH);
  digitalWrite(LED2, HIGH);
  digitalWrite(LED3, HIGH);
  digitalWrite(LED4, HIGH);
  digitalWrite(LED5, HIGH);
  digitalWrite(LED6, HIGH);
  digitalWrite(LED7, HIGH);
  digitalWrite(LED8, HIGH);
  digitalWrite(LED9, HIGH);
}


void display_co2(uint16_t value){
  led_all_off();
  if(value < 500){
    // nothing
  } else if(value < 600){
    digitalWrite(LED1, LOW);
  } else if(value < 700){
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
  } else if(value < 800){
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
  } else if(value < 1000){
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, HIGH);
  } else if(value < 1150){
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, LOW);
    digitalWrite(LED5, LOW);
  } else if(value < 1300){
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, LOW);
    digitalWrite(LED5, LOW);
    digitalWrite(LED6, LOW);
  } else if(value < 1500){
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, LOW);
    digitalWrite(LED5, LOW);
    digitalWrite(LED6, LOW);
    digitalWrite(LED7, LOW);
  } else if(value < 2000){
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, LOW);
    digitalWrite(LED5, LOW);
    digitalWrite(LED6, LOW);
    digitalWrite(LED7, LOW);
    digitalWrite(LED8, LOW);
  } else {
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, LOW);
    digitalWrite(LED5, LOW);
    digitalWrite(LED6, LOW);
    digitalWrite(LED7, LOW);
    digitalWrite(LED8, LOW);
    digitalWrite(LED9, LOW);
  }
}

void setup() {
  Serial.begin(115200);
  
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED5, OUTPUT);
  pinMode(LED6, OUTPUT);
  pinMode(LED7, OUTPUT);
  pinMode(LED8, OUTPUT);
  pinMode(LED9, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);

  led_all_off();
  
  Wire.begin();
  //Initialize sensor

  if (mySensor.begin() == false) {
    for(int i=0; i<10 ; i++){
      led_all_on();
      delay(200);
      led_all_off();
      delay(200);
    }
    while (1);
  }
  for(int i=0; i<3 ; i++){            // 電源投入時にすべてのLEDを3回ブリンク
    led_all_on();
    delay(200);
    led_all_off();
    delay(200);
  }

  //Initializes sensor for air quality readings
  //measureAirQuality should be called in one second increments after a call to initAirQuality
  mySensor.initAirQuality();
}

void loop() {
  //First fifteen readings will be
  //CO2: 400 ppm  TVOC: 0 ppb
  delay(800); //Wait 2 second
  //measure CO2 and TVOC levels
  mySensor.measureAirQuality();
  display_co2(mySensor.CO2);
  Serial.print("CO2: ");
  Serial.println(mySensor.CO2);
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(200);                        // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
}
```
-------
同じ基板で表示用にOLEDを使ったバージョンも作りましたので近日中に投稿します。
[OLED版はこちら](https://qiita.com/kaz19610303/items/76d7540b5349573d83ae)