UWP(ユニバーサルWindowsプラットフォーム)アプリとArduinoを連携させてみよう。
以前、C#アプリとのArudinoのシリアル通信はやったので、似たようなものだろうと思っていたが、思いの他はまったのでメモ。
UWPはよりセキュアになったようで、デスクトップアプリ使っていた、
System.IO.Ports の SerialPortクラスの代わりに
Windows.Devices.SerialCommunication の SerialDeviceクラスを使うようだ。
マニフェストに追加
Windows.Devices.SerialCommunicationを使う為には、まず”Package.appxmanifest”ファイルのコードを表示し、”Capabilitiesタグ”の中に以下を追加する。
<DeviceCapability Name="serialcommunication" > <Device Id="any"> <Function Type="name:serialPort"/> </Device> </DeviceCapability>
ポートオープン
serialPort.Open()的な感じを期待していたのだが、どうやら違うようだ。
“COM5″を使いたい場合、まずは”COM5″の情報を取得。
string portName = "COM5"; string aqs = SerialDevice.GetDeviceSelector(portName);
次に”COM5″の情報を使ってデバイスの候補を検索。
var myDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(aqs, null);
見つかった候補のデバイスをオープン+通信の初期設定。
ポートオープンした後に設定変更しているような感じで若干気持ち悪い。
device = await SerialDevice.FromIdAsync(myDevices[0].Id); device.BaudRate = 9600; device.DataBits = 8; device.StopBits = SerialStopBitCount.One; device.Parity = SerialParity.None; device.Handshake = SerialHandshake.None; device.ReadTimeout = TimeSpan.FromMilliseconds(1000); device.WriteTimeout = TimeSpan.FromMilliseconds(1000);
一連のコード
string portName = "COM5"; string aqs = SerialDevice.GetDeviceSelector(portName); var myDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(aqs, null); if (myDevices.Count == 0) { return; } device = await SerialDevice.FromIdAsync(myDevices[0].Id); device.BaudRate = 9600; device.DataBits = 8; device.StopBits = SerialStopBitCount.One; device.Parity = SerialParity.None; device.Handshake = SerialHandshake.None; device.ReadTimeout = TimeSpan.FromMilliseconds(1000); device.WriteTimeout = TimeSpan.FromMilliseconds(1000);
送信
serialPort.Write(message)的な感じを期待するもやはり違うようだ。
DataWriterクラスのWriteStringメソッドをつかうようだ。以下のような感じにdeviceのOutputStreamと関連付けして使い、StoreAsync()で送信実行といったところか? ん~難しい。
DataWriter dataWriteeObject = new DataWriter(device.OutputStream); dataWriteeObject.WriteString(message); await dataWriteeObject.StoreAsync();
受信
受信には Windows.Storage.Streams のDataReaderクラスを使うようだ。
送信と同じようにdevice.InputStreamと関連づけすればいいようだ。
以下のように、LoadAsync()で受信実行し、UnconsumedBufferLengthで受信バイト数を確認し、ReadString(bytesToRead)でようやく文字列変数に格納できた。難しいけどなんとかできたといったところかな。
DataReader dataReaderObject = new DataReader(device.InputStream); await dataReaderObject.LoadAsync(128); uint bytesToRead = dataReaderObject.UnconsumedBufferLength; string receivedStrings = dataReaderObject.ReadString(bytesToRead);
バージョン情報
Visual Studio Community 2015, windows 10