赤外線アレイセンサ(AMG8833)を使って、非接触体温計に挑戦 ~前編~

最近は、新型コロナの影響で体温を測る機会が増えてきました。人との接触を最小限にして、短時間で検温するには、赤外線を使った検温システムが必要になると思い、赤外線アレイセンサ(AMG8833)を使って、非接触型の体温計に挑戦したので紹介します。

システム構成

今回の考えたシステム構成は以下です。

赤外線アレイセンサは、安価で入手しやすさを考慮して「AMG8833(愛称:Grid-EYE)」を使用しました。顔認証用のカメラとサーモセンサの表示を組み合わせて、面白いシステムができないかと考えてみました。

赤外線アレイセンサを使った非接触体温計システムの構成

基板配線図

AMG8833とラズパイの基板配線は以下です。

AMG8833端子ラズパイ(GPIO端子)
VDD1番ピン (3.3V)
GND6番ピン (GND)
INT
SCL5番ピン (GPIO3)
SDA3番ピン (GPIO2)


AMG8833とラズパイの接続図

AMG8833のデータシートに記載されたいた推奨回路です。今回購入した基板には、AD_SELECTの端子はなかったので、スレーブアドレスは0x68固定のようです。

ちなみに、AD_SELECT端子があると、接続をVDD/GNDに切り替えることで、スレーブアドレスを選択できるようです。

・スレーブアドレス:0x68の場合(AD_SELECT端子がGNDに接続)

スレーブアドレス:0x68の場合のAMG8833推奨回路

・スレーブアドレス:0x69の場合(AD_SELECT端子がVDDに接続)

スレーブアドレス:0x69の場合のAMG8833推奨回路

ラズパイ側の設定&インストール

まずは、ラズパイのI2C端子を有効にします。

$ sudo raspi-config

「5 Interfacing Options」⇒「P5 I2C」⇒「はい」の順に選択します。

赤外線アレイセンサ(AMG8833)を接続して、i2cdetect コマンドを使って接続確認を行います。スキャン対象のアドレスを指定しない場合は、スレーブアドレスの0x03~0x77までをスキャンして応答があったものを表示してくれます。0x68か0x69アドレスの応答が返ってくると思います。

$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Adafruit社から提供されている「adafruit-circuitpython-amg88xx」をダウンロードしてインストールします。

$  sudo pip3 install adafruit-circuitpython-amg88xx

以上でラズパイ側の設定&インストールは完了です。

赤外線アレイセンサ(AMG8833)の確認

データシートからAMG8833のブロック図を見てみました。

AMG8833の内部ブロック図

さっと見てみると、サーミスタレジスタと温度レジスタの変換方法が記載されていました。

0x0E, 0x0F番地がサーミスタの出力値が入っています。

サーミスタ温度は、出力値×0.0625℃で温度データに換算できるようです。

サーミスタレジスタの変換方法について(AMG8833データシートより)
$ python
Python 2.7.16 (default, Oct 10 2019, 22:02:15)
[GCC 8.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import smbus
>>> i2c = smbus.SMBus(1)
>>> temp = i2c.read_word_data(0x68, 0x0E)
>>> temp * 0.0625
28.375

0x80番地以降に各画素の温度データが入っています。

温度レジスタは、出力値×0.25℃で温度データに換算できるようです。

温度レジスタの変換方法について(AMG8833データシートより)
$ python
Python 2.7.16 (default, Oct 10 2019, 22:02:15)
[GCC 8.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import smbus
>>> i2c = smbus.SMBus(1)
>>> temp = i2c.read_word_data(0x68, 0x80)
>>> temp * 0.25
22.75

なんか、いい感じの値(温度データ)になっていますね。

ただ、距離が離れると若干低い温度になるようです。ここらあたりのキャリブレーションが必要そうです・・・

「adafruit-circuitpython-amg88xx」を使うと、この値を計算して、温度データとして配列に格納してくれるみたいです。

せっかくなので、このライブラリを使って、GUI画面で確認できるようにしてみました。

左側にサーモグラフィ、右側にカメラ映像を表示して、映像を見ながらサーモセンサからの温度を確認できます。

温度確認用のGUI画面

使用したプログラムは以下です。

# -*t  coding: utf-8 -*-
import time
import busio
import board
import cv2
import numpy as np
from PIL import Image

import adafruit_amg88xx

import matplotlib.pyplot as plt

plt.ion()
plt.subplots(figsize=(8, 4))

# I2Cバスの初期化
i2c_bus = busio.I2C(board.SCL, board.SDA)

# カメラ設定
cam = cv2.VideoCapture(0)

# 画像サイズを設定(640x480)
cam.set(3, 640) # set video widht
cam.set(4, 480) # set video height

try:
    while True:
        # センサーの初期化:I2Cスレーブアドレス(0x68)
        sensor = adafruit_amg88xx.AMG88XX(i2c_bus, addr=0x68)

        # センサーの初期化待ち
        time.sleep(.1)

        # 画像の読み込み
        ret, img =cam.read()
        # matplotlibで表示のためBGR画像をRGBに変換
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 
        #img = cv2.flip(img, -1) # 映像を上下左右反転

        ## 8x8センサアレイ内の最大温度を取得
        max_temp = max(max(sensor.pixels))

        # 画面の左側にサーモグラフィを表示 

        plt.subplot(1,2,1)
        plt.imshow(sensor.pixels, cmap="inferno", interpolation="bicubic",vmin=25,vmax=37)
        plt.colorbar()
        plt.show

        # 画面の右側にカメラ映像をを表示 
        plt.subplot(1,2,2)
        plt.imshow(img)
        plt.text(0, 0, str(max_temp) + 'deg',size = 14, color = "red")
        plt.draw()
        plt.pause(0.01)
        plt.clf()

except KeyboardInterrupt:
    print("finish")

サーモセンサの画角調整や、温度データのキャリブレーション方法を検討しないといけないですね。

ちょっと思案中・・・・

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA