スポンサーリンク

関東甲信が梅雨入り。BME280温湿度・気圧センサーで遊ぶ

関東甲信が梅雨入りしたらしい。なので(?)買い置きしていた温湿度・気圧センサーで遊ぶことにした。以前、デジタル時計を作ったときに温度と湿度が測れるDHT11(秋月で¥480)を試したことがあったけれど、測定できないことがあって不安定だった。今回は、気圧も測れるBME280(同¥1,380)を使うことにした。お値段は3倍くらいするのだけれど、結果、気圧も測れて、欠測なく非常に安定しているので、BME280にして正解だったと思う。

ラズパイPico Wを使う(写真は2Wだけどオーバースペック)。まずは配線。こんなかんじにした。BME280にはピンは6本あるが、使うのは4本。Picoとは、赤が電源、黒がGND、黄色がSCK、青がSDIにつながってる。ブレッドボードに見える9がGP6,10がGP7。

取得したデータはグラフにして可視化したい。自宅のサーバーにFlaskをAPIサーバーとして立てるという手もあるけれど、安定稼働に自信がないので、IoTデータの可視化サービスである「Ambient」を使うことにした。ただし、データの保存期間は4ヶ月とのこと。課金すれば1年保存できるけど、月2万円は痛い。無料コースで行く。アカウントを取得し、チャネルIDとライトキーを控えておく。

IoTデーター可視化サービス Ambient

次、ソフトウェア側。PicoはThonyで組むのが便利。メインのプログラム(main.py)とドライバ(bme280.py)が必要。BME280のドライバは、下記から拾ってくる。bme280.pyとしてコピペしてpicoに保存しておく。ソースを展開したくないので、先頭のhははずしておいた。

ttps://gist.github.com/futureshocked/287606dd7556a82c90f86473a6cf2ed0

下記、MicroPythonのスクリプト。Geminiさんが秒で書いてくれた(Chat GPTさんは障害中)。絵文字とかエラートラップとか、私だったらここまで書かない。WiFiの接続先は複数選べるようにした。場所が変わっても対応できる。書き換えるにあたって注意する点、Wi-Fiの接続先はg(2.4GHz)を選ぶこと。Picoはaの5GHz帯に対応していない。

# Ambient情報とある部分、チャンネルIDとライトキーを書き込む。I2Cのアドレスが違う場合があるので、次の行(22行目)のaddress=0x76address=0x77に変更する必要があるかも。

sensor = BME280(i2c=i2c, address=0x76)

main.py本体

import network
import time
import urequests
from machine import Pin, I2C
from bme280 import BME280 

# --- ▼▼▼ ここから設定 ▼▼▼ ---

# Wi-Fi情報
WIFI_LIST = [
    {"ssid": "YourSSID1", "password": "YourPassword1"},
    {"ssid": "YourSSID2", "password": "YourPassword2"},
]

# Ambient情報
AMBIENT_CHANNEL_ID = "YOUR_CHANNEL_ID" # ★★★ あなたのチャネルIDに書き換えてください ★★★
AMBIENT_WRITE_KEY = "YOUR_WRITE_KEY" # ★★★ あなたのライトキーに書き換えてください ★★★

i2c = I2C(1, scl=Pin(7), sda=Pin(6))

AMBIENT_URL = f"https://ambidata.io/api/v2/channels/{AMBIENT_CHANNEL_ID}/data"
sensor = BME280(i2c=i2c, address=0x76)

def connect_wifi():
    """Wi-Fiに接続する"""
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)

    for net in WIFI_LIST:
        print(f"接続中: {net['ssid']}...")
        wlan.connect(net["ssid"], net["password"])
        for _ in range(20):
            if wlan.isconnected():
                print("✅ Wi-Fi接続成功")
                print(wlan.ifconfig())
                return True
            time.sleep(0.5)
    print(f"❌ {net['ssid']}への接続失敗")
return False

def send_to_ambient(temp, hum, press):
    """取得したデータをAmbientに送信する"""
    headers = {"Content-Type": "application/json"}
    data = {
        "writeKey": AMBIENT_WRITE_KEY,
        "d1": f"{temp:.2f}",
        "d2": f"{hum:.2f}",
        "d3": f"{press / 100:.2f}" # PaからhPaに換算
    }

try:
    res = urequests.post(AMBIENT_URL, json=data, headers=headers)
    print(f"📡 Ambient送信: {res.status_code}")
    res.close()
except Exception as e:
    print("❌ 送信エラー:", e)

def main():
    """メイン処理"""
    if not connect_wifi():
        raise RuntimeError("Wi-Fi接続に失敗しました。")

while True:
    try:
        # センサーデータの読み取り
        temp, press, hum = sensor.read_compensated_data()
        print(f"🌡️ 温度: {temp:.2f} ℃, 💧 湿度: {hum:.2f} %, 🌀 気圧: {press / 100:.2f} hPa")

        # Ambientへ送信
        send_to_ambient(temp, hum, press)

        # 5分待機
        time.sleep(300)

        except Exception as e:
            print(f"エラー発生: {e}")
            time.sleep(60) # エラー発生時は60秒待機してリトライ

# 処理の開始
main()

スクリプトを走らせる。動いた! センサーデータの取得はできているようだ。200番が返ってきているので、Ambientにデータが正常に送られているみたいだ。

gにつなぐこと

Ambientを確認する。グラフ化されている。グラフはメーターとか棒もAmbientの設定画面から選べる。

Screenshot

百葉箱的に外に置くことも考えたけれど、ベランダに電源がないので、とりあえず部屋のデータを記録することにする。遠征先に持っていって、超ピンポイントな気象データが5分おきに確認できる仕組みとしても使える。結露アラートをLINEに送るようにもできると思うが、そこまでしなくていいか。きょうはここまで。いずれケーシングをプリントして百葉箱にするかもしれない。

Solar Radiation Shield by Batu | Download free STL model | Printables.com
Simple and compact Stevenson screen for small meteorological sensors. | Download free 3D printable STL models

この記事へのコメント

タイトルとURLをコピーしました