(2019/1/14 追記) 接続方法に誤りがあったため修正
前提条件(環境)と準備したもの
- Raspberry Pi 3 Model B
- Raspbien 9.6(Strech)
- 上記にSSH接続する端末
- CJMCU-680(BME680を搭載したブレークアウトボード)
自分がやりたいこと
- ラズパイでI2Cを利用するための初期設定
- コマンドラインを利用してBME680と通信
- Cで接続する場合は、こちら
この記事で扱わないこと
- I2Cの説明
- SPI接続全般
- CJMCU-680を利用しない場合のBME680接続
手順1:Raspberry PiでI2Cを利用可能にする
raspi-configでI2Cを有効にする
$ sudo raspi-config
5 Interfacing Options → P5 I2C から有効化
関連コマンドをインストール
$ sudo apt install pigpio i2c-tools
手順2:CJMCU-680をGPIOに接続する
CJMCU-680 | GPIO | 補足 |
---|---|---|
VCC | 3V3 | |
GND | GND | |
SCL | GPIO03(SCL) | |
SDA | GPIO02(SDA) | |
SDO | 3V3 | BME680のアドレスを変更するために利用する。H:0x77 L:0x76 |
CS | 3V3 | |
SDOは、未接続の場合Hにした場合と同等だった |
接続確認
SDOの設定により、77または76が検出される
pi@raspberrypi:~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- 77
手順3:BME680と通信
※公式ライブラリを利用するほうが確実かと思います。
ここでは、I2Cの勉強を兼ねてコマンドラインで実行します。
設定値を送信する
公式のデータシート(ここからダウンロード)の3.2.1 QuickStartに沿って試してみる
以下、意訳
まず、湿度・気温・気圧の設定を行う。
それぞれのoversumplingを変更することで精度を変更可能。
気温と気圧はoversumpling設定値により16-20bit
湿度は16bitだが、oversumplingを上げることにより誤差を減らすことができる
oversumplingを0xにすると、その項目はスキップする。
- 湿度のoversumplingを1xに設定する→osrs_h<2:0>に0b001を書き込む
- 温度のoversumplingを2xに設定する→osrs_t<2:0>に0b010を書き込む
- 気圧のoversumplingを16xに設定する→osrs_p<2:0>に0b101を書き込む
$ i2cset -y -m 0x07 1 0x77 0x72 0x01
$ i2cset -y -m 0xE0 1 0x77 0x74 0x40
$ i2cset -y -m 0x1C 1 0x77 0x74 0x14
次に、室内空気質(IAQ, Indoor Air Quality)の設定を行う。
設定は10種類保存できる。(設定0~9)
4. 設定0の予熱時間を100msに設定する→gas_wait_0<7:0>に0x59を書き込む
5. 設定0のヒーターの温度を設定する→res_heat_0<7:0>に Datasheetの§3.3.5で計算される値を設定する(=0x10)
6. 設定0を利用するようにする→nb_conv<3:0>に0b0000を書き込む
7. gas計測を有効にする→run_gas<0:0>に0b1を書き込む
$ i2cset -y 1 0x77 0x64 0x59
$ i2cset -y 1 0x77 0x5A 0x10
$ i2cset -y -m 0x0F 1 0x77 0x71 0x00
$ i2cset -y -m 0x10 1 0x77 0x71 0x10
準備ができたので、計測を行う
8. 計測を行う→mode<1:0>に0b01を書き込む
$ i2cset -y -m 0x03 1 0x77 0x74 0x01
計測結果を受信する
気圧
0x1Fと0x20と0x21の先頭4bitを連結
※oversumpling設定により精度は変化
$ i2cget -y 1 0x77 0x1F;i2cget -y 1 0x77 0x20;i2cget -y 1 0x77 0x21
0x4b
0xbd
0xb0
0x4d57a=316,794
分解能20bit、気圧のレンジは300~1100hPaなので、
300+800*316,794/1,048,576=541.69hPa
あれ・・・?
温度
0x22と0x23と0x24の先頭4bitを連結
※oversumpling設定により精度は変化
$ i2cget -y 1 0x77 0x22;i2cget -y 1 0x77 0x23;i2cget -y 1 0x77 0x24
0x78
0xf9
0x80
0x78f98=495,512
分解能20bit、温度のレンジは-40~85℃なので、
-40+125*495,512/1,048,576=19.07℃
湿度
0x25と0x26を連結
$ i2cget -y 1 0x77 0x25;i2cget -y 1 0x77 0x26
0x3d
0x75
0x3d75=15,733
分解能16bit、湿度のレンジは0~100%なので、
100*15,733/65,536=24.01%
IAQ
0x2A・0x2Bの値を計算式(Datasheet §3.4.1)に従って計算
(2019/1/14 追記) 接続方法を修正することで正しい値が取れるようになった
$ i2cget -y 1 0x77 0x2A;i2cget -y 1 0x77 0x2B;i2cget -y 1 0x77 0x04
0x4f
0x62
0x13
gas_res=1097063.621
とのことだが、値の意味がわからない
おわりに
気圧が正しく取得できていないが、ラズパイでI2C通信の基礎を学ぶことができたのでよしとする。
次は、公式ライブラリを利用してみる。