DelphiでBluetooth(1)
目的
Arduino(+ HC-05)とWindowsPCの間で、Bluetooth使って無線通信したい。(PCでBluetoothラジコン用のコントローラー作りたい)
手段
PC側は無料で利用できるDelphi 10.3.3 Community Editionを使う。Delphiのコントロールに TBluetooth というのがあるので、これを使ってみる。
公式の記事
この中の「リモート デバイスの検出とそれらとのペア設定」の部分に沿ってやってみる。
手順メモ
(※見出しは上のリンク先公式記事に沿ったもの)
※アプリケーションへの TBluetooth コンポーネントの追加
・Delphiフォームに Bluetoothのコントロール(TBluetooth)貼った。(済)
・ボタン(TButton)とメモ枠(TMemo)も追加。
※リモート デバイスの検出とそれらとのペア設定
※※デバイスを検出可能にする・・今検出したい対象は、HC-05のモジュールなので、アプリが走るPC側は検出可能にするとか考える必要はないはず。たぶん読み飛ばしてOK。
※※リモート デバイスを検出する
TBluetooth.DiscoverDevices を呼んで、タイムアウト時間まで待つ。タイムアウト時間になると、TBluetooth.OnDiscoveryEndイベントが呼ばれる。
TBluetooth.LastDiscoveredDevicesで、検出されたデバイスのリストが得られるそうで。
試行錯誤の記録
今回、「デバイスリスト」を得るところまでは試したい。
まず、ボタンクリックしたときにBluetoothのスキャン5秒する。
procedure TForm1.Button1Click(Sender: TObject);
begin
//五秒スキャンする
Bluetooth1.DiscoverDevices(5000);
end;
五秒経過して、終わると、OnDiscoveryEndイベントが呼ばれるはず。
procedure TForm1.Bluetooth1DiscoveryEnd(const Sender: TObject;
const ADeviceList: TBluetoothDeviceList);
begin
end;
OnDiscoveryEndイベントが呼ばれていることを確認しようと・・
procedure TForm1.Button1Click(Sender: TObject);
begin
//五秒スキャンする
Memo1.Lines.Clear;
Memo1.Lines.Add('スキャンするよ');
Bluetooth1.DiscoverDevices(5000);
end;
procedure TForm1.Bluetooth1DiscoveryEnd(const Sender: TObject;
const ADeviceList: TBluetoothDeviceList);
begin
Memo1.Lines.Add('5秒たったよ');
end;
こんなふうにしてまず試そうと思った。
・・のだけど、Button1クリックして5秒経っても、Memoになにも追加されない。OnDiscoveryEndイベントが呼ばれていないみたい。おかしいなぁと結構悩んじゃいました。
困ったときのサンプルコード。インストールしたフォルダの、次の場所にClassic Bluetooth Basic appのサンプルコードがあるんで
Embarcadero\Studio\20.0\Samples\Object Pascal\Multi-Device Samples\Device Sensors and Services\Bluetooth\Classic Bluetooth Basic app
走らせてみたら、うむ、あっさり、HC-05を発見してペアリングもできましたよ。ただこのサンプルは、TBluetoothのコントロールを直接使っていないようなんですね。
自分のテストのコードに戻ってきてにらめっこ。
あーっ。分かってみればつまらない話。コードの問題じゃなかった。Bluetooth1のEnabledプロパティがFalseだったという(笑)。 Trueに設定。
procedure TForm1.Button1Click(Sender: TObject);
begin
//五秒スキャンする
Memo1.Lines.Clear;
Memo1.Lines.Add('スキャンするよ');
Bluetooth1.DiscoverDevices(5000);
end;
procedure TForm1.Bluetooth1DiscoveryEnd(const Sender: TObject;
const ADeviceList: TBluetoothDeviceList);
var DeviceCount : Integer;
begin
Memo1.Lines.Add('5秒たったよ');
Memo1.Lines.Add(IntToStr(ADeviceList.Count));
end;
でまた問題が発生。何度やっても得られるCountがゼロで、デバイスを見つけてくれないようなんです(´;ω;`)
・・これもわかってみればつまらない話。公式のサンプルClassic Bluetooth Basic appで、
>あっさり、HC-05を発見してペアリングもできました
とした後だったので見つけられなかったようです。サンプルコード「Classic Bluetooth Basic app」で、Unpairしてから自分のテストコードに戻る。
やった、検出できた(Countが1になった)。うれしい。
ここまでくれば今回のゴールも見えてきた気がする。
ソース
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
System.Bluetooth, FMX.Controls.Presentation, FMX.StdCtrls,
System.Bluetooth.Components, FMX.Layouts, FMX.ListBox, FMX.ScrollBox, FMX.Memo;
type
TForm1 = class(TForm)
Bluetooth1: TBluetooth;
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Bluetooth1DiscoveryEnd(const Sender: TObject;
const ADeviceList: TBluetoothDeviceList);
private
{ private }
public
{ public }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
procedure TForm1.Button1Click(Sender: TObject);
begin
//五秒スキャンする
Memo1.Lines.Clear;
Memo1.Lines.Add('スキャンするよ');
Bluetooth1.DiscoverDevices(5000);
end;
procedure TForm1.Bluetooth1DiscoveryEnd(const Sender: TObject;
const ADeviceList: TBluetoothDeviceList);
var DeviceCount : Integer;
I: Integer;
dname : String;
begin
Memo1.Lines.Add('5秒たったよ');
DeviceCount := ADeviceList.Count;
Memo1.Lines.Add('見つかった件数'+IntToStr(DeviceCount)+'件');
if DeviceCount > 0 then begin
for I := 0 to DeviceCount-1 do begin
dname := ADeviceList[I].DeviceName;
Memo1.Lines.Add('DeviceName:'+dname);
end;
end;
end;
end.
実行結果
やった、見つかりました。"APW"というのは、HC-05の一つにつけてある名前です。複数使い分けるので、あらかじめATコマンド使い、AT+NAME=APW と設定してあります。それを検出できたわけです。
まとめ
「Arduino(+ HC-05)とWindowsPCの間で、Bluetooth使って無線通信」
(PCでBluetoothラジコン用のコントローラー作る)ことを今後の目標に
今回は、準備として、無料で利用できるDelphiのCommunity Editionで使える Bluetoothコントロール使って、ArduinoにつないだBluetoothモジュール、HC-05を検出するところまでを試しました。