BluetoothやEthernetなどの通信層のプログラムはとても複雑で様々な通信仕様に対応し、通信状況に応じた異常対応もする必要があります。BlueUSBのプログラムはWiiリモコンやBluetoothマウスと通信するのみの単機能な実装しかされておらず、異常時の対応も不十分な状態です。それでもこれだけのプログラムがすぐ動かせるレベルで公開されているのはとてもありがたいことです。またmbed.orgでは、BlueUSBを元に改善、または機能を追加プログラムも公開されているので、それらも参考になると思います。
 ここではとりあえずBlueUSBをそのまま使い、簡単にWiiリモコンのボタンと傾きでmbed上のLEDをコントロールしてみます。

 TestShell.cppの最初の部分に以下(太字)を追加します。
#include "Utils.h"
#include "USBHost.h"
#include "hci.h"
#include "mbed.h"

DigitalOut  led1(LED1);
DigitalOut  led2(LED2);
 次にBluetooth  HIDプロトコルの受信で呼ばれる処理の以下部分に処理を追加(太字)。
(説明のためコメントを追加しています。ブラウザ上で直接日本語は書けません。)
                case 0x37: // Accelerometer http://wiki.wiimoteproject.com/Reports // ----- <<2>>

                {
                    int pad = (d[2] & 0x9F) | ((d[3] & 0x9F) << 8);	// ボタン
                    int x = (d[2] & 0x60) >> 5 | d[4] << 2;		// 加速度センサX軸
                    int y = (d[3] & 0x20) >> 4 | d[5] << 2; 		// 加速度センサY軸
                    int z = (d[3] & 0x40) >> 5 | d[6] << 2; 		// 加速度センサZ軸
                    printf("WII %04X %d %d %d\r\n",pad,x,y,z);

                    led1 = (pad & 0x0800);	// AボタンでLED1を点灯する。

                    if( x > 500 )		//傾きでLED2をON/OFFする。
                    {
                        led2 = 1;
                    }
                    else
                    {
                        led2 = 0;
                    }
                }
                break;
 これでWiiリモコンのAボタンを押すとLED1が、Wiiリモコンを傾けるとLED2が点灯します。

sイメージ-4.jpg
WiiリモコンのAボタンを押すとmbedのLEDが点灯、離すと消灯

sイメージ-5.jpg
Wiiリモコンを横に傾けるとmbedのLEDが点灯、戻すと消灯



 それでは次にWiiリモコンへ指令を送ってみます。LEDの点灯とバイブレーションの動作は指令を送信するメソッドが用意されているので、それを使います。
                case 0x37: // Accelerometer http://wiki.wiimoteproject.com/Reports // ----- ②
                {
                    int pad = (d[2] & 0x9F) | ((d[3] & 0x9F) << 8);	// ボタン
                    int x = (d[2] & 0x60) >> 5 | d[4] << 2;		// 加速度センサX軸
                    int y = (d[3] & 0x20) >> 4 | d[5] << 2; 		// 加速度センサY軸
                    int z = (d[3] & 0x40) >> 5 | d[6] << 2; 		// 加速度センサZ軸
                    printf("WII %04X %d %d %d\r\n",pad,x,y,z);

                    led1 = (pad & 0x0800);	// AボタンでLED1を点灯する。

                    if( x > 500 )		//傾きでLED2をON/OFFする。
                    {
                        led2 = 1;
                    }
                    else
                    {
                        led2 = 0;
                    }

                    int home = (pad & 0x8000);		// HOMEボタンを取得。
                    static int old = home;		// 前回値保持用。
                    
                    if( home != old )			// 変化があったら処理をする。
                    {
                        old = home;			// 前回値を保持。
                        if( home != 0 )			// HOMEボタンが押されている。
                        {
                            t->Led(0x91);		// LED4とバイブレーションをON。
                        }
                        else
                        {
                            t->Led(0x10);		// LED1のみONにする。
                        }
                    }
                }
                break;
 HOMEボタンを押すと押している間のみWiiリモコン上のLED4が点灯し、バイブレーションが動きます。ボタンが変化したタイミングでLed()のメソッドをコールして、指令を送るようになっています。
 Wiiリモコンに対するLEDの指令もビット単位で指定します。Led()のメソッドは引数で指令値を受け取り、ヘッダを付けてWiiリモコンに送信します。指令値はビット単位で以下のようになっています。

c-1.jpg 実際にWiiリモコンで動くロボットとして組み立てたものを紹介します。ただWiiリモコンで走りまわる車ではつまらないので、筆者の場合は磁石を取り付けてホワイトボードや冷蔵庫の側面を壁走りができるようにしました。このロボットは壁(ウォール)とロボットから「うおーるぼっと」と呼んでいます。

sイメージ-6.jpg


勝純一




| | トラックバック(0)

トラックバック(0)

このブログ記事を参照しているブログ一覧: 壁を這うロボット <5>

このブログ記事に対するトラックバックURL: http://www.eleki-jack.com/mt/mt-tb.cgi/5514





カテゴリ


Copyright (C) 2006-2015 CQ Publishing Co.,Ltd. All Rights Reserved.