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

2021.8.24 Coskx Lab  

1 はじめに

micro:bitにモータドライバボード(KITRONIK-5620)または(KITRONIK-5698)を接続し,モータを回転させます。
モータドライバボード(KITRONIK-5620/5698)の外部電源は4.5Vです。



Kitronikから,このボードを使用するための拡張機能が公開されていますが,子供の使用を想定しているため,次の点が不満です。
(1)まだ負の数を学習していないので,モータの正転逆転のデューティー比指示に-100から100のような連続値が使えません。これはカートのフィードバック制御のときは不便です。
(2)ショートブレーキの概念はイメージが難しいので,この機能を使えるようになっていません。
そこで,この2つを使えるような拡張機能を作成し,ここで使用します。


2 使用環境

3 端子の割り付け

モータドライバボード(KITRONIK-5620)または(KITRONIK-5698)を使用しますが,これらはすでにP8,P12,P0,P16を使用することになっているので,新たな端子を割りつける必要はありません。しかし,他の端子を使用するセンサなどを同時に使用するときにはすでにこれらの端子が使用済であることに気を付ける必要があります。(二重割り当てしないようにします)

補足
micro:bitのP8,P12はモータドライバボード内で,モータ1の制御に用いられ,モータ1ドライバ回路のIN1,IN2に接続されています。
micro:bitのP0,P16はモータドライバボード内で,モータ2の制御に用いられ,モータ2ドライバ回路のIN1,IN2に接続されています。

4 接続

micro:bitをモータドライバボード(KITRONIK-5620)または(KITRONIK-5698)に取り付け,モータを接続します。
信号線はモータドライバボード内で接続済なので,新たな配線は不要です。
KITRONIK-5620の電源として4.5V~6Vを与えるとボード内で,3.3Vロジック回路用電源を供給することができ,micro:bitに供給するため,この電源だけでシステムが動作可能です。
KITRONIK-5698では電源としてて3V~10Vを与えるとボード内で,3.3Vロジック回路用電源を供給することができ,micro:bitに供給するため,この電源だけでシステムが動作可能です。(3.3Vでセンサ等を駆動する場合は電源は4V~10Vが必要)

(1) KITRONIK-5620を使用する場合

図のように2つのモータを駆動できますが,ここではテストなので1つだけモータを回します。

(2) KITRONIK-5698を使用する場合

図のように2つのモータを駆動できますが,ここではテストなので1つだけモータを回します。


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

→ モータへのノイズ対策

5 拡張機能「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にしておきます。)。当然のことながらモータは回転しません。
タイヤを手で回してください。回しにくくなったり回しやすくなったりを交互に感ずるはずです。回しにくくなったときがショートブレーキ効果です。


6 テストプログラム

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




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

初期化(initialize Driver)の所で,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つのモータを同時に駆動できます。

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



コピペする場合は,拡張機能「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=」の端子を交換することで,モータの回転方向を逆に変更することができます。


7 まとめ

KITRONIK-5620またはKITRONIK-5698を使用し,拡張機能「nifty-motor-driver-microbit」を使ってモータの駆動を行いました。 符号付きの指令値に合わせて,モータの正逆転をさせました。
また惰性回転とショートブレーキ状態への指示もできました。


補足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が挿入された状態では,micro:bitのP8とP12の信号を取り出して見ることができません。
そこで,micro:bit内のプログラムをそのままにして,次のようにブレイクアウトボードに差し替えて,信号観察を行います。


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