Berbagi teknologi

Masalah saat menggunakan Delphi untuk pengembangan Bluetooth BLE

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

konsep

Untuk pengembangan BLE di Delphi, seret TBlueToothLe ke antarmuka dan gunakan kontrol ini untuk mengembangkan BLE, seperti menghubungkan gelang Bluetooth.

Terdapat program BLEScanner dalam Demo yang disertakan dengan Delphi, yang dapat digunakan sebagai titik awal pengembangan.

pertanyaan

Jika program di atas dijalankan di Windows, setelah perangkat dipindai, jika mouse mengklik perangkat, antarmuka mungkin terhenti dan program tidak akan merespons. Melihat area manajemen tugas, memang benar programnya tidak responsif dan crash.

Analisis Penyebab

Klik mouse untuk memindai layanan perangkat yang dipilih. Kemudian, ketika layanan perangkat ditemukan, peristiwa OnServicesDiscovered TBluetoothLE dipicu. Dalam kejadian ini, beberapa layanan perangkat dibaca dalam satu lingkaran, dan kemudian untuk layanan tertentu, nama Karakternya dibaca dalam satu lingkaran. Crash adalah tempat loop membaca Karakter.

Kenapa jatuh, saya tidak tahu. Tapi saya menemukan solusinya, kodenya sebagai berikut:

  1. procedure TForm6.BluetoothLE1ServicesDiscovered(const Sender: TObject; const AServiceList: TBluetoothGattServiceList);
  2. var
  3. ServiceIndex: Integer;
  4. Service: TBluetoothGattService;
  5. CharacteristicIndex: Integer;
  6. Characteristic: TBluetoothGattCharacteristic;
  7. begin
  8. //以下代码如果不包到 TTask.Run 里面(原本的代码没有),在 WINDOWS 底下,执行到 for
  9. //CharacteristicIndex := 0 to Service.Characteristics.Count 会界面冻结,而且单步跟踪也停止
  10. //了,没有往下执行。
  11. TTask.Run(
  12. procedure
  13. var
  14. ServiceIndex: Integer;
  15. CharacteristicIndex: Integer;
  16. begin
  17. if AServiceList.Count > 0 then
  18. begin
  19. for ServiceIndex := 0 to AServiceList.Count - 1 do
  20. begin
  21. Service := AServiceList[ServiceIndex];
  22. TThread.Synchronize(nil,
  23. procedure
  24. begin
  25. Listbox2.Items.Add((ServiceIndex + 1).ToString + ' - ' + Service.UUIDName + ' - ' + Service.UUID.ToString);
  26. end
  27. );
  28. //以下代码会导致死机,如果断点跟踪,直接就是停在 for 这一行,不会继续往下执行。
  29. for CharacteristicIndex := 0 to Service.Characteristics.Count - 1 do
  30. begin
  31. Characteristic := Service.Characteristics[CharacteristicIndex];
  32. TThread.Synchronize(nil,
  33. procedure
  34. begin
  35. Listbox2.Items.Add(' - ' + Characteristic.UUIDName + ' - ' + Characteristic.UUID.ToString);
  36. end
  37. );
  38. end;
  39. end;
  40. end
  41. else
  42. TThread.Synchronize(nil,
  43. procedure
  44. begin
  45. Listbox2.Items.Add('- Access not allowed or no service available');
  46. end
  47. );
  48. end
  49. );
  50. //Listbox1.Enabled := True;
  51. end;

Penjelasan kode

Dalam kode di atas, TTask.Run telah saya tambahkan. TThread.Synchronize juga ditambahkan oleh saya. Hapus TTask.Run dan TThread.Synchronize dan kode yang tersisa adalah kode asli Demo yang disertakan dengan Delphi.

Pertama, masukkan kode asli ke dalam TTask.Run, yang berarti memasukkan kode-kode ini ke dalam thread untuk dieksekusi. Daripada membiarkan thread yang awalnya memunculkan acara OnServicesDiscovered dijalankan. Kemungkinan alasan: Thread yang memicu OnServicesDiscovered tidak dapat melakukan terlalu banyak tugas yang memakan waktu.

Kode dijalankan di thread. Saat Anda perlu menulis data ke kontrol antarmuka, seperti kode Listbox2.Items.Add, Anda perlu melakukan sinkronisasi thread. Jadi tambahkan TThread.Synchronize.

lingkungan pengembangan saya

Di lingkungan yang berbeda, fenomenanya mungkin berbeda. Oleh karena itu, inilah lingkungan pengembangan saya:

Delphi 11 Edisi Komunitas;

Edisi Windows 11 Rumah;

Program target yang akan dikompilasi dan dijalankan adalah versi Win32.

Tidak ada pengujian apakah Demo ini akan mengalami masalah di atas pada Android. Tapi saya yakin di Android, akan lebih baik menambahkan TTask.Run.

Lokasi program demo

Demo yang disebutkan di sini, setelah menginstal Delphi, jika diinstal secara default, program Demonya adalah:

C:UsersPublicDocumentsEmbarcaderoStudio22.0SamplesObject PascalSampel Multi-PerangkatSensor dan Layanan PerangkatBluetoothBLEScanner

Kesimpulannya

Tidak ada masalah dalam menggunakan Delphi untuk mengembangkan program BLE, seperti membuat APP gelang. Namun, perlu dicatat bahwa dalam banyak kejadian kontrol TBluetoothLE, yang terbaik adalah tidak mengeksekusi terlalu banyak kode. Jika ada logika bisnis yang kompleks, yang terbaik adalah menjalankannya di thread terpisah. Dalam metode kejadian, cukup mulai thread yang sesuai.

Untuk Delphi, TTask.Run yang baru ditambahkan memungkinkan kita memasukkan banyak kode ke dalam eksekusi thread. Metode penulisan kode jauh lebih sederhana daripada sebelumnya ketika kita harus membuat kelas thread.