【Raspberry Pi】照度センサ(フォトトランジスタ)と温度センサ(TMP36)

【Raspberry Pi】照度センサ(フォトトランジスタ)と温度センサ(TMP36)
【Raspberry Pi】照度センサ(フォトトランジスタ)と温度センサ(TMP36)

今回はRaspberry Piで、光の強さを測定できる照度計と温度計の使い方を解説していく。照度センサはフォトトランジスタの NJL7502L 、温度センサは TMP36 を使った。どちらもアナログセンサなので、2チャネルのADコンバータMAX1118を使う。なお、MAX1118の使い方は Raspberry PiでSPI通信できるようにする設定【ADコンバータMAX1118】 を参考に。

照度センサ (NJL7502L)

NJL7502Lのデータシートはこちら NJL7502Lデータシート - 秋月電子通商

NJL7502Lの構造
NJL7502Lの構造

フォトトランジスタの出力電圧を測定するために組んだ回路図は次のとおり。Raspberry Piの+3.3V電源を NJL7502L のコレクタ(2番)につなぐ。エミッター(1番)には1kΩの負荷抵抗Rを通してグランドへつなぎ、抵抗Rにかかる電圧を照度センサの出力電圧として MAX1118 のCH0へ接続した。

フォトトランジスタの回路例
フォトトランジスタの回路例

さて、NJL7502Lのデータシートから照度と電流のグラフを確認すると、100Luxの時33μA電流が流れるようになっている。照度と電流は比例関係にあり1000Luxの時330μAの電流が流れると言う具合に、照度が10倍になれば電流も10倍流れる関係になっている。

フォトトランジスタの照度と電流の関係グラフ
フォトトランジスタの照度と電流の関係グラフ

照度をL、電流をIとして、グラフの関係を数式に表すと次のようになる。

$$I = a \times L + b\tag{1}$$

100Luxの時33μA、1000Luxの時330μAより、a、bは次のように求められる。

$$a = 0.33 \times 10^{-6}$$ $$ I = 0.33 \times 10^{-6} \times L\tag{2}$$

これを(1)式に当てはめると、

$$I = \frac{Vout}{R}\tag{3}$$

となる。

ところで、抵抗Rにも電流Iが流れるので電圧Voutは、オームの法則より

$$ \frac{Vout}{1 \times 10^3} = 0.33 \times 10^{-6} \times L$$

の関係になる。

また、R=1kΩであるから、(3)式を(2)式に代入すると、

$$ L = \frac{Vout}{0.33} \times 10^3\tag{4}$$

となる。

これを展開して次の式となり、電圧Voutから照度Lを計算できるようになる。

$$T = \frac{Vout - 0.75}{0.01} + 25$$

温度センサ (TMP36)

TMP36のデータシートはこちら。 TMP36データシート

TMP36のピン役割
TMP36のピン役割

TMP36を使ったアナログ出力の回路図は次のようになる。+VsはRaspberry Piの+3.3V電源に接続、Voutは MAX1118 のCH1へつないだ。また、+VsとGNDの間の0.1μFは安定化させるためのおまじない。入れておこう。

TMP36の回路例
TMP36の回路例

さて、TMP36は、電源電圧が2.7〜5.5Vの範囲で動作する。+25℃の時、Voutからは750mV出力され、1℃上がるごとに10mV出力電圧が上がっていく。よって、ADコンバータで TMP36 のVoutを検知できれば、次の簡単な式で温度Tが導き出される。

$$ΔV = \frac{3}{125 - (-40)} = 0.018$$ TMP36 の測定できる温度は−40°C〜+125°Cとなっている。また精度は±1℃である。基準電圧を3Vとした場合、1℃の変化を測定できる出力電圧の最小単位ΔVは次の計算から導き出される。

$$ΔV = \frac{3}{125 - (-40)} = 0.018$$

つまり、1℃の変化を検知するのに、18mVの変化をADコンバータ側で検知できればよい。max1118 の分解能は8bitなので、リファレンス電圧を仮に3Vとして、256で割れば12mVが導き出される。これは TMP36 の分解能18mVより小さいので、max1118 の組み合わせで十分だと言える。

照度と温度を測定するPythonプログラム

ADコンバータ MAX1118 へ次にように接続して、プログラムを組んでいく。

MAX1118名称役割接続先
1Vdd正電源電圧+5V
2Ch0アナログ電圧入力NJL7502L
3Ch1アナログ電圧入力TMP36
4GNDグランドGND
5(REF)I.Cリファレンス入力3.3V
6CNVST変換/スタート入力SPIO CS0 (GPIO 8)
7DOUTシリアルデータ出力SPIO MISO (GPIO 9)
8SCLKシリアルクロックSPIO SCLK (GPIO 11)

照度と温度を測定するPythonプログラムがこちら。

py
# -*- coding: utf-8 -*-

import spidev
import time
import RPi.GPIO as GPIO

# MAX1118データシート
# http://akizukidenshi.com/download/ds/maxim/max111x.pdf
#
# NJL7502L
# http://akizukidenshi.com/download/NJL7502L.pdf
#
# TMP36
# https://www.analog.com/media/jp/technical-documentation/data-sheets/TMP35_36_37_jp.pdf

Vref = 3.335  # Raspberry Piの3.3V電源をテスターで実測

GPIO.setmode(GPIO.BCM)
GPIO.setup(8, GPIO.OUT)  # CNVST

spi = spidev.SpiDev()
spi.open(0, 0)  # bus0,cs0
spi.no_cs = True  # CSを使わない
spi.max_speed_hz = 1000000  # 1MHz
spi.bits_per_word = 8

def sendCNVST(CH):
    if CH == 0:
        GPIO.output(8, GPIO.LOW)
        GPIO.output(8, GPIO.HIGH)
        GPIO.output(8, GPIO.LOW)
    elif CH == 1:
        GPIO.output(8, GPIO.LOW)
        GPIO.output(8, GPIO.HIGH)
        GPIO.output(8, GPIO.LOW)
        GPIO.output(8, GPIO.HIGH)
        GPIO.output(8, GPIO.LOW)

def getVolts():
    adc = spi.xfer2([0x00])
    return adc[0] / 255.0 * Vref

time.sleep(1.0)

try:
    while True:
        sendCNVST(0)
        v0 = getVolts()
        lux = v0 / 0.33 * 1000

        time.sleep(0.1)

        sendCNVST(1)
        v1 = getVolts()
        temp = (v1 - 0.75) / 0.01 + 25.0
        # 25C = 0.75V
        # 10mV/C

        print("Lux: {:.0f}Lux (ch0: {:.3f}V)".format(lux, v0))
        print("Temp: {:.0f}C (ch1: {:.3f}V)".format(temp, v1))

        time.sleep(1.0)

except KeyboardInterrupt:
    spi.close()
    GPIO.cleanup()

Ambientへデータ送信

先ほどのプログラムで取得したセンサデータを保存して、ウェブブラウザでグラフ表示できたらとても便利だ。それを可能にしてくれるのが、Ambientの無料のクラウドサービスだ。こちらの記事では、Raspberry PiからAmibentへデータを送る方法を説明している。

関連記事

最後までご覧いただきありがとうございます!

▼ 記事に関するご質問やお仕事のご相談は以下よりお願いいたします。
お問い合わせフォーム

スマート農業(スマートアグリ)で使えるセンサー
水耕栽培はじめよう!
関連記事