Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Обзор
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: }
Последовательность действий и алгоритм программы
- Пользователь щелкает кнопку Discover (обнаружить), в результате чего порождается поток, который просматривает находящиеся поблизости устройства Bluetooth.
- Поток завершается и обновляет содержимое списка Devices (устройства).
- Пользователь выбирает одно из обнаруженных устройств и щелкает кнопку «Add to watchlist» (добавить в список поиска). Порождается форма искомого устройства, в которой задаются текст сообщения, путь к рисунку и путь к исполняемой программе.
- Пользователь щелкает кнопку сохранения, после чего создается объект WatchItem, который добавляется в список watchList.
- Запускается таймер, по которому каждые 10 секунд создается поток, анализирующий наличие устройства с заданным именем.
- При обнаружении данного устройства, оно добавляется в список deviceSeenList, отправляется сообщение-оповещение и запускается назначенная программа.
- Если в следующем цикле таймера данное устройство по-прежнему обнаруживается, уведомление не отправляется. Если устройство больше не обнаруживается, оно удаляется из deviceSeenList.