UWPアプリでArduinoとシリアル通信

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

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です