【補足説明】Simulink Support Package for Arduino Hardware で DC モータを動かしてみる


# <font color="#33CC33">1. はじめに<font>

　本記事では，[MinSeg.com](https://minseg.com/) が販売している <b>MinSegShield M2V5 Dual Axis Balancing Kit</b> に含まれるマイコンボード（Arduino Mega 2560 互換ボード）とシールド（MinSegShield M2V5）により，<b>DC モータを駆動する方法</b>について説明します．そのために，

* <b>Simulink Support Package for Arduino Hardware</b>

を利用します．

　なお，本記事で使用した MATLAB/Simulink のバージョン（リリース）は <b>R2021b</b> であり，ファイル一式は<b>[ここ](https://github.com/Prof-Carter/matlab_arduino_motor)</b>からダウンロードできます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/b7519138-9866-647c-a79d-c61d247ab1ff.png)



# <font color="#33CC33">2. モータドライバ<font>

　今回，使用するシールド <b>MinSegShield M2V5</b> に搭載されているモータドライバは <b>DRV8833</b> です．<b>DRV8833</b> は PWM (Pulse Width Modulation：パルス幅変調) 方式のモータドライバであり，2 つの DC モータを駆動することができます．H ブリッジ回路であるため，正転，逆転が可能です．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/658855b1-f85f-550a-e2c0-e73e1de4b66c.png)

DRV8833 のピン配置と動作モードを以下に示します．

|IN1|IN2|OUT1|OUT2|モード|
|:-:|:-:|:-:|:-:|:-:|
|0|0|ハイインピーダンス|ハイインピーダンス|ストップ<br>（惰性）|
|1|0|H|L|正転|
|0|1|L|H|逆転|
|1|1|H|H|ブレーキ|

|IN3|IN4|OUT3|OUT4|モード|
|:-:|:-:|:-:|:-:|:-:|
|0|0|ハイインピーダンス|ハイインピーダンス|ストップ<br>（惰性）|
|1|0|H|L|正転|
|0|1|L|H|逆転|
|1|1|H|H|ブレーキ|

また，DC モータ，モータドライバとマイコンボードとの接続図を以下に示します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/db005a07-56cc-5a8e-77c9-a71b38a97c7d.png)


# <font color="#33CC33">3. DC モータを動かす方法（その 1）－ 駆動 / 惰性動作</font>

## <font color="#33CC33">3.1　Simulink ブロック "PWM" の動作</font>

　PWM 信号を出力する Simulink ブロックとして，"PWM" が用意されています．「Simulink ライブラリブラウザ」を起動して，

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/079e1f16-1f3a-4bba-93f8-4ec1e0bf7ef7.png)

のように，マウスの右ボタンで Simulink Support Package for Arduino Hardware を選択します．このとき，別ウィンドウに

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/cfef2e24-2eed-45f0-3f0c-4a4b9a81c2e8.png)

が表示されるので，"Common" をダブルクリックすると，

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/d792c833-37c4-e467-70e6-e7e63f354735.png)

のように，"Arduino Common Blocks" が表示されます．このなかに，Simulink ブロックとして "PWM" があります．

　Simulink ブロック "PWM" を 2 つ，Simulink モデルに配置し，<b><font color="#E32D91">6 番ピン</font></b>と <b><font color="#00B0F0">7 番ピン</font></b>に設定します．それぞれを <b><font color="#E32D91">"PWM1"</font></b>, <b><font color="#00B0F0">"PWM2"</font></b> としたとき，これらのはたらきは以下のとおりです．

* <b><font color="#E32D91">6 番ピンに設定した Simulink ブロック "PWM1"</font></b><br>　<b>0 から 255</b> の <b>1 バイト (8 ビット) 符号なし整数</b>を入力すると，6 番ピンから出力される<b>PWM 信号のデューティ比が 0 % から 100 %</b> に変化します．そして，モータドライバでは，<b><font color="#E32D91">PWM 信号が ON のとき IN1 に 1</font></b> が，<b><font color="#E32D91">PWM 信号が OFF のとき IN1 に 0</font></b> が入力されます．<br>　したがって，<b><font color="#00B0F0">IN2 が 0</font></b> であれば，<b><font color="#E32D91">PWM 信号が ON（IN1 が 1）のとき</font></b><b><font color="#0CA274">正転</font></b>，<b><font color="#E32D91">PWM 信号が OFF（IN1 が 0）のとき</font></b><b><font color=#0070C0>ストップ（惰性）</font></b>となります．

* <b><font color="#00B0F0">7 番ピンに設定した Simulink ブロック "PWM2"</font></b><br>　<b>0 から 255</b> の <b>1 バイト (8 ビット) 符号なし整数</b>を入力すると，7 番ピンから出力される<b>PWM 信号のデューティ比が 0 % から 100 %</b> に変化します．そして，モータドライバでは，<b><font color="#00B0F0">PWM 信号が ON のとき IN2 に 1</font></b> が，<b><font color="#00B0F0">PWM 信号が OFF のとき IN2 に 0</font></b> が入力されます．<br>　したがって，<b><font color="#E32D91">IN1 が 0</font></b> であれば，<b><font color="#00B0F0">PWM 信号が ON（IN2 が 1）のとき</font></b><b><font color="#E48312">逆転</font></b>，<b><font color="#00B0F0">PWM 信号が OFF（IN2 が 0）のとき</font></b><b><font color=#0070C0>ストップ（惰性）</font></b>となります．


## <font color="#33CC33">3.2　正転させてみる！</font>

　<b><font color="#00B0F0">"PWM2"</font></b> の入力を <b><font color="#00B0F0">0</font></b> に固定し，<b><font color="#E32D91">"PWM1"</font></b> の入力を <b><font color="#E32D91">1～255</font></b> に設定すると，<b><font color="#0CA274">正転</font></b>します（厳密には，<b>静止摩擦の影響により小さい値では回転しません</b>が）．

　たとえば，

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/59c96c88-596e-1a13-80dc-3e225c70fab4.png)|
|:-:|
|<b>Simulink モデル <font color="#0CA274">"sample1_cw.slx"</font></b>|

のように，<b><font color="#E32D91">"PWM1"</font></b> の入力を <b><font color="#E32D91">204</font></b> や <b><font color="#E32D91">51</font></b> に設定してみましょう．このときの PWM 信号のデューティ比は
```math
\begin{align}
\dfrac{204}{255} = 80\ [\%],\ 
\dfrac{51}{255} = 20\ [\%]
\end{align}
```
です．

　"Manual Switch" が "Constant" 側になっている状態で <b>Simulink モデル <font color="#0CA274">"sample1_cw.slx"</font></b> を<b>エクスターナル実行</b>すると，<b><font color="#0CA274">高速で正転</font></b>します．また，"Manual Switch" をダブルクリックして "Constant1" 側に切り替えると，<b><font color="#0CA274">低速で正転</font></b>します．

https://www.youtube.com/watch?v=t1yG_633lpk

　"Manual Switch" が "Constant" 側になっているとき，<b><font color="#E32D91">IN1</font></b>，<b><font color="#00B0F0">IN2</font></b> に加わる PWM 信号は

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/e236d8da-eb45-2157-4dee-79e13ec1387b.png)

となっていますので，6 番ピンを介してモータドライバの <b><font color="#E32D91">IN1</font></b> にデューティ比 80 % の ON/OFF 信号が加わります．したがって，

|<b><font color="#E32D91">IN1</font></b>|<b><font color="#00B0F0">IN2</font></b>|OUT1|OUT2|モード|
|:-:|:-:|:-:|:-:|:-:|
|<b><font color="#E32D91">0<br>(OFF)</font></b>|<b><font color="#00B0F0">0<br>(OFF)</font></b>|ハイインピーダンス|ハイインピーダンス|<b><font color=#0070C0>ストップ<br>（惰性）</font></b>|
|<b><font color="#E32D91">1<br>(ON)</font></b>|<b><font color="#00B0F0">0<br>(OFF)</font></b>|H|L|<b><font color="#0CA274">正転</font></b>|

のように，<b><font color="#00B0F0">IN2</font></b> は PWM 信号が OFF なので常に <b><font color="#00B0F0">0</font></b> ですが，<b><font color="#E32D91">IN1</font></b> は PWM 信号の ON/OFF により <b><font color="#E32D91">1</font></b> と <b><font color="#E32D91">0</font></b> が切り替わり，それに応じて，<b><font color="#0CA274">正転</font></b>と<b><font color=#0070C0>ストップ（惰性）</font></b>が<b>切り替わります</b>．切り替えの周期は非常に短いので，見た目にはなめらかに回転しているように感じます．


## <font color="#33CC33">3.3　逆転させてみる！</font>

　逆に，<b><font color="#E32D91">"PWM1"</font></b> の入力を <b><font color="#E32D91">0</font></b> に固定し，<b><font color="#00B0F0">"PWM2"</font></b> の入力を <b><font color="#00B0F0">1～255</font></b> に設定すると，<b><font color="#E48312">逆転</font></b>します（先に述べたように，厳密には，<b>静止摩擦の影響により小さい値では回転しません</b>が）．

　たとえば，

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/3fb825f2-4543-1edd-c547-92106af8e26b.png)|
|:-:|
|<b>Simulink モデル <font color="#E48312">"sample1_acw.slx"</font></b>|

のように，<b><font color="#00B0F0">"PWM2"</font></b> の入力を <b><font color="#00B0F0">204</font></b> や <b><font color="#00B0F0">51</font></b> に設定してみましょう．

　"Manual Switch" が "Constant" 側になっている状態で <b>Simulink モデル <font color="#E48312">"sample1_acw.slx"</font></b> を<b>エクスターナル実行</b>すると，<b><font color="#E48312">高速で逆転</font></b>します．また，"Manual Switch" をダブルクリックして "Constant1" 側に切り替えると，<b><font color="#E48312">低速で逆転</font></b>します．

https://www.youtube.com/watch?v=lyCPnnrYQK0

　"Manual Switch" が "Constant" 側になっているとき，<b><font color="#E32D91">IN1</font></b>，<b><font color="#00B0F0">IN2</font></b> に加わる PWM 信号は

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/86fffed6-3a70-dd6b-c904-f1627818357b.png)

となっていますので，7 番ピンを介してモータドライバの <b><font color="#00B0F0">IN2</font></b> にデューティ比 80 % の ON/OFF 信号が加わります．したがって，

|<b><font color="#E32D91">IN1</font></b>|<b><font color="#00B0F0">IN2</font></b>|OUT1|OUT2|モード|
|:-:|:-:|:-:|:-:|:-:|
|<b><font color="#E32D91">0<br>(OFF)</font></b>|<b><font color="#00B0F0">0<br>(OFF)</font></b>|ハイインピーダンス|ハイインピーダンス|<b><font color=#0070C0>ストップ<br>（惰性）</font></b>|
|<b><font color="#E32D91">0<br>(OFF)</font></b>|<b><font color="#00B0F0">1<br>(ON)</font></b>|H|L|<b><font color="#E48312">逆転</font></b>|

のように，<b><font color="#E32D91">IN1</font></b> は PWM 信号が OFF なので常に <b><font color="#E32D91">0</font></b> ですが，<b><font color="#00B0F0">IN2</font></b> は PWM 信号の ON/OFF により <b><font color="#00B0F0">1</font></b> と <b><font color="#00B0F0">0</font></b> が切り替わり，それに応じて，<b><font color="#E48312">逆転</font></b>と<b><font color=#0070C0>ストップ（惰性）</font></b>が<b>切り替わります</b>．



## <font color="#33CC33">3.4　正転と逆転を切り替えてみる！</font>

　以上，説明したように，<b><font color="#0CA274">正転</font></b>，<b><font color="#E48312">逆転</font></b>は

* <b><font color="#0CA274">正転</font></b>：<b><font color="#E32D91">"PWM1" に 1～255</font></b>，<b><font color="#00B0F0">"PWM2" に 0</font></b> を入力
* <b><font color="#E48312">逆転</font></b>：<b><font color="#E32D91">"PWM1" に 0</font></b>，<b><font color="#00B0F0">"PWM2" に 1～255</font></b> を入力

としていました．しかし，モータ駆動を考えると，<b><font color="#0CA274">正の整数 1～255</font></b> を加えると<b><font color="#0CA274">正転</font></b>，<b><font color="#E48312"><b>負の整数 -255～-1</font></b> を加えると<b><font color="#E48312">逆転</font></b>としたほうが整合性が良いでしょう．

　このような動作をさせるため，以下の Simulink モデルを作成しました（両者は同じ動作をします）．

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/414ee721-54c6-b2da-278c-a70883c89d17.png)|
|:-:|
|<b>Simulink モデル "sample1_cw_acw1_signal.slx"</b>|

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/0900ae2e-36c9-3540-2cd7-494e198abf22.png)|
|:-:|
|<b>Simulink モデル "sample1_cw_acw2_signal.slx"</b>|

ここで，<b><font color="#E84746">Simulink ブロック "Ramp (-255 to +255)"</font></b> はモータを駆動するために与える<b><font color="#E84746">指令電圧（-255 ～ 255 の整数値）</font></b>に相当します．この Simulink モデルでは，
* <b><font color="#E84746">pwm = -255, -254, -253, ... , 255</font></b>

のように 1 刻みで指令電圧の整数値を変化させています．また，<b><font color="#E32D91">Simulink ブロック "To Workspae1 (PWM1)"</font></b> は <b><font color="#E32D91">"PWM1"</font></b> に入力することを想定している信号，<b><font color="#00B0F0">Simulink ブロック "To Workspae2 (PWM2)"</font></b> は <b><font color="#00B0F0">"PWM2"</font></b> に入力することを想定している信号です．

　<b>M ファイル "[plot_sample1_cw_acw_signal.m](https://github.com/Prof-Carter/matlab_arduino_motor/blob/main/plot_sample1_cw_acw_signal.m)"</b> を実行すると，

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/c692ea57-b0c0-87a0-aac8-6339f475bb72.png)

となり，所望の結果が得られます．

> * <b>Simulink モデル "sample1_cw_acw1_signal.slx"</b><br><b>[Rensselaer Arduino Support Package Library (RASPLib)](https://jp.mathworks.com/matlabcentral/fileexchange/62702)</b> の「Libraries / M2V5 Library」に含まれている Simulink ブロック<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/6f3a376a-b5e4-11c4-b2c7-876140d9be73.png" width="150"><br>と同様の方法です．<b>Simulink ブロック "Left Motor Driver PWM6, PWM7 FD"</b> を空の Simulink モデルに移動し，Simulink ブロックを選択したうえで，マウスの右ボタンで「マスク / マスク内を表示」を選ぶと，中身を確認できます．
> * <b>Simulink モデル "sample1_cw_acw2_signal.slx"</b><br>参考文献 1.（[平田先生の本](https://www.amazon.co.jp/gp/product/B01CNSJTX0/ref=dbs_a_def_rwt_bibl_vppi_i0)）の 102 頁に記述されている方法です．

　そこで，モータを駆動するための Simulink モデルを以下のように修正します．

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/9393d36a-8e7b-73aa-41a7-387be16cdb99.png)|
|:-:|
|<b>Simulink モデル "sample1_cw_acw1.slx"</b>|

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/34eed633-59bf-3cde-29ae-1c272a510b24.png)|
|:-:|
|<b>Simulink モデル "sample1_cw_acw2.slx"</b>|

　"Manual Switch" が "Constant1" 側になっている状態で Simulink モデル "sample1_cw.slx" を<b>エクスターナル実行</b>すると，<b><font color="#0CA274">デューティ比 20% で正転</font></b>します．また，"Manual Switch" をダブルクリックして "Constant2" 側に切り替えると，<b><font color="#E48312">デューティ比 20% で逆転</font></b>します．

https://www.youtube.com/watch?v=SwkdZYCcqrk

https://www.youtube.com/watch?v=KguG7Yr5_jc

## <font color="#33CC33">3.5　指令電圧と角速度の関係は線形？非線形？</font>

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/de380f7e-f281-5121-7647-13e5768c141e.png)|
|:-:|
|図 1　定値の指令電圧を加えたときの角度と角速度|

　モータ駆動系に定値の指令電圧
```math
\begin{align}
	v(t) = \left\{\begin{array}{ll}
			0 & \hspace{-5pt}(t < 0) \\
			{v}_{\rm c} & \hspace{-5pt}(t \ge 0) \\
		\end{array}\right.
\end{align}
```
を加えると，モータの角度 $\theta(t)$ は一定の割合で増加し，角速度 $\omega(t) = \dot{\theta}(t)$ は一定値に収束します．このとき，図 1 のような時間応答となりますので，指令電圧 $v(t)$ と角速度 $\omega(t)$ の関係は
```math
\begin{align}
	\omega(s) = {P}_{\rm v}(s)v(s),\quad 
	{P}_{\rm v}(s) = \dfrac{K}{1 + Ts}
\end{align}
```
のように，<b>1 次遅れ</b>となります．つまり，角速度は
```math
\begin{align}
	\omega(t) = K\bigl(1 - {e}^{-t/T}\bigr){v}_{\rm c}
\end{align}
```
となりますので，定常角速度は
```math
\begin{align}
	{\omega}_{\infty} = \lim_{t \rightarrow \infty}\omega(t)
	= K{v}_{\rm c}
\end{align}
```
となります．これより，<b>定値の指令電圧 $v(t) = v_{\rm c}$ と定常角速度 ${\omega}_{\infty}$ は比例関係</b>にあると考えられます．

　それでは，本当に比例関係にあるのかを実験により検証してみましょう．実験では，スイッチサイエンスさんの 9V/1.3A の外部電源

https://www.switch-science.com/catalog/1795/

を使用しています．検証用の Simulink モデル

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/80d84600-7510-f3da-3dad-0f9adb3235f3.png)|
|:-:|
|<b>Simulink モデル "sample1_cw_acw1_plot.slx"</b>|

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/61ace882-9854-8337-6c91-7da8315c2b7c.png)|
|:-:|
|<b>Simulink モデル "sample1_cw_acw2_plot.slx"</b>|

のいずれかにおいて，<b><font color="#E84746">"Constant (-255 to +255)"</font></b> の数値 <b><font color="#E84746">pwm</font></b> を

* <b><font color="#E48312">逆転</font></b>：<b>-255</b> (100%), <b>-250</b> (98.0%), ... , <b>-5</b> (1.96%)
* 静止：<b>0</b> (0%)
* <b><font color="#0CA274">正転</font></b>：<b>5</b> (1.96%), <b>10</b> (3.92%), ... , <b>250</b> (98.0%), <b>255</b> (100%)

のように 5 刻みに変化させ，<b>エクスターナル実行</b>を行います．

>* <b>Simulink モデル "sample1_cw_acw1_plot.slx", "sample1_cw_acw2_plot.slx"</b> では，<b>[Rensselaer Arduino Support Package Library (RASPLib)](https://jp.mathworks.com/matlabcentral/fileexchange/62702)</b> の「Libraries / M2V5 Library」に含まれている <b><font color="#E84746">Simulink ブロック "M1 Right Connector 2, 3"</font></b> が利用されています．
> * <b><font color="#E84746">Simulink ブロック "M1 Right Connector 2, 3"</font></b> では，DCモータに取り付けられている磁気式のインクリメンタル型エンコーダのパルス信号を，<b>4 逓倍でカウント</b>した値 (データ型：int32，データサイズ：$1 \times 1 \times n$) を得ることができます．また，データサイズを $n \times 1$ に変更するために <b>Simulink ブロック "Reshape"</b> を用い，データ型を double にするために <b>Simulink ブロック "Data Type Conversion"</b> を用いています．
> * <b>Simulink ブロック "To Workspace"</b> は保存形式を「配列」にしています．また，私は取得したデータを集約したくないので，以下のように設定しています．
> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/9652910d-8dd8-ada9-5e0b-dd61e1c23e6c.png)
> * 今回，使用した <b><font color="#E84746">MinSegShield M2V5 Dual Axis Balancing Kit</font></b> に搭載されている DFRobot 社のギヤード DC モータ ([FIT0482](https://www.dfrobot.com/product-1432.html)) は，<b>ギヤ比（減速比）が 50:1</b> であり，また，<b>エンコーダの分解能が 7 PPR</b>（パルス / 回転）です．したがって，カウント数に $360/(50 \times 7 \times 4)$ をかけると，角度 (deg) に変換することができます．

　<b>Simulink モデル "sample1_cw_acw1_plot.slx"</b> もしくは <b>"sample1_cw_acw2_plot.slx"</b> を起動している状態で，

* <b>M ファイル "[exec_sample1_cw_acw_plot.m](https://github.com/Prof-Carter/matlab_arduino_motor/blob/main/exec_sample1_cw_acw_plot.m)"</b> 

を実行します．

> * 角度 $\theta(t)\ (= y(t))$ を <b>y</b>，角速度 $\omega(t)\ (= \dot{y}(t))$ を <b>dy</b> と記述しています．
> * サンプリグ周期を $h = 0.01\ {\rm [s]}$ としたとき，角速度は次式の中心差分近似により計算しています．
> ```math
> \begin{align}
> 	\dot{y}[n] = \dfrac{y[n+1] - y[n-1]}{2h}
> \end{align}
> ```
> * 定常角速度 $\omega_{\infty}$ を <b>dyinf</b> と記述しています．<b>dy</b> の最後の 10 個の平均としています．

　<b>M ファイル "[exec_sample1_cw_acw_plot.m](https://github.com/Prof-Carter/matlab_arduino_motor/blob/main/exec_sample1_cw_acw_plot.m)"</b> を実行すると，<b>フォルダ "data1"</b> に

* <b><font color="#0CA274">正転</font></b>の実験データ：data1_cw0.mat, data1_cw5.mat, … , data1_cw255.mat
* <b><font color="#E48312">逆転</font></b>の実験データ：data1_acw5.mat, data1_acw10.mat, … , data1_acw255.mat
* 定常角速度の実験データ：data1_pwm_dy.mat

が保存されます．なお，私の環境では，<b>M ファイル "[exec_sample1_cw_acw_plot.m](https://github.com/Prof-Carter/matlab_arduino_motor/blob/main/exec_sample1_cw_acw_plot.m)"</b> の実行時間はおおよそ 1 時間でした．103 回の反復処理を行っていますので，1 回のエクスターナル実行あたりおおよそ 33 秒でした．

　<b>M ファイル "[exec_sample1_cw_acw_plot.m](https://github.com/Prof-Carter/matlab_arduino_motor/blob/main/exec_sample1_cw_acw_plot.m)"</b> の実行終了後，実験結果を描画するために，

* <b>M ファイル "[plot_custom_sample1_cw_acw.m](https://github.com/Prof-Carter/matlab_arduino_motor/blob/main/plot_custom_sample1_cw_acw.m)"</b>

を実行します．実行結果を以下に示します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/a3bdb96a-22bd-82fa-e88e-15ad6edf3fdb.png)

ここで，<b><font color="#0CA274">CW</font></b> (clockwise) は<b><font color="#0CA274">正転</font></b>，<b><font color="#E48312">ACW</font></b> (anticlockwise) は<b><font color="#E48312">逆転</font></b>を意味します．

　Figure 12, 22 からわかるように，<b>角速度は 1 次遅れ系のステップ応答の形状</b>をしていますが，Figure 31 からわかるように，大域的に見ると，

* 「<b>指令電圧</b>」と「モータの<b>角速度</b>」の関係は，<b>非線形性が強く，比例関係ではない</b>

ことがわかります．また，指令電圧の整数値が -25, -20, ..., 0, 5, ..., 25, 30 のとき，静止摩擦に打ち勝つことができず，モータは回転しませんでしたので，

* <b>不感帯が大きい</b>

ことも確認できました．

　同様の結果は，参考文献 1.（[平田先生の本](https://www.amazon.co.jp/gp/product/B01CNSJTX0/ref=dbs_a_def_rwt_bibl_vppi_i0)）の 80-81 頁に記述されています．


# <font color="#33CC33">4. DC モータを動かす方法（その 2）－ 駆動 / ブレーキ動作</font>

　ここでは，「<b>指令電圧</b>」と「モータの<b>角速度</b>」がほぼ<b>比例関係</b>となるような方法について説明します．

## <font color="#33CC33">4.1　動作原理</font>

　ここで説明する方法は，<b>[Rensselaer Arduino Support Package Library (RASPLib)](https://jp.mathworks.com/matlabcentral/fileexchange/62702)</b> の「Libraries / M2V5 Library」に含まれている Simulink ブロック<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/565206fe-0080-3419-3d8e-137c5d6c027f.png" width="150"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/85ed088e-3798-0189-4dbd-d2219529a6ec.png" width="150"><br>と同様の方法です（これら Simulink ブロックの中身は，マウスの右ボタンで「マスク / マスク内を表示」を選ぶことで確認できます）．

　まず，以下の Simulink モデルを用意します．

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/e4d4ed0d-a1e1-70dd-5f5e-1389ad1ac2a0.png)|
|:-:|
|<b>Simulink モデル "sample2_cw_acw_signal.slx"</b>|

　<b>M ファイル "[plot_sample2_cw_acw_signal.m](https://github.com/Prof-Carter/matlab_arduino_motor/blob/main/plot_sample2_cw_acw_signal.m)"</b> を実行すると，

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/81022c9e-e564-176b-2f4e-ad7d02e99c2a.png)

という結果が得られます．つまり，以下のように動作させています．

* <b><font color="#0CA274">正転</font></b>させるときは<b><font color="#E32D91">常に "PWM1" に最大値 255 を入力</font></b>し，<b><font color="#00B0F0">"PWM2" に 0 から 254 の値を入力することで動きを妨げる</font></b>ようにする．
	* <b><font color="#E84746">pwm = 255</font></b> のとき：<br>　<b><font color="#E32D91">PWM1 への入力は 255</font></b>，<b><font color="#00B0F0">PWM2 への入力は 0</font></b>
	* <b><font color="#E84746">pwm = 204</font></b> のとき：<br>　<b><font color="#E32D91">PWM1 への入力は 255</font></b>，<b><font color="#00B0F0">PWM2 への入力は 51 (= 255 - 204)</font></b>
	* <b><font color="#E84746">pwm = 51</font></b> のとき：<br>　<b><font color="#E32D91">PWM1 への入力は 255</font></b>，<b><font color="#00B0F0">PWM2 への入力は 204 (= 255 - 51)</font></b>

* <b><font color="#E48312">逆転</font></b>させるときは<b><font color="#00B0F0">常に "PWM2" に最大値 255 を入力</font></b>し，<b><font color="#E32D91">"PWM1" に 0 から 254 の値を入力することで動きを妨げる</font></b>ようにする．
	* <b><font color="#E84746">pwm = -255</font></b> のとき：<br>　<b><font color="#00B0F0">PWM2 への入力は 255</font></b>，<b><font color="#E32D91">PWM1 への入力は 0</font></b>
	* <b><font color="#E84746">pwm = -204</font></b> のとき：<br>　<b><font color="#00B0F0">PWM2 への入力は 255</font></b>，<b><font color="#E32D91">PWM1 への入力は 51 (= 255 - 204)</font></b>
	* <b><font color="#E84746">pwm = -51</font></b> のとき：<br>　<b><font color="#00B0F0">PWM2 への入力は 255</font></b>，<b><font color="#E32D91">PWM1 への入力は 204 (= 255 - 51)</font></b>


## <font color="#33CC33">4.2　正転と逆転を切り替えてみる！</font>

　<b><font color="#0CA274">正転</font></b>と<b><font color="#E48312">逆転</font></b>を <b>Simulink ブロック "Manual Switch"</b> で切り替える Simulink モデル

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/d6302a21-0fbf-945d-2d20-d0b510288c9f.png)|
|:-:|
|<b>Simulink モデル "sample2_cw_acw.slx"</b>|

を<b>エクスターナル実行</b>すると，

https://www.youtube.com/watch?v=5gai6DDaUCs

のように動作します．


## <font color="#33CC33">4.3　指令電圧と角速度の関係は線形！！</font>

　最後に，この方法を利用した場合，指令電圧と角速度の関係を調べます．

　先と同様，検証用の Simulink モデル

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/6f93343a-f18a-4953-3a6a-a8f4d06ba26b.png)|
|:-:|
|<b>Simulink モデル "sample2_cw_acw_plot.slx"</b>|

において，<b><font color="#E84746">"Constant (-255 to +255)"</font></b> の数値 <b><font color="#E84746">pwm</font></b> を

* <b><font color="#E48312">逆転</font></b>：<b>-255</b>, <b>-250</b>, ... , <b>-5</b>
* 静止：<b>0</b>
* <b><font color="#0CA274">正転</font></b>：<b>5</b>, <b>10</b>, ... , <b>250</b>, <b>255</b>

のように 5 刻みに変化させ，<b>エクスターナル実行</b>を行います．

　<b>Simulink モデル "sample2_cw_acw_plot.slx"</b> を起動している状態で

* <b>M ファイル "[exec_sample2_cw_acw_plot.m](https://github.com/Prof-Carter/matlab_arduino_motor/blob/main/exec_sample2_cw_acw_plot.m)"</b> 

を実行します．

　<b>M ファイル "[exec_sample2_cw_acw_plot.m](https://github.com/Prof-Carter/matlab_arduino_motor/blob/main/exec_sample2_cw_acw_plot.m)"</b> の実行終了後，実験結果を描画するために，

<b>M ファイル "[plot_custom_sample2_cw_acw.m](https://github.com/Prof-Carter/matlab_arduino_motor/blob/main/plot_custom_sample2_cw_acw.m)"</b>

を実行します．その結果，

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/452e88b7-4868-11e4-a983-a6841f778309.png)

が描画されます．これらのグラフより，

* 「<b>指令電圧</b>」と「モータの<b>角速度</b>」の関係は，<b>ほぼ比例関係である</b>

ことがわかります．また，指令電圧の整数値が -10, -5, 0, 5, 10 のとき，静止摩擦に打ち勝つことができず，モータは回転しませんでしたが，3 章で説明した方法と比べて，

* <b>不感帯が小さい</b>

ことがわかります．


# <font color="#33CC33">5. おわりに<font>

　本記事では，

* <b>Simulink Support Package for Arduino Hardware</b>

を利用して，DC モータを駆動する方法について説明しました．

　記事をアップした後，宇都宮大学の平田先生から [Pololu の DRV8835 のページ](https://www.pololu.com/product/2135)に

> Drive/brake operation usually provides a more linear relationship between PWM duty cycle and motor speed than drive/coast operation, and we generally recommend using drive/brake operation when possible.
> （翻訳）
> 「駆動 / ブレーキ動作」は，通常，「駆動 / 慣性動作」よりも PWM デューティサイクルとモータ速度の関係がより線形の関係にあるため，一般的には，可能な限り「駆動 / ブレーキ動作」の使用が推奨されています．

って書いてありますよと教えてもらいました．参考文献 1. の改訂版が出版予定のようで，モータドライバを DRV8835 に更新し，「駆動 / ブレーキ動作」でモータ駆動をしているとのこと．楽しみですね．


# <font color="#33CC33">参考文献</font>

1. 平田光男：[Arduino と MATLAB で制御系設計をはじめよう！](https://www.amazon.co.jp/gp/product/B01CNSJTX0/ref=dbs_a_def_rwt_bibl_vppi_i0)，TechShare (2012)

1. https://www.pololu.com/product/2135


# <font color="#33CC33">付録</font>

　<b>[Rensselaer Arduino Support Package Library (RASPLib)](https://jp.mathworks.com/matlabcentral/fileexchange/62702)</b> の「Libraries / M2V5 Library」に含まれているモータ駆動用の Simulink ブロック

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552191/1a188b46-61b5-c467-a9b2-4a86350eaf2b.png" width="300">

は，入力が -255 ～ 255 の整数値ではなく，電圧（-Vsupply [V] ～ Vsupply [V] の実数値）となっています．Simulink ブロックをダブルクリックすると，Driver Voltage の値 (<b>Vsupply</b>) を設定するようになっています．電力供給の方法により，この値を適当に設定してください．

* <b>USB から電力供給する場合</b>
* <b>単三電池 6 本 (6AA batteries) により電力供給する場合</b>
* <b>外部電源により電力供給する場合</b>：購入した AC アダプタに依存

　RASPLib のモータ駆動用の Simulink ブロックの内部では，255/Vsupply をかけることで，電圧を整数値に変換する処理が行われていますので，Vsupply の値は厳密である必要はありません．