LoginSignup
1
0

More than 1 year has passed since last update.

StrawberryLinux CCS811 と ESP32 で CO2 を測る

Last updated at Posted at 2022-07-26

環境

コード

#include <Wire.h>
#define ADDRESS 0x5B

void setup()
{
    int data;
    Serial.begin(115200);
    delay(1000);
    Serial.println("CCS811 CO2 SENSOR");
    Wire.begin();
    Wire.beginTransmission(ADDRESS);
    Wire.write(0x20);       // HW_ID GET
    Wire.endTransmission();
    Wire.requestFrom(ADDRESS,1);
    data = Wire.read();
    Serial.println(data,HEX);   // may be 0x81(HW_ID)
    Wire.beginTransmission(ADDRESS);
    Wire.write(0x21);       // HW_Version GET
    Wire.endTransmission();
    Wire.requestFrom(ADDRESS,1);
    data = Wire.read();
    Serial.println(data,HEX);   // may be 0x12(HW_Version)
    Wire.beginTransmission(ADDRESS);
    Wire.write(0xF4);       // APP_START command
    Wire.endTransmission();
    Wire.beginTransmission(ADDRESS);
    Wire.write(0x01);       // 0x01 register(MEAS_MODE)
    delay(30);  // 重要 ?
    Wire.write(0x10);       // Constant power mode, IAQ measurement every second)
    delay(30);  // 重要 ?
    Wire.endTransmission();
    delay(30);  // 重要 ?
}
void loop()
{
    static int counter=0;
    Serial.print(counter++);
    readData();
    delay(1000);
}
void readData()
{
    uint8_t data[32];
    int i=0;
    Wire.beginTransmission(ADDRESS);
    Wire.write(0x02);
    Wire.endTransmission();
    Wire.requestFrom(ADDRESS,8);
    while(Wire.available()){
        data[i] = Wire.read();
        i++;
    }
    int co2=data[0]*256+data[1];
    Serial.print(" co2:");
    Serial.print(co2);
    int tvoc=data[2]*256+data[3];
    Serial.print(" TVOC:");
    Serial.print(tvoc);
    Serial.print(" STATUS:");
    Serial.print(data[4],BIN);
    Serial.print(" ERROR_ID:");
    Serial.print(data[5]);
    Serial.print(" RAW_DATA:");
    Serial.print(data[6],HEX);
    Serial.print(" ");
    Serial.print(data[7],HEX);
    Serial.print(" (");
    for ( i = 0 ; i < 8 ; i++){
        Serial.print(" ");
        Serial.print(data[i],HEX);
    }
    Serial.println(" )");
}

実行結果


CCS811 CO2 SENSOR
81
12
0 co2:0 TVOC:0 STATUS:0 ERROR_ID:0 RAW_DATA:0 0 ( 0 0 0 0 0 0 0 0)
1 co2:0 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 8F ( 0 0 0 0 98 0 25 8F)
2 co2:0 TVOC:0 STATUS:10010000 ERROR_ID:0 RAW_DATA:25 8C ( 0 0 0 0 90 0 25 8C)
3 co2:0 TVOC:0 STATUS:10010000 ERROR_ID:0 RAW_DATA:29 B6 ( 0 0 0 0 90 0 29 B6)
4 co2:400 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 8D ( 1 90 0 0 98 0 25 8D)
5 co2:400 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 91 ( 1 90 0 0 98 0 25 91)
6 co2:405 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 90 ( 1 95 0 0 98 0 25 90)
7 co2:446 TVOC:7 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 87 ( 1 BE 0 7 98 0 25 87)
8 co2:436 TVOC:5 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 89 ( 1 B4 0 5 98 0 25 89)
9 co2:433 TVOC:5 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 8A ( 1 B1 0 5 98 0 25 8A)
10 co2:425 TVOC:3 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 8B ( 1 A9 0 3 98 0 25 8B)

しばらくすると落ち着きます

102 co2:403 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 96 ( 1 93 0 0 98 0 25 96)
103 co2:400 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 97 ( 1 90 0 0 98 0 25 97)
104 co2:403 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 96 ( 1 93 0 0 98 0 25 96)
105 co2:400 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 97 ( 1 90 0 0 98 0 25 97)
106 co2:403 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 96 ( 1 93 0 0 98 0 25 96)
107 co2:408 TVOC:1 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 95 ( 1 98 0 1 98 0 25 95)
108 co2:408 TVOC:1 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 95 ( 1 98 0 1 98 0 25 95)
109 co2:403 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 96 ( 1 93 0 0 98 0 25 96)
110 co2:400 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 97 ( 1 90 0 0 98 0 25 97)
111 co2:400 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 97 ( 1 90 0 0 98 0 25 97)
112 co2:403 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 96 ( 1 93 0 0 98 0 25 96)
113 co2:403 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 96 ( 1 93 0 0 98 0 25 96)
114 co2:403 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 96 ( 1 93 0 0 98 0 25 96)
115 co2:408 TVOC:1 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 95 ( 1 98 0 1 98 0 25 95)
116 co2:408 TVOC:1 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 95 ( 1 98 0 1 98 0 25 95)

息を吹きかけると反応していることがわかります。


129 co2:400 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 97 ( 1 90 0 0 98 0 25 97)
130 co2:403 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 96 ( 1 93 0 0 98 0 25 96)
131 co2:415 TVOC:2 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 93 ( 1 9F 0 2 98 0 25 93)
132 co2:1882 TVOC:556 STATUS:10011000 ERROR_ID:0 RAW_DATA:24 ED ( 7 5A 2 2C 98 0 24 ED)
133 co2:1798 TVOC:446 STATUS:10011000 ERROR_ID:0 RAW_DATA:24 F8 ( 7 6 1 BE 98 0 24 F8)
134 co2:1515 TVOC:181 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 27 ( 5 EB 0 B5 98 0 25 27)
135 co2:915 TVOC:78 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 4F ( 3 93 0 4E 98 0 25 4F)
136 co2:905 TVOC:76 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 50 ( 3 89 0 4C 98 0 25 50)
137 co2:742 TVOC:52 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 60 ( 2 E6 0 34 98 0 25 60)
138 co2:659 TVOC:39 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 69 ( 2 93 0 27 98 0 25 69)
139 co2:600 TVOC:30 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 72 ( 2 58 0 1E 98 0 25 72)
140 co2:537 TVOC:20 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 7C ( 2 19 0 14 98 0 25 7C)
141 co2:526 TVOC:19 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 7E ( 2 E 0 13 98 0 25 7E)
142 co2:537 TVOC:20 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 7C ( 2 19 0 14 98 0 25 7C)
143 co2:537 TVOC:20 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 7C ( 2 19 0 14 98 0 25 7C)
144 co2:531 TVOC:19 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 7D ( 2 13 0 13 98 0 25 7D)
145 co2:526 TVOC:19 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 7E ( 2 E 0 13 98 0 25 7E)
146 co2:531 TVOC:19 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 7D ( 2 13 0 13 98 0 25 7D)
147 co2:543 TVOC:21 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 7B ( 2 1F 0 15 98 0 25 7B)
148 co2:531 TVOC:19 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 7D ( 2 13 0 13 98 0 25 7D)
149 co2:493 TVOC:14 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 83 ( 1 ED 0 E 98 0 25 83)

トラブルシュート

I2C 応答が FDばかりになる

しばらく動かすと、データが FD ばかり帰ってくるようになりました。


330 co2:482 TVOC:12 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 93 ( 1 E2 0 C 98 0 25 93)
331 co2:482 TVOC:12 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 93 ( 1 E2 0 C 98 0 25 93)
332 co2:482 TVOC:12 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 93 ( 1 E2 0 C 98 0 25 93)
333 co2:482 TVOC:12 STATUS:10011000 ERROR_ID:0 RAW_DATA:25 93 ( 1 E2 0 C 98 0 25 93)
334 co2:65021 TVOC:65021 STATUS:11111101 ERROR_ID:253 RAW_DATA:FD FD ( FD FD FD FD FD FD FD FD)
335 co2:20225 TVOC:0 STATUS:1010 ERROR_ID:0 RAW_DATA:0 0 ( 4F 1 0 0 A 0 0 0)
336 co2:20481 TVOC:0 STATUS:1010 ERROR_ID:0 RAW_DATA:0 0 ( 50 1 0 0 A 0 0 0)
337 co2:65021 TVOC:65021 STATUS:11111101 ERROR_ID:253 RAW_DATA:FD FD ( FD FD FD FD FD FD FD FD)
338 co2:20993 TVOC:0 STATUS:1010 ERROR_ID:0 RAW_DATA:0 0 ( 52 1 0 0 A 0 0 0)
339 co2:21249 TVOC:0 STATUS:1010 ERROR_ID:0 RAW_DATA:0 0 ( 53 1 0 0 A 0 0 0)
340 co2:21505 TVOC:0 STATUS:1010 ERROR_ID:0 RAW_DATA:0 0 ( 54 1 0 0 A 0 0 0)
341 co2:65021 TVOC:65021 STATUS:11111101 ERROR_ID:253 RAW_DATA:FD FD ( FD FD FD FD FD FD FD FD)
342 co2:65021 TVOC:65021 STATUS:11111101 ERROR_ID:253 RAW_DATA:FD FD ( FD FD FD FD FD FD FD FD)
343 co2:65021 TVOC:65021 STATUS:11111101 ERROR_ID:253 RAW_DATA:FD FD ( FD FD FD FD FD FD FD FD)
344 co2:65021 TVOC:65021 STATUS:11111101 ERROR_ID:253 RAW_DATA:FD FD ( FD FD FD FD FD FD FD FD)
345 co2:65021 TVOC:65021 STATUS:11111101 ERROR_ID:253 RAW_DATA:FD FD ( FD FD FD FD FD FD FD FD)
346 co2:65021 TVOC:65021 STATUS:11111101 ERROR_ID:253 RAW_DATA:FD FD ( FD FD FD FD FD FD FD FD)
347 co2:65021 TVOC:65021 STATUS:11111101 ERROR_ID:253 RAW_DATA:FD FD ( FD FD FD FD FD FD FD FD)
348 co2:65021 TVOC:65021 STATUS:11111101 ERROR_ID:253 RAW_DATA:FD FD ( FD FD FD FD FD FD FD FD)

これは、ソースコード中の delay(30) を当初入れていないときに起こりました。以下のように入れると解消しました。

    Wire.beginTransmission(ADDRESS);
    Wire.write(0x01);       // 0x01 register(MEAS_MODE)
    delay(30);  // 重要 ?
    Wire.write(0x10);       // Constant power mode, IAQ measurement every second)
    delay(30);  // 重要 ?
    Wire.endTransmission();
    delay(30);  // 重要 ?


また、一度このようになると、エラーリセットしないと正常動作に復帰しませんでした。エラーは以下でリセットされます

  • 電源投入時リセットを発行する
  • nRESET 信号をパルス駆動する
  • I2C で SW_RESET (メールボックスID 0xFF )にリセットシーケンスを書き込む
  • I2C で ERROR_ID (メールボックスID 0xE0 )を読む

CO2値にスパイクが発生する

時々、謎の値が出ています


191 co2:405 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:21 BC ( 1 95 0 0 98 0 21 BC)
192 co2:400 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:21 BD ( 1 90 0 0 98 0 21 BD)
193 co2:400 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:21 BD ( 1 90 0 0 98 0 21 BD)
194 co2:49664 TVOC:0 STATUS:1010 ERROR_ID:0 RAW_DATA:0 0 ( C2 0 0 0 A 0 0 0)
195 co2:413 TVOC:1 STATUS:10011000 ERROR_ID:0 RAW_DATA:21 BA ( 1 9D 0 1 98 0 21 BA)
196 co2:405 TVOC:0 STATUS:10011000 ERROR_ID:0 RAW_DATA:21 BC ( 1 95 0 0 98 0 21 BC)
197 co2:415 TVOC:2 STATUS:10011000 ERROR_ID:0 RAW_DATA:21 B9 ( 1 9F 0 2 98 0 21 B9)
198 co2:415 TVOC:2 STATUS:10011000 ERROR_ID:0 RAW_DATA:21 B9 ( 1 9F 0 2 98 0 21 B9)
384 co2:427 TVOC:4 STATUS:10011000 ERROR_ID:0 RAW_DATA:21 B5 ( 1 AB 0 4 98 0 21 B5)
385 co2:424 TVOC:3 STATUS:10011000 ERROR_ID:0 RAW_DATA:21 B6 ( 1 A8 0 3 98 0 21 B6)
386 co2:33281 TVOC:0 STATUS:1010 ERROR_ID:0 RAW_DATA:0 0 ( 82 1 0 0 A 0 0 0)
387 co2:432 TVOC:4 STATUS:10011000 ERROR_ID:0 RAW_DATA:21 B4 ( 1 B0 0 4 98 0 21 B4)

CO2にスパイクが発生、TVOCは0で STATUS が 0b00001010 であることは共通しているようです。

STATUS についてデータシートを見るとこの状況では FW_MODEが boot mode となっていることがわかります。
以下に、データシートの内容を転記しました。

bit 名前 0の場合 1の場合
7 FW_MODE Firmware is in boot mode, this allows new firmware to be loaded Firmware is in application mode. CCS811 is ready to take ADC measrements
6 (Reserved)
5 (Reserved)
4 APP_VALID No application firmware loaded Valid application firmware loaded
3 DATA_READY No new data samples are ready A new data sample is ready in ALG_RESULT_DATA,this bit is cleared when ALG_RESULT_DATA is read on the I2C interface
2 (Reserved)
1 (Reserved)
0 ERROR No error has occured There is an error on the I2C or sensor, the ERROR_ID register (0xE0) contains the error source

なので、STATUSを見てbit7が0のときのデータを使わないようにするのが良さそうです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0