CircuitPython 10行プログラミング Step9 (7) CO2センサSCD30

 ここでは、マイコン・ボードESP32-S3-DevKitC-1-N8のI2Cバスを使います。CircuitPython は8.0.0-beta.5です。

CO2センサSCD30

 AdafruitのSDC30をI2Cで接続します。SCL信号はIO5、SDA信号はIO6の端子に接続しました。

ESP32-S3-DevKitC-1-N8ボード SCD-30ボードのSTEMMA QTコネクタ
+3V3 赤色
GND 黒色
IO6 (黄色)
IO5(SCL) 緑色

 ライブラリを利用したプログラムです。I2Cバスのスピードは50kHzにしてありました。


# SPDX-FileCopyrightText: 2020 by Bryan Siepert, written for Adafruit Industries
#
# SPDX-License-Identifier: Unlicense
import time
import board
import busio
import adafruit_scd30

# SCD-30 has tempremental I2C with clock stretching, datasheet recommends
# starting at 50KHz
i2c = busio.I2C(board.IO5,board.IO6, frequency=50000)
scd = adafruit_scd30.SCD30(i2c)

while True:
    # since the measurement interval is long (2+ seconds) we check for new data before reading
    # the values, to ensure current readings.
    if scd.data_available:
        print("Data Available!")
        print("CO2: %d PPM" % scd.CO2)
        print("Temperature: %0.2f degrees C" % scd.temperature)
        print("Humidity: %0.2f %% rH" % scd.relative_humidity)
        print("")
        print("Waiting for new data...")
        print("")

    time.sleep(0.5)

 実行例です。測定場所は机の上です。

レジスタを直接アクセス

 読み取ったデータは、CO2、温度、湿度で、合計18バイトとあります。2バイトずつにCRC-8が付いたデータが送られてきます。CRCを除くと一つのデータは4バイト構成で、IEEE754 単精度浮動小数点数の形式:binary32です。unpackで実数に戻します。


# SPDX-FileCopyrightText: 2020 by Bryan Siepert, written for Adafruit Industries
# SPDX-License-Identifier: Unlicense
import time
import board
import busio
import struct

# SCD-30 has tempremental I2C with clock stretching, datasheet recommends
# starting at 50KHz
i2c = busio.I2C(board.IO5, board.IO6, frequency=50_000)

scd30_addr = 0x61
while not i2c.try_lock():
    pass

#i2c.writeto(scd30_addr, bytearray([0xd3,0x04]))  # reset <-dont use
#time.sleep(2)
i2c.writeto(scd30_addr, bytearray([0x00,0x10,0x00,0x00,0x81]))  # coutinue
time.sleep(0.05)
i2c.writeto(scd30_addr, bytearray([0x46,0x00,0x00,0x02,0xe3]))  # interbal
time.sleep(0.05)
i2c.writeto(scd30_addr, bytearray([0x03,0x00]))  # read data
resultT = bytearray(18)
data = i2c.readfrom_into(scd30_addr, resultT)
print(resultT)  # bytearray(b'D\x89y$\tVA\xa6\xa6\x18\xf8\xe3BHU\x17p\xb9')

co2=struct.unpack('>f',resultT[0:2] + resultT[3:5])[0]
temp=struct.unpack('>f',resultT[6:8] + resultT[9:11])[0]
humi=struct.unpack('>f',resultT[12:14] + resultT[15:17])[0]

print(co2)
print(temp)
print(humi)

i2c.unlock()

 実行例です。測定値のbytearray()では、可読文字はASCIIに変更されているので、何バイト目かを目視では認識しにくいです。スライスを使うと、正しく切り出せました。