記事に長いブランクを空けてしまいました。前回はFirmウェアのバージョンアップ記事。仕事がらみで、通信部分をBLEからAndroidの外付けでTWE-LITEを使うようになり、OTGでUSBシリアル経由のデータ取得が必要となり、見よう見まねでandroidのアプリの対応などの時間が取られてしまい、こちらがお留守に、、
RN4020でI2C
BME280やらRN4020のマニュアルとにらめっこする必要がありますが、さらっとメモっておきます
BME280では電源投入直後はSleepモードとなっているのでレジスタにモードを書き込み、状態を遷移させる必要があります。その際には、サンプリング情報なども一緒に書き込みをしてしまいます
大まかな流れは以下
- I2C初期化
- I2Cスタート
- I2Cアドレスを書き込み設定+書き込むレジスタの先頭アドレスと書き込むデータを指定
- I2Cをリスタート
- I2Cアドレスを書き込み設定+読み込むレジスタの先頭アドレスを指定
- I2Cアドレスを読み込み設定で指定
- 読みたいバイト数で読み込み
- I2Cをリスタート
- 5.から繰り返すことが可能
]A,1,1
I2Cの初期化をする
1つ目の”1″はクロック100K
2つ目の”1″はGPIO番号の指定で
I2Cスタート時にHighになる
センサーの電源がわりに使えるので
BME280の電源としてPIO1を使う
実際のピン番号はモジュールの17ピン
]C,0
I2Cのスタート
この時にGPIOがHighになる
]W,[I2Cadr(W)]XXYY
I2Cのアドレスは7ビット
最後に書き込みの0
もしくは読み込みの1をつける
BME280の場合
I2Cアドレスは0x76なので
0x76=>0111-0110
左シフトして
111-0110-0=>0xEC(書き込み)
111-0110-1=>0xED(読み込み)
要は左1Bitシフトして
LSBに0か1を加える
書き込むレジスタの
先頭アドレスXXに
データYYを書き込む
]C,1
I2Cをリスタートする
]W,[I2Cadr(W)]ZZ
データリードはI2Cアドレスを
書き込み設定で
読み出すレジスタの
先頭ZZアドレスを指定
]C,1
I2Cをリスタートする
]W,[I2Cadr(R)]
I2Cアドレスの読み込み設定を指定
]R,NN
読み込むバイトするNNを指定すると
読み込まれた値が返ってくる
]C,1
ここでI2Cをリスタートすると
リードアドレス指定からの繰り返しで
読み込みができる
BME280のレジスタ設定
ここを見ると
天気をモニタリングする設定として
ForceMode
オーバーサンプリングは全て”1″
IIRフィルタはOFF
との推奨
設定するレジスタは3つ
ctrl_hum -> レジスタアドレス0xF2
ctrl_meas -> レジスタアドレス0xF4
config -> レジスタアドレス0xF5
ctrl_measの設定
温度と気圧のオーバーサンプリング値と
モードをそれぞれ2ビットずつ
6ビットの値をセットします
温度のオーバーサンプリング値1
を5ビット左シフト
0000 0001=>0010 0000
気圧のオーバーサンプリング値1
を2ビット左シフト
0000 0001=>0000 0100
MODEはForceMode=1
0000 0001=>0000 0001
のorをとると
0010 0000
0000 0100
0000 0001
——————
0010 0101=0x25
Configの設定
tsの時間と
IIRフィルタ値と
SPIの設定を入れる
T_stanbyはForceModeは存在しない
のでとりあえず1秒に設定する
スペックシートから101を設定する
ので5を左5ビットシフト
0000 0101=>1010 0000
filterはOFFにするので0
したがって2ビットシフトしても0
SPIの設定は使わないので0
したがって
1010 0000
0000 0000
0000 0000
———————
1010 0000=0xA0
hum_ctrlの設定
オーバーサンプリング
は無効にするとSkippedに
なってしまうので
001
0000 0001=0x01
F4に0x25
F5に0xA0
F2に0x01
をセットするので
とにかくアクセスしてみる
1 2 3 4 5 6 |
]A,1,1 ]C,0 ]W,ECF425 ]W,ECF5A0 ]W,ECF201 ]C,1 |
次に、データを読み出すが 読み出し開始には時間をおく必要がある 多分T_stanby相当の時間1秒くらい
読み出すデータはキャリブレーションデータ と温度湿度、気圧のデータ レジスタマップを見るとキャリブレーションデータは 0x88〜A1と0xE1〜F0 と書いてあるが 0xA0と0xE8〜F0のデータは使われない
1 2 3 4 5 6 |
//Calibrationデータ 0x88-0x9Fの読み出し ]W,EC88 ]C,1 ]W,ED ]R,18 ]C,1 |
1 2 3 4 5 6 |
//Calibrationデータ 0xA1の読み出し ]W,ECA1 ]C,1 ]W,ED ]R,01 ]C,1 |
1 2 3 4 5 6 |
//Calibrationデータ 0xE1-E7の読み出し ]W,ECE1 ]C,1 ]W,ED ]R,07 ]C,1 |
肝心の温湿度、気圧を読み取るレジスタは
気圧MSB 0xF7
気圧LSB 0xF8
気圧拡張 0xF9
温度MSB 0xFA
温度LSB 0xFB
温度拡張 0xFC
湿度MSB 0xFD
湿度LSB 0xFE
なので、0xF7から8バイト分を読み出す
1 2 3 4 5 6 |
//測定データ 0xF7-FEの読み出し ]W,ECF7 ]C,1 ]W,ED ]R,08 ]C,1 |
Arduinoのライブラリをつかって読み出した 値と比べてみる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//Arduinoのライブラリを使って読み出したキャリブレーションデータ 646e78673200369034d6d00bc41babfff9ffac260ad8bd104b6601001428031e //RN4020で上記のコマンドで読み出した場合 Echo Off AOK AOK AOK AOK 646E78673200369034D6D00BC41BABFFF9FFAC260AD8BD10 ←ここと AOK AOK AOK AOK AOK 4B ←ここと AOK AOK AOK AOK AOK 6601001428031E ←ここ AOK AOK AOK AOK 503F007FE0008000 ←温湿度、気圧データ |
一致することが確認できます。
次は、これをどうやってBLEで渡すか・・・