スポンサーサイト

--.--.--.--.--:--
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Windows8.1でJoystick(GamePad)の状態を取得する

2013.08.15.Thu.01:00
久しぶりに余裕ができたので、すごい広島に行ってきました。


さて、Windows8.1からストアアプリでHIDがサポートされるようになりました。
http://msdn.microsoft.com/ja-jp/library/windows/apps/bg182882.aspx#one

これにより、ゲームパッドやジョイスティックはもちろん、HIDで通信するカスタムデバイスとのデータのやり取りも可能になりました。
ただし、HIDのうち下記のようなマウスやキーボードなどシステムが使用するものについては、APIでブロックされ使用できないため、注意が必要です。
http://msdn.microsoft.com/ja-jp/library/windows/apps/bg182882.aspx#limitations_of_the_hid_api

•HID_USAGE_PAGE_UNDEFINED
•HID_USAGE_PAGE_GENERIC
•HID_USAGE_GENERIC_KEYBOARD
•HID_USAGE_GENERIC_KEYPAD
•HID_USAGE_GENERIC_SYSTEM_CTL
•HID_USAGE_PAGE_KEYBOARD
•HID_USAGE_PAGE_CONSUMER
•HID_USAGE_PAGE_DIGITIZER
•HID_USAGE_PAGE_SENSOR
•HID_USAGE_PAGE_BARCODE_SCANNER
•HID_USAGE_PAGE_WEIGHING_DEVICE
•HID_USAGE_PAGE_MAGNETIC_STRIPE_READER
•HID_USAGE_PAGE_TELEPHONY

今回は、安価で入手しやすいゲームパッドでAPIについてチェックしてみたいと思います。
なお、使用したゲームパッドはこれです。
http://buffalo.jp/products/catalog/supply/input/gamepad/wire/bsgp1001/index.html

□ ManifestのCapabilitiesに、使用するデバイスについて記載する


HIDデバイスなど、外部機器をストアアプリから使用する場合、Capabilitiesにどのデバイスを使用するか明記する必要があります。
今回使用するゲームパッドは、HIDのデバイスのUsage Pageが0x01、Usage IDが0x04のJoystickになりますので、Capabilitiesには下記のように記載します









今回は、使用するデバイスのベンダーやデバイスIDなどは指定しないため、としています。

□ PCに接続されているJoystickを検索する


HidDevice.GetDeviceSelectorを使用して、セレクタ文字列を生成します。
http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.humaninterfacedevice.hiddevice.getdeviceselector.aspx

引数が(UsagePage, UsageId)のものと、(UsagePage, UsageId, VenderId, ProductID)のものがありますが、今回は前述の通り、メーカーは指定しないので引数2つのほうを使用します。

その後、セレクタ文字列を引数にDeviceInformation.FindAllAsyncを実行し、PCに接続されているJoystickを検索します。

ushort usagePage = 0x01;
ushort usageId = 0x04;

// セレクタ文字列を生成する
string selector = HidDevice.GetDeviceSelector(usagePage, usageId);

// セレクタ文字列を使ってデバイスを列挙する
var devices = await DeviceInformation.FindAllAsync(selector);


□ InputReport受信時のハンドラをセットする


使用したいJoystickが見つかったら、HidDevice.FromIdAsyncを使って、HidDeviceを取得します。
このままでは、Joystickの入力状態が取得できないため、Joystickからの情報を受信した時のイベントハンドラを登録します。


// ターゲットのHIDをオープンする
HidDevice device = await HidDevice.FromIdAsync(deviceInformation.Id, FileAccessMode.Read);

if (device == null)
{
return;
}

// InputReport受信時のハンドラを登録する
device.InputReportReceived += device_InputReportReceived;


□ InputReportからJoystickの状態を調べる


受信時はargs.Report.DataにJoystickの情報が格納されています。
下記コードでは、1バイトずつ読み取ってデバッグ用に文字列をTextBlockに表示しています。


async void device_InputReportReceived(HidDevice sender, HidInputReportReceivedEventArgs args)
{
var data = args.Report.Data;
var dataReader = DataReader.FromBuffer(data);

StringBuilder sb = new StringBuilder();
for (int index = 0; index < data.Length; index++)
{
sb.Append(dataReader.ReadByte().ToString() + ":");
}
//Debug.WriteLine("data = " + sb.ToString());
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, new Windows.UI.Core.DispatchedHandler(() =>
{
textBlockLog.Text = sb.ToString();
}));
}


なにも押していない状態で出力される値は下記の通りです。
0:128:128:0:0:0:0:0:0:

ボタン1を押下した状態では
0:128:128:1:0:0:0:0:0:

ボタン2を押下した状態では
0:128:128:2:0:0:0:0:0:

ボタン3を押下した状態では
0:128:128:4:0:0:0:0:0:

もうお分かりですね。
4バイト目は押下されたボタンのビットフラグが立った値のようです。

もちろん、ボタン1と2を両方押すと
0:128:128:3:0:0:0:0:0:
になりました

ちなみに、ボタン9を押下すると
0:128:128:0:1:0:0:0:0:
になり、5バイト目のビットフラグが変わりました。

このあたりの、何ボタンのコントローラか等の情報は何かで取得できる気はしているのですが、まだ調べていません。

2,3バイト目の128が気になりますが、これは十字キーの値になります。
左を押すと
0:0:128:0:0:0:0:0:0:

右を押すと
0:255:128:0:0:0:0:0:0:
でしたので、アナログジョイスティックのついたコントローラでは0~255まで連続的に変化するものと思われます。

こんな感じでJoystickの状態が取得できますので、ストアアプリをジョイスティックを使ったアプリを作る場合はこんな感じになると思います。

PWMでアナログっぽい出力

2013.08.05.Mon.01:31
引き続き、netduinoネタです。

今回は、PWMを使ってアナログっぽい出力を実現します。


.Net MF 4.2 では、PWMクラスという、そのまんまのクラスがあります。

このクラスを使うことで、PWM出力ができ、LEDの明るさの調整、サーボモーターの制御などが行えます。

以下、今回作成したサンプルコードです。

private static void PwmTest()
{
const int STEPS = 10;
PWM pwm = new PWM(PWMChannels.PWM_PIN_D3, 200.0, 0.3, false);
pwm.Start();

while (true)
{
for (int step = 0; step <= STEPS; step++)
{
pwm.DutyCycle = (double)step / STEPS;
Thread.Sleep(200);
}
}
}


PWMクラスのコンストラクタをIntellisenseに任せて入力すると、第一引数にCpu.PWMChannel列挙体がサジェストされ、PWM_0~PWM_7のどれかを選ぶことになりますが、どれがどのポートやらさっぱりです。

代わりに、上記コードのようにPWMChannels列挙体を使用することで、netduinoのポートと対応したポート番号を指定することができます。

・IntellisenseでサジェストされたPWM可能なポート一覧
inteli.png

ONBOARD_LEDと、D3/D5/D6/D9/D10/D11が使えるようです。


第二引数はPWMの周波数です。上記ではとりあえず、200Hzに指定しています。
私が調べた限りでは15Hz以下では例外が発生し、300KHz以上ではPWM出力が停止しました。
なので、周波数は16~300KHzを指定するようにしましょう。

第三引数はDuty比です。
この値を0.0~1.0に変化させることで、Duty比が変わります。

第四引数は出力の反転です。
falseの時、1.0で常にHighになり、trueの時、1.0で常にLowになります。(多分)

while内で、Duty比を0~1.0に段階的に変化させています。
このとき、netduinoのD3ポートにLEDなどを接続していると、段階的に明るさが変わる様子が観察できます。

netduino plus 2を文鎮にする方法

2013.08.04.Sun.02:55
ひとつ前の記事で、netduinoが認識できなくなった原因が大体わかりました。

※このコードをnetduino plus 2で実行すると、netduinoが文鎮になります。
OutputPort port = new OutputPort(Cpu.Pin.GPIO_Pin11, true);


どうも、ポート番号としてCpu.Pin.GPIO_Pin11を指定したのがまずかったらしいです。

全く同じレポートがフォーラムにありました

Reproducable firmware crash

良い子のみんなはCpu.Pinではなく、Pins列挙型から使いたいポートを選んでね!

netduinoが不明なデバイスになった

2013.08.04.Sun.02:39
先日購入して、いろいろ遊んでいる"netduino plus 2"ですが、いろいろ遊んでいると、デバッグできなくなってしましました。

正確にいうと、一瞬netduinoとして認識され、その後netduinoが"不明なデバイス"になってしまい、どうしようもない状態です。
おそらく、テストで書いていたコードがまずいか、書き込み中に何か問題が発生したため、
netduinoがブート→プログラム読み込み→クラッシュ
みたいな状態ではないかなと思います。

netduino上のボタンを押すと、また一瞬認識されますが、すぐに不明なデバイスになるような状態です。


※注意
お約束ですが、ここに書いてある情報は私が試した内容であり、ほかの人にも有効な手段かどうかは分かりません。
万が一、あなたのnetduinoが壊れても一切責任をおいません。
自己責任でお願いいたします。

ファームウェアを書き換える


なんとなく、書き込んだプログラムがまずそうなので、ファームウェアを上書きして、クリーンな状態に戻せないかチェックしてみます。

1. ファームウェアをフォーラムからダウンロード

http://forums.netduino.com/

netduino plus 2 の場合は
  "Netduino Plus and Netduino Plus 2" > "Netduino Plus 2 Firmware v4.2.2 (update 2)"
とアクセスして、1つ目のポストの下のほうにある

NetduinoPlus2_Firmware_4.2.2.2.zip

をダウンロードします。

あと、ファームウェア書き換え時に必要になるので、
  "STDFU Tester v3.0.1"
というのもダウンロードして、インストールします。


2. ファームウェア書き換え

ファームウェアの書き換え方法も同じポストに書いてあるので、その手順に従えばOKです。

まず、ボード上のボタンを押しながらnetduinoをPCに接続して、DFUモードで起動します。


DFUTesterでフラッシュメモリをクリア
dfutester.png
①「Protocol」タブを選択
②Create from Mapボタンを押下
③Eraseを選択
④Goボタンを押下


DfuSe Demoでファームウェア書き込み
dfudemo.png
①"Verify after download"にチェックを入れる
②"Chose"ボタンを押下し、先にダウンロードしていたファームウェアのdfuファイルを選択
③Upgradeで更新

で完了です。

netduino でHelloWorld

2013.08.02.Fri.01:19
前々から欲しかったnetduinoをとうとう買ってしまいました。

netduino plus 2
http://www.netduino.com/netduino2/specs.htm

netduino.jpg

netduinoとは


簡単にnetduinoについて説明すると、
・オープンプラットフォームでARMなマイコンボード
・Arduinoとピンコンパチ
・.net Micro Framework 4.2搭載
・Visual C# 2010 Express(無償)で開発できる
・なんとブレークポイントも張れるし、デバッガで値の確認などもできる
という、素晴らしいマイコンボードです。

スイッチサイエンスで購入しました
http://www.switch-science.com/catalog/1260/

有線LAN付きにしたので、少しお高いですが、LANなしのnetduino 2であれば4000円弱で購入可能です。


環境構築


まずは、netduinoの開発環境を準備します。

必要なファイルは下記URLからダウンロードできます。
http://netduino.com/downloads/

以下のファイルをダウンロード・インストールします。
・Microsoft Visual C# Express 2010
・.NET Micro Framework SDK v4.2
・Netduino SDK v4.2.2.0


Hello world!


プログラミングの世界では、目に見える形で"Hello world!"を出力するのが一般的ですが、マイコンボードでhelloworldといえば、Lチカです。

今回はnetduinoのボードに搭載されているLEDを1秒ごとに点滅させます。

環境構築が完了したら、VisualStudioを起動し、netduino plus 2用のプロジェクトを作成します。
そして、main関数の中にLチカのプログラムを書いていきます。


public static void Main()
{
// 出力ポートの設定
OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);

while (true)
{
led.Write(true); // LED点灯
Thread.Sleep(1000); // 1秒スリープ
led.Write(false); // LED消灯
Thread.Sleep(1000); // 1秒スリープ
}
}


大体、見ての通りです。
1秒点灯して、1秒消してを永遠に繰り返すプログラムです。
出力ポートの設定では、ピン番号を指定する必要がありますが、ONBOARD_LEDという定数があるので、わざわざ調べる必要はありませんでした。
« Prev | HOME | Next »
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。