はじめに
Raspberry pi にて、
温度、湿度、気圧を測定できる環境を構築することを目的とする。
BME280の基本部分のみを使用する。
追記:2022/10/10
Appソースの一部を修正
使用機材
raspi : raspberry pi 4 (4GB)
sensor : bme280 (GYBMEP)
$ cat /etc/debian_version
> 10.13
$ go version
> go version go1.11.6 linux/arm
i2c 準備
i2c 系ライブラリのインストール
sudo apt install i2c-tools
raspberry pi 側の i2c の Enabe
sudo raspi-config
3 Interface Option
P5 I2C
Yes
OK
Finish
の順
再起動(不要かも)
sudo reboot
i2c 確認
sudo i2cdetect -l
>i2c-1 i2c bcm2835 (i2c@7e804000) I2C adapter
センサの接続
raspberry pi を正面に見て左上6ピンを図のように接続する
センサ取り付け後の確認
sudo i2cdetect -y 1
Chip ID 読み
sudo i2cget -y 1 0x76 0xD0
> 0x60
BME280は0xD0アドレスに0x60のChipIDが記載されている
(ので上記のコマンドは成功している)
Golang app
main.go
package main
import (
"os/exec"
"time"
"strconv"
"fmt"
)
func sread(adr string) int8 {
res, _ :=exec.Command("i2cget", "-y", "1", "0x76", adr).Output()
val, _ := strconv.ParseInt(string(res)[:4], 0, 16)
// fmt.Printf("Adr%s:0x%02x\n", adr, val)
return int8(val)
}
func uread(adr string) uint8 {
return uint8(sread(adr))
}
func write(adr, val string) {
exec.Command("i2cset", "-y", "1", "0x76", adr, val).Run()
}
func main() {
//Check Chip ID
if (uread("0xD0") != 0x60) {
fmt.Printf("Chip ID Error\n")
return
}
//Reset
write("0xE0", "0xB6")
uread("0xF4")
//ForceMode (once)
write("0xF2", "0x01")
write("0xF4", "0x25")
uread("0xF4")
time.Sleep(time.Millisecond)
uread("0xF4")
t_fine, tmp := getTemp()
fmt.Printf("TEMP : %7.2f [Deg]\n", float32(tmp) /100.0)
hum := getHum(t_fine)
fmt.Printf("HUM : %7.2f [%%RH]\n", float32(hum) /1024.0)
press := getPress(t_fine)
fmt.Printf("PRESS : %7.2f [hPa]\n", float32(press) /25600.0)
}
func getPress(t_fine int) int {
//GetData
press_msb := uread("0xF7")
press_lsb := uread("0xF8")
press := int64(press_msb) << 12 | int64(press_lsb) << 4
//digP1
dig_p1_msb := uread("0x8F")
dig_p1_lsb := uread("0x8E")
dig_p1 := int64(dig_p1_msb) << 8 | int64(dig_p1_lsb)
//digP2
dig_p2_msb := sread("0x91")
dig_p2_lsb := uread("0x90")
dig_p2 := int64(dig_p2_msb) << 8 | int64(dig_p2_lsb)
//digP3
dig_p3_msb := sread("0x93")
dig_p3_lsb := uread("0x92")
dig_p3 := int64(dig_p3_msb) << 8 | int64(dig_p3_lsb)
//digP4
dig_p4_msb := sread("0x95")
dig_p4_lsb := uread("0x94")
dig_p4 := int64(dig_p4_msb) << 8 | int64(dig_p4_lsb)
//digP5
dig_p5_msb := sread("0x97")
dig_p5_lsb := uread("0x96")
dig_p5 := int64(dig_p5_msb) << 8 | int64(dig_p5_lsb)
//digP6
dig_p6_msb := sread("0x99")
dig_p6_lsb := uread("0x98")
dig_p6 := int64(dig_p6_msb) << 8 | int64(dig_p6_lsb)
//digP7
dig_p7_msb := sread("0x9B")
dig_p7_lsb := uread("0x9A")
dig_p7 := int64(dig_p7_msb) << 8 | int64(dig_p7_lsb)
//digP8
dig_p8_msb := sread("0x9D")
dig_p8_lsb := uread("0x9C")
dig_p8 := int64(dig_p8_msb) << 8 | int64(dig_p8_lsb)
//digP9
dig_p9_msb := sread("0x9F")
dig_p9_lsb := uread("0x9E")
dig_p9 := int64(dig_p9_msb) << 8 | int64(dig_p9_lsb)
var1 := int64(t_fine) - int64(128000)
var2 := var1 * var1 * dig_p6
var2 = var2 + ((var1 * dig_p5) << 17)
var2 = var2 + (dig_p4<<35)
var1 = ((var1 * var1 * dig_p3) >>8) + ((var1 * dig_p2) <<12)
var1 = (((int64(1)<<47) + var1)) * dig_p1 >> 33;
if (var1 == 0) {
return 0;
}
p := int64(1048576) - press
p = (((p<<31) - var2) * 3125) / var1
var1 = (dig_p9 * (p>>13) * (p>>13)) >> 25
var2 = (dig_p8 * p) >> 19
p = ((p + var1 + var2) >> 8) + (dig_p7 << 4)
return int(p)
}
func getHum(t_fine int) int {
//GetData
hum_msb := uread("0xFD")
hum_lsb := uread("0xFE")
hum := int(hum_msb) << 8 | int(hum_lsb)
//digH1
dig_h1 := int(uread("0xA1"))
//digH2
dig_h2_msb := sread("0xE2")
dig_h2_lsb := uread("0xE1")
dig_h2 := int(dig_h2_msb) << 8 | int(dig_h2_lsb)
//digH3
dig_h3 := int(uread("0xE3"))
//digH4
dig_h4_msb := sread("0xE4")
dig_h4_lsb := uread("0xE5") & 0x0F
dig_h4 := int(dig_h4_msb) << 4 | int(dig_h4_lsb)
//digH5
dig_h5_msb := sread("0xE6")
dig_h5_lsb := uread("0xE5") & 0xFF
dig_h5 := int(dig_h5_msb) << 4 | int(dig_h5_lsb)
//digH6
dig_h6 := int(sread("0xE7"))
v_x1_u32r := t_fine - 76800
v_x1_u32r = (((((hum<<14) - (dig_h4<<20) - (dig_h5*v_x1_u32r)) + 16384) >>15) *
(( (( (( (v_x1_u32r*dig_h6) >>10) * (((v_x1_u32r *
dig_h3) >>11) + 32768)) >>10) + 2097152) * dig_h2 + 8191) >>14))
v_x1_u32r = v_x1_u32r - (( (( (v_x1_u32r>>15) * (v_x1_u32r>>15)) >>7) * dig_h1) >> 4)
if (v_x1_u32r < 0) {
v_x1_u32r = 0
} else if (419430400 < v_x1_u32r) {
v_x1_u32r = 419430400
}
vhum := v_x1_u32r >> 12
return vhum
}
func getTemp() (int, int) {
//GetData
temp_msb := uread("0xFA")
temp_lsb := uread("0xFB")
temp := int(temp_msb) << 12 | int(temp_lsb) << 4
//digT1
dig_t1_msb := sread("0x89")
dig_t1_lsb := uread("0x88")
dig_t1 := int(dig_t1_msb) << 8 | int(dig_t1_lsb)
//digT2
dig_t2_msb := uread("0x8B")
dig_t2_lsb := uread("0x8A")
dig_t2 := int(dig_t2_msb) << 8 | int(dig_t2_lsb)
//digT3
dig_t3_msb := uread("0x8D")
dig_t3_lsb := uread("0x8C")
dig_t3 := int(dig_t3_msb) << 8 | int(dig_t3_lsb)
var1 := ((temp>>3 - dig_t1<<1) * dig_t2) >>11
var2 := ((((temp>>4 - dig_t1) * (temp>>4 - dig_t1)) >> 12) * (dig_t3)) >>14
t_fine := var1 + var2
t := (t_fine * 5 + 128) >> 8
return t_fine, t
}
sudo go run main.go
> TEMP : 22.10 [Deg]
> HUM : 59.70 [%RH]
> PRESS : 1010.45 [hPa]