Поделиться через


BlueBoss — обнаружение Bluetooth

Обзор

Bluetooth сейчас применяется во многих устройствах, предоставляя их пользователям возможность работы с беспроводными аксессуарами. Этот протокол позволяет пользователям обнаруживать любые совместимые устройства, находящиеся поблизости. Почему бы не посмотреть, кто находится рядом с вами? Почему бы при обнаружении совместимого устройства не запустить некоторую программу или не известить вас?

Энди Конкол (Andy Konkol) – https://copyandwaste.com

Оборудование:

· адаптер Bluetooth («свисток» для USB);

· внутренний («мама») коаксиальный разъем (SMA Female);

· кабель-переходник с коаксиального «папы» на ВЧ-«папу» (N-male);

· антенна 2.4 GHz с внутренним ВЧ-разъемом (N-female).

ПО:

· Coding4fun Developer Kit (EN);

· программа окна-уведомления Роберта Мисьяка (Robert Misiak) (EN).

Загрузки:

· загрузить исходный код и исполняемые файлы (EN).

Программное и аппаратные средства Bluetooth

Bluetooth служит для беспроводного взаимодействия устройств на малых расстояниях. Между тем, очень простая модификация аппаратуры позволяет расширить возможности Bluetooth — для этого используется антенна 2.4 ГГц, применяемая в WiFi-сетях 802.11 a/b/g.

Описание доработки Bluetooth-адаптера для подключения внешней антенны легко найти в Интернете. Принцип весьма прост: найти антенный контакт и припаять его к разъему для подключения внешней антенны. Я купил очень дешевый USB-адаптер Bluetooth на аукционе eBay. Открыв его корпус, я нашел на плате трассу антенны и припаял к ней коаксиальный разъем-«маму», закрепив его на адаптере изоляционным материалом. У меня получился Bluetooth-адаптер с разъемом для внешней антенны, подключив которую можно обнаруживать устройства на большем расстоянии.

Для подключения антенны нужен шнур-переходник. Я использую кабель-переходник коаксиальный «папа» — ВЧ-«папа». Один конец переходника я подключаю к своему адаптеру, а другой — к антенне 9 дБ с внешним ВЧ-разъемом.

ПО

Для работы с моим модернизированным «железом» мне потребовался набор инструментальных средств Coding4Fun Toolkit, содержащий API для Bluetooth-устройств. Этот API позволяет делать многие интересные вещи, но мне нужны лишь два метода из библиотеки ServiceAndDeviceDiscovery: DiscoverAllDevices и DiscoverDeviceByName.

DiscoverAllDevices позволяет «сканировать» эфир на частоте 2.4 ГГц и сообщать о найденных устройствах.

С помощью DiscoverDeviceByName можно искать устройство с определенным именем и сообщать о его наличии или отсутствии.

    1: private bool DevicePresent()
    2: {
    3:     BluetoothDeviceServicesManager workerBTMgr = new BluetoothDeviceServicesManager();
    4:     Device workerDevice = workerBTMgr.DiscoverDeviceByName(_watchItem.DeviceName);
    5:  
    6:     return (workerDevice != null);
    7: }
    8:  
    9: public void Run(String Operation)
   10: {
   11:     switch (Operation)
   12:     {
   13:         case "SingleDevice":
   14:             if (DevicePresent())
   15:             {
   16:                 _parentForm.Invoke(_parentForm.AddToDeviceSeenList, new object[] { _watchItem });
   17:             }
   18:             else
   19:             {
   20:                 _parentForm.Invoke(_parentForm.RemoveFromDeviceSeenList, new object[] { _watchItem });
   21:             }
   22:             break;
   23:         case "AllDevices":
   24:             BluetoothDeviceServicesManager workerBTMgr = new BluetoothDeviceServicesManager();
   25:             List<Device> Devices = workerBTMgr.DiscoverAllDevices();
   26:             _parentForm.Invoke(_parentForm.ThreadUpdateDiscoverBox, new object[] { Devices });
   27:             break;
   28:     }
   29: }

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

Чтобы интерфейс пользователя программы не зависал при выполнении поиска, мне требуется два рабочих потока. Один поток обнаруживает все устройства и отображает их в окне со списком, а другой ищет устройства по их именам, записанным в списке поиска. Я не специалист по многопоточному программированию, но реализовать эти два потока мне удалось без проблем.

Интерфейс пользователя

Поскольку кнопки «Add to watchlist» (добавить в список поиска) и «Edit» (изменить), по сути, имеют идентичное назначение, я решил реализовать перегрузку формы. Мне также требуется отслеживать родительскую форму и отключать ее при появлении WatchItemForm.

Вторая перегрузка позволяет мне вносить в элемент управления формы текст, соответствующий выбранному элементу списка WatchItem (кнопка «Edit»).

    1: public WatchItemForm(Form1 f, String DeviceName)
    2: {
    3:     InitializeComponent();
    4:     this._parentForm = f;
    5:     lblDeviceName.Text = DeviceName;
    6: }
    7:  
    8: public WatchItemForm(Form1 f, WatchItem item)
    9: {
   10:     InitializeComponent();
   11:     this._parentForm = f;
   12:  
   13:     lblDeviceName.Text = item.DeviceName;
   14:     tbxPicturePath.Text = item.ImagePath;
   15:     tbxProgramPath.Text = item.ProgramPath;
   16:     this._parentForm.Enabled = true;
   17: }

Я захотел использовать всплывающее окно с уведомлением и использовал программу Роберта Мисьяка NotifyWindow (EN). Это очень простая библиотека, позволяющая легко создавать всплывающие окна. Я изменил NotifyWindow, добавив переменную picturepath и окно с рисунком на форме. Как видите, создание NotifyWindow проблем не представляет:

    1: public void NotifyDeviceWindow(WatchItem x)
    2: {
    3:     NotifyWindow nw;
    4:     nw = new NotifyWindow();
    5:     // Проверка уведомительного сообщения
    6:     if (x.AlertMessage == null)
    7:     {
    8:         nw.Text = x.DeviceName;
    9:     }
   10:     else
   11:     {
   12:         nw.Text = x.AlertMessage;
   13:     }
   14:     // Проверка рисунка
   15:     if (x.ImagePath != null)
   16:     {
   17:         FileInfo imgfile = new FileInfo(x.ImagePath);
   18:         if (imgfile.Exists)
   19:         {
   20:             nw.PicturePath = x.ImagePath;
   21:         }
   22:         else
   23:         {
   24:             MessageBox.Show("Image does not exist");
   25:         }
   26:     }
   27:     nw.Notify();
   28:  
   29:     if (x.ProgramPath != null)
   30:     {
   31:         RunProcess(x.ProgramPath);
   32:     }
   33: }

Последовательность действий и алгоритм программы

  1. Пользователь щелкает кнопку Discover (обнаружить), в результате чего порождается поток, который просматривает находящиеся поблизости устройства Bluetooth.
  2. Поток завершается и обновляет содержимое списка Devices (устройства).
  3. Пользователь выбирает одно из обнаруженных устройств и щелкает кнопку «Add to watchlist» (добавить в список поиска). Порождается форма искомого устройства, в которой задаются текст сообщения, путь к рисунку и путь к исполняемой программе.
  4. Пользователь щелкает кнопку сохранения, после чего создается объект WatchItem, который добавляется в список watchList.
  5. Запускается таймер, по которому каждые 10 секунд создается поток, анализирующий наличие устройства с заданным именем.
  6. При обнаружении данного устройства, оно добавляется в список deviceSeenList, отправляется сообщение-оповещение и запускается назначенная программа.
  7. Если в следующем цикле таймера данное устройство по-прежнему обнаруживается, уведомление не отправляется. Если устройство больше не обнаруживается, оно удаляется из deviceSeenList.
Снимки экрана