ラビット・エンジニアリング

趣味の電子工作を、備忘録もかねて・・・・

M5CAMERAでラジコン戦車作ってみた〜【Part3: 対話モードでモータを動かしてみる】

M5CAMERAでラジコン作りの記事です^^)

 

前回、Part2 ではファームウエアのインストールについて解説しました。

今回、Part3 ではPythonの対話モードで開発の準備として、モータを動かしてみます

 

 

目標

Pythonの対話モードでモータを動かし、左右のキャタピラを前進・後退方向に動かします。

 

ハードの設置

PCとUSBケーブルで接続しておきます。

この状態で、M5CAMERAおよびモータドライバICにもUSB経由で給電されるので、電池ボックスはOFFのままでOK

f:id:Pin-Pon-Usagi:20210530145236j:plain

PCとUSBで接続。動作チェックの時に戦車が動かないように、

M5CAMERAの空箱に乗せてキャタピラを浮かせています。

 

写真ではわかりにくいですが、動作テスト時に戦車が動かないようにM5CAMERAの空箱に乗せてキャタピラをうかせています。

 

接続確認

モータは、モータドライバICに電線でつながっています。

マイコンから命令をモータドライバに送ると、命令を受けたモータドライバが命令にしたがってモータに電流を流します。今回は主に、次の2点について調べていきます。

  • 命令の送り先である、モータドライバICのアドレスの確認方法
  • 命令の内容となる、回転方向と電圧の指示方法

f:id:Pin-Pon-Usagi:20210530100135p:plain

マイコンとモータドライバの接続

ドライバ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先からどちらのモデルかご確認いただき、適切なピンを宣言してください。」と書いてあります。

f:id:Pin-Pon-Usagi:20210530105821p:plain

説明書のPin番号では、i2c.scan()で検出できない!

自分はここでハマったので、みなさんは気をつけてください。

 

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に設定するようになっています。

f:id:Pin-Pon-Usagi:20210530165155p:plain

drv8830のレジスタマップ

 

第3引数のb'\x90':レジスタ0のコントロール

ここでは、レジスタ0に設定する出力電圧値を指定します。

データシートには、以下のように書かれています。

f:id:Pin-Pon-Usagi:20210530160605p:plain

レジスタ0の設定値について

設定する8bitのうち、D7~D2の上位6桁は、VSETとして電圧を決めるための設定値です。

f:id:Pin-Pon-Usagi:20210530171201p:plain

設定電圧と設定値の対応表

例えば、3.05Vを設定したい時には、表の左下の0x26hをVSETとして設定します。

これで、上位の6桁が決まります。

 

設定する8bitのうち、下位の4桁は、状態を決めます。

同じく、データシートには、下記のように定義されています。

 

f:id:Pin-Pon-Usagi:20210530163328p:plain

モータの状態を決める、組み合わせ

例えば、正転駆動したい場合は、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

 

動作確認風景はこんな感じです。

youtu.be

 

右側のキャタピラ動かす時に、ギアノイズがかなり大きい・・・

組み立て方が雑だったかな?

 

次回はWiFi接続を行う予定です。