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

2021.9.29 Coskx Lab  

1 はじめに

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



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

2 使用環境

3 端子の割り付け

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

→ 利用可能な端子

4 モータドライバDRV8833

モータドライバDRV8833はTexas Instruments社のモータ駆動用ICです。
小さすぎて使いにくいので,使いやすい大きさに端子を引き出してあるのが,HiLetgoの製品HiLetgo DRV3388です。

micro:bitはプログラムに従ってモータを駆動するための信号を生成します。しかしこの信号は直接モータに電流を流す能力は持っていません。そこで,モータドライバDRV8833が,信号をモータを駆動する電流に変える働きを持っています。
DRV8833のデータシートにはDRV8833各端子の信号によってモータがどのように駆動されるかを示す表があります。
モータドライバDRV8833への2つの入力IN1,IN2に応じてモータの動作は次のようになります。(モータを2個制御できるので,モータA用とモータB用があり,端子名の1文字目がA,Bになっています。それぞれ同じ動作をします。)
STBYIN1IN2OUT1OUT2モード
HLLOFF(Hi-Z)OFF(Hi-Z)ストップ
HHLHL正転
HLHLH逆転
HHHLLブレーキ
ただし
H:High 電源電圧と同じ電圧,プログラム上で端子に1を出力した信号
L:Low 約0V,プログラム上で端子に0を出力した信号
OUT1,OUT2は信号ではないが,電圧測定すればH,Lに見える。

5 接続

micro:bitにはUSBから給電し,モータ用電源として3Vまたは4.5Vを与えます。そして,次の図のように配線します。
DRV8833のSTBYにはHを与えるために,3.3Vを接続しています。
DRV8833基板では GNDが3つありますが,基板内部でこの3つはつながっています。
複数の電圧電源が出てくる回路では,グランドは共通にするため,それぞれのグランドを接続すべきですが,この例に限っては接続する必要はありません。


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ブロックプログラムでプログラミングします。
MakeCode画面で「拡張機能」を開き, 拡張機能の一覧の見えているところの検索ボックスで,「https://github.com/healthywalk/nifty-motor-driver-microbit」のURLで検索すると 「nifty-motor-driver-microbit」が見つかるので,これを取り込ます。




拡張機能「nifty-motor-driver-microbit」が取得出来たら,あとは,組み立てるだけです。
テストプログラムではモータ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モータを駆動するとき,低デューティ比で,電流が小さくなり,電流に比例してモータの発生トルクも小さくなり,静止状態からモータを起動できない場合があります。
次のような対策が考えられます。
・モータ電源電圧を高くする
・モータ指令値を高めにシフトする


8 まとめ

モータドライバDRV8833を使用し,拡張機能「nifty-motor-driver-microbit」を使ってモータの駆動を行いました。
駆動電源電圧3Vより4.5Vの方が130モータは安定して回りました。ドライバ回路の内部抵抗が小さくなっている分,自動復帰型過電流保護回路が入っているのですが,低デューティ比駆動の時は起動時に瞬時電流が大きくて,過電流保護回路が働いてしまうことがあります。この傾向は駆動電源電圧が3Vの時に目立ちます。
符号付きの指令値に合わせて,モータの正逆転をさせました。
また惰性回転とショートブレーキ状態への指示もできました。


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

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

 drive motor signed speed  

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

PWM信号はモータドライバでモータの駆動などに使われます。信号が1(High, 3.3V)の区間はモータに通電し,信号が0(Low, 0V)の区間はモータに通電しないというようにモータドライバは動作します。
この動作が1秒間に50回なので,モータは小刻みに動いたり止まったりするはずですが,モータの回転軸には慣性があるので,小刻みな動作にはなりません。
そして,duty cycle 20%のときよりduty cycle 60%のときの方がモータは力強く回ります。
(発生トルクが大きくなりますが,残念ながら比例はしません。)
duty cycle 0%のときは通電無しになり,duty cycle 100%のときには連続通電となります。


補足2 PWM信号の観察

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


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指令のときの状態です。)


実際にはPWM駆動されているので forward で duty cycle が20%のときは,状態Aを4msec,状態Cを16msecという動作を連続しています。

モータ2に関しても,P0とP16で同様な操作がなされています。


補足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周期と同じ長さのパルスになってしまうからです。)