Armoris日記 ラズパイと BME280 で温度・湿度・気圧を測って グラフ化して表示する編 [その 1]

このブログは、N 高等学校と VRChat の世界からやってきた株式会社 Armoris アルバイトの Shadero が書いています。
あるもりすぶろぐの内容は個人の意見です。

こんなことがやりたい!

  1. 温度・湿度・気圧を計測する
  2. 計測した値を DB に保存する
  3. グラフ化して表示する

ブログでは、作業プロセスを段階的に記載します。
[その 1] では温度・湿度・気圧を計測しログに出力するところまでを行います。

完成写真

本記事に書かれている事を行うとこういったものが出来上がります。
(しばらく動かして問題なさそうだったら基板をユニバーサル基板に変えたい…)
f:id:Armoris:20210218185035j:plain

環境

Type Name
Machine Raspberry Pi 3 Model B+
OS Raspbian 10 buster
Temperature, humidity & pressure sensor BME280

ラズパイはセットアップ済みの状態で進めます。

また BME280 は秋月電子で販売されているモジュールキットを使用しました。
同じセンサーを使用していてもモジュールキットの違いによって、微妙に仕様や各種ピン表記などが異なる場合があるため、他のモジュールキットを使用しラズパイと接続する際は、念の為取扱説明書を参照することをオススメします。

使用ソフトウェア

Name Version
Golang 1.15.7

ラズパイで IoT っぽいことをする記事を探すと Python を採用した文献が多くヒットしたため Python も検討したのですが、どうしても動的型付け言語を触りたくなかったので今回開発言語には Golang を選びました。

また、Golang のビルド環境はセットアップ済みの状態で進めます。
あくまでラズパイ側にビルドされた実行ファイルが存在していれば良いので、別 PC に Golang を導入し、そこでビルドした実行ファイルをラズパイに移す方式でも構いません。

制作手順

I2C 接続を有効にする

ラズパイと BME280 間の通信は I2C を使用するのですが、ラズパイのデフォルト設定で I2C 通信が無効になっているためraspi-configを開き有効にします。

  1. $ sudo raspi-config
  2. Interface Optionsと書かれた項目を選択
    f:id:Armoris:20210217161947p:plain
  3. I2Cと書かれた項目を選択
    f:id:Armoris:20210217162041p:plain
  4. I2C を有効にするためYesを選択
    f:id:Armoris:20210217162104p:plain

ラズパイと BME280 を接続する

本記事で使用している BME280 のモジュールキットの取扱説明書を参照し、J3 をジャンパ接続します。
(はんだ付けが下手すぎて若干基板を焦がしてしまった…。)
f:id:Armoris:20210218185506j:plain

次に、各ピンを以下のピンに接続します。

BME280 Raspberry Pi 3 Model B+
VDD 3V3 P01
GND Ground P09
CSB (接続しない)
SDI GPIO2(SDA) P03
SDO Ground P09
SCK GPIO3(SCL) P05

接続を行ったら、i2cdetectを使用し確認します。

  1. $ sudo i2cdetect -y 1
    f:id:Armoris:20210217162156p:plain

上記の画像のようになっていたら成功です。
これは I2C 通信で使用されているアドレスを表示していて、今回は 76 に BME280 が割り当てられています。

BME280 のセンサーからの値をログに出力するソフトを作り実行する

綺麗と言えるコードではありませんがお許しください…。

  1. $ vi iot-sensor-logger.go
package main

import (
    "fmt"
    "time"

    "github.com/quhar/bme280"
    "golang.org/x/exp/io/i2c"
)

func initBme280() (*bme280.BME280, error) {
    d, err := i2c.Open(&i2c.Devfs{Dev: "/dev/i2c-1"}, 0x76) // 0x76は今回使用するBME280のI2Cアドレス
    if err != nil {
        return nil, err
    }

    b := bme280.New(d)
    err = b.Init()
    return b, err
}

func outputSensorValues(b *bme280.BME280) (err error) {
    t, p, h, err := b.EnvData()
    if err != nil {
        return
    }

    fmt.Printf("Temp: %.2fC, Hum: %.2f%%, Press: %.2fhpa\n", t, h, p)
    return
}

func main() {
    const outputIntervalSec = 5

    b, err := initBme280()
    if err != nil {
        panic(err)
    }
    ticker := time.NewTicker(outputIntervalSec * time.Second)
    defer ticker.Stop()
    for {
        select {
        case <-ticker.C:
            err = outputSensorValues(b)
            if err != nil {
                panic(err)
            }
        }
    }
}
  1. $ GOOS=linux && GOARCH=arm && GOARM=6
  2. $ go build ./iot-sensor-logger.go
  3. $ chmod 744 ./iot-sensor-logger
  4. $ ./iot-sensor-logger

$ GOOS=linux && GOARCH=arm && GOARM=6の箇所はビルドする際に、どのマシン向けにビルドするかを指定しています。
今回はラズパイ向けにビルドしたいので上記のように書いています。
これについて詳しく知りたい方は「Golangロスコンパイル」などで調べると良いかもしれません。

完成!

上記のコードをビルドし、ラズパイ上で実行すると 5 秒ごとに BME280 が計測した温度と湿度と気圧がログに出力されます…!
f:id:Armoris:20210218185540p:plain

感想

センサー部分を(ほんとはあまり良くない気がしますが)指で温めてあげると出力される温度の値が上昇するのでとてもたのしい…()

次回はグラフ化する前準備として、計測した値を DB に保存するところまでを行う予定です…!