Перейти к содержанию
Fire Monkey от А до Я
  • 0

Как работать с Bluetooth?


evdroniy

Вопрос

В ХЕ7 появилась поддержка Bluetooth. Примеров как организовать работу с блютухом я не нашёл (может быть плохо искал), по этому хотелось бы узнать как с ним работать? Если кто занимался этим вопросом покажите пример кода для delphi как вывести список устройств, подключение двух (и может быть более) устройств и пример обмена данными между ними. 

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

Первое что попалось "под руку" при поиске:

http://community.embarcadero.com/index.php/blogs/entry/bluetooth-le-support-in-rad-studio-xe7

http://www.youtube.com/watch?v=LcACJNNCkFo

http://www.youtube.com/watch?v=oeyGzuC_QqU

 

А вообще - гугл в помощь ("delphi xe7 Bluetooth")

Ссылка на комментарий
  • 0
  • Модераторы

Продублирую сюда ответ из блога:

Справка: http://docwiki.embarcadero.com/RADStudio/XE7/en/Using_Bluetooth

Примеры:

C:\Users\Public\Documents\Embarcadero\Studio\15.0\Samples\Object Pascal\Mobile Samples\Device Sensors and Services\Bluetooth

C:\Users\Public\Documents\Embarcadero\Studio\15.0\Samples\Object Pascal\RTL\Tethering

Ссылка на комментарий
  • 0

Добрый день! У меня тоже такой вопрос.

Я использую XE10

В примерах есть получение списка устройств, подключение к ним, и даже как отправить текст на устройство, но к сожалению этот пример не рабочий (про отправку текста). Т.е. я подключаюсь к устройству, пытаюсь отправить на него текст и после ожидания появляется ошибка в логе.  

Помогите пожалуйста разобраться с приемом/передачей текстовой информации с/на устройство.

Спасибо!

Ссылка на комментарий
  • 0
В 07.08.2016 в 22:01, Dmitry Sobko сказал:

Добрый день! У меня тоже такой вопрос.

Я использую XE10

В примерах есть получение списка устройств, подключение к ним, и даже как отправить текст на устройство, но к сожалению этот пример не рабочий (про отправку текста). Т.е. я подключаюсь к устройству, пытаюсь отправить на него текст и после ожидания появляется ошибка в логе.  

Помогите пожалуйста разобраться с приемом/передачей текстовой информации с/на устройство.

Спасибо!

Ошибка решается изменением service gui

  ServiceGUI = '{00001101-0000-1000-8000-00805F9B34FB}';

У меня с этим заработало, понятия не имею как это работает, но начал отправляться текст, а вот с приемкой - если глянуть код, она реализована. Там есть кнопка старт текст сервис, которая по идее создает поток и пытается принимать байты, но она не работает. Для приема используйте Socket.RecieveData , но он почему то у меня отказывается работать в потоке, а без него - фризит приложение.

Ссылка на комментарий
  • 0
В 27.11.2021 в 14:44, Hevard сказал:

В каком месте изменяется?

в тексте - между Const и var (глобальными). Я так понимаю речь идёт о примере "h:\Documents_Plextor\Embarcadero\Studio\Projects\Bluetooth\Classic Bluetooth Basic app". 
 

В 28.07.2017 в 09:21, M1shQa сказал:

но он почему то у меня отказывается работать в потоке

мешает строка где-то (после моего шаманства) 438 в методе TServerConnectionTH.Execute  
 

//      FSocket := nil;

постольку-поскольку в Делфи соображаю НЕ фундаментально допиливать пришлось не мытьём, так катаньем... Но заработало: и отправляет, и принимает... А принимает как-то странновато:
Screenshot_20221104_222949_com.embarcadero.ClBluetooth.thumb.jpg.3959b6d3b7f37adcedc0a9cd3263475e.jpg

монитор сериал-порта в Ардуино ИДЕ строку отправляет вродь как целиком, а сюда попадает вот в таком вот "порванном" виде, при чём Самс А52 может принять как 123+456789... Так где же собака "порылась"?

Заранее благодарен
 

 

Ссылка на комментарий
  • 0

EXSIMA.Connection.7z
Доброго времени суток.
Тема старая, но вдруг кому-то все еще интересно.
Проблема в примере от Embarcadero в том, что прием сообщений и отправка происходят через два разных соединения. Думаю, что в этом и проблема. Я запихал и отправку, и прием в один процесс и делаю это через один сокет. Условная проблема в том, что отправка происходит асинхронно, т.е. сообщение пихается в кэш, а уже внутри нити с установленным соединением происходит реальная отправка. Поэтому момент отправки я снабдил соответствующим событием. События срабатывают в контексте нити.
Надеюсь, в качестве отправной точки начинающим разработчикам моя писанина поможет.

Ссылка на комментарий
  • 0
В 05.11.2022 в 20:00, UFO 007 сказал:

в тексте - между Const и var (глобальными). Я так понимаю речь идёт о примере "h:\Documents_Plextor\Embarcadero\Studio\Projects\Bluetooth\Classic Bluetooth Basic app". 
 

мешает строка где-то (после моего шаманства) 438 в методе TServerConnectionTH.Execute  
 

//      FSocket := nil;

постольку-поскольку в Делфи соображаю НЕ фундаментально допиливать пришлось не мытьём, так катаньем... Но заработало: и отправляет, и принимает... А принимает как-то странновато:
Screenshot_20221104_222949_com.embarcadero.ClBluetooth.thumb.jpg.3959b6d3b7f37adcedc0a9cd3263475e.jpg

монитор сериал-порта в Ардуино ИДЕ строку отправляет вродь как целиком, а сюда попадает вот в таком вот "порванном" виде, при чём Самс А52 может принять как 123+456789... Так где же собака "порылась"?

Заранее благодарен
 

 

 

В 23.11.2022 в 23:09, UFO 007 сказал:

Гм... Не понял: что - пора есть пирожки по усопшему языку программирования?

Сделайте задержку в скетче на секунду (delay(1000)), что бы ваш текст успел собраться из потока в одно целое. Блютуз делает постоянный обмен с подключением к устройству через микросекунды из-за чего одна часть в одно время падает, а друга в другое и по этому идет 2 строками.  

Ссылка на комментарий
  • 0
23 часа назад, delcpy сказал:

 

Сделайте задержку в скетче на секунду (delay(1000))

Плохая идея организовывать протокол на задержках (delay) в системах с вытесняющей многозадачностью.
Только разделители (csv, json, PChar(#0)) или префиксы длины (http Content-Length) или жесткий фиксированный размер (packed record).
Человеsleep(1000)ко читаеsleep(1000)мый теsleep(1000)кст - каково тебе И и ии ии ииилон  мм мма мммааа... 

Изменено пользователем Slym
Ссылка на комментарий
  • 0
В 30.01.2024 в 17:03, vanechka25 сказал:

Проблема в примере от Embarcadero в том, что прием сообщений и отправка происходят через два разных соединения

Да не проблема это, может быть такая ситуация что вам устройство будет отправлять данные допустим "12" потом в JInputStream будет доступных байт ноль, потом придет "345", поэтому тут нужно делать проверку на завершающий символ сообщения и на необходимый таймаут. Все делается через java код, за 10 минут.

Ссылка на комментарий
  • 0
В 19.03.2024 в 12:28, UFO 007 сказал:

А мона слегонца развернуть:

это в *.pas вставка типа asm или на Андрюхину студию пересаживаться?

Это просто использовать Androidapi.JNI.Bluetooth

Это для примера
Допустим инициализировали адаптер  

BtObject := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.BLUETOOTH_SERVICE);
  if BtObject <> nil then
     FJBluetoothManager := TJBluetoothManager.Wrap((BtObject as ILocalObject).GetObjectID);
  if FJBluetoothManager <> nil then
    FJBluetoothAdapter := FJBluetoothManager.getAdapter;

тут подключились
mmBluetoothDevice := FJBluetoothAdapter.GetRemoteDevice(StringTOJString(mac));
tmpBluetoothSocket := mmBluetoothDevice.createInsecureRfcommSocketToServiceRecord
                     (TJUUID.JavaClass.fromString(StringToJString('00001101-0000-1000-8000-00805F9B34FB')));
mmBluetoothSocket.Connect();

отправка и прием ответа
    repeat
    if mmBluetoothSocket.isConnected = true then
       begin

         isOk := false;
         Answer := '';
         mmInStream := mmBluetoothSocket.getInputStream;
         mmOutStream := mmBluetoothSocket.getOutputStream;


         try
            mmOutStream.Write(StringToJAMove(command + #13#10));
            mmOutStream.Flush();
         except
         end;

         isClose := false;
         SW := TStopwatch.StartNew;
         milisec := 0;

         repeat

           try
               if mmInStream.available > 0 then
                 begin
                   LData := mmInStream.read();
                   isDataAviable := True;
                 end else
                   isDataAviable := false;
           except
               LData := -1;
           end;

           if (LData <> -1) and (isDataAviable = true) then
             begin

               try
                 Wdata := LData;
                 sym := Chr(WData);
               except
                 LData := -1;
               end;

               if sym <> '>' then
                   Answer := Answer + sym;
             end;

            try
              if Assigned(OBDListner) then
                isClose := OBDListner.Terminated;
            except
               Form1.LogOBDAdd('SendBTData except 3');
            end;

         milisec := SW.ElapsedMilliseconds;
         until  (LData = -1) or
                (sym = '>') or
                (isClose = true) or
                (milisec > 5000);

 

Изменено пользователем OnePeople
Ссылка на комментарий
  • 0
В 23.11.2023 в 06:49, Pavel San сказал:

Можете свой проект с работой по блутуз, сюда выложить?

Вообще-то - проект не мой, а лежит по адресу: c:\Users\Public\Documents\Embarcadero\Studio\22.0\Samples\Object Pascal\Multi-Device Samples\Device Sensors and Services\Bluetooth\ и окромя ГолубыхЗубов (базируется, правда на System.Bluetooth) там ещё кучи: ВиФи, акселерометр, геолокация, ... но самый прикольный TabSliding. Как и подсказал OnePeople в потоке TJReceiver ждём CRLF (#10 + #13) и строка выходит целиком, НО время её "коллекционирования" в System.Bluetooth занимает где-то секунд 5, а у мя таймер каждые 500 мС посылает запрос состояния и выводит положение датчиков.... Так что System.Bluetooth - не вариант, а вот исходник (точнее - обрывки) из последнего поста OnePeople после кувалды и напильника шлифанул "нулёвкой" и заработало... Кстати, для таких же почемучек как я (а мож и погоремычнее) приаттачиваю отшлифованный проект на Androidapi.JNI.Bluetooth (Ас Из - искушённые Гуру заметят в нём угловатости но критику эту - в студию: допилим). И чтобы чат заработал необходимо в среде Arduino IDE прошить ЕСП32 скетчем c:\Users\Администратор\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.11\libraries\BluetoothSerial\examples\SerialToSerialBT\... Затем проект затолкать Дэлфёй в телефон, в БТ-меню тела нажать "добавить устройство" и тел начнёт дискаверить.... По завершении законнектиться с ESP32-BT-Slave и тут же разорвать коннект, запустить J_BT, нажать btGetPaired и в комбобоксе (что рядом с ней) выбрать ESP32-BT-Slave и как увидите TJReceiver = Started и FJSocket <> nil  - можно чатиться с ЕСПхой открыв в Arduino IDE монитор сериал порта (Ctrl+Shift+M).  Вот и добрались к центральному вопросу поста:  а как средствами  Androidapi.JNI.Bluetooth  дискаверить устройства поблизости? Нет можно, конечно, забить костыль из System.Bluetooth, но хотелось бы чтобы если уж АПИ, то АПИ.

Заранее благодарен.

J_BT.ZIP

Ссылка на комментарий
  • 0
10 часов назад, UFO 007 сказал:

как средствами  Androidapi.JNI.Bluetooth  дискаверить устройства поблизости

   blStartDiscovery := FJBluetoothAdapter.startDiscovery;

   if TJBuild_VERSION.JavaClass.SDK_INT >= 29  then
     тогда нужно доп разрешение
     FPermissionBackgroundLocation := JStringToString(TJManifest_permission.JavaClass.ACCESS_BACKGROUND_LOCATION);

тут через BroadcastReceiver


ловим 
TJBluetoothDevice.JavaClass.ACTION_FOUND и TJBluetoothAdapter.JavaClass.ACTION_DISCOVERY_FINISHED и 
TJBluetoothAdapter.JavaClass.ACTION_DISCOVERY_STARTED



в методе BroadcastReceiver
OnReceive(Context: JContext; Intent: JIntent);    
if JStringToString(Intent.getAction).Equals(JStringToString(TJBluetoothDevice.JavaClass.ACTION_FOUND)) then
        begin

            Parcel := intent.getParcelableExtra(TJBluetoothDevice.JavaClass.EXTRA_DEVICE);
            if Parcel <> nil then
               BluetoothDevice := TJBluetoothDevice.Wrap((Parcel as ILocalObject).GetObjectID);

            if BluetoothDevice <> nil then
            if (BluetoothDevice.getBondState() = TJBluetoothDevice.JavaClass.BOND_NONE) then
            begin
                  Form1.AddListViewItem(Form1.lvBTOBD, jstringtostring(BluetoothDevice.getName),
                    jstringtostring(BluetoothDevice.getAddress),'Bluetooth');

            end;
        end;

 

 

 

 

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...