ADPi とクランプ式 CT センサで電流計測

[メカトラックス](https://mechatrax.com/)の[maeda01](https://qiita.com/maeda01)です。

本記事は Raspberry Pi 用高精度 A/D 変換モジュールである ADPi Pro (以下 ADPi) の使用例として、 CT (Current Transformer) センサを接続して電流値を計測してみる というものになります。


# 今回使用するもの
* Raspberry Pi 3 Model B
* micro SD カード (32 GB)
* ADPi Pro
* CTL-16-CLS : 小型クランプ式交流電流センサ (株式会社ユー・アール・ディー)
* 抵抗 250 &Omega;
* slee-Pi3 : Raspberry Pi 用電源管理/死活監視モジュール (詳細は [こちら](https://mechatrax.com/products/slee-pi/))
    * slee-Pi3 は必須ではありませんが、Raspberry Pi への安定した電源供給のために使用を推奨します。
    * slee-Pi3 のセットアップについては[弊社 GitHub ページ](https://github.com/mechatrax/slee-pi3/wiki/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2#1-%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97) をご参照ください。

## ADPi Pro
弊社が販売している Raspberry Pi 用高精度 A/D 変換モジュールです。24bit 分解能の ADコンバータを使用しており、高精度で電圧計測をすることができます。今回は CT センサを1つ接続するだけなので1チャンネルしか使用しませんが、 ADPi 基板1枚につき最大4チャンネルでの計測が可能です。

ADPi の製品紹介については以下のページをご参照ください。

https://mechatrax.com/products/adpi/

ADPi の技術資料は弊社 GitHub で公開しています。

https://github.com/mechatrax/adpipro


## CTL-16-CLS
製品の詳細についてはユー・アール・ディー社のページをご覧ください。

https://www.u-rd.com/products/CTL-16-CLS.html

交流電流を測定するために使用します。
このセンサはクランプ式となっており、分電盤など既存設備への取り付けが簡単に行えます。



# OSイメージをSDカードに書き込む
Raspberry Pi Imager を使用して OS を micro SD カードに書き込んでいきます。
本記事では Raspberry Pi OS Lite (32bit) を使用します。

![OSLiteをやく.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104552/fbde3c91-e690-e134-fade-371c25174867.png)


# 必要なパッケージのインストール

以下のサイトに従って ADPi のパッケージをインストールします。

https://github.com/mechatrax/adpipro/wiki/%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97

まずはリポジトリを追加します。

```
$ curl https://mechatrax.github.io/setup.sh | sudo bash
```


パッケージのインストールを行います。
今回は SPI を使用するので以下のコマンドでパッケージをインストールします。

```
$ sudo apt update
$ sudo apt install python3-adpi adpi-utils-backend-spidev adpi-utils
```

インストールが完了したら以下のコマンドで Raspberry Pi を再起動させます。

```
$ sudo shutdown -r now
```

以上で ADPi に必要なパッケージのインストールは終了です。


# センサの接続

Raspberry Pi に slee-Pi3 と ADPi をスタックします。
次に、ADPi に CTL-16-CLS を接続していきます。
接続方法は簡単です。ADPi のターミナルブロックに CTL-16-CLS の端子を挿入してネジを閉めて固定するだけです。
CTL-16-CLS の端子は ADPi のターミナルブロックの Vin+ と Vin- (真ん中の2つ) に接続します。
出力電圧から電流を計算するために 250 &Omega; の抵抗もCTL-16-CLS の端子と同じ場所に挿入します。

![ctと抵抗の接続_正面.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104552/e57c5e2f-8f48-bd43-5f9b-281fa64f215a.jpeg)

このように接続できれば接続は完了です。ターミナルブロックのネジを回して端子を固定します。抵抗や端子を軽く動かしてみて、動かなければ大丈夫です。今回はチャンネル2 (画像の場所) に接続していますが、どのチャンネルに接続しても大丈夫です。


# 電流計測プログラムの作成
次は実際に ADPi を使用して電流を計測するプログラムを作成していきます。
ファイル名は `CTL_16_CLS.py` としています。

```CTL_16_CLS.py
#!/usr/bin/python3

import csv
import datetime
import time

import smbus
import spidev
from adpi import AD7794, ADPiPro

ADPI_CHANNEL = 2
ADPI_SAMPLE_HZ = 470

CT_FACTOR = 3000 / (250*0.99)  # for CTL-16-CLS
CT_OFFSET = 0

RAW_OFFSET = (1 << 23)
RAW_SCALE = 5 / (1 << 23)

def get_voltage(dev, ch):
    dev.write_configuration(AD7794.gain["1"], AD7794.channel[str(ch)])
    dev.write_mode(AD7794.mode["single"], AD7794.rate[str(ADPI_SAMPLE_HZ)])

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

    raw = dev.read_data()
    return RAW_SCALE * (raw - RAW_OFFSET)

def v2i(vol):
    current = CT_FACTOR * (vol + CT_OFFSET)
    return round(current, 3)

if __name__ == "__main__":
    spi = spidev.SpiDev()

    try:
        spi.open(0, 0)
        spi.mode = 0b11
        spi.max_speed_hz = 1000000
        ad = ADPiPro(spi, smbus.SMBus(1))
        with open("./CTL_16_CLS_test.csv", "w", encoding="utf-8_sig") as f:
            writer = csv.writer(f)
            writer.writerow(["日時", "電流[A]"])
            while True:
                voltage = get_voltage(ad, ADPI_CHANNEL)
                value = v2i(voltage)
                print(f"電流[A]: {value}")
                timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S.%f")
                writer.writerow([timestamp, value])
                f.flush()

    finally:
        spi.close()
```

このプログラムでは ADPi のチャンネル2 に接続した CT センサの値をターミナルに出力すると同時に `CTL_16_CLS_test.csv` というファイルにデータを書き込んでいます。

以下、プログラムに関しての補足です。
* 使用する ADPi のチャンネルを変更する場合はプログラムの変数 `ADPI_CHANNEL` を使用するチャンネルの値に変更してください。
* csv 書き込み時はデータの安全性のために flush() でファイルバッファを使用しています。安全よりも速度を優先したい場合は `f.flush()` の行を削除してください。 

* ADPi の出力電圧から電流に変換する部分については以下の式を使用しています。

```math
E_{0} = K \cdot I_{o} \cdot R_{L} / n 

```

参考 : https://www.u-rd.com/products/CTL-16-CLS_tab1.html#detail_tab


この式から電流 $ I_{o} $ を算出しています。
$K, R_{L}, n$ は使用するCT センサや抵抗器によって変わります。これらを変更する場合は変数 `CT_FACTOR` の計算式を変更してください。

このコードを実行すると、チャンネル2から計測した電流の値が出力されます。
今は電流が流れていないので 0 に近い値しか出ません。

```
$ sudo python3 CTL_16_CLS.py
電流[A]: 0.0
電流[A]: 0.0
電流[A]: -0.0
電流[A]: 0.0
```

また、電流値を記録した csv ファイルも生成されます。

```
 $ ls
CTL_16_CLS.py
CTL_16_CLS_test.csv
```






# 実際に計測してみる
作成したプログラムを使用して実際に電流の値を計測してみます。
今回使用するのはこちらのヒートガンです。このヒートガンで温風を出すときの電流を計測してみます。

![使用したヒートガン.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104552/08ef93e3-ff73-5fb2-ad5a-36f497c0fad7.jpeg)


https://www.hakko.com/japan/products/hakko_heating_gun_883b.html


このヒートガンの電源コードのうちの一本を下の画像のように CT センサに通します。

![ctにコードを通す(1回巻き).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104552/273b5a2e-5dcb-897c-bf07-2869b899ef8f.jpeg)

これで準備は完了です。プログラムを動かして電流を計測してみましょう。

```
$ sudo python3 CTL_16_CLS.py
電流[A]: -4.779
電流[A]: -1.217
電流[A]: 7.65
```

生成された csv ファイルから電流の波形を確認してみるとこのような感じになっていました。

![電流_1回巻き(0-20秒).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104552/7020a369-0870-2a98-7bd9-a66bab79dd29.png)






# まとめ
本記事では ADPi とCT センサを使用してヒートガンの電流を測定してみました。既存品の組み合わせで電流値が測定できるのでぜひ参考にしてください。