二足歩行ロボットコミュニティサイト

【サイトの使い方】  【サイトマップ】  【お問い合わせ】 
ロボット動画  |   ロボット写真  |   BBS  |   ダウンロード  |   イベント予定  |   スタッフ日記  |   リンク  |  
ログイン パスワード    新規登録   パスワード紛失  

 

第11回 ロボットをシリアル通信で動かす(後編)

 後編は、Bluetoothなどを利用した無線での通信や、その他もう少し詳しく踏み込んだ部分まで説明します。ただ、技術的な詳細まではあまり細かく説明できないため、デバイスやソフトの使用方法で分らないところは各自で調べてみてください。

Bluetoothで接続する

 Bluetoothは近年台頭してきた無線通信の規格で、音声やその他様々なデータを対応モジュール同士で簡単にやり取りできるようになっています。シリアル通信もこの中に含まれており、「SPP(Serial Port Profile)」に対応したBluetoothモジュールであれば、前回のハイパーターミナルで通信した方法とまったく同じように、簡単に通信できます。

 今回、CPUボードとの接続には浅草ギ研の「AG-BT20E」を使いました。ただし、この商品は既に生産終了しており、後継機種として「BlueMaster」というものが出ているようです。紹介ページを確認すると基本仕様はAG-BT20Eとほぼ同じようなので、「通信速度の設定」「ケーブルをはんだ付けするポート」「マスター・スレーブの設定(スレーブで使用?)」などを参考に設定を変更すれば、こちらでも同じことができるかもしれません。

 また、当然PC側にもBluetoothのモジュールが必要です。前述の浅草ギ研のモジュールに対応する場合、「Ver2.0以上」「プロファイルがSPP対応」を満たす使用であれば問題ありません。Bluetoothモジュールは、あらかじめPCに搭載されている場合もありますが、PCに搭載されていない場合は市販のUSBに接続するBluetoothモジュールを使用します。PCショップに行けば「Ver2.1+EDR Class2」程度の商品が数千円程度で購入できます。

 それでは、まずAG-BT20EとCPUボードを接続する部分を作成します。両者の接続にはフラットケーブルと10芯コネクタ1個、半田ごてとハンダを使用します。

 まずフラットケーブルに10芯コネクタを圧着してください。相変わらず▲印と茶色のケーブルをあわせる点に気をつけます。また、コネクタを圧着したら、ケーブルの反対の端から、黒・白・赤・茶の4本のケーブルを一本ずつばらけさせ、ケーブルの皮膜を先端から数mmむきます。


 続いて、基板の「RX」「G」「TX」「3.3V」の4つのポートにケーブルをはんだ付けします(今回はケーブルを直接半田付けしていますが、見た目や耐久性の面でブレッドボードなどを用いてはんだ付けした方が望ましいです)。正しい接続は、「RX」に茶、「G」に黒、「TX」に赤「3.3V」に白を接続します。接続する場所を間違えると正しく通信できないばかりか、基板を壊す可能性もあるので注意してください。特に白、黒と「G」「3.3V」の部分ははんだ付けを絶対に間違えないでください。また、半田を流しすぎてケーブルがショートしないように注意してください。また、ここで使わないケーブルは、先端にビニールテープを貼るなど絶縁対策をしてください。


 最後に、AG-BT20Eの通信速度を、本体のディップスイッチより変更します。CPUボードの通信速度は115200bpsなので、ここではディップスイッチを1,2とも「OFF」に合わせます。


 CPUボードへBluetoothデバイスの取り付けが完了したら、続いてPCとCPUボードをBluetoothで接続します。なお、PCへのBluetoothデバイスの接続や、他のBluetoothデバイスへの接続については、使用するBluetoothモジュールによって異なるため、詳しい説明を省きます。PCからBluetoothを利用できる状態にしてCPUボードに電源を供給すると、AG-BT20Eの「RADY」のLEDが赤く光り、接続可能なBluetoothデバイスに「AG-BT20E」という名前の接続先が見えるようになります。ここでPCから「AG-BT20E」に接続してください。


 また、この接続で使用するシリアルポート番号(COM番号)も忘れず確認しましょう(この確認方法もBluetoothモジュールにより異なるので説明を省きます)。


 Bluetoothの接続とシリアルポート番号の確認ができれば、あとは前回とまったく同じ方法で通信テストができます。ハイパーターミナルを起動し、シリアルポート番号に調べたものを選択、通信設定は前回とまったく同じにして、メッセージを送信してみましょう。前回と同じように通信できれば作業は完了です。正しく通信できない場合、ディップスイッチの設定を見直してください。また、はんだ付け箇所でTXとRXのポートを逆に接続したりしていないか確認してみてください。

C言語から制御する

 Bluetoothにより無線制御できるようになったとしても、これまで紹介してきた方法では全てハイパーターミナルからの制御だけなので、いまいち実用に欠けました。もう少しシリアル通信をうまく活用したいと思います。そこで、C言語の自作プログラムでシリアル通信をしてみたいと思います。

 ちなみに、ここで紹介する内容は、もちろん前回のようにVS-IX003などで接続する方法で使用可能ですが、先ほど紹介したBluetoothによる通信にも問題なく使用できます。ということは、PCからロボットを簡単にリモートブレイン形式で操作できるようになります。

 C言語でCPUボードとシリアル通信するプログラムについては、サンプルソースがサポートページに公開されています。この項目ではサンプルソースに従って説明を進めるので、こちらをダウンロードしておいてください。

●VS-RC003シリアル通信 C言語サンプルソース

 ちなみに、サンプルソースは、Microsoft VC++6.00以降を想定して記述されています。ライブラリやヘッダファイルなどはVCに最初から含まれるものだけを使っているので、他のライブラリをダウンロード・インストールする必要はありません。Linux及び他のOS・開発環境では、このサンプルソースをそのまま使うことはできませんが、「シリアルポートの取得」と「通信データの送受信」の二つを使用している環境に応じて置き換えできれば、比較的容易に移植できると思います。

サンプルソースの実行

 サンプルソースをビルドする場合は、まず。VCで新しいプロジェクト(最近のVCならソリューションとも言います)を作成します。このとき作成するプロジェクトの形式は、「Win32 コンソールアプリケーション」で「空のプロジェクト」にします。


 プロジェクトを作成したら、ダウンロードしたサンプルソースをプロジェクトに組み込みます。続いてソース16行目の「#define TARGET_PORT _T("\\\\.\\COM3")」という部分を、各自のCPUボードのシリアルポート番号に変更してください。


 ソースを書き換えたら、あとはそのままビルドするだけで実行ファイルを作成できます。VCのバージョンによっては、ビルドの際にprintf関数などに関して警告が出ることがありますが、基本的に問題ありません。

 ビルドしたソースを実行すると、画面に「0〜3:コントローラの△,○,×,□ボタン入力〜」と表示されます。これが表示されずすぐにプログラムが終了する場合は、PCがCPUボードと正しく通信できていません。CPUボードとPCが正しく通信できる状態であるか、また、通信できる状態であっても、ハイパーターミナルなど別のプログラムから既にCPUボードと通信していないか、確認してください。

 正しく通信できている場合、画面に表示されているように「0〜3」もしくは「C,Z,X,R」をキーボードから入力してエンターキーを押すと、CPUボードにメッセージを送信します。また、「Q」を入力するとプログラムを終了します。プログラムの途中で通信が途切れた場合、プログラムを中断します。

 プログラムの仕組みは、主に「シリアルポートの取得」「送信メッセージの作成」「メッセージの送受信」の三つに分かれます。それぞれの要素を理解すれば、簡単にシリアル通信用プログラムを作成できます。

シリアルポートの取得

 サンプルソースでは、シリアルポートの取得をmake_handle関数で行なっています。make_handle関数では、「シリアルポートのオープン」「通信速度等の設定」「タイムアウトの設定」の三つを行なっています。「シリアルポートのオープン」「通信速度等の設定」は、このソースとまったく同じ記述です。また、タイムアウトの設定は必ずしも入れなくても良いですが、プログラムのフリーズ対策などのために設定しておく方が良いです。このプログラムでは、受信が100msec、送信が200msecでタイムアウトするようにしています。

 また、Windowsでは、シリアルポート番号が10以上の場合「\\.\COM??」と記述しないと正しく認識されません。サンプルソースではこの部分を正しく対処しているので、自作プログラムを作成する場合も忘れずに対応しましょう。

 正しくシリアルポートを取得できれば、関数は戻り値にそのシリアルポートの通信ハンドルを返します。この戻り値はメッセージの送受信にも使うため、必ずHANDLE型の任意の変数に記録しておきます。また、シリアルポートの取得・設定変更に失敗した場合、戻り値に「INVALID_HANDLE_VALUE」を返します。また、ここで取得したシリアルポートのハンドルは、プログラムの終了時にCloseHandle関数で必ず開放してください。

通信メッセージの作成・送信

 メッセージはsprintf関数などを使用して、文字列の形式で作成します。メッセージの書式(r,wコマンドや変数のアドレスなど)は前回の解説とまったく同じです。また、メッセージの最後に改行文字として「\r\n」の2文字を必ず入れてください。また、文字コードはASCII準拠で1文字が1byteの形式で作成してください。

 最近はUNICODEをはじめ、様々な文字コードがプログラミングで使用されており、使用される文字コードも開発環境・OSなどによって左右されます。これがプログラム中に明示的に切り替えられるとまだ把握しやすいのですが、最近の環境ではプログラムが煩雑にならないようにOSや開発環境側で自動的に文字コードを切り替える形式も多くなっています。VCでは、char型で配列変数を確保してsprintf関数で文字列を作成すれば正常な形式のメッセージを作成できるので(2010年2月時点)、サンプルプログラムでもこの方法を使用しています。

 メッセージを作成したら、WriteFile関数で送信します。WriteFile関数には5つの引数がありますが、最低限先頭から4つ目までの引数を与えれば問題ありません。引数は、1番目よりそれぞれ「シリアルポートの通信ハンドル」「通信メッセージのデータへのポインタ」「通信メッセージのサイズ(長さ)」「実際に送信できたメッセージのサイズを書き込む変数へのポインタ(DWORD型)」です。5番目の引数は、とりあえずNULL(0)を与えてください。

 メッセージのサイズの取得にstrlen関数を使用していますが、これも文字コードの影響があるため、VCではこれ以外の関数を使わない方が無難です。また、「実際に送信できたメッセージのサイズを書き込む変数へのポインタ(DWORD型)」はNULLを与えないようにしてください。

 メッセージを送信したら、WriteFile関数は送信結果に応じて戻り値を返します。メッセージ送信が正しく行われた場合は0以外、正しく行われなかった場合は0を返します。

通信メッセージの受信

 メッセージを送信するとCPUボードからも何らかのメッセージが返されるので、それを受信します。なお、メッセージの送信後に必ず受信を行なってください。

 メッセージの受信はReadFile関数を使用します。関数の引数はWriteFile関数とほぼ同じです。引数は、1番目よりそれぞれ「シリアルポートの通信ハンドル」「受信メッセージを格納する変数へのポインタ」「一度にメッセージを受信するサイズ(長さ)」「実際に受信できたメッセージのサイズを書き込む変数へのポインタ(DWORD型)」です。5番目の引数は、とりあえずNULL(0)を与えてください。与える変数の型もまったく同じです。

 メッセージの受信は、送信とは異なり1byteずつ文字を読み込んでいます。そして、それぞれ「改行文字(\n)が2回出てきた場合」「戻り値が0(異常が発生)の場合」「実際に読み込めたデータサイズが0の場合」の3つのケースで読み込みを終了します。

 1byteずつ読み込む理由は、通信メッセージがデータサイズが状況によって変わる、いわゆる「可変長」であり、更に直前に送信したメッセージと長さが異なることも多いです。つまり、実際に読み込みを実行してみないとデータサイズが分りません。そこで、「CPUボードにコマンドを実行させて返ってくるメッセージには、改行文字(\n)が二つ含まれ、二つ目は必ずメッセージの最後に記述される」という仕様を利用します。ちなみに、1つ目の改行文字はこちらから送信したエコーバック、2つ目の改行文字はCPUボードが作成したメッセージの最後に付けられるものです。

 なお、「長さが分らなければ、とりあえずかなり大きめのサイズを一度に受信してみる」という方法もありますが、ReadFile関数は、引数の「一度にメッセージを受信するサイズ(長さ)」に与えられたサイズだけ受信するまで待つ仕様になっています(これは設定で変更可能ですが)。そのため、タイムアウトを設定していなければここでプログラムがフリーズし、タイムアウトを設定していても、その指定時間だけ必ず待ち時間が入ってしまいます。

 ちなみに、通信データの内容は前回の受信メッセージと同じなので、解読処理もそれに従って作成すれば良いですが、送信メッセージと同様「ASCII準拠で1文字が1byte」という仕様なので、文字列としての扱いには注意が必要です。

iPhoneから操縦する

 ※ここからの内容は特に難しいため、あくまでわかる方のみ参考にしてください。以下の内容に関する詳しい質問は基本的に受け付けておりませんのでご了承ください。

 先日公開したiPhoneからロボットを動かす動画でも、CPUボードのシリアル通信を使用しています。また、ロボット制御用のソフトウェアには、iPhoneSDKで開発した自作ソフトを使用しています。

 iPhoneSDKを用いたソフトウェア開発については、環境の準備がものすごく複雑なのでここでは説明できません。こちらやこちらのwebページを参照して調べてください。また、iPhoneSDKのソフト開発には必ずMac本体が必要です(Mac OS Leopardが動作するものが望ましいようです)。他にも、実際にiPhone実機で動作させるためには、ADCへの登録・ライセンス取得(有料)、ユーザ認証キーの取得、OSのバージョンなどかなりややこしい手続きがあります。

 iPhoneSDKの開発環境がそろったら、実際に動作させる手順を説明します(こちらも詳細説明が長くなるので、ある程度さわりだけを説明します)。

 iPhone及びiPodTouchにもBluetoothが標準で搭載されているので、先ほど説明したBluetoothの考えを応用すれば、iPhoneやiPod touchからもCPUボードを制御できそうです。しかし、iPhoneに搭載したBluetoothデバイスをそのまま利用できると考えていると、実は大きな問題があります。なんと、2010年2月時点では、iPhoneのBluetoothで接続できる相手はかなり制限されており、「別のiPhone」「Bluetooth対応のスピーカー、イヤホン」程度にしか接続できません(なんとMacintoshにすら接続できません)。シリアル通信デバイスにも当然のごとく未対応のため、これではCPUボードと通信することができません。

 ちなみに、メーカーがiPhoneをBluetooth機器として登録したプロファイルには、ちゃんとSPPも含まれているので、ハードウェアとしては対応しているはずです。なのになぜ対応しないかは、サードパーティの周辺機器売り上げに影響するためだと推測されています。将来的にはこのような制限が解禁される可能性もあるので、そこを期待して待つしかありません。

 さて、いきなり出足をくじかれましたが、iPhoneにはもう一つの無線通信手段としてWiFi(無線LAN)を搭載しています。調べてみると、こちらは使用に際してBluetoothのような制限は無いようなので、今回はこれを利用して通信してみたいと思います。

 では、WiFiはシリアル通信に対応しているのでしょうか?通常、WiFiはTCP/IPという形式で通信が行なわれます。これはシリアル通信とはかなり仕様が異なるため、Bluetoothのようにシリアルポートと同じ感覚扱うことができません。そこでシリアル通信とTCP/IPとを変換できる方法を探してみると、お互いの信号を変換する「MatchPort b/g Pro」というデバイスが見つかりました。

 このデバイスは、浅草ギ研のBluetoothと同じく「TX」(送信)「RX」(受信)「Vcc」「GND」(電源)の4つのポートにケーブルを接続することで利用できます。MatchPort b/g Proにはシリアル通信用の端子が2系統備わっていますが、ここでは「P1.5 TX1」に赤、「P1.9 RX1」に茶を接続しています。また、電源は「P1.37 S3.3V」に白、「P1.39 GND」弐黒を接続しています。また、念のため「P1.7 RTS1」と「P1.11 CTS1」を接続し、また動作確認のためアクセスランプ用のLEDをつないでおきましょう。LEDは、まずアノードを「P1.37 S3.3V」に接続します。カソードには220Ωの抵抗を接続し、その抵抗の先を「P2.22 W_LINKLED」に接続します。


かなりいい加減な配線。実際に作業するときはブレッドボードを使いましょう。

 通信速度などの設定は、無線LANのネットワーク環境を用意してデバイスをネットワークに接続させ、また別にPCなどを用意してwebブラウザからデバイスの設定画面に入ります。このとき無線LAN環境は名前やセキュリティの設定を指定の状態にする必要があるため、既存のネットワーク環境を利用しづらいので、現在使っていない適当な無線LANルータを用意してください。

 無線LANネットワークでは、ESSIDを必ず「Lantronix Initial Infra Network」にします。この名前にしておかないとMatchPort b/g Proがネットワークにアクセスできないため、大文字・小文字や空白も含めて間違えないようにしましょう。また、パスワードやその他セキュリティは全て無効にしておきましょう。


 ネットワーク環境を正しく設定したら、CPUボードにMatchPort b/g Proを接続して電源を供給してみましょう。MatchPort b/g Proは、電源をONにした直後にLEDが細かく何度か点滅します。その後、正しくネットワークに接続できたらLEDが点灯状態になります。LEDが点滅し続ける場合は、MatchPort b/g Pro自体は正しく起動していますが、ネットワーク環境にアクセスできない状態です。無線LANルータの設定や電波状況などを良くかくにんしましょう。もしLEDがまったく点滅しない場合は、配線関係に問題が無いか(白・黒のケーブルの接続場所、LEDの接続方法、ショートなど)を良く確認しましょう。

 MatchPort b/g Proがネットワークにアクセスできたら、別のPCからwebブラウザでMatchPort b/g Proにアクセスして、通信速度の設定を変更します。まず、無線LANルータの設定画面に入り、現在ネットワーク中に存在するIPアドレスを調べて、そこからMatchPort b/g ProのIPアドレスを調べます。MatchPort b/g Proのユーザ名は空白なので、そこを参照します。


 IPアドレスを調べたら、webブラウザでそこにアクセスします。アクセスすると設定画面が表示されるので、下図の通りにMatch port b/g pro内のシリアルポートの設定を変更します。


 あと、TCP/IP側の通信に使うポート番号の設定があったような気がしますが、今回探しきれませんでした。実際にこれに挑戦してみたい場合は、そのところも調べてみてください。

 やっとのことで、iPhoneとCPUボードの接続経路を確保できました。あとはアプリケーションの開発ですが、さすがにこの部分は詳しく説明できません。どのような技術が必要かを一言で言うと、「TCP/IPでソケット通信をする」ことです。iPhoneはOSのベースがBSDであり、BSD用のsocketを用いたTCP/IP通信処理がそのまま使えます。そのため、これをヒントにweb上でソケット通信のサンプルプログラムを探せば、開発できると思います。

最後に

 今回はシリアル通信の利用方法について主に説明してきました。さすがにiPhoneでの通信制御は若干無理がありますが、Bluetoothによる無線通信はかなり便利だと思います。


前のページ
第10回 ロボットをシリアル通信で動かす(前編)
コンテンツのトップ


検索
Loading
メインメニュー