1.計測ボードの所要機能
前回RTCを設置した計測ボードに次の機能を持たせることにします。
①センサー増設への柔軟性
各種センサーの増設に弾力的に対応できるハードウェア・ソフトウェア構造。
②測定データの管理機能
複数センサーの測定結果をシンプルに管理できるデータ構造。
③測定結果の編集機能
測定結果を簡潔に編集できる機能の装備。
2.使用する部品
(1)部品の規格・仕様
今回のセンサーは以下のものを使用します。
なお、BME280モジュールキットは秋月電子通商で購入しました。
・BME280使用 温湿度・気圧センサモジュールキット | 1個 | 1,080円 |
・BH1750デジタル光量センサモジュール(手持ちのもの) | 1個 | 200円 |
・配線材料 | 少々 |
ボッシュ社のBME280を搭載したセンサモジュールで、温度、湿度、気圧の3種を同時に測定できます。
・動作電圧 | : 1.71~3.6V |
・温度 | : -40~+85℃ ±1℃ |
・湿度 | : 0~100% ±3% |
・気圧 | : 300~1100hpa ±1hpa |
・I2Cアドレス | : 0x76, 0x77 5番ピン(SDO)で選択、GND接続で0x76 |
・基板サイズ | : 10mm × 16mm |
〔BH1750の仕様〕
照度をアナログ電圧で出力するセンサ、ローム社のBH1750を搭載したセンサモジュールです。
・動作電圧 | : 3~5V |
・照度 | : 0~65535lux ±1lux |
・基板サイズ | : 32.5mm × 15mm |
(2)BME280の内部構造
BME280は、下図のようなメモリー・レジスターで測定条件やキャリブレーション・データ、計測データなどを保持しています。大まかに整理すると次のとおりです。
・0x88~0xa1 | : キャリブレーション・データ |
・0x0d | : チップID |
・0xe1~0xf0 | : キャリブレーション・データ |
・0xf2 | : 湿度センサーの設定 |
・0xf4 | : 温度センサー・湿度センサーの設定、動作モードの設定 |
・0xf5 | : 測定間隔、フィルター等の設定 |
・0xf7~0xfe | : 測定データ |
・Bosch Sensoertec社の英文データシート(秋月電子のサイトから入手できます)
・SWITCH SCIENCE社 『BME280搭載 温湿度・気圧センサモジュールの使い方』
SWITCH SCIENCE社ではサンプルスケッチをダウンロードすることができます。今回のBME280関係の計測処理には、このサンプルスケッチを利用しています。
(3)BH1750の内部構造
BH1750はとてもシンプルで使いやすいセンサーです。次の図はローム社のマニュアルからの抜粋です。
この例から、H-Resolution Mode(測定時間:120ms、分解能:1lx.)で計測する場合は、BH1750宛に測定モード指定として0x10を送信し、2バイトのデータを受信すればよいことがわかります。
光量(照度)は、受信したHigh Byteを8ビット上位へシフトしてLow Byteと合成し、1.2で除算すれば求めることができまるわけです。
3.組み立てと配線
(1)計測ボードの配線
BME280とBH1750モジュールの端子と接続先は図のとおりです。
計測ボードの空きスペースに2つのセンサーを追加します。上図の接続先に従って写真のように配線します。ここで注意しなければならないのは、BH1750はRTCと同じ5V電源を使用しますが、BME280は3.3Vを使用する点です。写真のブレッドボードでは、上側の赤線を5V、下側の赤線を3.3Vラインとして組み付けています。電源のマイナスラインは共通なので、ボード上の右端で緑のジャンプワイヤーで直結しています。各センサーのSCLとSDAは、それぞれオレンジと黄色のジャンパーコードで並列に結ぶだけです。
(2)ボード間の配線
MCUボードから計測ボードへの接続はI2Cの2本の線だけです。計測ボードの電源は、専用電源から5Vが赤色ジャンパーコードで上のプラスライン(赤色)へ、その下のマイナスライン(青色)には緑色でGNDが接続されています。3.3Vはオレンジのコードで下のプラスライン(赤色)へつながれています。
〔回路図〕
4.ソフト開発のポイント
先にも述べたように、BME280の計測関係のコードはSWITCH SCIENCE社のサンプルスケッチを利用しています。コードの細かい部分については、前掲のSWITCH SCIENCE社のページを参照してください。またBosch Sensoertec社のデータシートは英文ですが、きわめて詳細な説明があるので一読をお勧めします。
(1)計測用データ領域と計測結果を収納するデータ型
1行目: BME280用のグローバル変数は次の2行です。unsigned long型のhum_raw, temp_raw, pres_rawは
気圧、温度、湿度レジスターから取り込んだ計測値が格納されます。t_fineは計測値の較正処理で使用
する共用フィールドです。
5行目: BME280の初期化時に、計測値の較正処理に使用する値をレジスターから取得して格納します。
26行目: 較正処理された計測結果と計測日時を収納するための構造体MeasuredResultを定義します。
33行目: MeasuredResult型のデータ領域rstMeasuredを割り付けます。
//BME280 Global variables
unsigned long int hum_raw, temp_raw, pres_raw;
signed long int t_fine;
//BME280 Calibration variables
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
int8_t dig_H1;
int16_t dig_H2;
int8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;
//Measured result
struct MeasuredResult {
double temperature;
double pressure;
double humidity;
int illuminance;
String datetime;
};
MeasuredResult rstMeasured;
(2)BME280サンプルスケッチ内の計測メソッド
SWITCH SCIENCE社サンプルスケッチのうち、初期化処理setupに記述されている計測条件の設定部分は、prepareBME280というメソッド名で独立させました。これを含め、サンプルスケッチ内のメソッドを簡単に整理しておきます。
・void prepareBME280()
温度、湿度、気圧それぞれの測定条件を設定して、readTrimメソッドを実行します。
・void readTrim()
BME280のI2Cスレーブアドレスで通信を開始し、レジスターに記録されているキャリブレーション
(較正)用のデータをグローバル変数に格納します。
・void writeReg(uint8_t reg_address, uint8_t data)
reg_addressで指定されたレジスターに1バイトのdataを書き込みます。
・void readData()
計測値が記録されているレジスターから、グローバル変数に気圧、温度、湿度の計測値を格納します。
・signed long int calibration_T(signed long int adc_T)
adc_Tで与えられた計測値とグローバル変数の較正値を使って温度の較正結果を通知します。
・unsigned long int calibration_P(signed long int adc_P)
adc_Pで与えられた計測値とグローバル変数の較正値を使って気圧の較正結果を通知します。
・unsigned long int calibration_H(signed long int adc_H)
adc_Hで与えられた計測値とグローバル変数の較正値を使って湿度の較正結果を通知します。
各メソッドともかなり複雑になっていますが、先のBME280の内部構造のレジスター図を見ながら、データのビットシフトと合成・分割を意識して眺めると納得、ガッテンでしょう!
(3)BH1750のメソッド
2つのメソッドで構成されています。
・void prepareBH1750(int i2cAddress)
与えられたI2CアドレスのBH1750を初期化して、H-Resolution Mode(測定時間:120ms、分解能:1lx.)
で計測するよう指示します。
ここでは標準的な計測モードに固定していますが、さらに分解能の精粗を指定することもできます。
・int measureIlluminance(int i2cAddress)
後続のint measureIlluminance(int i2cAddress, byte *buff)を使って、レジスターから2バイトの
計測結果を取り出し、1.2で除算して得られた照度を通知します。
(4)その他のメソッド
主処理の反復処理部は、次の2つのメソッドを利用するだけで計測と結果編集が完了します。
・void doMeasurement()
計測結果の取得、較正処理、日時情報の取得など一連の処理を行って、MeasuredResult型の
rstMeasuredに結果を格納します。
・String editMeasuredResult(MeasuredResult data)
MeasuredResult型の結果情報をカンマ区切りのテキスト文字列に編集して通知します。
なお編集処理では、次の2つのメソッドを使用しています。
・char *printNum(char *buf, double field, int len, int decimal)
実数型の編集。
・char *printNum(char *buf, int field, int len)
整数型の編集。
5.スケッチの実行
(1)実行結果と評価
シリアルモニターを表示させた状態でスケッチを実行すると、項目見出しに続いて1秒ごとに測定結果が表示されます。照度Illum(lx)の左に空白が多いのは、センサーにLEDライトなどを当てると2桁大きい値を表示するためです。
スケッチの計測関連のメソッドはかなり複雑ですが、主処理はシンプルな記述で計測と結果編集を行うことができます。また今後のI2Cセンサーの増設に対しても、個別の計測・較正ロジックさえ追加すれば、MeasuredResult型へのフィールド追加と、doMeasurmentとeditMeasuredResultへの軽微な追加で対応することが可能になりました。
(2)スケッチ全景