1. はじめに
本記事では,MinSeg.com が販売している MinSegShield M2V5 Dual Axis Balancing Kit に含まれるマイコンボード(Arduino Mega 2560 互換ボード)とシールド(MinSegShield M2V5)により,DC モータを駆動する方法について説明します.そのために,
- Simulink Support Package for Arduino Hardware
を利用します.
なお,本記事で使用した MATLAB/Simulink のバージョン(リリース)は R2021b であり,ファイル一式はここからダウンロードできます.
2. モータドライバ
今回,使用するシールド MinSegShield M2V5 に搭載されているモータドライバは DRV8833 です.DRV8833 は PWM (Pulse Width Modulation:パルス幅変調) 方式のモータドライバであり,2 つの DC モータを駆動することができます.H ブリッジ回路であるため,正転,逆転が可能です.
DRV8833 のピン配置と動作モードを以下に示します.
IN1 | IN2 | OUT1 | OUT2 | モード |
---|---|---|---|---|
0 | 0 | ハイインピーダンス | ハイインピーダンス | ストップ (惰性) |
1 | 0 | H | L | 正転 |
0 | 1 | L | H | 逆転 |
1 | 1 | H | H | ブレーキ |
IN3 | IN4 | OUT3 | OUT4 | モード |
---|---|---|---|---|
0 | 0 | ハイインピーダンス | ハイインピーダンス | ストップ (惰性) |
1 | 0 | H | L | 正転 |
0 | 1 | L | H | 逆転 |
1 | 1 | H | H | ブレーキ |
また,DC モータ,モータドライバとマイコンボードとの接続図を以下に示します.
3. DC モータを動かす方法(その 1)- 駆動 / 惰性動作
3.1 Simulink ブロック "PWM" の動作
PWM 信号を出力する Simulink ブロックとして,"PWM" が用意されています.「Simulink ライブラリブラウザ」を起動して,
のように,マウスの右ボタンで Simulink Support Package for Arduino Hardware を選択します.このとき,別ウィンドウに
が表示されるので,"Common" をダブルクリックすると,
のように,"Arduino Common Blocks" が表示されます.このなかに,Simulink ブロックとして "PWM" があります.
Simulink ブロック "PWM" を 2 つ,Simulink モデルに配置し,6 番ピンと 7 番ピンに設定します.それぞれを "PWM1", "PWM2" としたとき,これらのはたらきは以下のとおりです.
-
6 番ピンに設定した Simulink ブロック "PWM1"
0 から 255 の 1 バイト (8 ビット) 符号なし整数を入力すると,6 番ピンから出力されるPWM 信号のデューティ比が 0 % から 100 % に変化します.そして,モータドライバでは,PWM 信号が ON のとき IN1 に 1 が,PWM 信号が OFF のとき IN1 に 0 が入力されます.
したがって,IN2 が 0 であれば,PWM 信号が ON(IN1 が 1)のとき正転,PWM 信号が OFF(IN1 が 0)のときストップ(惰性)となります. -
7 番ピンに設定した Simulink ブロック "PWM2"
0 から 255 の 1 バイト (8 ビット) 符号なし整数を入力すると,7 番ピンから出力されるPWM 信号のデューティ比が 0 % から 100 % に変化します.そして,モータドライバでは,PWM 信号が ON のとき IN2 に 1 が,PWM 信号が OFF のとき IN2 に 0 が入力されます.
したがって,IN1 が 0 であれば,PWM 信号が ON(IN2 が 1)のとき逆転,PWM 信号が OFF(IN2 が 0)のときストップ(惰性)となります.
3.2 正転させてみる!
"PWM2" の入力を 0 に固定し,"PWM1" の入力を 1~255 に設定すると,正転します(厳密には,静止摩擦の影響により小さい値では回転しませんが).
たとえば,
Simulink モデル "sample1_cw.slx" |
のように,"PWM1" の入力を 204 や 51 に設定してみましょう.このときの PWM 信号のデューティ比は
\begin{align}
\dfrac{204}{255} = 80\ [\%],\
\dfrac{51}{255} = 20\ [\%]
\end{align}
です.
"Manual Switch" が "Constant" 側になっている状態で Simulink モデル "sample1_cw.slx" をエクスターナル実行すると,高速で正転します.また,"Manual Switch" をダブルクリックして "Constant1" 側に切り替えると,低速で正転します.
"Manual Switch" が "Constant" 側になっているとき,IN1,IN2 に加わる PWM 信号は
となっていますので,6 番ピンを介してモータドライバの IN1 にデューティ比 80 % の ON/OFF 信号が加わります.したがって,
IN1 | IN2 | OUT1 | OUT2 | モード |
---|---|---|---|---|
0 (OFF) |
0 (OFF) |
ハイインピーダンス | ハイインピーダンス | ストップ (惰性) |
1 (ON) |
0 (OFF) |
H | L | 正転 |
のように,IN2 は PWM 信号が OFF なので常に 0 ですが,IN1 は PWM 信号の ON/OFF により 1 と 0 が切り替わり,それに応じて,正転とストップ(惰性)が切り替わります.切り替えの周期は非常に短いので,見た目にはなめらかに回転しているように感じます.
3.3 逆転させてみる!
逆に,"PWM1" の入力を 0 に固定し,"PWM2" の入力を 1~255 に設定すると,逆転します(先に述べたように,厳密には,静止摩擦の影響により小さい値では回転しませんが).
たとえば,
Simulink モデル "sample1_acw.slx" |
のように,"PWM2" の入力を 204 や 51 に設定してみましょう.
"Manual Switch" が "Constant" 側になっている状態で Simulink モデル "sample1_acw.slx" をエクスターナル実行すると,高速で逆転します.また,"Manual Switch" をダブルクリックして "Constant1" 側に切り替えると,低速で逆転します.
"Manual Switch" が "Constant" 側になっているとき,IN1,IN2 に加わる PWM 信号は
となっていますので,7 番ピンを介してモータドライバの IN2 にデューティ比 80 % の ON/OFF 信号が加わります.したがって,
IN1 | IN2 | OUT1 | OUT2 | モード |
---|---|---|---|---|
0 (OFF) |
0 (OFF) |
ハイインピーダンス | ハイインピーダンス | ストップ (惰性) |
0 (OFF) |
1 (ON) |
H | L | 逆転 |
のように,IN1 は PWM 信号が OFF なので常に 0 ですが,IN2 は PWM 信号の ON/OFF により 1 と 0 が切り替わり,それに応じて,逆転とストップ(惰性)が切り替わります.
3.4 正転と逆転を切り替えてみる!
以上,説明したように,正転,逆転は
- 正転:"PWM1" に 1~255,"PWM2" に 0 を入力
- 逆転:"PWM1" に 0,"PWM2" に 1~255 を入力
としていました.しかし,モータ駆動を考えると,正の整数 1~255 を加えると正転,負の整数 -255~-1 を加えると逆転としたほうが整合性が良いでしょう.
このような動作をさせるため,以下の Simulink モデルを作成しました(両者は同じ動作をします).
Simulink モデル "sample1_cw_acw1_signal.slx" |
Simulink モデル "sample1_cw_acw2_signal.slx" |
ここで,Simulink ブロック "Ramp (-255 to +255)" はモータを駆動するために与える指令電圧(-255 ~ 255 の整数値)に相当します.この Simulink モデルでは,
- pwm = -255, -254, -253, ... , 255
のように 1 刻みで指令電圧の整数値を変化させています.また,Simulink ブロック "To Workspae1 (PWM1)" は "PWM1" に入力することを想定している信号,Simulink ブロック "To Workspae2 (PWM2)" は "PWM2" に入力することを想定している信号です.
M ファイル "plot_sample1_cw_acw_signal.m" を実行すると,
となり,所望の結果が得られます.
- Simulink モデル "sample1_cw_acw1_signal.slx"
Rensselaer Arduino Support Package Library (RASPLib) の「Libraries / M2V5 Library」に含まれている Simulink ブロック
と同様の方法です.Simulink ブロック "Left Motor Driver PWM6, PWM7 FD" を空の Simulink モデルに移動し,Simulink ブロックを選択したうえで,マウスの右ボタンで「マスク / マスク内を表示」を選ぶと,中身を確認できます.- Simulink モデル "sample1_cw_acw2_signal.slx"
参考文献 1.(平田先生の本)の 102 頁に記述されている方法です.
そこで,モータを駆動するための Simulink モデルを以下のように修正します.
Simulink モデル "sample1_cw_acw1.slx" |
Simulink モデル "sample1_cw_acw2.slx" |
"Manual Switch" が "Constant1" 側になっている状態で Simulink モデル "sample1_cw.slx" をエクスターナル実行すると,デューティ比 20% で正転します.また,"Manual Switch" をダブルクリックして "Constant2" 側に切り替えると,デューティ比 20% で逆転します.
3.5 指令電圧と角速度の関係は線形?非線形?
図 1 定値の指令電圧を加えたときの角度と角速度 |
モータ駆動系に定値の指令電圧
\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)$ の関係は
\begin{align}
\omega(s) = {P}_{\rm v}(s)v(s),\quad
{P}_{\rm v}(s) = \dfrac{K}{1 + Ts}
\end{align}
のように,1 次遅れとなります.つまり,角速度は
\begin{align}
\omega(t) = K\bigl(1 - {e}^{-t/T}\bigr){v}_{\rm c}
\end{align}
となりますので,定常角速度は
\begin{align}
{\omega}_{\infty} = \lim_{t \rightarrow \infty}\omega(t)
= K{v}_{\rm c}
\end{align}
となります.これより,定値の指令電圧 $v(t) = v_{\rm c}$ と定常角速度 ${\omega}_{\infty}$ は比例関係にあると考えられます.
それでは,本当に比例関係にあるのかを実験により検証してみましょう.実験では,スイッチサイエンスさんの 9V/1.3A の外部電源
を使用しています.検証用の Simulink モデル
Simulink モデル "sample1_cw_acw1_plot.slx" |
Simulink モデル "sample1_cw_acw2_plot.slx" |
のいずれかにおいて,"Constant (-255 to +255)" の数値 pwm を
- 逆転:-255 (100%), -250 (98.0%), ... , -5 (1.96%)
- 静止:0 (0%)
- 正転:5 (1.96%), 10 (3.92%), ... , 250 (98.0%), 255 (100%)
のように 5 刻みに変化させ,エクスターナル実行を行います.
- Simulink モデル "sample1_cw_acw1_plot.slx", "sample1_cw_acw2_plot.slx" では,Rensselaer Arduino Support Package Library (RASPLib) の「Libraries / M2V5 Library」に含まれている Simulink ブロック "M1 Right Connector 2, 3" が利用されています.
- Simulink ブロック "M1 Right Connector 2, 3" では,DCモータに取り付けられている磁気式のインクリメンタル型エンコーダのパルス信号を,4 逓倍でカウントした値 (データ型:int32,データサイズ:$1 \times 1 \times n$) を得ることができます.また,データサイズを $n \times 1$ に変更するために Simulink ブロック "Reshape" を用い,データ型を double にするために Simulink ブロック "Data Type Conversion" を用いています.
- Simulink ブロック "To Workspace" は保存形式を「配列」にしています.また,私は取得したデータを集約したくないので,以下のように設定しています.
- 今回,使用した MinSegShield M2V5 Dual Axis Balancing Kit に搭載されている DFRobot 社のギヤード DC モータ (FIT0482) は,ギヤ比(減速比)が 50:1 であり,また,エンコーダの分解能が 7 PPR(パルス / 回転)です.したがって,カウント数に $360/(50 \times 7 \times 4)$ をかけると,角度 (deg) に変換することができます.
Simulink モデル "sample1_cw_acw1_plot.slx" もしくは "sample1_cw_acw2_plot.slx" を起動している状態で,
- M ファイル "exec_sample1_cw_acw_plot.m"
を実行します.
- 角度 $\theta(t)\ (= y(t))$ を y,角速度 $\omega(t)\ (= \dot{y}(t))$ を dy と記述しています.
- サンプリグ周期を $h = 0.01\ {\rm [s]}$ としたとき,角速度は次式の中心差分近似により計算しています.
\begin{align} \dot{y}[n] = \dfrac{y[n+1] - y[n-1]}{2h} \end{align}
- 定常角速度 $\omega_{\infty}$ を dyinf と記述しています.dy の最後の 10 個の平均としています.
M ファイル "exec_sample1_cw_acw_plot.m" を実行すると,フォルダ "data1" に
- 正転の実験データ:data1_cw0.mat, data1_cw5.mat, … , data1_cw255.mat
- 逆転の実験データ:data1_acw5.mat, data1_acw10.mat, … , data1_acw255.mat
- 定常角速度の実験データ:data1_pwm_dy.mat
が保存されます.なお,私の環境では,M ファイル "exec_sample1_cw_acw_plot.m" の実行時間はおおよそ 1 時間でした.103 回の反復処理を行っていますので,1 回のエクスターナル実行あたりおおよそ 33 秒でした.
M ファイル "exec_sample1_cw_acw_plot.m" の実行終了後,実験結果を描画するために,
- M ファイル "plot_custom_sample1_cw_acw.m"
を実行します.実行結果を以下に示します.
ここで,CW (clockwise) は正転,ACW (anticlockwise) は逆転を意味します.
Figure 12, 22 からわかるように,角速度は 1 次遅れ系のステップ応答の形状をしていますが,Figure 31 からわかるように,大域的に見ると,
- 「指令電圧」と「モータの角速度」の関係は,非線形性が強く,比例関係ではない
ことがわかります.また,指令電圧の整数値が -25, -20, ..., 0, 5, ..., 25, 30 のとき,静止摩擦に打ち勝つことができず,モータは回転しませんでしたので,
- 不感帯が大きい
ことも確認できました.
同様の結果は,参考文献 1.(平田先生の本)の 80-81 頁に記述されています.
4. DC モータを動かす方法(その 2)- 駆動 / ブレーキ動作
ここでは,「指令電圧」と「モータの角速度」がほぼ比例関係となるような方法について説明します.
4.1 動作原理
ここで説明する方法は,Rensselaer Arduino Support Package Library (RASPLib) の「Libraries / M2V5 Library」に含まれている Simulink ブロック
と同様の方法です(これら Simulink ブロックの中身は,マウスの右ボタンで「マスク / マスク内を表示」を選ぶことで確認できます).
まず,以下の Simulink モデルを用意します.
Simulink モデル "sample2_cw_acw_signal.slx" |
M ファイル "plot_sample2_cw_acw_signal.m" を実行すると,
という結果が得られます.つまり,以下のように動作させています.
-
正転させるときは常に "PWM1" に最大値 255 を入力し,"PWM2" に 0 から 254 の値を入力することで動きを妨げるようにする.
-
pwm = 255 のとき:
PWM1 への入力は 255,PWM2 への入力は 0 -
pwm = 204 のとき:
PWM1 への入力は 255,PWM2 への入力は 51 (= 255 - 204) -
pwm = 51 のとき:
PWM1 への入力は 255,PWM2 への入力は 204 (= 255 - 51)
-
pwm = 255 のとき:
-
逆転させるときは常に "PWM2" に最大値 255 を入力し,"PWM1" に 0 から 254 の値を入力することで動きを妨げるようにする.
-
pwm = -255 のとき:
PWM2 への入力は 255,PWM1 への入力は 0 -
pwm = -204 のとき:
PWM2 への入力は 255,PWM1 への入力は 51 (= 255 - 204) -
pwm = -51 のとき:
PWM2 への入力は 255,PWM1 への入力は 204 (= 255 - 51)
-
pwm = -255 のとき:
4.2 正転と逆転を切り替えてみる!
正転と逆転を Simulink ブロック "Manual Switch" で切り替える Simulink モデル
Simulink モデル "sample2_cw_acw.slx" |
をエクスターナル実行すると,
のように動作します.
4.3 指令電圧と角速度の関係は線形!!
最後に,この方法を利用した場合,指令電圧と角速度の関係を調べます.
先と同様,検証用の Simulink モデル
Simulink モデル "sample2_cw_acw_plot.slx" |
において,"Constant (-255 to +255)" の数値 pwm を
- 逆転:-255, -250, ... , -5
- 静止:0
- 正転:5, 10, ... , 250, 255
のように 5 刻みに変化させ,エクスターナル実行を行います.
Simulink モデル "sample2_cw_acw_plot.slx" を起動している状態で
- M ファイル "exec_sample2_cw_acw_plot.m"
を実行します.
M ファイル "exec_sample2_cw_acw_plot.m" の実行終了後,実験結果を描画するために,
M ファイル "plot_custom_sample2_cw_acw.m"
を実行します.その結果,
が描画されます.これらのグラフより,
- 「指令電圧」と「モータの角速度」の関係は,ほぼ比例関係である
ことがわかります.また,指令電圧の整数値が -10, -5, 0, 5, 10 のとき,静止摩擦に打ち勝つことができず,モータは回転しませんでしたが,3 章で説明した方法と比べて,
- 不感帯が小さい
ことがわかります.
5. おわりに
本記事では,
- Simulink Support Package for Arduino Hardware
を利用して,DC モータを駆動する方法について説明しました.
記事をアップした後,宇都宮大学の平田先生から Pololu の DRV8835 のページに
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 に更新し,「駆動 / ブレーキ動作」でモータ駆動をしているとのこと.楽しみですね.
参考文献
-
平田光男:Arduino と MATLAB で制御系設計をはじめよう!,TechShare (2012)
付録
Rensselaer Arduino Support Package Library (RASPLib) の「Libraries / M2V5 Library」に含まれているモータ駆動用の Simulink ブロック
は,入力が -255 ~ 255 の整数値ではなく,電圧(-Vsupply [V] ~ Vsupply [V] の実数値)となっています.Simulink ブロックをダブルクリックすると,Driver Voltage の値 (Vsupply) を設定するようになっています.電力供給の方法により,この値を適当に設定してください.
- USB から電力供給する場合
- 単三電池 6 本 (6AA batteries) により電力供給する場合
- 外部電源により電力供給する場合:購入した AC アダプタに依存
RASPLib のモータ駆動用の Simulink ブロックの内部では,255/Vsupply をかけることで,電圧を整数値に変換する処理が行われていますので,Vsupply の値は厳密である必要はありません.