見出し画像

DelphiでPCとスマホをBluetoothでつなぐ

0.はじめに

最初に、このソフトを作るにあたってLiuk様の「DelphiでBluetooth」を参考にさせていただきました。ありがとうございました。

実は現役引退後に仕事を初めまして、リモコン機能のスマホアプリを開発しています。リモコン対象とはBluetoothで接続しますが、リモコン対象をいうと業界がわかってしまうので内緒とさせて下さい。うるさい業界です。
アプリの商品化にはデザイン化されたボタンなどのコンポーネント作成や、GoogleやAppleの認証も必要となりますので、アプリ開発そのものは外部に発注しています。

一方でアマチュアプログラマーとしての興味と、リモコン対象も同時開発なので作られたスマホアプリの正しさを検証するためのソフトが必要じゃね、と勝手に思い込んでの今回のソフト作成となっています。
ただし、Bluetoothとの通信手順の説明が主で、コードは最低限しか記載しませんのでご容赦ください。

1.システム構成

iPhoneもしくはAndroidスマホにリモコンソフトをインストールして、その出力を仮想リモコン対象としてのPCで読み取る、という構成になります。

システム構成

使用したスマホは使わなくなったPixel 3で、開発者モードに設定してアプリをインストール済みです。

2.デバイススキャン

まずは周囲にどんなBluetoothデバイスがあるのかを調べます。
標準で用意してあるBluetoothコンポーネントをFormに追加し、その際、Enabled=Trueになっていることを確認しておいてください。
みつけたデバイスを表示するListBoxと、ソフトが処理した結果を表示するMemoを用意しておくと状況を見ることができて便利だと思います。

画面構成

Scan Buttonを追加してOnClickにスキャンするコードを記載します。
 Bluetooth1.DiscoverDevices(5000);  //5000はスキャンする時間でmsec単位 

また、スキャンした結果を表示するコードも、BluetoothコンポーネントのOnDiscoveryEndに記載します。
 if ADeviceList.Count > 0 then  //次のアクションを記載
で検出できたかを確認しつつ、DeviceNameをList Boxに表示します。
 ListBox1.Items.Add(ADeviceList[i].DeviceName);  //iはデバイス数

Pixel 3を検出

3.ペアリング

スキャンで見つけたBluetoothデバイスに対して、デバイスを選んでペアリングする必要があります。
Paring Buttonを追加してOnClickにペアリングするコードを記載しますがpublicに
 ADevice : TBluetoothDevice;
を追加しておいてください。

まずはList Boxでデバイス(このケースはPixel 3)を選択してそれをAdeviceに代入します。
 ADevice:= Bluetooth1.LastDiscoveredDevices[ListBox1.ItemIndex];

ADeviceに対してペアリングの動作を行います。
 Bluetooth1.Pair(ADevice);
この時、スマホとPCの両方に”ペアリングしますか”という感じのメッセージが出ますので共に”はい”を選択すると、ペアリングが完了します。

PCのペアリング画面

ペアリングの結果は下記で確認できます。
 if ADevice.IsPaired then  //成否がBooleanで返ってくるのでそれに合わせて
             処理を記載する

4.サービス

次はペアリングしたデバイスから、デバイスが提供可能なサービス一覧を入手します。
Service Buttonを追加してOnClickにサービスを取得するコードを記載しますが、publicに
 AServices : TBluetoothServiceList;
を追加しておいてください。

ADeviceにServiceを代入します。
 AServices:=ADevice.GetServices;

その結果を表示しますが、varに下記の変数を追加しておいてください。
  i : integer;
  AListItem : TListItem;

ListViewを使用しましたが、他の方の見様見真似で下記のコードとなっていますが、うまく説明できないのでそのまま貼り付けておきます。

  for i := 0 to AServices.Count-1 do
    begin
      AListItem:=ListView1.Items.Add;
      AListItem.ImageIndex:=GetServiceImageIndex(AServices[i].UUID);
      AListItem.Caption:=AServices[i].Name;
      if AListItem.Caption='' then
        AListItem.Caption:='<Unknown>';
      AListItem.SubItems.Add(GUIDToString(AServices[i].UUID));
    end;

下記はPixel 3の取得したサービスとなりますが、「★ Remote」がインストールされているリモコンのアプリケーションです。

Service List

5.ソケット

最後にソケットを接続しますが、その前にService Listの対象UUIDをServiceUUIDに代入しておく必要がありますので、List ViewのOnClickにコードを記載する必要があります。
なお、publicに
 ServiceUUID : String;
を記載しておいてください。

Socket Buttonを追加してOnClickにサービスを取得するコードを記載しますが、publicに
 ASocket : TBluetoothSocket;
を記載しておいてください。

ASocketにUUIDを代入して、接続します。  
 ASocket := Adevice.CreateClientSocket(StringToGUID(ServiceUUID),false);
 ASocket.Connect;

接続の結果を確認します。
 if ASocket.Connected then  //成否がBooleanで返ってくるのでそれに合わ 
             せて処理を記載する

6.受信

最後に受信するためにReceive Buttonを追加してOnClickに
 var
  res : String:
としてfunction ASocketReceiveData()で読み込むようにしました。
 res := ASocketReceiveData(ASocket, 2000);  //受信時間を2000msecに設定

function TForm1.ASocketReceiveData(ASocket: TBluetoothSocket; 
     ATimeout: Integer): string;
var
  AData : TBytes;
  ReadData : TBytes;
begin
  SetLength(ReadData, 256);
  AData:=Nil;
  AData:= ASocket.ReceiveData;
end;

実際には受信したADataを表示するためのコードが必要になりますが、リモコンの仕様に沿って下記のように表示しています。最後のDataはこのアプリでは送られてきていないので、”0x”表示のみとなっています。

受信データ

7.まとめ

今回もプログラムについてはBluetoothに特化し、エラー処理や表示処理などは触れていません。実際のコードは色々なエラー処理を記載していますが、記事の中ではエラー処理などは一切考慮していませんのでご注意ください。

また、理解しやすいようにステップを踏んで接続するようにしましたが、使用するサービスが決まっているなら一回のClickで処理を終わらせてもいいと思います。

なお、今回は受信のみでしたが、受信したコマンドに応じたステータスを送信する処理に今後は取り組む予定です。

この記事が気に入ったらサポートをしてみませんか?