micro:bit MakecodeでモータドライバTB6612FNGの動作テスト
-- 拡張機能「nifty-motor-driver-microbit」を使う --

2022.12.30 2021.9.25 Coskx Lab  

1 はじめに

micro:bitにモータドライバTB6612FNGを接続し,DCブラシモータを回転させます。



プログラミングではmicro:bit MakeCodeを用い,拡張機能「nifty-motor-driver-microbit」を使用します。
モータ駆動用外部電源は,3Vを使いますが,4.5Vなどでも使用できます。

2 使用環境

3 端子の割り付け

第1のモータ駆動のためにP8,P12を第2のモータ駆動のためにP0,P16を使用することにします。端子を必要とするセンサなどを同時に使用するときには二重割り当てしないように気を付ける必要があります。
モータ駆動用端子として,利用可能な他の端子を割り当てることもできます。
利用可能な端子についてはこちらで検討してください。

→ 利用可能な端子

4 モータドライバTB6612FNG

micro:bitはプログラムに従ってモータを駆動するための信号を生成します。しかしこの信号は直接モータに電流を流す能力は持っていません。
モータドライバICは,信号をモータを駆動する電流に変える働きを持っています。
そこでモータドライバICであるTB6612FNGを使ってモータを駆動します。

モータドライバTB6612FNGは東芝デバイス&ストレージ株式会社のモータ駆動用ICです。
小さすぎて使いにくいので,使いやすい大きさに端子を引き出してあるのが,秋月電子通商の販売してるAE-TB6612です。



TB6612FNGのデータシートにはTB6612FNG各端子の信号によってモータがどのように駆動されるかを示す表があります。
その表では,1つのモータの駆動にIN1,IN2,PWMの3つの信号を与えるようにも読み取れます。
しかし,PWMとSTBY信号をH(High,電源電圧と同じ電圧を与える)に固定しておくと,他の多くのモータドライバICの制御方式と同じIN1,IN2の2信号のみでの制御が可能となります。
モータドライバTB6612FNGへの2つの入力IN1,IN2に応じてモータの動作は次のようになります。
(モータを2個制御できるので,モータA用とモータB用があり,それぞれ同じ動作をします。)

PWMSTBYIN1IN2OUT1OUT2モード
HHLLOFF(Hi-Z)OFF(Hi-Z)ストップ
HHHLHL正転
HHLHLH逆転
HHHHLLショートブレーキ
ただし
H:High 電源電圧と同じ電圧,プログラム上で端子に1を出力した信号
L:Low 約0V,プログラム上で端子に0を出力した信号
OUT1,OUT2は信号ではないが,電圧測定すればH,Lに見える。

なお,AE-TB6612は組み立てられていない状態で販売されています。 組み立て方の詳細はこちらへどうぞ

→ AE-TB6612 組立

ちょっと便利にしたかったらどうぞ ちょっと便利に

5 接続

micro:bitにはUSBから給電し,モータ用電源として3Vを与えます。そして,次の図のように配線します。
(AE-TB6612のシルク印刷で示されたピンの名前と実際のピンの並び順は合っていますが,位置がずれているので注意)

micro:bitAE-TB6612
P0B IN1
P16B IN2
P8A IN1
P12A IN2

AE-TB6612のPWMA,PWMB,STBYにはHを与えるために,3.3Vを接続しています。
複数の電圧電源が出てくる回路では,グランドは共通にするため,それぞれのグランドケーブルを接続すべきです。
しかし,AE-TB6612の基板上で2つのグランドは接続されているため,接続する必要はありません。



micro:bitのP12などの端子へ直接ケーブルを接続するのは難しいです。
接続を簡単にするため,micro:bitブレイクアウトボードが使われます。
ブレイクアウトボードではmicro:bit端子がピンに引き出されています。
ブレイクアウトボードはいろいろなものが市販されていますが,ここではSparkfunのmicro:bitブレイクアウトボードを使います。



micro:bitブレイクアウトボードには端子名が書いてあるので,それに従って配線します。
ただし,P0,P1.P2,P3は0,1,2,3のように記されています。3V3は3.3Vの意味です。
配線部を拡大すると次のようになります。



モータは1つだけ接続して,モータ駆動テストを行えるようになりました。



注意 モータは,電磁ノイズを発生するため,モータへのノイズ対策をしておかないと,他のセンサなどが誤動作することがあります。

→ モータへのノイズ対策

6 拡張機能「nifty-motor-driver-microbit」

プログラミングにおいて,モータ駆動には,モータドライバ拡張機能「nifty-motor-driver-microbit」を使用します。
「nifty-motor-driver-microbit」には次の特徴があります。
(1)2つのモータドライバ回路を駆動できます。
(2)1つのモータ駆動には2つのmicro:bit端子を使います。初期化においてどの端子を使用するか指定できます。
モータの正負回転方向が設計時と逆だった場合,ここで指示する端子を逆順にすれば修正できます。
(3)モータ指令値は-100から100の値を使います。負の値の場合は逆方向にモータが回転します。指令値の絶対値が大きいほどモータは元気よく回ります。
(4)モータ指令値を0にするとモータの駆動力はなくなります。これと同じ状態を作る専用の命令coast motorが使えます。
(5)電源からの電流を遮断し,モータの両端をショートさせると,回転中のモータは急激に止まります。この状態はショートブレーキと呼ばれます。専用の命令brake motorでこの状態を作り出せます。

ショートブレーキの体験
次の「テストプログラム」のところで,次のことを試してください。
「coast motor,1秒間停止」と「brake motor,1秒間停止」を交互に与えるだけのプログラムを動かしてください。(モータ駆動の電源はONにしておきます。)。当然のことながらモータは回転しません。
タイヤを手で回してください。回しにくくなったり回しやすくなったりを交互に感ずるはずです。回しにくくなったときがショートブレーキ効果です。


7 テストプログラム

汎用モータドライバ用拡張機能「nifty-motor-driver-microbit」を用いて,MakeCodeブロックプログラムでプログラミングします。
(1) MakeCode画面で「拡張機能」を開き,
(2) 拡張機能の一覧の見えているところの検索ボックスで,「https://github.com/healthywalk/nifty-motor-driver-microbit」のURLで検索すると
(3) 「nifty-motor-driver-microbit」が見つかるので,これを取り込ます。




拡張機能「nifty-motor-driver-microbit」が取得出来たら,あとは,Makecodeでプログラムを組み立てるだけです。
次のテストプログラムではモータ1だけを駆動しています。
2秒ごとにモータ指令値を変えてモータ1を回転させます。

初期化命令で,モータ1のために端子P8と端子P12を使うことを指示します。(このように1つのモータに2つのピンを割り当てます。)
モータへの指令値(signed speedと書いてあります。指令値範囲:-100~100)はここでは50と-50を使います。 符号の正負は,正転逆転を意味します。絶対値が大きな値ほどモータが力強く回転します。
coast motorでは,モータをOFFにして惰性回転させます。やがては止まります。(これはsigned speed=0を指示したときと同じです。)
brake motorでは,モータの両端をショートさせ,ショートブレーキの状態にします。
coastのときよりbrakeのときの方がはやくモータが停止するのがわかると思います。
モータ2を使うときは,「motor1」のところを「motor2」に変更し,初期化では別な2つのピンを割り当てるようにすれば,出来ます。
「motor1」「motor2」の両方を指示すれば2つのモータを同時に駆動できます。

  モータドライバの動作テスト用プログラム



コピペする場合は,拡張機能「nifty-motor-driver-microbit」を取り込んでから,次のソースコードをPythonソースとして貼り付ければ完了です。

NiftyMotorDriver.initialize_motor_driver(MotorEnum.M1, DigitalPin.P8, DigitalPin.P12)

def on_forever():
    NiftyMotorDriver.drive_motor(MotorEnum.M1, 50)
    basic.pause(2000)
    NiftyMotorDriver.coast_motor(MotorEnum.M1)
    basic.pause(2000)
    NiftyMotorDriver.drive_motor(MotorEnum.M1, -50)
    basic.pause(2000)
    NiftyMotorDriver.brake_motor(MotorEnum.M1)
    basic.pause(2000)
basic.forever(on_forever)

ちょっと便利な機能
モータ駆動時には正負の値を指令値として与えますが,正または負の値を与えたとき,モータが思っていたのと逆に回るとき,通常は,モータの配線を逆につなぎ変えますが,面倒ですね。
そこで,この拡張機能の「initialize Driver ...」において,「pin1=」と「pin2=」の端子を交換することで,モータの回転方向を逆に変更することができます。


低デューティ比での駆動の弱点
モータドライバを使って,PWM方式でDCモータを駆動するとき,低デューティ比で,電流が小さくなり,電流に比例してモータの発生トルクも小さくなり,静止状態からモータを起動できない場合があります。
特にモータドライバAE-TB6612はON時の内部抵抗が0.5Ω(モータ駆動電源が5V以上の時,データシートによる)(ここでは電源電圧が低いので内部抵抗はもっと大きいと考えられます)と大きく,この傾向が強いです。
次のような対策が考えられます。
・モータ電源電圧を高くする
・モータ指令値を高めにシフトする


8 まとめ

モータドライバAE-TB6612を使用し,拡張機能「nifty-motor-driver-microbit」を使ってモータの駆動を行いました。
AE-TB6612は,最近の低内部抵抗ドライバICに比べて内部抵抗が大きく,過電流保護回路もついていないのですが,それが幸いして,駆動用電源3Vでの130モータの駆動用として使いやすいです。
符号付きの指令値に合わせて,モータの正逆転をさせました。
また惰性回転とショートブレーキ状態への指示もできました。


補足1 モータ駆動の緑色のブロックの動作

MakeCodeブロックプログラムにおけるモータ駆動の緑色のブロックの動作の舞台裏を考えます。

「最初だけ」ブロック中で,「Initialize Driver」ブロックを使い,ドライバの初期化が行われています。
micro:bitのP8とP12がモータ1の制御に使われています。

次の「drive notor」ブロックを例にとります。

 drive motor signed speed  

この命令は,モータ1を指令値60で正転駆動させなさいの意味で,指令値60 はduty cycle 60%の意味です。
「signed speed」という表現はduty cycle(duty ratio)のことで,micro:bitが作り出すPWM(pulse width moduration:パルス幅変調)信号の時間的変化を指示しています。
PWM信号は周期的に0,1を繰り返す信号になります。繰り返し1回分の時間を周期(ここではPWM周期)と言います。周期の逆数は周波数です。
この拡張機能では周波数(ここではPWM周波数)は決められていて,50Hz(周期は20msec)でした。
これは,周期的信号の1の部分の長さを1周期の60%にするという意味です。



signed speed -60 のときは duty cycle 60% で逆転します。
PWM信号はデジタル信号なので,0または1の値を取ります。micro:bitの端子に見えるのは電気信号ですので,0Vまたは3.3Vの値をとります。
正転・逆転の時,モータドライバのIN1,IN2には次のような信号がP8・P12から送出されます。(75%駆動での正転・逆転のとき)



IN1が1(High, 3.3V)でIN2が0(Low, 0V)の区間はモータドライバはDCモータに正転方向に通電し,IN1が0(Low, 0V)でIN2が0(Low, 0V)の区間の区間はDCモータへの通電をやめます。
IN1が0(Low, 0V)でIN2が1(High, 3.3V)の区間はモータドライバはDCモータに逆転方向に通電し,IN1が0(Low, 0V)でIN2が0(Low, 0V)の区間の区間はDCモータへの通電をやめます。
この動作が1秒間に50回なので,モータは小刻みに動いたり止まったりするはずですが,モータの回転軸には慣性があるので,小刻みな動作にはなりません。

そして,duty cycle 20%のときよりduty cycle 60%のときの方がモータは力強く回ります。
(発生トルクが大きくなりますが,残念ながら比例はしません。)
duty cycle 0%のときは通電無しになり,duty cycle 100%のときには連続通電となります。


補足2 PWM信号の観察

micro:bitのP8とP12の信号をオシロスコープで観察します。
micro:bit内のプログラムをそのままにして,次のように配線して,信号観察を行います。(モータドライバAE-TB6612への配線は残っていても構いません。)


duty cycle 20%のときとduty cycle 60%のときのP8とP12の信号の観察は次のようになりました。
(P8のみにPWM信号が現れています。周期は20msecでduty cycleの違いがわかると思います。)

(1) duty cycle 20%のとき


(2) duty cycle 60%のとき


補足3 モータ正逆転の仕組み

正転指令のときは,P8(モータドライバIN1)のみにPWM信号が現れました。逆転指示のときはP12(モータドライバIN2)のみにPWM信号が現れます。
これでどうしてモータの正逆転ができるのか考えてみます。
次の図はモータドライバの中味の重要な部分だけを取り出したものです。
FETは単純にスイッチのように働きます。ただし,FETは上向きダイオードがあり(寄生している)図の上向きには電流はいつでも流れる性質があります。


P8(モータドライバIN1)信号とP12(モータドライバIN2)信号の組み合わせは4通りあるのですが,4つのFETがどのように働くのかを次に示します。

A. P8(モータドライバIN1):1 P12(モータドライバIN2):0 のとき
FET1とFET4がONになり,正転方向に電流が流れます。


B. P8(モータドライバIN1):0 P12(モータドライバIN2):1 のとき
FET3とFET2がONになり,逆転方向に電流が流れます。


C. P8(モータドライバIN1):0 P12(モータドライバIN2):0 のとき
4つのFETはすべてOFFになり,モータは静止するか,惰性回転しています。これはcoast指令の状態です。


D. P8(モータドライバIN1):1 P12(モータドライバIN2):1 のとき
FET2とFET4がONになります。FETは上向きには電流はいつでも流れる性質があるので,モータはショートブレーキ状態です。(break motor指令のときの状態です。)


補足4 PWM周期より短い周期でのデューティ値変更

モータドライバ拡張機能の舞台裏では,デフォルトで20ミリ秒周期のPWM信号が生成されています。プログラムではPWMデューティ比を決めるデューティ値(0から1023までの値)を設定します。(例えばモータドライバ指令ブロックで指令値50を与えるとデューティ値512が設定されます。)
PWM信号生成のメカニズムは次のようになっています。
1周期の間にPWMカウンタが0から1023までを数えています。
このPWMカウンタは1024になった瞬間に0に戻ってしまいます。この瞬間にPWM出力信号は1(High, 3.3V)になります。
PWMカウンタは増え(20/1024ミリ秒毎に1増える)続け,デューティ値と等しくなった時に,PWM出力信号は0(Low, 0V)になります。

さて,PWM周期より短い周期でデューティ値を変更したらどうなるかは興味深いです。
これはプロセッサの設計がどうなっているかに依存します。
次のようなプログラムでテストしました。
PWM周期はデフォルトで20msになっています。



このプログラムではPWM周期より速い周期でのデューティ値変更になっているでしょう。
次の図はこのプログラム実行時のPWM信号です。



パルスの周期は20msになっているのがわかります。
3種類のパルスが見えています。一番長いのがデューティ値512のパルス,中くらいなのがデューティ値256のパルス,線のようにしか見えない短いのがデューティ値16のパルスのようです。
PWM信号は滅茶苦茶にはなっていませんが,パルス長変更の順番は滅茶苦茶です。
PWM信号生成のメカニズムでは,PWMカウンタがクリアされた瞬間にPWM出力信号はHになり,PWMカウンタの値がデューティ値と等しくなった時にPWM出力信号はLになります。

実際の動作は次のようになっていると考えられます。

そのため,プログラムが続けざまに,PWMデューティ値を設定しても,第1のレジスタの値が変化するだけで,PWM信号の生成には何も影響を与えません。
PWMカウンタがクリアされた瞬間に第1のレジスタに保存されていた値が第2のレジスタにコピーされるので,その時点での最新の第1のレジスタの値がコピーされます。
上記のプログラムでは第1のレジスタの値は高速に変化しているので,PWMカウンタがクリアされた瞬間に第2のレジスタにコピーされる値はその時点での最新の第1のレジスタの値ということになります。
このような理由で,3種類のパルスの発生順はランダムになっていると考えられます。
(もし,プログラムがPWMデューティ値を設定した時に第2のレジスタに直接書き込まれると,パルス幅は滅茶苦茶になります。例えば,デューティ値が512で,PWMカウンタが400くらいのときに,デューティ値256が書き込まれたとすると,その回のパルスはLになることなくPWM周期と同じ長さのパルスになってしまうからです。)