環境
- Arduino 1.8.16 for Linux
- esp32 by Espressif System Version 2.0.1
- WEMOS LOLIN32
- StrawberryLinux エアークオリティセンサモジュール CCS811
https://strawberry-linux.com/catalog/items?code=11811
コード
#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のときのデータを使わないようにするのが良さそうです。