公開日:2024/03/09
title.png

29th Season


#29-5 ロボットカーを組み立てよう(無線操縦)

 先日組み上げたロボットカー(下図)を無線操縦できるように拡張してみたいと思います。

a292_robotcar.jpg

 無線操縦と言えば、ラジオコントロールカーですね。小学生の頃、出来合いのラジオコントロールカーを買ってもらって、遊んでいました。

 一般的なラジオコントロールカーは、プロポと呼ばれる送信機で操縦すると、操作に応じた電波が発信され、それを車の模型が受信して、操作した通りに走ります。プロポが送信した電波が直接ラジオコントロールカーに届くので、見通し数10mの範囲が無線操縦可能範囲です。

 おもちゃのラジオコントロールカーの中には、赤外線を使って操縦するタイプの物もあります。それも確かに、「無線操縦」ですが、赤外線は光なので、ほとんど回折しません。つまり、模型が障害物の影に入ってしまうと届かないので操縦不能となってしまいます(※)。
 赤外線受信モジュールを使った無線操縦を実現するのは、お手軽ではあるけれども、ちょっと違いますよね。

※赤外線は反射するので、壁などに跳ね返った赤外線が、障害物の影に入った模型に届いて操縦可能な場合は、あります。

 「無線」と言うと、「線(ケーブル)が繋がっていない」事なので、ワイヤレスコントロールの方が、より広義の概念です。本ページでは少し狭めて、ラジオコントロール(電波無線操縦)を実現したいと思います。

 手持ちのマイコンで、電波を使った無線通信と言えばM5StickC Plusなので、キミに決めた!

システム設計

 M5StickC Plusの無線通信を使って、無線操縦を実現して行きます。システム全体の構成を考える、システム設計からスタートです。

 M5StickC Plusの無線通信は、2.4GHz帯のWiFiか、Bluetoothでの通信となります。普通のラジオコントロールカーだと、プロポから送信した電波の届く範囲が無線操縦可能範囲です。このラジオコントロールカーに近いのは、Bluetoothを使った通信ですね。Bluetoothの電波が届く範囲で直接通信するためです。

 しかし今回は、UIFlow(下図)のスマホ連携機能(Remote+ブロック)を使って、簡易にシステムを構築しようと思っています。UIFlowのスマホ連携機能はWiFi通信なので、「WiFi無線操縦」と、なります。

a236_m5flow.png


 M5StickC Plusとスマホ間はインターネット通信なので、WiFiと携帯電話📶が通じる限り、地球の裏側からでも操縦が可能です。……まあ、本当に地球の裏側だと、ロボットカーを視認できないので、操縦できないのですけどね……。
 また、操縦した情報はインターネット(TCP/IP)を通って届くため、プロポからの操縦と比べてタイムラグがあることは欠点です(下図)。

a295_rmtctrl.png

 以下、UIFlowを使う前提で、システム設計を進めて行きます。

M5StickC Plusと328duino協調動作

 まず、ロボットカーのブラシDCモータ制御を思い出してみてください(以下記事参照)。

  「#29-1 ロボットカーを組み立てよう

  「#29-2 ロボットカーを組み立てよう(自動走行)

 2WDロボットカーには、2個のブラシDCモータがあって、それぞれ制御しなくてはなりません。モータ1個当たり、制御信号が3本必要なので、モータ2個では6本の制御信号が必要です。M5StickC PlusはI/Oポート数が少ないので、モータドライバモジュールを制御して2個のブラシDCモータを動かすことは困難なのです。

 現在、手持ちのロボットカーは、328duinoモータドライバモジュールを制御しています(上にリンクした記事を参照)。このブロック(下図)は、そのまま使う事にします。

a291_mtrdrv.jpg

 M5StickC Plusと328duinoの分業体制を確認しておきましょう。

  M5StickC Plusが果たすべき役割は:


  328duinoが果たすべき役割は:

 現時点で既に、328duinoはシリアルモニタからコマンドを受け付けるようになっていて、こちらのコマンドで操作可能です。この機構をそのまま使って、M5StickC PlusからUART通信を通して328duinoを制御することにしました。

M5StickC Plusと328duinoの通信はUART

 つまり、328duinoのプログラム(robot_car.ino)が受け付けている、シリアルモニタコマンドを使って、M5StickC Plusから328duinoへ指示を伝えるのです。

 328duinoへコマンドを送信すると、その結果をレスポンスとして返してきますが、このレスポンスは無視して受信しません。どうせ、「OK:」メッセージが返って来るだけだし、一々受信してハンドリングするコードを書くのは面倒だから、です。
 よって、接続するのはM5StickC Plus.TXD → 328duino.RXDだけで充足します。

 UIFlowでは、以下の様なブロックを使って、ハードウェアUARTを使用することができます。

a295_uartblk.png

 必要なのは送信データ端子txだけ、なのですが、上のブロックで明らかな様に、受信データ端子rxも、指定する必要があります。止むを得ないので、以下の様にI/Oポートを割り当てることとしました。

  M5StickC PlusのUART端子指定:

 受信端子RXDは使わないので、必要に応じて別な端子へ割り当てても良いです。
 本当は、RXDを無効にしておくとか、RXDに割り当てた端子をプルアップしておくとか、何らかの端子処理をしておかないと、ごみデータを受信してしまう恐れがあります。今回は、どうせ受信データをハンドリングしないので、そのまま放置してしまいます。

スマホ画面の設計

 UIFlowのスマホ連携機能については、以下記事をご参照ください。

  「#25-8 UIFlowとスマートホン連携

 UIFlowから「Remote+」ブロックを選択し、スマホ画面エディタで、以下図の様に制御インターフェイスを作り込みます。

a295_joystk.png

 今回の所は、シンプルにジョイスティックコントロールだけをド〜ンと配置しておきます。まだ、他に制御可能なセンサや機能が無いためです。将来、ロボットカーに機能を追加した場合、自動走行機能のON/OFFや、クラクションを鳴らす、ヘッドライトを点ける、等々の機能を制御するためのコントロールを随時追加可能です。

ジョイスティックと操縦

 2WDロボットカーの走行状態は、主に、前進/後退、左右旋回、左右その場回転、の3状態に分類できます。以下図は、3状態を図解したものです。

a295_drvstat.png

 これらの走行状態をジョイスティック操作に対応させてみましょう。以下図の様に対応させようと思います。

a295_drvjoy.png

 スマホ画面のジョイスティックコントロールからは座標値(x,y)が通知されるため、その座標値から、以下の様な角度θに変換して処理します。

 なお、ジョイスティックコントロールから通知される座標値は、−100≦(x,y)≦100の範囲です。

 座標値(x,y)から、逆正接atan()関数を使い、θを求めます。

  θ’=atan (y÷x)
  ※θ’は、x軸正方向からy軸正方向へ回転する角度なので、ここから調整してθを求める。

 更に、モータの回転速度を制御するため、ベクタ(x,y)の大きさLも求めておきます。

  L=√(x2+y2)

 以上の予備計算をもって、θから進行方向、Lからモータの回転速度を決定して制御します。

モータの制御コマンドに読み替える

 スマホ画面のジョイスティックコントロールから受信した角度θおよび長さLから更に、328duinoへ送信するシリアルモニタコマンドへ読み替えて行きます。

 M5StickC Plusが送信するシリアルモニタコマンドは、以下の2種類だけで十分です。

  送信するシリアルモニタコマンド:

 【mtr1】は左タイヤ、【mtr2】は右タイヤを駆動するブラシDCモータの制御コマンドです。<pwm_duty>の正/負がモータの正転/逆転に対応し、<pwm_duty>の絶対値(0〜255)がモータの回転速度を制御するパラメータです。
 θ,Lから<pwm_duty>を求める手順を以下の通りに決定します。

 ここで、記述{A,B}は、Aをモータ#1(左タイヤ)、Bをモータ#2(右タイヤ)としました。

コマンド送信

 送信するコマンドの中で一番長い文字列となる【mtr1,-255】は、改行コード(CR+LF)を含めて11バイトです。同時に左右両輪のモータ制御が発生するので、【mtr2】コマンドと合わせて22バイトほどのデータ量と、なります。
 マージンを取って32バイト/1送信と考え、9,600baudのUART通信する場合、通信に要する時間は以下計算の通りです。

  32バイト×10ビット(8N1)÷9,600baud≒33.3ms

 よって、50〜100[ms]間隔でθとLを参照し、328duinoに対してシリアルモニタコマンドを送信するのが良さそうだと解ります。

 送信間隔を狭めて、より細かな制御を目指す場合、UARTの通信速度を、もっと向上する必要があります。と言っても、UIFlowのスマホ連携機能はWiFi経由のインターネット通信(TCP/IP)のため、ネットワーク状態次第では情報の伝達にタイムラグが生じます。つまり、M5StickC Plus → 328duino間の通信間隔を短くしても、ネットワーク遅延が支配的となって限界がある、と言う事です。

 従って、通信速度は9,600baudのままで、50ms間隔のコマンド送信に決めました。

プログラム

 以上、検討の結果、完成したプログラムを以下にリンクしておきます。UIFlowで読み込んで、ご確認ください。

  無線操縦制御プログラム:robot_car_rc.m5f

※WiFiアクセスポイントへの接続などに関するコードを記述していないため、オンライン版UIFlowを使ってください。

 なお、M5StickC PlusのTFT画面には、スマホ画面のURLへ導くQRコードの他に、ジョイスティックの操作状態(θおよびLの値)と、その結果として328duinoへ送信するシリアルモニタコマンドの文字列を表示するようにしてあります(下図)。

a295_uirctrl.png

 こうしておくことで、M5StickC Plusを328duinoと接続して動作確認する前に、M5StickC Plus単体で動作検証とデバッグを実施することができ、デバッグや検証作業が楽になります。

ハードウェア設計

 ハードウェア設計、と言っても、既に組み上がっているロボットカーの基本システムに対してM5StickC Plusが追加となり、UARTで接続するだけで終了です。後は、電源についてちょっと考察が残っています。いずれにせよ、サラッと終わらせましょう。

328duinoとM5StickC Plusの接続

 こちらで決定した様に、328duinoとM5StickC Plus間の通信はUARTですので、以下接続を確立します。

 そうか、この接続が可能なのは328duinoならでは、でしたね。
 何故なら、もしArduino UNOを使った場合、UART端子はボード上の配線パタンで、USB⇔UART変換チップ(ATmega16U2)に接続されてしまっているため、上の接続は不可能です。しかも、UNOは5V定格なので、信号レベルも合いません。
 UNOを使う場合、UNO側はソフトウェアシリアルライブラリなどを使わなくてはなりませんし、場合によってはレベルシフタ(L/S)の挿入も必要となります。

 M5StickC Plus(3.3V定格)との間をL/S無しで直結できる様に、最初から、「UNO 3.3V化328duino」を使ってシステムを構築していたので、ここはサラッと終了です。

M5StickC Plusの電源

 M5StickC PlusはLiPOバッテリを搭載しているので、内蔵バッテリからの給電でも問題ありません。
 ただ、ロボットカーの電源として、単三型充電池×4本とM5StickC Plusの内蔵バッテリ、双方の残量を気にしながら走行させるのは、面倒です。片方でもバッテリ切れを起こすと、ロボットカーを操縦できなくなってしまいますから。

 M5StickC Plusへ、外部から電源を供給することも可能です(下図)。

a237_ioport.jpg

 注意して見ると、「5V→」と「5V←」の2端子が存在します。矢印の向きに注意して見てください。「5V←」の方が、電源の入力端子VINです。VIN端子は、電源管理ICであるAXP192のACIN端子に接続されています。AXP192データシートと、M5StickC Plus回路図から、VIN端子に供給すべき電圧は、3.8V≦VIN≦6.3Vなので、ロボットカーの電源として用意した充電池1.2V×4直列=4.8Vで充足します。

 よって、モータ駆動用、マイコン制御用に加えて、M5StickC Plus用の電源としても、以下の電池ボックスから電源を供給します。

a291_batbox.jpg

 これで、ロボットカーの電源が電池ボックスの単三型充電池×4本に集約されたので、充電池の残量だけを気にして使えば、無線操縦することができます。

無線操縦の実験

 こちらを参照して、最小構成のロボットカーを構築した上で、以下の接続を追加してください。

ロボットカー
制御モジュール(328duino)
接続 M5StickC Plus
Vcc(電池ボックス+電極4.8V) 5V←(電源入力VIN)
GND(電池ボックス−電極) GND
RXI G26(TXD)

 328duinoへ書き込むプログラムなどについては、こちらを参照して準備してください。M5StickC Plusには、今回UIFlowで作成した、こちらのプログラムを書き込んでおきます。


 以下、実験中の様子を示します。

a295_expr.jpg

 M5StickC PlusのTFTディスプレイに表示されたQRコードをスマホでスキャンするなどして制御ページを開き、スマホから無線操縦して見てください。


 当方で無線操縦して見た時の動画を以下にリンクしておきますので、ご覧ください。



 スマホからの操作によって、思い通りにロボットカーを操縦することができています。一方、インターネット(WiFi通信)経由の操縦となることで、多少、タイムラグが見られ、モサッとしている印象も見て取れました。


 これまでに、手持ちの部品やマイコンを組み合わせることで、安価にロボットカーを組み上げ、無線操縦まで到達することができました。引き続き、色々と見えてきた課題解決やアイディアの実現を進めて行きたいと思います。


btn_arduino.png

btn_prev.png btn_next.png

home