Arduino 入門 Lesson 71 【照度センサモジュール】

arduino-lesson71-00 Arduino入門編
記事に広告(アフィリエイト広告)が含まれています。
スポンサーリンク
子供と一緒に始める マイコンプログラム
Arduino 入門
Lesson 71
【照度センサモジュール】

こにんちは、管理人のomoroyaです。

センサーの使い方の基本を学習する入門編。

本Lessonの電子部品も、部品庫の奥から引っ張り出してきました!

BH1750が実装された、照度センサモジュール。

 

世の中には、まだまだ色々なセンサーがあります。

これからも、色々なセンサーで遊んでいきます。
※そろそろ部品庫のセンサがない・・・

本記事はLesson 71 【照度センサモジュール】です。

 

光を感知するということであれば下記Lessonにて使用したフォトレジスタで十分です。

 

今回のセンサーはBH1750が実装された、照度センサモジュール。

BH7150は、PD(Phot Diode)、AMP、ADC、OSC、I2Cのインターフェースが実装されており、検知した光を16bitのデジタル値に変換して出力してくれます。

また、モジュールには3.3V出力のレギュレータが実装。

電圧レベルを気にすることなくArduinoで使用できるところも、また使いやすい。

そのため、フォトレジスタ単体を使うよりは何かと使いやすいモジュールとなっております。

 

照度センサモジュール」はROHM社がリリースしているBH1750FVIが実装されたものを使用しています。

 

本Lessonで使用している「照度センサモジュール」は以下が同等品。
※prime対応品
※出荷元:Amazon

 

Arduino入門編の解説にて使用しているArduinoは互換品です。

互換品とは言え、Arduinoはオープンソースであり複製して販売するのもライセンス的に問題なし。

そのため互換品の品質も悪くなく、それでいて値段は安いです。

正規品本体の値段程度で豊富な部品が多数ついています。

正規品(Arduino UNO R3)の本体単品がほしい方はこちらとなります。

 

Arduino入門編2では「Arduino UNO R4 Minima」「Arduino UNO R4 WIFI」にて遊ぶため今のところは正規品を使用。(まだ互換品が・・・ほぼない)

 

 

スポンサーリンク

はじめに

本Lessonで使用する「照度センサモジュール」は「BH1750FVI」が実装されたモジュール。

データシートはすぐに見つけることができます。

 

Lesson 71 目標

本Lessonの目標は以下です。

1.照度センサモジュール、BH1750の使い方を学習する
2.照度センサモジュールを動かすスケッチを描く
3.照度センサモジュールからデータを取得する

いつものように、遊ぶことが重要です。

 

照度センサモジュール(BH1750FVI)」ですが、I2C通信にて制御します。

BH1750FVIのデータシートを参照することで制御方法はわかります。

 

本Lessonでは、Arduino標準ライブラリである「Wire.h」を使用します。

I2Cと言えば、Wire.hと覚えておくと良いと思います。

I2C通信って何?という方は下記で解説しています。

本Lessonを始める前に読んでおくと取り組みやすいと思います。

 

準備

ではLessonの準備に取り掛かりましょう。

電子部品は照度センサモジュール(BH1750FVI)のみ。

 

必要なもの

※ブレッドボードはセンサとUNOを直接つなぐ場合不要です。
※ジャンパワイヤーは「M-M」「M-F」を必要に応じて使い分けてください。

 

Jumper wire、抵抗は今後も頻繁に利用します。

Jumper wireはできれば、「オス-メス オス-オス メス –メス」の3種類を揃えておくことをお勧めします。

短めが使いやすい場合も。

 

抵抗も単品で揃えるよりはセットをおすすめします。

 

抵抗、LEDなどを個別でセット品を購入しても、そんなに使わない!

という方は、「電子工作基本部品セット」が使い勝手が良い。

 

使用部品説明

照度センサモジュール(BH1750FVI)について説明していきます。

 

「照度センサモジュール(BH1750FVI)」 実物写真

下の写真が照度センサモジュール(BH1750FVI)の実物写真です。

本Lessonで使用するものは、BH1750FVIが実装されたモジュール。

 

照度センサモジュール(BH1750FVI)実物写真

信号ピン(左側から):GNDADD、SDA、SCL、VCCとなっています。

ArduinoのI2C通信を利用する場合、Arduinoと照度センサモジュールの対応ピンは以下となります。

アナログ入力ピンのA4、A5がI2Cに割り当てられています。

温度センサモジュール(MAX6675) Arduino
GND GND
VCC 5V
ADD
基板上でGNDにプルダウン
H:0101_1100(0x5C)@DataSheet
L:0010_0011(0x23)@DataSheet
SDA A4(アナログ入力ピン)
SCL A5(アナログ入力ピン)

 

■BH1750FVI 実物写真

arduino-lesson71-01

 

照度センサモジュール(BH1750FVI) 回路図

照度センサモジュール(BH1750FVI)の回路図(ブロックダイアグラム)を示します。

回路に興味がないかたは必ず読み飛ばしてください。

 

BH1750FVI ブロックダイアグラム

省略:データシートに記載されていますので省略します。

フォトダイオード AMP ADC 論理+I2Cの回路となっています。

 

温度センサモジュール(BH1750FVI)の回路図

気が向いたら起こす予定・・・。

arduino-lesson71-02

 

回路としては下記が実装されています。

  • 3.3Vのレギュレータ(662K)
  • PNPバイポーラトランジスタ
  • ショットキーダイオード

そのほか、ADDはプルダウン、BH1750FVIのVDIピンはプルアップされています。

また、BH1750FVIの最大定格は4.5V、動作条件は3.0V(Typ.)です。

Arduinoの5.0Vはそのまま使用できません。

ただし、本Lessonで使用するBH1750が実装されたモジュールは、レギュレータ、ショットキーダイオードを使用することで3.3V対応ができています。

そのまま使用可能です!

 

照度(lx)について

照度の目安はWikiを参考にしてください。

Wikipedia ルクス(lx)

ルクス(英:lux、単位記号:lx)とは、国際単位系(SI)における照度の単位である。SI組立単位「ルーメン毎平方メートル」(lm/m2)に与えられた固有の名称であり、日本の計量単位令では「1平方メートルの面が1ルーメンの光束で照らされる時の照度」と定義されている。

 

照度センサモジュール(BH1750FVI) 仕様

遊び、学習で使う分には気にする特性はとくにありません。

ただしI2C通信にて動作させるためにはある程度データシートを読んで理解する必要があります。

■Pin仕様(BH1750FVI)

arduino-lesson71-03

Pin Name Function
1 VCC Power Supply
2 ADDR I2C Slave Address
ADDR = H “1011100”
ADDR =  L “0100011”
3 GND GND
4 SDA I2C SDA
5 DVI SDA、SCL リファレンス電圧
6 SCL I2C SCL

 

■仕様抜粋(BH1750FVI 動作電圧・電流・温度など)

・絶対最大定格(この範囲外で使うと壊れる可能性がある規格)

項目 仕様
最大定格 電圧 4.5 V
動作温度範囲 -40℃ ~ 85℃
保存温度範囲 -40℃ ~ 100℃
SDA流入電流 7 mA
許容損失 165 mW

 

・動作条件(通常使う範囲)

項目 仕様
電源電圧 3.0 V(Typ.)
I2Cバス リファレンス電圧 1.65(min.)

 

■照度換算に必要な値をデータシートから抜粋

データシートからは下記を読み取ります。

  • 測定確度
  • 暗状態出力
  • 選択モードの分解能
項目 仕様
Measurement Accuracy 1.2(Typ.) Sensor out / Actual lx
EV=1000lx
※光源は疑似白色を使用する
※受光部の入力光減衰補正機能でSensor out / Actual lxのTypを”1″に調整可能
Dark(0 lx)Sensor out 0(Typ.)
※10lx以下の照度データ必要な場合
H-resolution modeまたはH-resolution mode2を使う
H-Resolution Mode Resolution 1 lx(Typ.)

上記から・・・

  • 計算時に1.2が必要なこと
  • 10lx以下も必要な場合はH-resolution modeを使うこと
  • H-resolution modeの分解能は1lxであること

上記をI2C通信で設定することで照度(lx)を測定することが可能となります。

 

また、シーケンスに必要なアドレス、読み出しデータのフォーマット例は以下となります。

■BH1750のH-resolution mode

ST Slave Address R/W Ack operation code Ack SP
0 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0

 

■BH1750の測定結果

ST Slave Address R/W
0 1 0 0 0 1 1 1
Ack High Byte[15:8] Ack
X X X X X X X X
Low Byte[7:0] /Ack SP
X X X X X X X X

 

上記の「High ByteとLow Byteを10進に変換し1.2で割る」ことで照度(lx)を計算することができます。

必要なことは以上でしょうか。

 

本Lessonは遊び、学習を想定しています。

Arduinoの仕様範囲内で使用していれば問題になることもありません。

遊び、学習以外での使用用途をお考えの場合はデータシートを必ず確認しましょう。

 

実践 回路作成とコード作成

最初に回路図を確認してください。

次に、回路図に合わせて部品を接続します。

最後にコードを書いて、照度センサモジュール(BH1750FVIを動かしていきましょう。

 

Arduinoのピン配置を確認したい方は番外編02を参照してください。

 

回路図

Arduinoの使用ピンは以下。

  • I2Cピン:A4(SDA)、A5(SCL)
  • 5V、GND

 

回路図がこちら。

ADDピンは基板上でプルダウンされているため接続の必要はありません。

arduino-lesson71-04

 

こちらがブレッドボード図。

arduino-lesson71-05

 

回路図は「fritzing」を利用しています。

「fritzing」の使い方は下記を参照してください。

 

接続

下図に示すように、用意した部品を使用して接続しましょう。

電子部品は照度センサモジュール(BH1750FVIのみ。

 

使用するポートは

  • I2Cピン:A4(SDA)、A5(SCL)
  • 5V、GND

穴に挿入しづらいときは、ラジオペンチなどを使用してください。

今回はブレッドボードを使わずにM-Fワイヤで接続。

手持ちのELEGOO UNOの字が使いすぎて印字の字が見えない・・・

しょうがないので手持ちのArduino UNOに変更。

arduino-lesson71-06

 

コードの書き込み

接続が終わったら、USBケーブルを使用してUNOにプログラムを書き込んで行きましょう。

コードを書き終えたら、いつでも利用できるように「ファイル」⇒「名前を付けて保存」で保存しておきましょう。

 

コマンド説明

本Lessonでは、特に新しいコマンドはありません。

復習を兼ねてI2Cのコマンドを列挙しておきます。

I2C通信は下記で解説していますので興味のある方は下記を参照ください。

コマンド 内容
Wire.begin(address) Wireライブラリの初期処理。
I2Cバスに対してマスタ、スレーブとして接続。パラメータ
address:7ビットのスレーブアドレス
省略時は、マスタとしてバスに接続されます。
Wire.reuestFrom(address,count) 通信対象となるI2Cデバイスのアドレスおよびデータ量を指定。
他のデバイスに対してデータを要求。
そのデータはabailable(),receive()関数を使って取得できます。パラメータ
address:データを要求するデバイスのアドレス(7ビット)
quantity:要求するデータのバイト数
stop:
true ⇒ I2Cバスを開放。
false ⇒ バスを開放しない。
Wire.beginTransmission(address) 指定したI2Cデバイスとの送信を開始。
指定したaddressのI2Cスレーブに対して送信処理を開始。
送信処理実行後、write()関数でデータをキューへ送り、endTransmission()で送信を実行。パラメータ
address:送信対象のアドレス(7ビット)
Wire.endTransmission() I2Cデバイスとの送信を終了します。
スレーブデバイスに対する送信を完了します。パラメータ
stop:
true ⇒ I2Cバスを開放
false ⇒ コネクションを維持戻り値
0:成功
1:バッファサイズを超える
2:スレーブ・アドレスを送信、NACKを受信
3:データ・バイトを送信、NACKを受信
4:その他エラー
Wire.write(value)
Wire.write(string)
Wire.write(data,length)
I2Cデバイスにデータを書き込む。パラメータ
value:送信するデータ(1byte)
string:文字列(char)
data:配列(byte)
length:送信するバイト数(byte)
戻り値:送信したバイト数(byte)
Wire.available() 読み込み可能なデータ量を取得。
read()で読み取るバイト数を返します。戻り値
読み取り可能なバイト数
Wire.read() I2Cデバイスからのデータ読み取り。
戻り値
受信データ(byte)
Wire.onReceive(handler) マスターからデータが送られてきたときに呼び出す関数を指定。
パラメータ
handler:スレーブがデータを受信したときに呼ばれる関数名
Wire.onRequest(handler) マスターから割込みした際に呼び出す関数を指定。
パラメータ
handler:呼ばれる関数名

 

サンプルコード

仕様からデバイスのアドレス、レジスタのリセット、モード設定がわかっていますので設定します。

■デバイスのアドレス設定
int BH1750_addr = 0x23; // @ADD = L i2cデバイス(BH7150)のAddresse
■レジスタのリセット
Wire.beginTransmission(BH1750_addr);
Wire.write(0x07); // Reset Data register
Wire.endTransmission();
■H-resolution mode設定
Wire.beginTransmission(BH1750_addr);
Wire.write(0x10); // H-resolution mode設定
Wire.endTransmission();

 

//Lesson 70 照度センサモジュール(BH1750)
//BH1750 ICが実装されたモジュールを使用して照度を測定
//通信はI2C
//https://omoroya.com/

#include <Wire.h>       // I2C通信するためのライブラリ

int BH1750_addr = 0x23; // @ADD = L i2cデバイス(BH7150)のAddresse
byte buff[2];

void setup(){
  Wire.begin(); 

  Wire.beginTransmission(BH1750_addr); // 指定したアドレスのI2Cスレーブに対して送信処理開始
  Wire.write(0x07);                    // Reset Data register
  Wire.endTransmission();              // I2Cデバイスとの送信を終了

  Wire.beginTransmission(BH1750_addr); // 指定したアドレスのI2Cスレーブに対して送信処理開始
  Wire.write(0x10);                    // H-resolution mode設定
  Wire.endTransmission();              // I2Cデバイスとの送信を終了
  
  delay(200);                          // update 120ms以上@DataSheet
  Serial.begin(9600);
  Serial.println("Start!");
}

void loop(){
  
  float valf = 0;
  int   i = 0;
  
  Wire.beginTransmission(BH1750_addr);   // 指定したアドレスのI2Cスレーブに対して送信処理開始
  Wire.requestFrom(BH1750_addr, 2);      // I2Cデバイスのアドレスおよびデータ量を指定
  
  //2byte読み取り
  while(Wire.available()){
    buff[i] = Wire.read();
    i++;
  }
  
  Wire.endTransmission();                // I2Cデバイスとの送信を終了
    
  Serial.print("read data:");
  Serial.print(buff[0],BIN);           // 読み出した生値を参考に 上位8bit 2進表示 
  Serial.print("_");                   // 
  Serial.println(buff[1],BIN);         // 読み出した生値を参考に 下位8bit 2進表示
  
  valf=((buff[0]<<8)|buff[1]);         // buff[0]を8bitシフトしてbuff[1]とor取り2byteデータに変換
  valf = valf/1.2;                     // Measurement Accuracy 1.2倍@Typ.(@DataSheet)
  
  if(valf<0){ Serial.print("> 65535:Overflow"); // Overflowを表示(測定範囲 1 ~ 65535 lx @DataSheet)
  }
  else{
    Serial.print((int)valf,DEC);       // 整数および10進表示←分解能は1@DataSheet
  }
  Serial.println(" lx"); 
  
  delay(1000);                           // update 120ms以上@DataSheet
  
}

 

動作確認

では、さっそく動作を確認していきます。

シリアルモニタを開いて読みだしたデータをみてみましょう。

 

■暗闇

電気を消して、真っ暗にしています。

arduino-lesson71-07

 

■我が家の蛍光灯

arduino-lesson71-08

 

■ちょっと強めのライト

arduino-lesson71-09

 

■ライトを近づけすぎると・・・

見事にOverflow11111111_11111111」になっているのがわかります。

arduino-lesson71-10

 

いい感じで照度(lx)が測定できています!

 

まとめ

本Lessonは、以下を目標としました。

1.照度センサモジュール、BH1750の使い方を学習する
2.照度センサモジュールを動かすスケッチを描く
3.照度センサモジュールからデータを取得する

 

照度センサモジュール(BH1750FVI搭載)は手軽に広範囲の照度を測定することができます。

照度(lx)によって何かをさせたいというときに色々と使え道がありそうなセンサです。

いろんなものを制御して遊びましょう。

 

Lesson 71 【照度センサモジュール】 はここまで。

疑問点、質問などありましたら気軽にコメントください。

 

次回、Lesson 72は【照度センサモジュール】です。

Arduino 入門 Lesson 72 【非侵襲性AC電流センサ】
センサーの使い方の基本を学習する入門編。本Lessonの電子部品はAC電流センサ(SCT-013-030)。このセンサとArduinoを使用することで家庭のAC電流を測定することが可能です。また「SCT-013-030」は非侵襲性。測定対象…

 

最後に

疑問点、質問などありましたら気軽にコメントください。

この電子部品の解説をしてほしい!などなどなんでもOKです。

リンク切れ、間違いなどあればコメントいただけると助かります。

 

Arduino入門編、番外編、お役立ち情報などなどサイトマップで記事一覧をぜひご確認ください。

 

Arduino入門編Arduino入門編2で使用しているUNOはAmazonにて購入可能です。

Arduino入門編では互換品を使用。

Arduinoはオープンソース。

複製して販売するのもライセンス的に問題なし。

 

そのため互換品の品質も悪くなく、それでいて値段は安いです。

正規品本体の値段程度で豊富な部品が多数ついています。

 

学習用、遊び用、お試し用には安価な互換品がおすすめです。

 

上記のものでも十分に多数の部品が入っていますが、最初からもっと多数の部品が入っているこちらもお勧めです。

 

Arduino入門編2では「Arduino UNO R4 Minima」「Arduino UNO R4 WIFI」にて遊ぶため今のところは正規品を使用。(まだ互換品が・・・ほぼない)

 

Amazonでお得に買う方法

Amazonでお得に購入するならAmazon MastercardAmazonギフト券がおすすめです。

時期により異なりますが、様々なキャンペーンを実施しています。

\Amazonギフト券/
Amazonギフトカード キャンペーン

Amazon Mastercard お申込み
Amazon Mastercard 申し込み 

 

いずれの場合もプライム会員である方がお得!!

\Amazon Prime 30日間の無料会員を試す/
無料会員登録 

 

 

コメント

タイトルとURLをコピーしました