● 実験テーマ88
「PIC24F_温湿度・気圧センサ:BME280の、試用実験」
(1つのモジュールで、3つの気象情報を得られるセンサを、PIC24Fで動かしてみました。)
以下、この実験の顛末記です。
■ 2017.3.10
・ボッシュ センサーテック社の、BME280というデバイスに興味を持った。
2.5mm*2.5mmという極小サイズの中に、3つの気象情報を得られるセンサ(温湿度・気圧)と、ADC+
制御部(I2C or SPIが選択可能)が詰め込められています。
これを、PIC24Fで動かしてみようと思います。
秋月から、ピッチ変換基板に実装されている、AE-BME289というモジュールが、税込みで、1080円
という安価で販売されているので、これを実験に使うことにしました。
WEBを検索すると、PICでの例は、1件ほどで、PIC16F(XC8コンパイラ)での例でした。
殆どが、今流行りの、Arduino(AVR)の例でした。
これらも参考にはなるのですが、メインは、スイッチサイエンスの当該パーツのページに、記載されていた
「BME280の使い方」にある、AVRでのソースを参考にしました。
今のところ、これを何に応用するかは未定なので、とりあえずの試用実験としました。
応用することを考えると、I2Cの方が、他のI2Cデバイスをチェーン接続できて便利なので、
I2Cで動かすことにしました。
秋月のモジュールの、J3をハンダブリッジさせます。
それから、I2CプルアップRは、モジュールに、4.7kが実装されていますが、100kで動かすので、
10kで十分と考え、外部プルアップとしました。(モジュールの、J1,2は、そのままOPEN)
・水魚道による回路図作成と、パーツ手配を済ませる。
■ 2017.3.13
・いきなり、計測値取得までを考えるのは、敷居が高い感じがしたので、ステップ分けして作業を
進めることにした。
Step1としては、チップ内のレジスタ(adrs=0xD0)に格納されている、Chip
ID= 0x60 を読出して、
合否判定を行い、合っていれば、チップの初期設定を行うところまで、テストしてみたいと思います。
BMC280のマニュアルを見ると、I2C規格から逸脱した変則的なプロトコルではないようなので、
自前の、RTCの時作った、I2C関数を基本に考えることにした。
また、チップの初期設定値は、極く標準的な、以下の、スイッチサイエンスの例の通りにした。
<チップの初期設定>
設定項目 値
意味
-----------------------+-----+------------
@ 気温取得サンプリング数 1 x1
A 圧力取得サンプリング数 1 x1
B 湿度取得サンプリング数 1 x1
C センサ動作モード 3 normal
D スタンバイ時間 5 1000ms
E IIR Filter 0
off
F 3-sire SPI on/off
0
off
■ 2017.3.14
・Step1のソース書上げ、HEXまで準備できる。
IDの読込は、上手く行っているようである。
・ただ、初期値の書込みが上手く行っているかは、Step2以降で、実際に動かしてみないと
わからない。
Step2として、測定値の生データ(ADCデータ)を読込んで、hex表示するテストをやってみる。
レジスタアドレス:0xF7〜 0xFEに、各ADCデータが、バイト格納されている。
簡単に言うと、0xF7〜 0xF9までが、気圧ADC値(レジスタ名で、press_msb・press_lsb・press.xlsb)
で、20bitデータ、0xFA〜 0xFCまでが、温度ADC値(レジスタ名で、temp_msb・temp_lsb・temp.xlsb)
で、20bitデータ、0xFD〜 0xFEまでが、湿度ADC値(レジスタ名で、hum_msb・hum_lsb)
で、16bitデータとなっている。
これを、I2Cで読込む関数が必要になる。
ReadData()という関数にした。
それぞれ、I2Cリード関数で読込んだ、バイト格納されているデータを、32bit型にしてから、各変数(32bit型)
に代入することになる。
結果を液晶に、表示してみたが、おかしい。
例えば、気圧・温度の、生データ読み値が、0x80000
で固定されてしまう。
■ 2017.3.15
・昨日の現象は、直ぐ解った。
BME280のマニュアルをよく見ると、I2C書込みの場合、レジスタ・アドレスは、オート・インクリメントしないとのこと。
尚、読込みは、オート・インクリメントする。
なので、単純に、1バイトの書込み関数に修正して、個別にパラメータを書込むことにした。
これで、生データの読出しまでは、OKになる。
(気圧と、温度の生データ読み値の最下位が、0で動かないのが気になったが、これは、スイッチ・サイエンスさん
のHPでの説明で理解出来た。つまり、温度と気圧は、計測結果を20bitで取得するが、下位の4bit(xlsb)は、IIR
フィルタを有効にしない限り無効で、全て、0になるというこである。)
以下にその時の、液晶表示を示した。
尚、この時の、気圧・温度・湿度は、実験テーマ87で作った自作の測定器では、
気圧;おおよそ、1010.94hPa, 温度:おおよそ、16.16℃、湿度:おおよそ、54.77%だった。
■ 2017.3.16
・Step3として、センサ固有の補正パラメータをレジスタから読込んで、hex表示するテストをやってみる。
パラメータを読込んだとしても、それは合計32バイトのバイト型数値にすぎない。
これをもとに、補正計算をする際には、気圧・温度・湿度で、それぞれ、変数型を変えないといけない。
これは、BME280マニュアルの、Table 16:Compensation
parameter storage, naming and data type
の表に、詳しく書かれている。
それぞれ、バイト型のパラメータを組合わせて、16bit(符号無し、或いは符号有)にしたり、そのまま
8bit(符号無し、或いは符号有)にしてから、別名の変数に代入する必要がある。
ここまで、Step3に盛り込んでみた。
以下は、合計32バイトのバイト型補正パラメータをレジスタから読込んだ値を液晶に表示したものです。
左側の上から16バイトが、CALレジスタアドレス:0x88〜
0x97までの内容で、
右側の上から16バイトが、CALレジスタアドレス:0xA1,
0xE1〜 0xE7までの内容です。
■ 2017.3.17
・いよいよ最終ステップの、Step4である。
ここでは、補正変数に格納された、補正値を基に、補正計算を行い、換算後、液晶に、
温度(℃)・湿度(%)・気圧(hPa)の値を表示するテストを行う。
補正計算の部分は、シフトと、OR演算の嵐で、とても複雑・難解なので、スイッチ・サイエンスさん
のHPに掲載されている関数を、そのまま借用させて頂きました。
ただ、AVR対象のソースなので、PICのデータ型と整合を取る修正を加えた。
また、このソースとは異なるのだが、Python(パイソン:軽量なスクリプト型プログラミング言語)で書かれた
web例があり、これで書かれた、補正計算部を、式を起こして詳細に解析されている方もいた。
よくもまあ、ここまで解析出来るものだと、感心してしまいました。
このサイトです。(すごく参考になりました。)→ 「Raspberry
Pi3 で家庭用IoT」
・実験テーマ87で作った、測定器の表示値と比較して、そんなに差がなかったので、OKとした。
(湿度などは置く場所によって、4〜5%位変わる。気圧も、-4hPa位、差があった。)
動作の模様は、このページ・トップの写真を参照ください。
今後、これを応用するには、設定を室内観測用に変えたり、様子を見てみようと思っている。
<最終回路図>
・こちらから、どうぞ→ 「PIC24F_BME280実験」
<最終ソース>
・こちらから、どうぞ→ 「PIC24F_BME280_TEST.c」 (Step2〜3で行った、デバッグ用の、HEX表示の部分は、削除整理しました。)
///
QVGAカラー液晶ライブラリ
colorlcd_libdsPICVH.c
colorlcd_libdsPICVH.h
///
I2C基本関数ライブラリ
skI2C_PIC24F_lib.c
skI2C_PIC24F_lib.h
/// アスキーフォント
ASCII12dot.h