M5CAMERAでラジコン戦車作ってみた〜【Part3: 対話モードでモータを動かしてみる】
M5CAMERAでラジコン作りの記事です^^)
前回、Part2 ではファームウエアのインストールについて解説しました。
今回、Part3 ではPythonの対話モードで開発の準備として、モータを動かしてみます。
目標
Pythonの対話モードでモータを動かし、左右のキャタピラを前進・後退方向に動かします。
ハードの設置
PCとUSBケーブルで接続しておきます。
この状態で、M5CAMERAおよびモータドライバICにもUSB経由で給電されるので、電池ボックスはOFFのままでOK
写真ではわかりにくいですが、動作テスト時に戦車が動かないようにM5CAMERAの空箱に乗せてキャタピラをうかせています。
接続確認
モータは、モータドライバICに電線でつながっています。
マイコンから命令をモータドライバに送ると、命令を受けたモータドライバが命令にしたがってモータに電流を流します。今回は主に、次の2点について調べていきます。
- 命令の送り先である、モータドライバICのアドレスの確認方法
- 命令の内容となる、回転方向と電圧の指示方法
ドライバICのアドレス確認
マイコンとモータドライバは、I2Cと呼ばれる通信インターフェースで接続します。
I2Cはデバイス間を、SCL,SDA2本の通信線で接続し、信号を順番に送るいわゆるシリアル通信です。命令を送るには、まず接続したデバイスであるモータドライバICのアドレス確認からはじまます。
接続されているI2C部品のアドレス確認は以下の方法で行います。
- machineモジュールのインポート
- i2cオブジェクトの生成
- i2c.scan()の実施
順番に説明します
machineモジュールのインポート
今回使うI2Cインターフェースのような、ハードウエアを扱うには、machineモジュールを使います。screenコマンドでM5CAMERAと接続してPythonの対話モードに入ったら、次のコマンドを実行します。対話モードへの移行方法がわからない方は、こちらを参考にしてください。
>>>import machine
>>>
i2cオブジェクトの生成
i2cオブジェクトの生成は、次のコマンドを実行します。
>>>i2c = machine.I2C(scl=machine.Pin(13), sda=machine.Pin(4))
>>>
注意点としては、sclが13ピン、sdaが4ピンを指定してください。
説明書には、sdaが22ピン、sclが23ピンと書いてありますが、スイッチサイエンスさんのHPにも「本製品は時期によって異なるモデルが存在します。モデルによってピンの配置が異なりますので、下記URL先からどちらのモデルかご確認いただき、適切なピンを宣言してください。」と書いてあります。
自分はここでハマったので、みなさんは気をつけてください。
i2c.scan()の実施
下記のコマンドでi2c.scan()を実施します。
>>> devices = i2c.scan()
>>>
i2c.scan()は、接続されているi2cデバイスのアドレスを返します。
devices変数に結果が入るので、内容を以下のコマンドで確認します
>>> len(devices)
2
>>>
lenは、変数内に格納されているオブジェクトの数を確認するコマンドです。
2つのアドレスが格納されたようなので、次のコマンドでアドレスを確認します。
>>> devices[0]
96
>>> devices[1]
101
>>>
96と101がモータドライバICのアドレスであることが確認できました。
モータを動かしてみる
モータを動かすために、下記のコマンドを実行します。
>>> i2c.writeto_mem(96,0,b'\x99')
止めるには、下記のコマンドを実行します。
>>> i2c.writeto_mem(96,0,b'\x90')
コマンドの引数は、
I2C.writeto_mem(addr, memaddr, buf, *, addrsize=8)
順に解説します。
第1引数の96:命令対象デバイスのアドレス
これは、上のi2c.scan()で確認した、モータドライバICのアドレスです。
第2引数の0:モータドライバのメモリアドレス(レジスタ番号)
今回使っているドライバICは、テキサスインスツルメント社のdrv8830です。データシートを見ると、以下のようなI2Cレジスタ・マップの説明があり、出力電圧の設定はレジスタ0に設定するようになっています。
第3引数のb'\x90':レジスタ0のコントロール値
ここでは、レジスタ0に設定する出力電圧値を指定します。
データシートには、以下のように書かれています。
設定する8bitのうち、D7~D2の上位6桁は、VSETとして電圧を決めるための設定値です。
例えば、3.05Vを設定したい時には、表の左下の0x26hをVSETとして設定します。
これで、上位の6桁が決まります。
設定する8bitのうち、下位の4桁は、状態を決めます。
同じく、データシートには、下記のように定義されています。
例えば、正転駆動したい場合は、IN2=0, IN1=1を設定します。
今回、例としている以下のコマンドの電圧と状態を確認します
>>> i2c.writeto_mem(96,0,b'\x99')
レジスタ0のコントロール値は、16進数のx99を、2進数に変換して、10011011なので、
[D7 D6 D5 D4 D3 D2 D1 D0] =[1 0 0 1 1 0 01]
となります。
電圧は
[D7 D6 D5 D4 D3 D2] =[1 0 0 1 1 0 ] = 0x26hで3.05Vを
状態は
[D1 D0] =[IN2 IN1]=[0 1] 従って、正転であることがわかります。
なお、私の接続では、アドレス96が左側のキャタピラ、101が右側のキャタピラでした。
動作確認
設定色々変えて、実際に動かしてみました。
正回転、1.04V
VSET=0x0Dh なので、[D7 D6 D5 D4 D3 D2 D1 D0] =[0 0 1 1 0 1 01] ->設定値:0x35
逆回転、1.04V
VSET=0x0Dh なので[D7 D6 D5 D4 D3 D2 D1 D0] =[0 0 1 1 0 1 10] ->設定値:0x36
正回転、3.05V
VSET=0x26h なので、[D7 D6 D5 D4 D3 D2 D1 D0] =[1 0 0 1 1 0 01] ->設定値:0x99
逆回転、3.05V
VSET=0x26h なので、[D7 D6 D5 D4 D3 D2 D1 D0] =[1 0 0 1 1 0 10] ->設定値:0x9A
動作確認風景はこんな感じです。
右側のキャタピラ動かす時に、ギアノイズがかなり大きい・・・
組み立て方が雑だったかな?
次回はWiFi接続を行う予定です。