Raspberry Pi Pico(d_15)BH1750FVI 照度センサー
BH1750FVI GY-302モジュール(I2C)
ローム社製のBH1750FVIは環境光センサー(照度センサー)です。I2C通信で制御します。Raspberry Pi PicoでBH1750FVI搭載のGY-302モジュールを使ってみました。
ADDRの接続状態でスレーブアドレスを変更できます。’L’で0x23(35)、’H’で0x5c(92)です。
測定モードが(Continuously、One Time)×(resolution H、H2、L)の6つあります。
詳細はデータシートを参照してください。
※micro:bitの記事e_13からRaspberry Pi Picoで使えるように追記、修正等をしました。
外観
BH1750FVIモジュールHW-315の外観写真です。(以後はBH1750FVIと記載します)
接続例
BH1750FVIの電源電圧は2.4V~3.6VなのでRaspberry Pi Picoと接続できます。
I2C通信にはI2C1のSDA(GP10)SCL(GP11)を使いました。
ADDRをGNDと接続したのでスレーブアドレスは0x23(35)になります。
接続出来たらI2Cデバイスのスレーブアドレスを調べてみます。
ThonnyのShellで確認しました。
BH1750FVIのスレーブアドレスは以下のように35(0x23)でした。
>>> from machine import I2C,Pin
>>> i2c=I2C(1, scl=Pin(11), sda=Pin(10), freq=100_000)
>>> i2c.scan()
[35]
BH1750FVIの説明
データシートから抜粋してBH1750FVIの説明します。
測定モードには連続測定(Continuously)と単測定(One Time)があります。各々、解像度H(1lx)、L(4lx)、H2(0.5lx)が選択できます。測定時間はH、H2では120msec(Max 180msec)、Lで16msec(Max 24msec)です。
下表のOpecodeを送信して測定モードを設定します。
他にPower Down、Power On、Resetなどの処理がI2C送信で可能です。
※ BH1750FVIのデータシートから抜粋
単測定後はPowerDownされています。そのため再測定するには測定モードを再設定するか、PowerOn後にデータを読出しする必要があります。
※ BH1750FVIのデータシートから抜粋
測定するには下図のように
①測定モードのOpecodeを送ります(writeto)
②測定時間の待機をします。待機時間は各測定モードで変わります。
③測定データの2byteデータを受けます。(readfrom)
④ルクス計算します。16bitデータを10進数にします。高分解能H2(0.5lx)の場合は16bitデータを1bitシフト下げて10進数にします。10進数の値を1.2で割ります。
例えば、High Byte “10000011” and Low Byte is “10010000”の16bitデータなら
>>> 0b1000001110010000
33680
>>> 33680/1.2
28066.67 [ lx ]
になります。
高分解能H2モードなら
>>> 0b1000001110010000 >>1
16840
>>> 16840/1.2
14033.33 [ lx ]
になります。
※詳細はデータシートを参照ください。
スクリプト
BH1750FVIのスクリプトは以下のようにしました。
※開発環境はThonnyです。ThonnyでMicroPythonをRaspberry Pi Pico with RP2040にインストールして使っています。
pico_bh1750_01b.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from machine import I2C,Pin
import time
# BH1750FVI digital Ambient Light Sensor I2C
i2c=I2C(1, scl=Pin(11), sda=Pin(10), freq=100_000)
#ADDR='L'35(0x23) ADDR='H' 92(0x5c)
addr=0x23
# Power Down
def P_Down():
#mesure mode set
buf=bytearray(1)
buf[0]=0x00 #opecode reset 0x07
i2c.writeto(addr,buf)
# Power On
def P_On():
#mesure mode set
buf=bytearray(1)
buf[0]=0x01 #opecode reset 0x07
i2c.writeto(addr,buf)
# Reset
def D_Reset():
#mesure mode set
buf=bytearray(1)
buf[0]=0x07 #opecode reset 0x07
i2c.writeto(addr,buf)
## Mode Setting
# Measurement Mode Continue('C') Onetime('O')
# Resolution Mode High-1lx('H') High2-0.5lx('S') Low-4lx('L')
def S_Mode(con='O',res='H'):
global mode
mode=[con,res] #[Measure Mode,Resolution Mode]
if mode[0]=='C':
#Continuously
if mode[1]=='H':
wtime=200
opecode=0x10 #H-Resolution,Continuously
if mode[1]=='S':
wtime=200
opecode=0x11 #H-Resolution2,Continuously
if mode[1]=='L':
wtime=50
opecode=0x13 #L-Resolution,Continuously
if mode[0]=='O':
#One Time
if mode[1]=='H':
wtime=200
opecode=0x20 #H-Resolution,One Time
if mode[1]=='S':
wtime=200
opecode=0x21 #H-Resolution2,One Time
if mode[1]=='L':
wtime=50
opecode=0x23 #L-Resolution,One Time
# measure mode set
buf=bytearray(1)
buf[0]=opecode
i2c.writeto(addr,buf)
time.sleep_ms(wtime)
# lux measure
def L_Meas():
# H,L 2byte read data
r_data=i2c.readfrom(addr,2)
H_byte=r_data[0]
L_byte=r_data[1]
# caluculate
d_lux=H_byte << 8 | L_byte # high2-mode 0.5 lx/bit if mode[1]=='S': d_lux=d_lux >>1
lux=d_lux/1.2
return lux
## main
S_Mode('C','H')
lx=L_Meas()
print('Lux= %6.1f lx' % lx )
部分説明
■S_Mode(con=’O’,res=’H’)
測定のモードを設定します。
連続 Continue(‘C’) 単 Onetime(‘O’)
Resolution High(‘H’) High2(‘S’) Low(‘L’)
それぞれの文字を与えます。
■L_Meas()
測定したlxを返します。
■P_Down()
パワーダウンします。
■P_On()
パワーオンします。
■D_Reset()
照度データのレジスタをリセットします。
実行結果
連続の分解能Highで実行してみました。S_Mode(‘C’,’H’)
結果は以下のようになりました。※Thonnyのshellに表示されます。
>>> %Run -c $EDITOR_CONTENT
Lux= 1025.8 lx
>>>
次に、リセット動作を確認しました。Thonnyのshellで続けて実行しで確認しました。
>>> mode # スクリプト実行後なので
['C', 'H'] # 連続の分解能High
>>> D_Reset() # レジスタのリセット
>>> i2c.readfrom(addr,2)
b'\x00\x00' # リセットされている
>>> S_Mode('O','H') # 単発の分解能Highに変更
>>> L_Meas()
1025.0 # 照度測定値
>>> D_Reset() # レジスタのリセット
>>> i2c.readfrom(addr,2)
b'\x04\xce' # リセットされていない(単測定後はPower Downのため)
>>> P_On() # Power On
>>> D_Reset() # レジスタのリセット
>>> i2c.readfrom(addr,2)
b'\x00\x00' # リセットされた
まとめ
Raspberry Pi PicoでBH1750FVIを使って照度測定ができました。