はつねの日記

Kinect, Windows 10 UWP, Windows Azure, IoT, 電子工作

魔法の言葉は、「nuget Lego.EV3」

Lego Mindstorm EV3はLego社から発売されている教育用ロボットです。

EV3

 

EV3の凄いところはBluetoothでPCとつないでDirectCommandというデータを流し込むことでリアルタイムにPCからコントロールできる点です。

もちろん、Windows 8.1であればWindowsストアアプリからBluetooth 4.0 LEで繋いで使うことができます。

しかし、このDirectCommandの内容はドキュメントとしては存在せず、日本代理店のアフレル社さんが配布しているKinectと連携させる教育用ドキュメントのサンプルソースにもモーター制御はありますが、センサーからの入力は使用していませんでした。

 

そして今日は「「Windows 8.1 ストアアプリ開発デバイス祭り~周辺機器とつなぐアプリを創ろう!!」開催」です。

もちろん、ハード絡みなのに事前に何も準備せずに参加しようとは思えなかったので、なんとかセンサーの値をとる方法がないか、いろいろネットで検索していた時にそれっぽいページをみつけることができました。

しかしなんとなく違和感があります。DirectCommandという文字列はでてきるのですが、byte配列を作ってそれをBluetoothで送信してという感じではなく、また、Windows 8.1といえどもBluetoothからの受信イベントは自分で実装するしかないのですが受信イベントもあるような感じでした。

そして「あれ、これcodeplexだ!」ということで、なんと「Lego.Ev3」という便利クラスライブラリがcodeplexにありました。しかもnuget配布もされていました。

http://legoev3.codeplex.com/

Windowsデスクトップ、Windows Phone 8、Windows ストアアプリ (ただし8.1以降) と3つも公開されているというすばらしさ。

 

しかもNuGetに至っては、2013/11/06提供のほっかほかクラスライブラリ、ダウンロード数「13」というもぎたてクラスライブラリになります。

image

 

新規にWindows 8.1プロジェクトを作成したら、[ツール]-[ライブラリパッケージマネージャー]-[ソリューションのNuGetパッケージの管理]からLego.EV3を追加したら、もう今までとは別次元の簡単さでMindstorm EV3をコントロールするプログラムが作成できます。

使い方 step1

まずはEV3と接続するためのオブジェクトを作成します。

VB.NET
Private WithEvents Connecter As Lego.Ev3.Core.Brick
C#
private Lego.Ev3.Core.Brick Connecter;
使い方 step2

接続するときは接続方法を選択します。今回はBluetoothにします。

VB.NET
Me.Connecter = New Lego.Ev3.Core.Brick(New Lego.Ev3.WinRT.BluetoothCommunication)
Await Me.Connecter.ConnectAsync()
C#
this.Connector.BrickChanged += Connecter_BrickChanged();
this.Connecter = new Lego.Ev3.Core.Brick(new Lego.Ev3.WinRT.BluetoothCommunication);
await this.Connecter.ConnectAsync();
使い方 step3

データ受信したときはイベントが発生するので、そのパラメタからセンサー値を取得できます。

VB.NET
Private Sub Connecter_BrickChanged(sender As Object,
                                   e As Lego.Ev3.Core.BrickChangedEventArgs) Handles Connecter.BrickChanged
    If e.Ports(Lego.Ev3.Core.InputPort.One).Type <> Lego.Ev3.Core.DeviceType.Empty Then
        Debug.Print e.Ports(Lego.Ev3.Core.InputPort.One).SIValue
    End If
End Sub
C#
private void Connecter_BrickChanged(object sender,
                                    Lego.Ev3.Core.BrickChangedEventArgs e)
{
    if (e.Ports(Lego.Ev3.Core.InputPort.One).Type != Lego.Ev3.Core.DeviceType.Empty)
    {
        Debug.Print e.Ports(Lego.Ev3.Core.InputPort.One).SIValue
    }
}
使い方 step4

モーターをまわすためにはDirectCommandをつかいます。 500msごとに指定した速度でモーターをまわすには次のようなコードになります。

VB.NET
For index As Integer = 0 To Me.Motors.Count - 1
    If Me.Motors(index).Power = 0 Then
        Await Me.Connecter.DirectCommand.StopMotorAsync(Me.PowerPorts(index), True)
    Else
        Await Me.Connecter.DirectCommand.TurnMotorAtPowerForTimeAsync(
                      Me.PowerPorts(index),
                      Me.Motors(index).Power,
                      500,
                      False)
    End If
Next
C#
for (int index =0; index <= this.Motors.Count - 1; index++)
{
    if (this.Motors(index).Power == 0)
    {
        await this.Connecter.DirectCommand.StopMotorAsync(this.PowerPorts(index), true);
    }
    else
    {
        await this.Connecter.DirectCommand.TurnMotorAtPowerForTimeAsync(
                      this.PowerPorts(index),
                      this.Motors(index).Power,
                      500,
                      false);
    }
}
まとめ

近日中に、Code Recipeでサンプルコード提供予定です。現在、VB.NET版のデバッグ中、それが終わればC#版作成して同時公開という感じですので、もう少々お待ちください。

でも、需要あるのかなぁ。

Let's enjoy Programming !