Raspberry pi で BME280 を使用する (Golang)

# はじめに
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 を正面に見て左上６ピンを図のように接続する
![スクリーンショット 2022-10-09 12.26.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253609/5e050547-579c-822d-db55-c29c189c0311.png)

# センサ取り付け後の確認
```
sudo i2cdetect -y 1
```
![スクリーンショット 2022-10-09 12.07.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253609/e8447548-fb00-5751-19ef-45a1a7bd9f31.png)
 
# 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]
```