BH1750は、周囲の明るさを測定できるデジタル照度センサーです。
測定した明るさを「lux(ルクス)」として取得でき、ArduinoやESP32などのマイコンとはI²Cで通信します。
明るさに応じて照明を制御したり、室内環境を記録したり、ディスプレイの明るさを自動調整したりと、さまざまな用途に利用できます。
この記事では、BH1750の特徴や照度(lux)の意味、I²Cアドレス、Arduino・ESP32との接続方法、サンプルプログラムについて解説します。
記事後半では、BH1750を搭載した「KUMITATE-SENSOR」についても紹介します。
BH1750とは?
BH1750FVIは、ローム(ROHM)が開発したデジタル照度センサーICです。
人間の目が感じる明るさに近い特性で周囲光を測定し、内部のA/Dコンバータでデジタルデータへ変換します。
マイコン側でアナログ電圧をA/D変換する必要がなく、I²Cを使って測定結果を取得できるのが特徴です。
BH1750の主な特徴は次のとおりです。
- 周囲の明るさを測定できる
- 測定結果から照度(lux)を取得できる
- I²C通信に対応
- A/Dコンバータを内蔵
- 2種類のI²Cアドレスを選択できる
- 複数の測定モードを備えている
- ArduinoやESP32などから利用できる
電子工作ではBH1750を実装したモジュールも広く利用されています。
照度(lux)とは?
BH1750を使ううえで知っておきたいのが「lux(ルクス)」です。
luxはある面がどれくらい明るく照らされているかを表す照度の単位で、
lx
と表記します。
例えば、センサーから
350 lx
という値を取得した場合、その場所の照度がおよそ350ルクスであることを表しています。
luxの値が大きいほど明るい
基本的には、
- luxが小さい → 暗い
- luxが大きい → 明るい
と考えれば分かりやすいでしょう。
BH1750を使えば、単純に「明るい・暗い」を判定するだけではなく、明るさを数値として扱えます。
そのため、
- 一定以下の照度になったら照明を点灯する
- 部屋の明るさを定期的に記録する
- 窓際の日射状態を調べる
- ディスプレイの明るさを自動調整する
といった制御へ利用できます。
BH1750はI²Cで通信する
BH1750とArduino・ESP32などのマイコンとの通信にはI²Cを使用します。
基本的に使用する信号は次の4本です。
| 信号 | 内容 |
|---|---|
| VCC | 電源 |
| GND | GND |
| SDA | I²Cデータ |
| SCL | I²Cクロック |
I²CではSDAとSCLの2本の信号線を複数のデバイスで共有できます。
I²C通信そのものについては、以下の記事で詳しく解説しています。
BH1750のI²Cアドレスは0x23と0x5C
BH1750を使うときに重要なのがI²Cアドレスです。
BH1750では、ADDR端子の状態によって2種類のアドレスを使用できます。
| ADDR | I²Cアドレス |
|---|---|
| Low | 0x23 |
| High | 0x5C |
一般的なBH1750モジュールでは、ADDRをLowにした0x23が使用されていることが多いです。
プログラムを書いたのにBH1750から応答がない場合は、最初にI²Cアドレスを確認してみましょう。
なぜアドレスを変更できるの?
I²Cでは、同じSDA・SCLへ複数のデバイスを接続できます。
マイコンはそれぞれのI²Cアドレスを使って通信相手を指定します。
そのため、異なるアドレスを設定できれば、BH1750を複数接続するような構成も可能になります。
複数のI²Cセンサーを接続する方法については、こちらの記事でも解説します。
I²CスキャナでBH1750を確認する
BH1750を接続したら、いきなり照度測定プログラムを書く前にI²Cスキャナで確認しておくとトラブルを減らせます。
I²Cスキャナを実行すると、マイコンに接続されているI²Cデバイスのアドレスを確認できます。
ADDRがLowのBH1750であれば、
0x23
が表示されれば正常に通信できている可能性が高いです。
ADDRをHighにしている場合は、
0x5C
が表示されます。
I²Cスキャナの使い方についてはこちらの記事で解説します。
BH1750には複数の測定モードがある
BH1750には、用途に応じて複数の測定モードが用意されています。
大きく分けると、
- Continuous(連続測定)
- One Time(1回測定)
があります。
さらに測定分解能によって、High Resolution ModeやLow Resolution Modeなどを選択できます。
代表的なコマンドは次のとおりです。
| コマンド | 測定モード |
|---|---|
0x10 | Continuous High Resolution Mode |
0x11 | Continuous High Resolution Mode 2 |
0x13 | Continuous Low Resolution Mode |
0x20 | One Time High Resolution Mode |
0x21 | One Time High Resolution Mode 2 |
0x23 | One Time Low Resolution Mode |
Continuous Modeとは?
Continuous Modeでは、BH1750が継続して照度測定を行います。
マイコン側から定期的に照度を読み取りたい場合に使いやすいモードです。
例えば、
- 室内照度モニター
- IoT環境センサー
- 自動照明
- データロガー
など、継続的に明るさを監視する用途に向いています。
One Time Modeとは?
One Time Modeでは、1回測定したあと自動的にPower Down状態へ移行します。
必要なときだけ照度を測定したい場合に利用できます。
バッテリー駆動機器など、消費電力を抑えたい用途ではこちらを検討できます。
High Resolution ModeとLow Resolution Modeの違い
BH1750には測定分解能の異なるモードがあります。
High Resolution Modeでは、より細かい照度変化を測定できます。
一方、Low Resolution Modeでは測定時間を短くできます。
そのため、
細かな明るさの変化を測定したい
場合はHigh Resolution Mode、
高速に大まかな明るさを確認したい
場合はLow Resolution Mode、
というように用途に応じて使い分けられます。
通常の電子工作で室内照度などを測定する場合は、まずHigh Resolution Modeから試してみるとよいでしょう。
Arduino・ESP32でBH1750を使う
ここから実際にBH1750をマイコンから制御してみます。
BH1750にはArduino向けライブラリもありますが、今回はI²C通信の仕組みが分かりやすいようにWireを使って直接制御します。
ADDRをLowにしたBH1750を想定し、I²Cアドレスは、
0x23
を使用します。
Continuous High Resolution Modeのコマンドは、
0x10
です。
基本的な処理は、
- BH1750へ測定モードを送信する
- 測定を待つ
- 2バイトの測定結果を取得する
- RAWデータを照度へ変換する
という流れになります。
BH1750のサンプルプログラム
Arduino・ESP32系で使用できる基本的なサンプルです。
#include <Wire.h>
#define BH1750_ADDR 0x23
void setup() {
Serial.begin(115200);
Wire.begin();
// Continuous High Resolution Mode
Wire.beginTransmission(BH1750_ADDR);
Wire.write(0x10);
Wire.endTransmission();
delay(200);
Serial.println("BH1750 start");
}
void loop() {
Wire.requestFrom(BH1750_ADDR, 2);
if (Wire.available() == 2) {
uint16_t raw =
((uint16_t)Wire.read() << 8) |
Wire.read();
float lux = raw / 1.2;
Serial.print("Light: ");
Serial.print(lux, 1);
Serial.println(" lx");
}
delay(1000);
}
使用するマイコンによってSDA・SCLピンが異なる場合は、Wire.begin()の設定を使用するボードに合わせて変更してください。
なぜRAWデータを1.2で割るの?
BH1750から取得できる2バイトのデータは、そのままlux値として扱うのではなく、センサーの仕様に従って照度へ変換します。
High Resolution Modeの基本的な換算では、
照度[lx] = RAW値 / 1.2
として求められます。
例えばRAW値が、
600
だった場合、
600 ÷ 1.2 = 500
となるため、測定照度は約500 lxとなります。
ライブラリを使うとこの処理は内部で行われますが、直接I²C通信を行うと「センサーからどのようなデータが返ってきているのか」を確認できます。
Arduinoライブラリを使う方法もある
BH1750は広く利用されているセンサーなので、Arduino向けライブラリもあります。
ライブラリを利用すれば、
- I²Cコマンドの送信
- 測定モードの設定
- RAWデータの取得
- luxへの変換
などの処理を簡単に記述できます。
「とにかく照度を取得したい」という場合はライブラリを使い、I²C通信の仕組みを勉強したい場合はWireを使って直接制御してみるのもよいでしょう。
BH1750で何が作れる?
BH1750は明るさを数値として取得できるため、さまざまな電子工作に利用できます。
例えば、一定以下の照度になったらLEDを点灯する自動照明を作れます。
Wi-Fi対応のESP32と組み合わせれば、照度を定期的にサーバーへ送信するIoT照度ロガーにもできます。
温湿度センサーと組み合わせて、
- 温度
- 湿度
- 照度
をまとめて記録すれば、室内環境モニターへ発展させることもできます。
BH1750を実際に試すならKUMITATE-SENSOR
BH1750を使って照度測定やI²C通信を試したい場合は、センサーを実装済みの基板を利用すると簡単です。
KUMITATE-SENSORには、今回紹介したBH1750を含む3種類のセンサーを搭載しています。
| センサー | 測定内容 |
|---|---|
| SHT40 | 温度・湿度 |
| BH1750 | 照度 |
| MSA3S02 | 3軸加速度 |
3種類ともI²Cで制御できるため、同じSDA・SCLを共有しながら複数種類のセンサーを制御する実験ができます。
KUMITATE-C3だけでなく、3.3V系I²Cに対応した各種マイコンから使用できます。
HY2.0-4Pコネクタも搭載しているため、M5StackのI²Cセンサーなどを同じI²Cバスへ追加して拡張することもできます。
サンプルプログラムとREADMEもGitHubで公開しています。
GitHubでKUMITATE-SENSORのサンプルを見る
SHT40と組み合わせて温度・湿度・照度を測定する
KUMITATE-SENSORにはBH1750と一緒にSHT40も搭載しています。
SHT40を使えば、
- 温度
- 湿度
もI²Cで取得できます。
BH1750の照度と組み合わせれば、
温度・湿度・照度を1つのマイコンから同時に取得
できます。
SHT40の使い方についてはこちらの記事で詳しく解説しています。
SHT40とは?Arduino・ESP32で温度・湿度を測定する方法を解説
まとめ
BH1750は、周囲の明るさを照度(lux)として取得できるデジタル照度センサーです。
ArduinoやESP32などからI²Cで制御できるため、照度測定を使った電子工作にも取り入れやすいセンサーです。
BH1750を使用するときに覚えておきたいポイントは次のとおりです。
- BH1750は照度を測定するセンサー
- 測定値はlux(lx)で扱える
- Arduino・ESP32からI²Cで制御できる
- I²CアドレスはADDRによって
0x23または0x5C - Continuous ModeとOne Time Modeがある
- High Resolution ModeとLow Resolution Modeを選択できる
- Continuous High Resolution Modeでは
0x10を使用できる - 取得したRAW値から照度を計算できる
- SHT40など別のI²Cセンサーと同じバスに接続できる
まずBH1750単体で照度を取得し、その後SHT40などを追加して複数のI²Cデバイスを同時に制御すると、I²C通信の理解をさらに深められます。

