M5StackでCO2換気システム

CO2-triggered ventilation ・ CO2通风

CO2濃度が高いときに自動で換気ファンを回して空気を入れ替える。

この構成をエディタで開く・編集する →

部品リスト(BOM)

部品役割ポートリンク・価格
M5Stack Core2Controllergrove_i2c, grove_analog, grove_uart, mbusofficial page — $46.9
Unit PaHub2I2C hub (1→6)grove_i2cofficial page — $7.95
Unit CO2CO2 sensorgrove_i2cofficial page — $33.9
Unit 2Relay (2-Channel Relay Unit)2-channel relay (for fan)grove_i2cofficial page — $6.5
Unit FanFan unitgroveofficial page — $4.95

配線

作り方

M5Stack Core2とCO2ユニット、リレーユニット、ファンユニットを使って、CO2濃度が高くなったら自動で換気ファンを回す装置です。PaHub2でI2Cを分岐して複数のユニットを接続します。

  1. 部品を用意する — 用意するもの:M5Stack Core2本体、Unit PaHub2、Unit CO2、Unit 2Relay、Unit Fan、Groveケーブル4本(I2C用3本、アナログ用1本)、Core2とパソコンをつなぐUSB-Cケーブル。
  2. PaHub2をCore2に接続する — Groveケーブル(I2C用)で、PaHub2の入力ポート(IN)とCore2の赤いPort.A(I2Cポート)をつなぎます。コネクタは一方向にしか入らないので、向きを確認して差し込んでください。
  3. CO2ユニットとリレーユニットをPaHub2に接続する — 2本のGroveケーブル(I2C用)を使って、CO2ユニットをPaHub2のチャンネル0(CH0)に、リレーユニットをチャンネル1(CH1)に接続します。どちらのチャンネルでも動作しますが、コードのチャンネル番号と合わせてください。
  4. リレーユニットとファンユニットを接続する — Groveケーブル(アナログ用)で、リレーユニットのRelay1(リレー1)出力ポートとファンユニットの入力ポートをつなぎます。リレーユニットのRelay1はデフォルトでGPIO2で制御されます。
  5. パソコンにつないでMicroPythonを書き込む — USB-CケーブルでCore2をパソコンにつなぎます。UIFlowやThonnyなどのツールで、Core2にMicroPythonファームウェアが入っていることを確認し、下のコードをデバイスにコピーして実行します。
  6. 動作をテストする — コードを実行すると、CO2濃度がしきい値(デフォルト800ppm)を超えたときにファンが回り始めます。CO2濃度が下がるとファンが止まります。しきい値はコード内のCO2_THRESHOLDで調整できます。

サンプルコード(micropython)

# M5Stack Core2 + PaHub2 + CO2 + Relay + Fan
# Wiring:
#   Core2 Port.A (red) -> PaHub2 IN
#   PaHub2 CH0 -> CO2 Unit
#   PaHub2 CH1 -> 2Relay Unit
#   2Relay Unit Relay1 OUT -> Fan Unit IN
import time
from machine import Pin, I2C
from m5stack import lcd

# I2C bus on Core2 Port.A
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=100000)

# TCA9548A (PaHub2) I2C address
HUB_ADDR = 0x70

# SCD40 (CO2) I2C address
CO2_ADDR = 0x62

# Relay unit (2Relay) I2C address (default 0x27)
RELAY_ADDR = 0x27

# CO2 threshold in ppm
CO2_THRESHOLD = 800

def select_channel(channel):
    """Select a channel on the PaHub2 (TCA9548A)."""
    i2c.writeto(HUB_ADDR, bytes([1 << channel]))

def read_co2():
    """Read CO2 concentration from SCD40."""
    select_channel(0)  # CO2 on channel 0
    # Start measurement (0x21B1)
    i2c.writeto(CO2_ADDR, bytes([0x21, 0xB1]))
    time.sleep(0.5)  # wait for measurement
    # Read 3 bytes (CO2 high, CO2 low, CRC)
    data = i2c.readfrom(CO2_ADDR, 3)
    co2 = (data[0] << 8) | data[1]
    return co2

def relay_on():
    """Turn on Relay1 (channel 1)."""
    select_channel(1)  # Relay on channel 1
    # Relay1 control register: 0x01, value 0x01 = on
    i2c.writeto(RELAY_ADDR, bytes([0x01, 0x01]))

def relay_off():
    """Turn off Relay1."""
    select_channel(1)
    i2c.writeto(RELAY_ADDR, bytes([0x01, 0x00]))

# Main loop
while True:
    co2 = read_co2()
    lcd.clear()
    lcd.print('CO2: %d ppm' % co2, 10, 20)
    if co2 > CO2_THRESHOLD:
        lcd.print('Fan ON', 10, 60)
        relay_on()
    else:
        lcd.print('Fan OFF', 10, 60)
        relay_off()
    time.sleep(2)

コツ・安全上の注意

この作り方はAIが構成から生成したものです(未検証)。通電前に配線とコードをご確認ください。

この構成はAIが実在するM5Stack部品から設計し、ポート互換をサーバで検証したものです。編集・共有できます。

エディタで開く →

UnitKit は M5Stack® 製品向けの非公式ツール。作りたいものを書くと、部品リストと配線図が出ます。