157行目: 157行目:
Bluetoothを使用してPCまたはスマートフォンと接続して、温度データを受信するPCまたはスマートフォンのソフトウェアの作成手順を記載する。<br>
Bluetoothを使用してPCまたはスマートフォンと接続して、温度データを受信するPCまたはスマートフォンのソフトウェアの作成手順を記載する。<br>
<br>
<br>
スマートフォン(Android)のソフトウェア<br>
==== PCのソフトウェア ====
ソフトウェアの開発は、Visual Studio 2019のコンソールを用いている。<br>
<br>
標準ライブラリにあるBluetoothのAPIはUWP専用であるため、NuGetからコンソールでも使用できる<code>UwpDesktop</code>をインストールする。<br>
Visual Studioの[プロジェクト]メニューバー - [NuGet パッケージの管理]を選択して、UwpDesktopと入力してインストールする。<br>
<br>
以下に、Bluetooth通信の手順を大まかに記載する。<br>
* 周囲のBluetoothデバイスをスキャンする。
* 見つかったデバイスから、接続・通信を行う端末かどうかを確認して、データの受信を行う。
<br>
まず、周囲のBluetoothデバイスをスキャンする。<br>
Bluetoothデバイスは、アドバタイズパケットという自身の場所を伝えるためのデータを発信するため、<br>
そのパケットをスキャンすることでBluetoothデバイスを認識して接続することができる。<br>
<br>
以下の例では、<code>BluetoothLEAdvertisementWatcher</code>クラスのプロパティの値を設定した後、Startメソッドを実行してスキャンしている。<br>
<syntaxhighlight lang="c#">
private BluetoothLEAdvertisementWatcher advWatcher;
advWatcher = new BluetoothLEAdvertisementWatcher();
advWatcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(1000);
advWatcher.ScanningMode = BluetoothLEScanningMode.Passive;
advWatcher.Received += WatcherReceived;
advWatcher.Start();
</syntaxhighlight>
<br>
次に、スキャンして見つかったデバイスにおいて、接続・通信を行うデバイスかどうか確認する。<br>
<code>WatcherReceived</code>メソッドからスキャンされたデバイスの情報を受信するので、その情報を元に確認する。<br>
# スキャンして見つかったデバイスが持つUUIDと、接続・通信を行うデバイスのUUIDを比較する。
# 同じなら、スキャンを停止してそのデバイスと接続する。
# 接続したデバイスから、サービスのUUIDとキャラクタリスティックのUUIDを用いて目的のデータにアクセスする。
# アクセスに成功した後、コールバックを設定して、目的のデータの受信する。<br>以下のサンプルコードにおいて、<code>CharacteristicChangedVroomController</code>メソッド(ユーザ自身が作成したメソッド)は、<br>受信したデータ(バイト列)に対して、任意の処理を行うメソッドである。
<br>
UUIDを確認する理由は、Bluetooth通信で使用されるデータフォーマットGATTがあるためである。<br>
GATTは、<u>サービス</u>と<u>キャラクタリスティック</u>の2つから構成されており、各々がUUIDで設定されている。<br>
サービスがフォルダ、キャラクタリスティックがファイルに相当する。<br>
<br>
GATTに則っているBluetoothデバイスは、必ずこの形式でデータを送受信するため、UUIDを確認することで目的のデバイスを判別できる。<br>
UUIDを知る方法は、販売元が公開している場合や自身で全パケットを確認する方法がある。<br>
<syntaxhighlight lang="c#">
private GattDeviceService gattService;
private GattCharacteristic vroomService;
private async Task WatcherReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
    await Task.Run(() => CheckArgs(args));
}
private async Task CheckArgs(BluetoothLEAdvertisementReceivedEventArgs args)
{
    bool find = false;
    var bleServiceUUIDs = args.Advertisement.ServiceUuids;
    foreach (var uuidone in bleServiceUUIDs)
    {
      // serviceGuid : デバイス固有のGUID
      if (uuidone == serviceGuid)
      {
          // 発見
          find = true;
          break;
      }
    }
    if (find)
    {
      try
      {
          // スキャンの停止
          advWatcher.Stop();
          // デバイスと接続
          BluetoothLEDevice device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
          // UUIDを用いて目的のデバイスを取得
          gattService = device.GetGattService(serviceGuid);
          // キャラクタリスティックUUIDを用いて目的のキャラクタリスティックを取得
          var characteristics = gattService.GetCharacteristics(new Guid("キャラクタリスティックのGuid"));
          // 戻り値の配列が空かどうか確認
          if (characteristics.Count > 0)
          {
            vroomService = characteristics.First();
            if (vroomService == null)
            {
                throw new Exception("Not Exist Service");
            }
            // 読み取り可能な場合、キャラクタリスティックにアクセスしてコールバックを設定
            if (vroomService.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Read))
            {
                vroomService.ValueChanged += CharacteristicChangedVroomController;
                Console.WriteLine("Connect");
                await vroomService.ReadClientCharacteristicConfigurationDescriptorAsync();
            }
          }
      }
      catch (Exception ex)
      {
          Console.WriteLine($"Exception...{ex.Message})");
      }
    }
}
</syntaxhighlight>
<br>
==== スマートフォン(Android)のソフトウェア ====
クライアントからサーバに接続する時、RFCOMMチャネルを作成してBluetoothSocketを作成する必要があるが、<br>
クライアントからサーバに接続する時、RFCOMMチャネルを作成してBluetoothSocketを作成する必要があるが、<br>
この時に指定するUUIDは、SPP(シリアルポートプロファイル)のUUIDである"00001101-0000-1000-8000-00805f9b34fb"を指定する。<br>
この時に指定するUUIDは、SPP(シリアルポートプロファイル)のUUIDである"00001101-0000-1000-8000-00805f9b34fb"を指定する。<br>