この記事では、Raspberry Pi Pico Wとセンサーを接続して、温度・湿度・気圧を取得する方法を紹介します。
センサーには、秋月電子のAE-BME680を使用します。
必要なもの
こちらの記事で紹介する方法では、ジャンパワイヤは必要ありません。
そのため、必要なものは次の3つのみです。
画像で使っている物品は、秋月電子にて購入しました。実際に使用しているパーツにリンクを貼っています。
AE-BME680にはんだ付け
最初にAE-BME860にはんだ付けを行います。
はんだ付けするのは、ピンヘッダとJ1の2箇所です。
J1にはんだ付けをすることでSDAとSCLがプルアップされ、Raspberry Pi Pico Wとの接続にプルアップ抵抗を追加しなくて良くなります。
J2にはんだ付けをするとI2Cのアドレスが0x77から0x76 に変わります。今回は、0x77のまま利用するので、J2はそのままにしています。
完成系は画像のようになります。
ピンの接続方法
AE-BME680とRaspbeery Pi Pico Wを接続します。
使用する物理ピンは、3番から6番の4つです。
対応は下記の通りです。Pico W側は、MicroPythonのコードで設定を行います。
Raspberry Pi Pico W | AE-BME680 |
3番ピン, GND | GND |
4番ピン, GP2(I2C1 SDA) | SDA |
5番ピン, GP3(I2C1 SCL) | SCL |
6番ピン, GP4(Vout) | VIN |
完成系は画像のようになります。
BME680用のFirmwareの導入
BME680のデータをPico Wで使用するためにBME680のドライバが入ったFirmwareを導入します。
Pimoroni社がPico Wで使用できるBME680用のドライバを作成して公開してくれています。
FIrmwareをインストールする点は、通常のRaspberry PiとPicoとの違いです。
GithubのリリースページからPico W用のファームウェアをダウンロードし、通常のMicroPythonのファームウェアと同様の方法でファームウェアをインストールします。
Pico W用のファームウェアは、 picow-vx.x.x-pimoroni-micropython.uf2 という名前です。
こちらの方法は、BME680用ドライバーのIssueを参考にしています。
MicroPythonコード
最後にMicroPythonのコードを書き、Pico Wに転送します。
下記では、使い回しがしやすいように、BME680をClass化しています。
モジュール breakout_bme68xとpimoroni_i2c がPimoroniのドライバを入れることで利用可能になりました。通常のMicroPythonではエラーになります。
bme680.py
from breakout_bme68x import STATUS_HEATER_STABLE, BreakoutBME68X # type: ignore
from machine import Pin # type: ignore
from pimoroni_i2c import PimoroniI2C # type: ignore
class BME680:
def __init__(
self, pin_v: int, pin_sda: int, pin_scl: int, i2c_id: int, addr: int = 0x77
):
p_out = Pin(pin_v, Pin.OUT)
p_out.on()
i2c = PimoroniI2C(sda=pin_sda, scl=pin_scl)
self.bme = BreakoutBME68X(i2c, addr)
def read_sensor(self):
temperature, pressure, humidity, gas, status, _, _ = self.bme.read()
heater = "Stable" if status & STATUS_HEATER_STABLE else "Unstable"
return temperature, pressure, humidity, gas, heater
main.py
main.pyでは、BME680 Classをインスタンス化して使用しています。
pin_v, pin_sda, pin_sclにはそれぞれピン番号を指定します。
ここで指定するピン番号は、物理ピンの番号ではなくGPIOピンの番号であることに注意してください。
その他のコードのポイントは、次の2点です。
- 最初に10秒のスリープをしている: Firmwareが起動するまで待つために10秒間スリープしています。これがないと外部電源で起動した時にうまく動作しないことがあります。
- whileループの中でgc.collect()を行なっている: Pico Wはメモリが少ないので、ループの度にGC(Garbage Collection)を行っています。このコードがないと動作途中からメモリエラーになります。
import gc
import time
from machine import Pin # type: ignore
from bme680 import BME680
time.sleep(10)
INTERVAL = 60
LOG_FILE = "./log.txt"
LED = Pin("LED", Pin.OUT)
def main()
bme680 = BME680(pin_v=4, pin_sda=2, pin_scl=3, i2c_id=1)
while True:
try:
temperature, pressure, humidity, gas, heater = bme680.read_sensor()
print(
f"{temperature:0.2f}C, {pressure:0.2f}Pa, {humidity:0.2f}%, {gas:0.2f} Ohms, Heater: {heater}"
)
except Exception as e:
print(f"Error: {e}")
finally:
gc.collect()
time.sleep(INTERVAL)
while True:
try:
main()
except Exception as e:
LED.on()
print(f"Error: {e}")
with open(LOG_FILE, "a") as f:
print(f"{time.time()} Error: {e}", file=f)
time.sleep(10)
LED.off()
このコードを実行すると、次のような出力が得られます。
しばらくはUnstableとなるため、この間の値は捨てるといった対応をすることで測定誤差を軽減できます。
27.28C, 101510.24Pa, 60.99%, 996282.56 Ohms, Heater: Unstable
27.74C, 101505.84Pa, 59.25%, 9284.30 Ohms, Heater: Stable
27.89C, 101510.86Pa, 58.71%, 9807.21 Ohms, Heater: Stable
27.86C, 101512.15Pa, 58.01%, 12367.10 Ohms, Heater: Stable
また、初期化時に下記のエラーが出ることがあります。エラーを防ぐことは難しいので、このエラーが発生しても良いようにループ内でtry-exceptを使用して、プログラムが止まらないようにケアすることを推奨します。
Error: BreakoutBME68X: breakout not found when initialising
まとめ
本記事では、AE-BME680を使用して、温度・湿度・気圧の3つの値をRaspberry Pi Pico Wで取得する方法を紹介しました。
利用にあたって、BME680用のドライバをインストールするなど、多少トリッキーなことはありますが、動き出すと安定して動作しています。是非トライしてみてください。