Raspberry pi + インバータでBLモータを回転させる（BLモータの3相電流のAD変換と読み取り）

# 1. はじめに
私を含め、Raspberry piを買ったはいいものの、何をやったらいいかわからず、持て余している方は多いのではないでしょうか。
特に私の感覚では、「ハードウェアを動かすこと」に困っている方が多いように思います。
それに加え、私は仕事でBLモータを使ってはいるものの、BLモータが回転するメカニズムがわかっていなかったので、Raspberry piでBLモータを回転させる実験機を作ることにしました。
実験機を作りにあたり、ESCではなくインバータ（本記事ではIHM07M1）を使うことで、
より正確にBLモータが回転するメカニズムを理解できるように努めました。

# 2. 本記事で参考にしたサイト
本記事は以下サイトを参考にしております。作成者の方にはこの場を借りて、お礼を申し上げます。
- [BLモータのベクトル制御を実装する手順](https://qiita.com/fumiya_sato/items/ecc9f22c6f137f9dc0ac#6%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB%E5%88%B6%E5%BE%A1)
- [Raspberry PiでBLDCモータを120°通電制御する]( https://negligible.hatenablog.com/entry/2021/03/26/035001)

# 3. 本記事のゴールと注意点
BLモータの回転に最もよく使われる方法は「ベクトル制御」だと思われ、私も当初はベクトル制御実装を目指していましたが、
Raspberry piはPWMチャンネルが2つしかなく、BLモータの3相を独立で制御することができません。
よって本記事では「センサード120°制御+電流計測」までを解説します。

# 4. 本記事の構成
前述の「センサード120°制御+電流計測」を全て解説するとなると本文が膨大となるため、タスクとに、下記のように記事を分けます。

1. [BLモータの絶対角計測](https://qiita.com/hiyo_control/items/66affbccbd3b8dbe3892)
2. [インバータ（IHM07M1）からのPWM出力](https://qiita.com/hiyo_control/items/12f9591ebb9531184250)
3. BLモータの3相電流のAD変換と読み取り（本記事の範囲）
4. [実験機製作と動作確認]()

前半1章～3章で必要な機能の実装方法を述べ、後半4章と5章ではどのように実験機とプログラムを作ったかを述べます。

# 5. BLモータの3相電流のAD変換と読み取り
## 5.1. 使用する機器と配線図
本記事で紹介する機器を以下に示します。

|機器名|型番
|---|---|
|電流センサ     |[ACS712](https://akizukidenshi.com/catalog/g/g114533/)
|ADコンバータ   |[MCP3208](https://akizukidenshi.com/catalog/g/g100238)
|インバータ     |[IHM07M1](https://jp.rs-online.com/web/p/power-motor-robotics-development-tools/1438877?msockid=1e660b96eaaf6bc435eb1f5eeb8d6a61)
|BLモータ       |[A2212 KV1000](https://www.amazon.co.jp/dp/B01DBGY6OA?ref=ppx_yo2ov_dt_b_fed_asin_title)
|抵抗           | 220Ω
|コンデンサ     | 2.2μF
|コンピュータ   | Raspberry pi 4 Model B

上表で示した機器を下図のように接続します。ASC712の出力電圧にはノイズが乗っているので、LPF（RC回路）を使って除去します。
抵抗とコンデンサは手元にあったものを使用したので、大きさに根拠はありません。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/839547/c62564d4-4ced-4092-96e9-ee8f18e596e5.png" width=100%>
※ ACS712の図は[データシート](https://akizukidenshi.com/catalog/g/g114533/)から使わせていただきました。

上図中のLPFは下図のように、抵抗とコンデンサで作成しました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/839547/8521d986-5b5f-4ec6-9d1c-f8bcd3cfdbb4.png" width=60%>
今回はBLモータのU相とV相の電流のみをRaspberry piに取り込み、残りのW相電流はキルヒホッフの電流則
$$
0=I_{U-Phase}+I_{V-Phase}+I_{W-Phase}
$$
から算出します。

## 5.2 MCP3208～Raspberry pi間の通信フロー
MCP3208とRaspberry piの通信フローを下図に示します。
AS5048A同様、通信仕様はSPIですので、CSがLowである間のみデータのやり取りが発生します。
MCP3208はRaspberry piからの「Transmitted data」を受信した後、Transmitted dataに応じたCH番号の電圧値をRaspberry piに送信します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/839547/b8b4a45c-7655-48bc-9b3b-131d43dc9b58.png" width=60%>

Transmitted dataとCH番号の対応は下表の通りです。
|   |先頭8bit|中間8bit|最終8bit|
|---|---     |---     |---    |
|CH0|00000110|00000000|00000000
|CH1|00000110|01000000|00000000
|CH2|00000110|10000000|00000000

※ 各CHに入力される電圧自体を計測することを想定しています。
※ [MCP3208のデータシート](https://docs.rs-online.com/00d3/0900766b81380b03.pdf)にて詳細に説明されています

MCP3208の各CHに入る電圧は、下式で計算されてRaspberry piに送信されます。
$$
\text{Digital output Code}=4096\frac{V_{0}}{V_{ref}}
$$
ここで、
- Digital output Code：Raspberry piに送信される信号値
- $V_{0}$：各CHに入る電圧[V]
- $V_{ref}$：MCP3208の$V_{ref}$端子に入る電圧[V]（=5V）

となります。これは[MCP3208のデータシート](https://docs.rs-online.com/00d3/0900766b81380b03.pdf)にも記載があります。
よって、Raspberry piでは下記計算を実行すれば、MCP3208の各CHに入る電圧を取得することができます。
$$
{V_{0}}=\frac{V_{ref}}{4096}*\text{Digital output Code}
$$

この$V_{in}$と、ACS712調整で設定したセンサのオフセット（$b_{sensor}$）とゲイン（$a_{sensor}$）を使って下記のように計算すれば、BLモータの電流をRaspberry piにて取得することができます。
$$
{V_{0}}=\frac{V_{ref}}{4096}*\text{Digital output Code}
$$

## 5.3 ASC712のオフセット・ゲイン調整
ACS712はIN→OUTに流れる電流を電圧に変換する電流センサであり、
- センサのオフセット（＝入力電流が0Aの時、どの程度の出力電圧（$V_{0}$）にするか）
- センサのゲイン（＝入力電流が1mA増えたとき、どれだけ出力電圧（$V_{0}$）を増加させるか）
は下図のオフセットとゲインのつまみを回すことで調整することができます。

[MCP3208のデータシート](https://docs.rs-online.com/00d3/0900766b81380b03.pdf)にも記載されていますが、調整の際は磁化されていないドライバーを使ってください。
※ センサは磁気を近づけただけでゲインとオフセットが変化するため

今回は下図のように調整回路を作成し、オフセットとゲインを調整しました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/839547/6bbfbc24-1e61-4c11-ad22-fd3343b39dba.png" width=80%>
図中の抵抗、コンデンサ、電圧値を下表のようにしました。
|名称|値|
|---|---|
|抵抗$R_{1}$        |218.0Ω
|抵抗$R_{2}$        |220.2Ω
|コンデンサ$C$      |2.2μF
|入力電圧$V_{in}$   |4.99V

よって、IN-OUT間に流れる電流は下記となります。
$$
I=\frac{V_{in}}{R_1}=\frac{4.99}{218.0}\approx22.9\text{[mA]}
$$

この回路を使い、2つACS712を下表のように調整しました。
|-          |IN-OUT間電流 [mA]|出力電圧$V_0$ [V]
|---        |---            |---    |
|ACS712 No1 |0（スイッチOFF）|2.5689
|           |22.9           |2.5441
|ACS712 No2 |0（スイッチOFF）|2.5629
|           |22.9           |2.5162

※ 出力電圧は小数第1位まで同じなので、そこから3桁の小数第4位までを示しています。
※ ノイズでスイッチON/OFFによる電圧変化がわかりづらければ、プログラムでもLPFを掛けます。
※ 筆者は「サンプリング周期 10μsec」、「カットオフ周波数10Hz」の一次遅れのフィルタを掛けました。

この調整結果を元にACS712のゲインとオフセットを計算すると下表のようになります。
|-          |ゲイン a [V/mA]|オフセット b [V]
|---        |---        |---    |
|ACS712 No1 |-0.00109   |2.57
|ACS712 No2 |-0.00204   |2.56

このゲインとオフセットを使い、下記計算をすれば電流$I$[mA]を計測できます。
$$
I=\frac{V_{0}-b}{a}
$$

この計算をRaspberry piに実装すれば、Raspberry piでBLモータの3相電流を計測することができます。

## 5.4 BLモータの3相電流のAD変換と読み取りプログラム
著者の作成したインバータPWM発生プログラムは以下Githubリンクにて公開しております。

https://github.com/hiyo-control/02_BL_motor/tree/main/Chapter3_MCP3208_ACS712_program

プログラム作成では下記Githubで公開されているコードを参考しました。

https://github.com/RodolfoPrieto/MCP3208/blob/Arduino-Library/MCP3208.cpp