![]() | BrainPad上部には直流モーターを動かすための出力ピンがあります。これはPWMを用いてモーターのスピードをコントロールすることができます。しかし、回転方向は決まっています。まずは、この原理から勉強していきましょう。 |
スピード調節の考え方 | |
---|---|
モーターと言えば大概の人は子供のころに遊んだマブチモーターをイメージします。実はこれが基本です。 乾電池を一個つなげれば、回転します。二個直列につなげれば高速回転します。三個直列につなげると、さらに高速回転しますが、変な臭いがし始めて壊れるかもしれません。 |
![]() |
今度は乾電池一個よりも遅く回転させるにはどうしたら良いでしょうか? 例えば半分のスピードにするために半分の電圧にすることを考えます。 電圧を下げるために抵抗を直列につなぐと考える人もいるでしょう。使用条件に依存しますが、0.5A流れるとして半分の電圧がモーターにかかるとすると、 2R = 1.5(V)/0.5(A) = 3、 従ってR=1.5Ω、抵抗で消費される電力 P=IV = 0.5*0.75=0.375、従って1.5Ωで1/2Wの抵抗が必要になります。 電流がスピードに比例すると仮定して、3/4のスピードにするには、抵抗値は0.5Ωとなります。 では、連続的にスピードを変えるにはどうするかというと、消費電力が大きい可変抵抗が必要になります。さらにこれをコンピュータでコントロールするには? と考えるとだんだんと複雑になります。従って、大変なことが起こりそうなので、ここでこの延長を考えるのをやめます。 モーターを乾電池1個つなぐ場合を考えます。
実際には、逆回転ができないと意味が無いので、制御パルス幅のある値より大きい場合と小さい場合で逆回転するように制御します。 これをハードウェアで行う回路をHブリッジと呼びます。 |
![]() |
|
実際には、HブリッジのスイッチをPWMで高速にON/OFFさせます。これをすべてCPUが行うと大変なので専用IC(集積回路、モータードライバ)を用います。このICにコマンドやデータを送ってモーターの制御を行います。ここでは、この通信にはI2C(アイ スクウェアー シー あるいは アイ ツー シー)のプロトコル(通信規約、通信手順)を用います。 ここでは、このモータードライバとして「DRV8830使用DCモータードライブキット」を用います。 ![]() | |
![]() ![]() |
I2Cのデバイスはは7bitのアドレスを持ちます。複数のデバイスを同時に使うには、別のアドレスを付与しなければいけません。ここでは、両方ともオープンの0x64とA0側をLにした0x63の二つのデバイスを用いることにします。 |
二つのモーター動作チェックプログラム | |
---|---|
public partial class Program { private void main() { DCMotor leftMotor = new DCMotor(0x63, CPU.E5, CPU.E6); DCMotor rightMotor = new DCMotor(0x64, CPU.E5, CPU.E6); int speed = 30; // 30%のスピード while (true) { leftMotor.Move(speed); Thread.Sleep(1000); leftMotor.Stop(); Thread.Sleep(1000); leftMotor.Move(-speed); Thread.Sleep(1000); leftMotor.Stop(); Thread.Sleep(1000); rightMotor.Move(speed); Thread.Sleep(1000); rightMotor.Stop(); Thread.Sleep(1000); rightMotor.Move(-speed); Thread.Sleep(1000); rightMotor.Stop(); Thread.Sleep(1000); } } } // DRV8830使用DCモーター public class DCMotor { private static SoftwareI2CBus motor; private byte address; private byte dir; byte[] buf1 = { 0, 0x49 }; byte[] buf2 = { 0 }; byte[] faultClear= {0x01,0x80 };//faultレジスタクリア int speed; public const byte Stanby = 0x00; public const byte Reverse = 0x02; public const byte Normal = 0x01; public const byte Brake = 0x03; private const int maxVoltage = 0x40; int wc, rc; // 書き込みバイト、読み込みバイト数 public DCMotor(int address,Cpu.Pin SCL, Cpu.Pin SDA) { this.address = (byte)address; // プルアップ抵抗が必要 if(motor==null) motor = new SoftwareI2CBus(SCL, SDA); } public void Move(int speed) { byte dir; if (speed < 0) { dir = Reverse; speed = -speed; } else dir = Normal; speed = speed * maxVoltage / 100; // スピードの絶対値のパーセント int slow = 0x18; motor.WriteRead(address, faultClear, 0, 2, buf2, 0, 1, out wc, out rc); if (dir != this.dir) { buf1[1] = (byte)(slow | Stanby); motor.WriteRead(address, buf1, 0, 2, buf2, 0, 1, out wc, out rc); Thread.Sleep(200); buf1[1] = (byte)(slow | Brake); motor.WriteRead(address, buf1, 0, 2, buf2, 0, 1, out wc, out rc); Thread.Sleep(200); buf1[1] = (byte)(slow | Stanby); motor.WriteRead(address, buf1, 0, 2, buf2, 0, 1, out wc, out rc); Thread.Sleep(200); buf1[1] = (byte)(slow | dir);// 目的の方向へ motor.WriteRead(address, buf1, 0, 2, buf2, 0, 1, out wc, out rc); Thread.Sleep(200); } buf1[1] = (byte)((speed << 2) | dir); motor.WriteRead(address, buf1, 0, 2, buf2, 0, 1, out wc, out rc); this.dir = dir; this.speed = speed; } public void Stop() { motor.WriteRead(address, faultClear, 0, 2, buf2, 0, 1, out wc, out rc); buf1[1] = (byte)(0x18 | Stanby); motor.WriteRead(address, buf1, 0, 2, buf2, 0, 1, out wc, out rc); Thread.Sleep(200); buf1[1] = (byte)((0x18) | Brake); motor.WriteRead(address, buf1, 0, 2, buf2, 0, 1, out wc, out rc); Thread.Sleep(200); } } |
1 2 3 4 SCLをE5、SDAをE6に接続 5 左のモーターのオブジェクト 6 右のモーターのオブジェクト 7 8 9 左のモーターを 10 正回転させる 11 1秒待つ 12 止める 13 1秒待つ 14 逆回転させる 15 1秒待つ 16 止める 17 1秒待つ 18 右のモーターを 19 正回転させる 20 1秒待つ 21 止める 22 1秒待つ 23 逆回転させる 24 1秒待つ 25 止める 26 1秒待つ 27 28 29 30 31 32 33 34 35 36 コントロールレジスタ設定用 37 データ読み取り用 38 FAULTレジスタクリア用 39 40 41 42 43 44 45 46 47 48 コンストラクタ 49 50 51 52 I2Cオブジェクト生成 53 54 55 56 パーセントで動かす 57 58 59 マイナスの時は逆回転 60 61 逆方向にする 62 絶対値にする 63 64 正方向回転 65 パーセントからの変換 66 67 エラークリア 68 69 前回と回転方向が異なる場合 70 71 72 スタンバイにする 73 200ms待つ 74 75 ブレーキをかける 76 200ms待つ 77 78 スタンバイにする 79 200ms待つ 80 81 遅く回転させる 82 200ms待つ 83 84 85 目的のスピードで回転させる 86 回転方向を記憶させる 87 スピードを記憶させる 88 89 停止させるメソッド 90 91 エラークリア 92 93 スタンバイにする 94 200ms待つ 95 96 ブレーキをかける 97 200ms待つ 98 99 |