1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ラズパイとA/D変換モジュール ADPiで熱電対を用いた簡易温度計測

Last updated at Posted at 2025-11-04

はじめに

今回は、弊社製品のメタルケースセット(ADPi Pro + slee-Pi 3)を使用し、熱電対を用いた簡易温度計測の方法をご紹介します。

メタルケースセット(ADPi Pro + slee-Pi 3)には、Raspberry Pi 4 Model Bと、高精度A/D変換モジュールのADPi Proと、電源管理/死活監視モジュールのslee-Pi 3が搭載されています。さらに、環境構築済みSDカードやACアダプタ等も付属しており、すぐにお使いいただくことが可能です。

また、熱電対による温度計測では基準温度(リファレンス温度)が必要となりますが、本記事ではADPi Proに搭載されているAD7794の内蔵温度センサーを基準温度として使用します。
なお、この温度センサーの仕様は±2℃の精度となっているため、より高精度な計測が必要な場合は、別途基準温度を取得できるセンサー等のご用意をおすすめいたします。

ADPi Proは単体での使用も可能ですが、電源ノイズの低減やラズベリーパイへの安定した電源供給のためにslee-Pi 3との併用を推奨します。さらにslee-Pi 3の死活監視機能により、長期運用時の信頼性も向上します。
そこで本記事では、これらがセット構成となったメタルケースセット(ADPi Pro + slee-Pi 3)を使用しています。

使うもの

image.png

ハードウェア

image.png
メタルケースセットのカバーを外し、CH1~CH4のターミナルを外します。

PXL_20251028_094629253.MP.jpg
各CHのターミナルは、図の向きのとき上から順に 12V/CH+/CH−/GND となっています。熱電対は CH+ と CH− に接続してください。

PXL_20251028_094720688.MP.jpg
熱電対を接続したCH1~CH4のターミナルをADPi Proに差し込みます。また、付属のDCジャック - XHP-2コネクタ変換ハーネスslee-Pi 3のCN1に取り付け、付属のACアダプタから電源を投入します。

ソフトウェア

電源を投入し、ラズパイが起動したらPCからログインしてください。初期ログイン情報はこちらを参照してください。ラズパイへのログイン方法についてはこちらなどを参照してください。

任意のディレクトリに移動し、以下のスクリプト(temp_logger.py)を作成します。本記事では /home/mtx/adpi-thermocouple-logger に作成しました。ディレクトリを変更する場合は、スクリプト内の DIR = の値も合わせて変更してください。

今回は熱電対での計測に合わせ、サンプリング周波数を4 Hz、ゲイン倍率を128としています。設定可能なパラメータについてはこちらを参照してください。

また、T型以外の熱電対を使用する場合はTHERMOCOUPLE_TYPE = 'T'を変更してください。本記事では、熱起電力から温度への変換にはthermocouples_referenceライブラリを使用しています。詳細はこちらからご確認ください。

temp_logger.py

#!/usr/bin/python3

import spidev
import smbus
import adpi
import time
import csv
from datetime import datetime
from time import sleep
from thermocouples_reference import thermocouples # ITS-90準拠の熱電対用ライブラリ

DIR = '/home/mtx/adpi-thermocouple-logger'
THERMOCOUPLE_TYPE = 'T'

RAW_OFFSET = (1 << 23) # AD7794の24bit ADC出力(2の補数形式)で0Vに相当する値(=8388608)
RAW_SCALE = (
    0.000596040,
    0.000298020,
    0.000149010,
    0.000074500,
    0.000037250,
    0.000018620,
    0.000009310,
    0.000004650,
) # AD7794のゲインごとの1bitあたりの電圧換算係数(mV/LSB)

def v2k(rate, val):
    for k, v in rate.items():
        if v == val:
            return k

def set_calib(dev):
    g = dev.adc.gain['128']
    r = dev.adc.rate['4']
    bias = dev.load_bias(g)
    scale = dev.load_scale(g)
    _, r = dev.read_mode()
    for i in range(dev.channels):
        dev.write_configuration(g, i)
        dev.write_mode(dev.adc.mode['idle'], r)
        dev.write_offset(bias[i])
        dev.write_mode(dev.adc.mode['idle'], r)
        dev.write_fullscale(scale[i])

def single_conversion(dev, ch):
    c = dev.adc.channel[ch]
    g, _ = dev.read_configuration()
    dev.write_configuration(g, c)
    _, r = dev.read_mode()
    dev.write_mode(dev.adc.mode['single'], r)
    rate = v2k(dev.adc.rate, r)

    while True:
        sleep(2 * 1.0 / float(rate))
        if not dev.read_status() & 0x80:
            break

    raw = dev.read_data()
    return raw, g

def get_voltage(dev, ch):
    raw, g = single_conversion(dev, ch)
    vol = RAW_SCALE[g] * (raw - RAW_OFFSET) / (1 << g)
    return float(vol)

def get_temperature(dev):
    raw, _ = single_conversion(dev, 'temp')
    temp = 1170.0 * (raw - RAW_OFFSET) / (2 ** 23) / 0.81 - 273.15
    return float(temp)

def calc_thermocouple(dev, ch, temp):
    tc = thermocouples[THERMOCOUPLE_TYPE]
    E_meas = get_voltage(dev, ch)
    T_hj = tc.inverse_CmV(E_meas, Tref=temp)
    return float(T_hj)


if __name__ == "__main__":
    spibus = 0
    spics = 0
    eeprombus = 1
    eepromaddr = 0x57
    gpiobus = 1
    gpioaddr = 0x27
    spi = spidev.SpiDev()
    i2c = smbus.SMBus(eeprombus)

    timestamp = datetime.now().strftime("%Y%m%d_%H%M")
    csv_path = f"{DIR}/temp_log_{timestamp}.csv"

    try:
        spi.open(spibus, spics)
        spi.mode = 0b11
        spi.max_speed_hz = 1000000
        ad = adpi.ADPiPro(spi, i2c, eepromaddr, gpioaddr)
        set_calib(ad)
        sleep(0.5)

        with open(csv_path, "w", newline="") as f:
            writer = csv.writer(f)
            writer.writerow(["timestamp", "CH1[℃]", "CH2[℃]", "CH3[℃]", "CH4[℃]"])
        
            while True:
                timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                T_cj = get_temperature(ad)

                T1 = calc_thermocouple(ad, '1', T_cj)
                T2 = calc_thermocouple(ad, '2', T_cj)
                T3 = calc_thermocouple(ad, '3', T_cj)
                T4 = calc_thermocouple(ad, '4', T_cj)

                print(timestamp, T1, T2, T3, T4)
                writer.writerow([timestamp, T1, T2, T3, T4])

                sleep(1.0)

    except KeyboardInterrupt:
        pass
    finally:
        spi.close()
        i2c.close()

次に、Pythonモジュールを実行するための仮想環境を構築します。以下のコマンドを/home/mtx/adpi-thermocouple-loggerで実行してください。

python3 -m venv venv
source venv/bin/activate
pip install "numpy==1.26.4" "scipy==1.12.0" thermocouples_reference spidev smbus
cp -r /usr/lib/python3/dist-packages/adpi ~/adpi-thermocouple-logger/venv/lib/python3.11/site-packages/

インストールが完了したら、以下のコマンドを実行してスクリプトを起動します(仮想環境内で実行してください)。

python3 temp_logger.py

下記のようなCSVファイルが作成されます。
image.png

作成したスクリプト(temp_logger.py)は、仮想環境で実行してください。仮想環境を有効にするにはディレクトリを移動後、source venv/bin/activateを実行します。仮想環境を終了するにはdeactivateを実行します。

まとめ

今回は弊社製品のメタルケースセット(ADPi Pro + slee-Pi 3)を使用し、熱電対を用いた簡易温度計測の方法をご紹介しました。
ADPi Proを利用することで、ラズベリーパイ上で手軽に高精度なアナログセンサ計測が可能になります。ぜひお試しください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?