Обмен технологиями

Проблема с использованием Delphi для разработки Bluetooth BLE.

2024-07-12

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

концепция

Для разработки BLE в Delphi перетащите TBlueToothLe на интерфейс и используйте этот элемент управления для разработки BLE, например для подключения браслета Bluetooth.

В демо-версии Delphi есть программа BLEScanner, которую можно использовать в качестве отправной точки для разработки.

вопрос

Если вышеуказанная программа выполняется под Windows, то после сканирования устройства, если щелкнуть мышью по устройству, интерфейс может зависнуть и программа не будет реагировать. Если посмотреть на область управления задачами, то действительно, программа не отвечает и вышла из строя.

Анализ причин

Щелкните мышью, чтобы сканировать службы выбранного устройства. Затем, когда службы устройства обнаруживаются, запускается событие OnServicesDiscovered TBluetoothLE. В этом случае несколько служб устройства считываются в цикле, а затем для определенной службы в цикле считывается ее имя символа. Сбой происходит там, где цикл читает символ.

Почему он разбился, я не знаю. Но я нашел решение, код такой:

  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;

Объяснение кода

В приведенном выше коде TTask.Run был добавлен мной. TThread.Synchronize также был добавлен мной. Удалите TTask.Run и TThread.Synchronize, а оставшийся код — это исходный код демо-версии, поставляемой с Delphi.

Сначала поместите исходный код в TTask.Run, что означает помещение этих кодов в поток для выполнения. Вместо того, чтобы позволить выполнить поток, который первоначально вызвал событие OnServicesDiscovered. Возможная причина: поток, вызвавший OnServicesDiscovered, не может выполнить слишком много трудоемких задач.

Код выполняется в потоке. Когда вам нужно записать данные в элемент управления интерфейсом, например код Listbox2.Items.Add, вам необходимо выполнить синхронизацию потока. Поэтому добавьте TThread.Synchronize.

моя среда разработки

В разных средах явления могут быть разными. Итак, вот моя среда разработки:

Delphi 11 Community Edition;

Windows 11 Домашняя версия;

Целевая программа, которую необходимо скомпилировать и запустить, — это версия Win32.

Не существует проверки того, будут ли в этой демо-версии вышеуказанные проблемы под Android. Но я считаю, что под Android лучше будет добавить TTask.Run.

Расположение демо-программы

Упомянутая здесь демо-версия, после установки Delphi, если она установлена ​​по умолчанию, демо-программа:

C:UsersPublicDocumentsEmbarcaderoStudio22.0SamplesObject PascalMulti-Device SamplesDevice Sensors and ServicesBluetoothBLEScanner

в заключение

Нет проблем с использованием Delphi для разработки программ BLE, например для создания приложения для браслета. Однако следует отметить, что во многих событиях элемента управления TBluetoothLE лучше не выполнять слишком много кода. Если есть сложная бизнес-логика, лучше всего выполнить ее в отдельном потоке. В методе события просто запустите соответствующий поток.

В Delphi недавно добавленный TTask.Run позволяет нам запускать большой объем кода в выполнение потока. Метод написания кода стал намного проще, чем раньше, когда нам приходилось создавать класс потока.