タイトルの通りなんですが、Amazonで購入した HDC1080 という温度と湿度を測るチップをRaspberry PI4 とGO言語を使ってI2Cバスから読み取ってみました
HDC1080のデータシートはここから手に入れました
# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
似たような温度湿度センサーSi7021と同じアドレスだ
Pythonは嫌だ
なんだってまたGo言語を使うのかというと、HDC1080の読み取りでググるとほとんどがPythonで書かれているんですよね
で、PythonはPython2とPython3で互換性がなく、パッとソースみただけじゃどっちかわかんない書き方をしているものが多いです
pipコマンドでライブラリを入れるんですが、pip3だとpip2だのいろいろバージョンがでてくる
しかも pip serch 欲しいライブラリすると...
$ pip3 search test
ERROR: XMLRPC request failed [code: -32500]
RuntimeError: PyPI's XMLRPC API has been temporarily disabled due to unmanageable load and will be deprecated in the near future. See https://status.python.org/ for more information.
ううーん、pip3 install ホゲホゲ はできるのに、サーチできない。
pip3をアップデートしろ、という書き込みをみたのでアップデートしたらpip(Python2のほう)がぶっ壊れたww
真の原因は、どうやら現在searchする為のサーバーが攻撃だかリクエスト有りすぎだかでダウンしていて、回復する見込みはないという絶望的な状態とのこと(2021/02現在)
意味わからんのでPythonは金輪際使いたくない。
昔インフラの仕事もしてたから、破壊的バージョンアップを平気でするスクリプト系は嫌いなんだよ。Dockerとかこのあたりを解決したかったんじゃないかとも思える
Rubyは2.0系にAppleが開発に加わって破壊的なのが激減したから許す
Raspberry PI on Go Lang
Go言語はクロスコンパイルがめっちゃ楽なので、本当はmacで実行ファイル作ってRaspberry PIに転送してたんだけど、Raspberry PI単体でも当然コンパイルできます
でもSDカードの寿命をうんとこ縮めるので、実機コンパイルするならSSDやHDDで起動したラズパイにしましょう
$ sudo apt install golang
...
$ go version
go version go1.11.6 linux/arm64
インストール終了。1.11はちょっと古いけどまぁいいか。環境変数 $GOPATHの取り扱いがどこかのバージョンで変更されているので気をつけたいけど、今回のようなちっさいプログラムだとあんま関係ない
さらにi2cのライブラリを入れるんだけど、gobotという無敵ライブラリはあまりにでっかいので、100行くらいの小さいライブラリをgithubからみつけたのでこれを入れる
$ go get github.com/davecheney/i2c
これでライブラリがgithubから読み込まれて、ソースコードから読み出せるようになった
で、Go言語はフォルダ名とかソース名にとても意味があるので注意しよう
$ mkdir hd1080
$ cd hd1080
ソースを書く(main.goにする事)
$ vi main.go
package main
import (
"fmt"
"time"
"github.com/davecheney/i2c" // go get github.com/davecheney/i2c
"encoding/binary"
)
const (
wait = 100 * time.Millisecond
)
func write(dev *i2c.I2C, s string) {
chars := []byte(s)
dev.Write(append([]byte{0x40}, chars...))
time.Sleep(wait)
}
func main() {
if len(os.Args) < 2 {
fmt.Println( "exp: hdc1080 0 or 1 (0=Ondo 1=Shitudo")
os.Exit(-1)
}
var b = []byte{0, 0}
var c float32
if os.Args[1] == "0" {
// 0x40 is I2C address , 4 is /dev/i2c-4
dev, _ := i2c.New(0x40, 4)
dev.Write([]byte{0x00})
time.Sleep(wait)
dev.Read(b)
c = float32(binary.BigEndian.Uint16(b))/65536.*165. - 40.
time.Sleep(wait)
fmt.Printf("%.2f\n",c)
} else {
dev, _ := i2c.New(0x40, 4)
dev.Write([]byte{0x01})
time.Sleep(wait)
dev.Read(b)
c = float32(binary.BigEndian.Uint16(b)) / 65536. * 100.
time.Sleep(wait)
fmt.Printf("%.2f\n",c)
}
}
自分のラズパイ4は i2c の4番を使っているので
dev,_ := i2c.New(0x40,4)
となっているが、普通は
dev,_ := i2c.New(0x40,1)
として、/dev/i2c-1 を使うようにしよう
I2Cの追加方法はこちら
コンパイル前に go.mod ファイルを作っておく
一度きりでOK
go mod init hdc1080
$ GOOS=linux GOARCH=arm go build
または
$ GOOS=linux GOARCH=arm64 go build
main.go というファイル名だと勝手にうまいことコンパイルして、ディレクトリ名の実行ファイルができる
$ ls
hdc1080 main.go
$ ./hdc1080
18.7127685546875
45.574951171875
部屋の温度は18.7度で、湿度が45%くらいとの事
懐かしい寒暖計もだいたいそのくらいを指しているので信じる事とする
あとはこの値をzabbixなどに食わせればグラフ化できたりする。
追加
I2Cをsudoしなくても読めるようにする
# sudo usermod -aG i2c zabbix
end
0 件のコメント:
コメントを投稿