光量センサモジュール(BH1750FVI)とESP32で照度を測定する | そう備忘録

光量センサモジュール(BH1750FVI)とESP32で照度を測定する

BH1750FVI

ローム社の照度センサー(BH1750FVI)をモジュール化した製品GY-302 を使って ESP-WROOM-32 モジュールで照度を測定した時の記事。

BH1750FVI 表面

GY-302 の特徴は以下の通り。

  • インターフェイス:I2C
  • アドレス:0x23 or 0x5C
  • 照度:0.11 ~ 100,000 ルクス
  • 電圧:3 ~ 5V(今回は 3.3V で使用した)

測定モード

測定は以下の3種類のモードがある。

H-Resolution Mode

高解像度モード

  • 測定時間:120 ミリ秒
  • 解像度:1 ルクス

H-Resolution Mode2

高解像度モード2

  • 測定時間:120 ミリ秒
  • 解像度:0.5 ルクス

※測定時間は高解像度モードと同じなので、それならばこちらを使ったほうが良さそうだが、測定可能な範囲が異なる(後述)

L-Resolution Mode

低解像度モード

  • 測定時間:16 ミリ秒
  • 解像度:4 ルクス

また、上記のモードの他に Continuously(連続)と One Time(1回)の2種類のモードがあるので3× 2 =6 通りの組み合わせがある。

Continuously

連続して測定する時に使用する

One Time

1回のみ

測定終了後は自動的にパワーダウンモードになる

MTReg

計測時間を調整するレジスタでセンサー感度を調整する事ができる。

設定値は31 ~ 254 が設定可能でデフォルトは 69。

大きな値(254)を設定すれば計測時間が長くなり、より細かい感度での測定が可能になるが、計測可能な最大照度が低く(H-Resolution Mode で Max 14,836 ルクス、Mode2 だとその半分の7,418 ルクス)なるので屋外(1 ~ 100,000ルクス)では向かない。

一方、室内ではデフォルトの 69 の設定で問題は無かった。

計算式

後述するライブラリーを使用すればライブラリ内部で計算をやってくれるので下記の計算式を理解しておく必要は無いが、一応書いておく。

H-Resolution Mode、Mode2 の時は以下の計算式で感度が計算される。

H-reslution mode : Illuminance per 1 count ( lx / count ) = 1 / 1.2 *( 69 / X )
H-reslution mode2 : Illuminance per 1 count ( lx / count ) = 1 / 1.2 *( 69 / X ) / 2

※ X : MTregの値

例)

H-Resolution Mode の時に X(MTreg)を254 に設定すると、

1 / 1.2 *( 69 / 254 ) = 0.2263・・・ ≒ 0.23

0.23 ルクス単位で計測される。(Mode2 の時はその半分)

同様の計算式で MTreg が 31 の時は 1.85 ルクス単位になる。

また、センサーで測定された値は下記の様(BH1750FVI データシートより引用)に High Byte と Low Byte にビットが格納されて返される。

測定結果の計算方法

ビットが 1 の所の 2 のべき乗を合算して 1.2(固定)で割っている。

上記のex)は MTreg にデフォルトの 69 がセットされている場合の計算例だが、仮に全てのビットに1が格納されて MTreg に254 をセットした場合の H-Resolution Mode の計算式は、

(2^15 + 2^14 + 2^13 + 2^12 + 2^11 + 2^10 + 2^9 + 2^8 + 2^7 + 2^6 + 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0) / 1.2 *( 69 / 254 ) = 14835.67913・・・ ≒ 14,836

で最大 14,836 ルクスの計測が可能と分かる。

Mode2 の時はその半分なので最大計測可能な照度は約 7,400 ルクス程度になるので、明るい所で高い感度で照度を測定しようとするなら注意が必要だ。

コネクタ

コネクタは下記の5つ。

  • VCC:3 ~ 5V
  • GND:GND
  • SCL:I2C接続
  • SDA:同上
  • ADDR:I2C アドレス変更用
BH1750裏面

I2Cアドレス

ADDR を LOW(0.3V 以下)に接続した時は 0x23、HIGH(0.7V 以上)に接続すると 0x5C になる。

その他のパーツ

その他、用意した主なパーツは以下の通り。

ESP32モジュール

ESP32 を使ったモジュールはスイッチサイエンスや秋月電子などから色々な製品が発売されているが、今回使用した ESP-WROOM-32 のモジュールは以下の製品だ。

ピン配置はESP32 DEVKIT V1(30ピン)のピン配置となっている。

シリコンワイヤ

最近購入したシリコンワイヤ(24AWG)

到着まで2週間かかったので、途中でキャンセルしようかとも思ったけどそのまま放置していたら忘れた頃に届いた。

しかし使ってみるとシリコンは柔らかくてとても使いが心地が良い。

温度範囲が -60 ~ +200 C なのも嬉しい。

事前準備

開発環境は Arduino IDE(Ver 1.8.19)を使用した。

Arduino IDE のダウンロード&インストールについてはこちらの記事を参照して欲しい。

事前に必要なライブラリーのインストールを行う。

BH1750ライブラリ

Arduino IDE を起動して、スケッチー>ライブラリをインクルードー>ライブラリ管理でライブラリマネージャを起動する。

検索欄に “BH1750” を入力して検索して、一番上に表示されたライブラリをインストールした。

Github はこちら

こちらのライブラリで上述した計算を内部でやってくれるのでスケッチからは MTreg のセットと照度を読み込む関数を呼び出すだけで良い。

BH1750ライブラリの検索

配線図

配線図は以下の通り。

ADDR は GND に接続したので I2C アドレスは 0x23 になる。

BH1750FVI とESP-WROOM-32との配線図

スケッチ

約 10秒ごとに照度を測定してコンソールに表示するスケッチは以下の通り。

bh1750.ino

/*
 * BH1750(光センサー)テストスケッチ
 * 
*/
#include <Wire.h>
#include <BH1750.h>

// I2C Pin
constexpr short int SDA_PIN = 21;
constexpr short int SCL_PIN = 22;

BH1750 lightMeter(0x23);

float lux;

void setup() {
    Serial.begin(115200);
    Wire.begin(SDA_PIN, SCL_PIN); // I2C

    /*
     * Modeは以下の6種類
     *   CONTINUOUS_HIGH_RES_MODE
     *   CONTINUOUS_HIGH_RES_MODE_2
     *   CONTINUOUS_LOW_RES_MODE
     *   ONE_TIME_HIGH_RES_MODE
     *   ONE_TIME_HIGH_RES_MODE_2
     *   ONE_TIME_LOW_RES_MODE
     *   
     */
    lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE_2);
}

void loop() {
    if (lightMeter.measurementReady(true)) {
        if (lightMeter.setMTreg(69)) { //MTreg(計測時間)の設定
            Serial.println("MTreg Normal Setting(69)");
        } else {
            Serial.println("MTreg setting error");
        }
        delay(500);
        lux = lightMeter.readLightLevel();
        
        Serial.print("Light: ");
        Serial.print(lux);
        Serial.println(" lx");
    } else {
        Serial.println(F("--------------------------------------"));
    }
    delay(10000);
}

補足説明

setup()

I2C 接続の初期処理と BH1750FVI の初期処理を行っている。

コード中にも記述しているが設定可能なモードは以下の6種類。

  • CONTINUOUS_HIGH_RES_MODE:連続・高解像度モード
  • CONTINUOUS_HIGH_RES_MODE_2:連続・高解像度モード2
  • CONTINUOUS_LOW_RES_MODE:連続・低解像度モード
  • ONE_TIME_HIGH_RES_MODE:一回のみ・高解像度モード
  • ONE_TIME_HIGH_RES_MODE_2:一回のみ・高解像度モード2
  • ONE_TIME_LOW_RES_MODE:一回のみ・低解像度モード

lightMeter.setMTreg(69)

MTreg を標準の 69 に設定している。

上記のスケッチは標準設定での1回の測定の例だが、非常に明るい場所から暗い場所まで高解像度モードでなるべく正確に測定したいのであれば、

  1. MTreg を69 に設定して高解像度モード2で一旦測定
  2. 測定結果が 10 ルクス以下なら 4.へ
  3. 測定結果が 5,000 ルクス以上なら 5.へ、それ以外なら 6.へ
  4. MTreg を 254 に設定して7.へ
  5. MTreg を 32 に設定して7.へ
  6. MTreg を 69 に設定して7.へ
  7. 高解像度2モードで再度測定

などの2段階での測定を行っても良いかも知れない。

実行結果

実行結果は以下の通り。

測定結果をコンソールに表示しているがセンサーに LEDライトで光を当てると高い照度が測定された。

実行結果

以上で今回の記事は終了とする。

最後に

この記事が何処かで誰かの役に立つことを願っている。

尚、当記事中の商品へのリンクはAmazonアソシエイトへのリンクが含まれています。Amazonのアソシエイトとして、当メディアは適格販売により収入を得ていますのでご了承ください。

souichirou

やった事を忘れない為の備忘録 同じような事をやりたい人の参考になればと思ってブログにしてます。 主にレゴ、AWS(Amazon Web Services)、WordPress、Deep Learning、RaspberryPiに関するブログを書いています。 仕事では工場に協働ロボットの導入や中小企業へのAI/IoT導入のアドバイザーをやっています。 2019年7月にJDLA(一般社団法人 日本デイープラーニング協会)Deep Learning for GENERALに合格しました。 質問は記事一番下にあるコメントかメニュー上部の問い合わせからお願いします。

質問やコメントや励ましの言葉などを残す

名前、メール、サイト欄は任意です。
またメールアドレスは公開されません。