フォトトランジスタ(NJL7502L)を使って照度を測ります。
デバイスはM5stack ATOM Lite(ESP32-PICO搭載)で、プログラムはMicroPythonを使います。
■ フォトトランジスタ
使用した照度センサーは下記のフォトトランジスタ。
照度センサ(フォトトランジスタ) 560nm NJL7502L (2個入) ¥100
https://akizukidenshi.com/catalog/g/gI-02325/
データシート
https://akizukidenshi.com/download/NJL7502L.pdf
ピ-ク感度波長560nmで、人の目の感度がたかい波長を合わせてある製品です。
さて、データシートにはA光源と白色LEDのデータがありますが、どちらを使えばいいのだろう?
A光源とは、CIE(国際照明委員会)によって定められた人工光源で、相関色温度2,855.6Kのタングステン電球とのことらしい。
太陽光、A光源、白色LEDのそれぞれのスペクトルは、下記のサイトで見られます。
白色光とは
https://opticaltale.blogspot.com/2020_10_20_archive.html
今回、照度を植物育成環境のデータの一つにしたい思惑があるので、波長的に白色LEDが太陽光に近い気がするので、白色LEDの方のデータを使用することにしました。
照度と電流の相関については、5Vで100Luxの照度の時に33uAの電流が流れ、1倍の比例関係にあるので、電流と照度の関係式は下式になります。
lux = I/(0.33*10**-6)
■ 照度の取得
フォトトランジスタは照度に応じた電流を通すので、所定の抵抗を直列に繋いで、その抵抗を通過した時の電圧を図ることで、オームの法則から電流を測り、関係式から照度を得ます。
下記のサイトを参考にさせてもらいました。
【ラズパイ】照度センサ(フォトトランジスタ)と温度センサ(TMP36)
https://101010.fun/iot/raspberry-pi-photo-temp.html
回路図
Rは1kΩにしました。
この時の照度の算出は下式。
Lux = Vout / R / (0.33*(10**-6))
抵抗の決め方としては、10,000Luxを測定範囲とするとき、流れる電流は10,000(Lux) x 0.33*10^-6 = 3.3mAになるので、その時に測定する電圧を3.3Vとしたいのであれば、3.3V/3.3mA = 1kΩ、みたいに決めれます。
ただこれをATOM LiteのADコンバータで測ると、光を直射する以外は0になります。テスターで電圧を確認するとフォトトランジスタが反応していないわけではなく、ATOM(ESP32)のADコンバータは、0〜0.15Vくらいは不感帯で測定できないためでした。
この範囲を無視してもいいのですが、並列抵抗を加えることで、電圧範囲を調整する事にしました。
回路図
R1は10kΩ、R2は1kΩにしました。
この時の照度の算出は下式になります。
I = min(Vout/R2-(Vcc-Vout)/R1,0.0033) lux = I/(0.33*10**-6)
0luxの時の電圧は下式で、
Vmin = R1/(R1+R2)*Vcc
今回の設定では、1k/(1k+10k)*3.3V = 0.3Vになります。
Voutの最大電圧ですが、フォトトランジスタに日光の直射日射が当たった状態、おそらく最大電流が流れている状態でも2.8Vでした。フォトトランジスタに、3.3-2.8=0.5V の電圧がかかってることになります。
理由はよくわかりませんが、普通のトランジスタをオンにするときに必要な電圧って0.7Vくらいらしいので、0.5V以下では、電流を流すことができずそんな感じになるんではないかと。よって、MaxはVcc-0.5Vくらいに考えるといいかもしれません。
ATOM Lite(ESP32-PICO)の線形範囲の電圧測定範囲は、0.15V~2.45V(11dB設定時)なので、10,000ルクスの時に、2.45Vにするなら、ホントはR2は720Ωが良いですが、丁度良い手持ちの抵抗がないので、今回は上記の設定でやりました。
ソースコード(MicroPython)
import machine Vcc = 3.2 R1 = 10000 R2 = 1000 adc = machine.ADC(machine.Pin(33)) adc.atten(machine.ADC.ATTN_11DB) Vout = adc.read_u16()* 5.326e-5 + 0.1276 I = min(Vout/R2-(Vcc-Vout)/R1,0.0033) lux = I/(0.33*10**-6) print('Vout:' + str(Vout)) print('I: '+str(I)) print('lux: ' + str(lux))
■ 入射角と温度の補正
データシートを見ると、指向性があり、入射角に応じてレスポンスが変わります。また、温度依存性もある。
これらを考慮する必要性がある場面は少ないかもしれませんが、これらを補正できるように関係式を出してみます。
ちなみに、データはデータシートのグラフ画像からの読み取りなので大体です。
入射角の関係式
【2直線】
最初は、正規分布っぽいなっと思って近似させてみたのですが、対して精度が良くなく、式の単純な2直線で良いような気がして、そちらを先に示します。
35度を分岐点にして各式は以下になります。
if deg < 35: y = -0.023*x+1.0 else: y = -0.003*x+0.3
精度は、まぁそこそこ。
【正規分布】
最初にやった正規分布の近似です。
それだけだと、40度以上の部分が合わなかったので、40度以上から直線式に場合分けしました。
40度以内
y = 40 * f(x) + 0.1
u=0、σ2=300
40度以上
y = -0.003 * x + 0.3
パラメータは手動で調整していったので、ある程度のところで。
温度の関係式
White LED
y = 0.0056 * x + 0.8607
今度、フォトトランジスタの測定値を日射量として使う試みをする予定です。