2021年2月28日日曜日

HDC1080 と RaspberryPI と Golang で温度湿度を読み取る

  タイトルの通りなんですが、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が開発に加わって破壊的なのが激減したから許す

2021年2月26日金曜日

Zabbix 4 LTS グラフ 日本語文字化けの修正方法

Zabbixのグラフが豆腐になってしまう

 Raspberry PI 4だとRAMが4Gもあってzabbixが楽々動作

 

 まずは日本語フォントをダウンロードする。

ipa00303.zip じゃないとダメ

リンクが切れていたらファイル名でググって手に入れてましょう。

 最新のipaフォント(IPAexfont00401)だとなんかうまく出ない

 ipa.go.jp っていつの間にかなくなってたのね。あちこちこの手の情報はあるけど、リンクが切れまくってるのと、最新フォントならいけるだろ、と思ったらイケなかった。


$ sudo su -

# wget https://ja.osdn.net/projects/ipafonts/downloads/51867/ipag00303.zip

# cd /usr/share/fonts

# unzip  ~/ipag00303.zip        

 //  ipag00303/ipag.ttf ができあがっている事


# cd /etc/alternatives/

# mv zabbix-frontend-font zabbix-frontend-font.org

# ln -s /usr/share/fonts/ipag00303/ipag.ttf /etc/alternatives/zabbix-frontend-font

zabbix-serverが動作したままでもこの変更でブラウザをリロードしたら即座に反映できた

なんか元のフォントに比べると、弱っちい見た目になるけど日本語である事のほうが重要

表示用のhtmlを修正してフォントサイズを少し大きくすればいい筈だけどめんどいからパス


end

2021年2月23日火曜日

Si7021 + Rasspberry PI + GoLang

HDC1080の記事を書いたあとに、「産業用高精度 温度湿度」センサーと書いてあったのできっとすごいセンサーだと思って amazonでポチッた

ポチったあとにデータシートみて驚愕したんだけどI2Cのアドレスは 0x40 固定だった

HDC1080とまったく同じだ。 

RaspberryPi3 だと I2Cが一個しかないので一個しかぶら下げられない。なんという事でしょう。Pi4なら複数のI2Cがあるけど

温度/湿度なんてI2Cほど速度いらないから1-wireのほうがいいのかな。こちらはデバイス毎に固有アドレスがあるし。 

どこかからソースパクってこよう、は安易すぎた 

なかなか古いデバイスのようで、GoLang + Si7021 でググるといくつか github にヒットする

けどなんかこうGoLangのバージョン依存してたり、OS依存しててコンパイルできなかったりした

結局 ここのデータシート 読んで自分で書いた方が早かった。3時間も無駄にしたよ.. 


CRCはちゃんと計算しよう 

最初10分で書いた信頼性がなさすぎた
実験でケーブルが短い時は大丈夫だったけど、3mの単芯ケーブルにしたら通信エラーが起きているっぽくで、湿度が-50%とかになってる

他のセンサー(DC-CO2-20)では通信エラーが起きていないので、デバイスのドライブが弱いのかな、と人のせいにしてはいけない 。ちゃんとCRC計算しよう...


ハードウェアの結線

Raspberry PIとの結線は SDA,SDL, 3.3V , GND の4本だけ

GoLang は 1.16 で macOSを使用 

アドレスの確認

# 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: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 

0x40にいた。HCM1080と同じアドレスだ。困る。

 

I2Cをsudoしなくても読めるようにする

これはグラフツールのzabbixが読めるようにする設定
ユーザー名がpiの人は zabbix を pi にするとよさそう

# sudo usermod -aG i2c zabbix


パッケージの準備

% mkdir si7021

% cd si7021

% go mod init si7021

go: creating new go.mod: module si7021

go: to add module requirements and sums:

go mod tidy


% go mod tidy

go: finding module for package github.com/davecheney/i2c

go: found github.com/davecheney/i2c in github.com/davecheney/i2c v0.0.0-20140823063045-caf08501bef2


ソース

// macOS closs compile

// GOOS=linux GOARCH=arm go build 

package main



import (

  "fmt"

  "os"

  "time"

  "github.com/davecheney/i2c"  // go get github.com/davecheney/i2c

  "encoding/binary"

)


const (

    wait = 100 * time.Millisecond // 100milisec 

)


func write(dev *i2c.I2C, s string) {

  chars := []byte(s)

  dev.Write(append([]byte{0x40}, chars...))

  time.Sleep(wait)

}



func help() {

    fmt.Println( "exp: hdc1080 0 or 1 (0=Ondo 1=Shitudo 9=reset")

}



// 2byteの値から1byteのcrcを返す

func calcCRC(seed byte, buf []byte) byte {

  for i := 0; i < len(buf); i++ {

    seed ^= buf[i]

    for j := 0; j < 8; j++ {

      if seed&0x80 != 0 {

        seed <<= 1

        seed ^= 0x31

      } else {

        seed <<= 1

      }

    }

  }

  return seed

}


func Reset() {

    dev, _ := i2c.New(0x40, 1)


    dev.Write([]byte{0xFE}) // CMD_RESET

    time.Sleep(wait * 5)

}


func ReadData(cmd byte) float32 {

    var i float32

    var b  = []byte{0, 0, 0}

    var b2 = []byte{0, 0}

  

    // 0x40 is I2C address , 1 is /dev/i2c-1

    dev, _ := i2c.New(0x40, 1)

    cnt := 0;

    

again:

    dev.Write([]byte{cmd}) // CMD_TEMPTURE

    time.Sleep(wait)

    dev.Read(b) // 3byte読み込み

    b2[0] = b[0]

    b2[1] = b[1] // 素人すぎるプログラムww

    

    crc := calcCRC( 0x00 , b2 )

    if crc != b[2] {

        fmt.Fprintln( os.Stderr , "CRC error")

        time.Sleep( wait * 10 ) // 1秒

        Reset()

        time.Sleep( wait * 10 ) // 1秒

        

        cnt += 1

        if cnt > 5 {

            return -1

        }   // error

        goto again

    }


    i = float32(binary.BigEndian.Uint16(b2))

    time.Sleep(wait)

    return i

}


func main() {

  if len(os.Args) < 2 {

    help()

    os.Exit(-1)

  }


  switch os.Args[1] { 

  case "0":

      f32 := ReadData(0xF3) // / CMD_TEMPTURE

      if ( f32 != -1 ) {

          c := float32(f32) * 175.72 / 65536. - 46.85

          fmt.Printf("%.2f\n",c)

      } else {

           fmt.Println(-1)

      }

  case "1":

      f32 := ReadData(0xF5) // / CMD_HUM

      if ( f32 != -1 ) {

          c := float32(f32) * 125. / 65536. - 6.

          fmt.Printf("%.2f\n",c)

      } else {

           fmt.Println(-1)

      }

  case "9":

    Reset()


  default:

    help()

  }

}




コンパイル

GOOS=linux GOARCH=arm go build 

これでバイナリができたので、RaspberryPIに scp して実行

# 温度

$ ./si7021 0

21.715549316406246


# 湿度

$ ./si7021 1

39.543670654296875


# リセット送信 (いるのかな? )

$ ./si7021 9



高精度?

うーんと、精度はどうなんだろう

hdc1080と温度で0.5度くらい、湿度で1%くらいの差くらい

hdc1080も割と高精度なんでは...


おしまい

2021年2月14日日曜日

Raspberry PI 4 には I2C が沢山あった

Raspberry PI4 は I2C がいっぱいあった

 電力をあまり食わせたくなかったので最新のRaspberry4(Rspi4)ではなく、PI3系(Rspi3)を好んで使っていたんですが、なんとRaspberry PI 4は BCM2711を搭載しているので、I2Cを4つも追加できるとの事

 Rspi3以前でもI2C-0を使おうと思えば使えたんですが、いろいろなHAT(拡張ボード)を上に乗っける時にこの端子でHATのチップと通信しているものが多く事実上使えませんでした

2021年2月12日金曜日

AirPods Maxを買いに行ったらMDR-Z7M2が手元にあった

 先日渋谷に出かける用事の帰りApple Storeが開いてたのでAirPods Maxが急激に欲しくなって飛び込んだ

 もうジジイでモスキート音も聞き取りづらいからハイレゾなんてわかんないだろ

 それより首を振ったら音場が移動する面白機能が欲しいんだよぉぉ

 自分のiPohne12を使って視聴させてくれと頼んだら消毒してくれて貸してくださいました


音質は音楽がきければなんでもいいや、と思ったけど

んんん??

音が...ゴミ

どの曲を聞いてもダメ。特にクラシックがダメ


 どこかの記事で AirPodsMaxの作りに比べたら、同価格帯の他のヘッドホンなんておもちゃみたいな作り、と絶賛していたけど...やはり提灯記事であったか

 音質ゴミぢゃん

 3万円から6万円くらいのワイヤレスもたくさん持ってるから、音質が不利になるのはわかってたけど。

 アメリカ人って音に対する分解能がないんだろうか(ひどい偏見)

 BOSEもそうなんだけど音がゴチャゴチャ

 いろいろ設定を変えてみたけど、グワーグワーン、ジョワーンジョワーンとなっててリバーブ成分が定着しない

 Appleの店員さんに丁寧にお礼と感謝を申し上げてAppleStoreを出て、新宿でMDR-Z7M2を買ってしまった

 ヘッドホンアンプが少々古くて(PHA-3)ヘッドホンについてるバランスケーブルが刺さらなかったのでケーブルも

 MDR-Z7M2は壊してしまったMDR-CD1000を聞いた時と同じ傾向で楽しい音だった

PHA-3とMDR-Z7M2を接続するケーブルはMUC-B12BL