- PVSM.RU - https://www.pvsm.ru -
— Чайники, весы, игрушки, лампочки, кофемашины… В эти и другие устройства встраивают bluetooth-модули.
— Зачем?
— Чтобы дать пользователю управлять своими устройствами через приложение. К примеру, управлять освещением в комнате.
— Ой, а можно ли собрать какое-то своё простое устройство и управлять им прямо через браузер?
— Да! И эта статья как раз об этом.
Здесь я приведу несколько основных терминов, которые необходимы нам для воплощения задачи (о ней мы поговорим немного позже) в жизнь.
Стандарт беспроводной радиосвязи, связывающий на коротком расстоянии различные типы устройств. Для управления железками через Web Bluetooth API нам потребуется Bluetooth v4.0.
The Generic Attributes — постоянно транслируемое дерево возможностей bluetooth-устройства.
Внутри bluetooth-устройства есть сервисы. Сам по себе сервис — это коллекция характеристик и связей с другими сервисами. У каждого сервиса есть свои UID и имя. Зачастую будут попадаться “Unknown services”. Это связано с тем, что количество устройств и вариантов их использования велико.
Внутри каждого сервиса есть характеристики, в которые можно писать, считывать их, а также подписаться на них. Характеристика также имеет свой UID.
В качестве задачи я выбрал реализацию сайта, который может:
И, как можно понять из постановки задачи, необходимо научиться подключаться и отключаться от bluetooth-устройства.
Для выполнения задачи я выбрал следующий список необходимого:
Данный список не является строгим для реализации. Я уверен, что можно заменить Arduino чем-то другим и выбрать другой bluetooth-модуль. Но в статье будет рассматриваться взаимодействие именно с этими компонентами.
Вкратце суть такова: мы подключаемся к bluetooth-модулю и передаём некий код (от 1 до 4 включительно). Если код валиден, то зажигается один из трёх цветов или же светодиоды начинают мигать всеми возможными цветами (красный, зелёный, синий) в течение какого-то времени.
Для начала необходимо собрать рабочую схему и загрузить Arduino-скетч. Ниже я даю схему (рис. 1) и код скетча, которые у меня получились.
Рис. 1 (Схема для сборки)
#include <SoftwareSerial.h>
int green_pin = 2;
int red_pin = 3;
int blue_pin = 4;
int BLINK_STEPS = 3;
int BLINK_DELAY = 100;
SoftwareSerial mySerial(7, 8); // RX, TX
void setup() {
Serial.begin(9600);
mySerial.begin(9600);
pinMode(green_pin, OUTPUT);
pinMode(red_pin, OUTPUT);
pinMode(blue_pin, OUTPUT);
}
int code;
void loop() {
if (mySerial.available()) {
code = mySerial.read();
shutDownAll();
if (code > 0 && code < 5) {
analogWrite(code, 200);
}
if (code == 1) {
blinked();
}
}
}
void shutDownAll() {
analogWrite(green_pin, 0);
analogWrite(red_pin, 0);
analogWrite(blue_pin, 0);
}
void blinked() {
int steps = 0;
while(steps <= BLINK_STEPS) {
analogWrite(green_pin, 200);
delay(BLINK_DELAY);
analogWrite(green_pin, 0);
delay(BLINK_DELAY);
analogWrite(red_pin, 200);
delay(BLINK_DELAY);
analogWrite(red_pin, 0);
delay(BLINK_DELAY);
analogWrite(blue_pin, 200);
delay(BLINK_DELAY);
analogWrite(blue_pin, 0);
delay(BLINK_DELAY);
steps += 1;
}
}
Итак, мы загрузили скетч, подключили схему к питанию. Что дальше? Для работы с Web Bluetooth API нам необходимо знать имя нашего устройства, и к какому сервису мы хотим получить доступ. Для этого можно воспользоваться приложением “nRF Connect”.
Включаем приложение и видим список bluetooth-устройств рядом с нами (рис. 2).
Рис. 2 (Список устройств, которое нашло приложение)
Устройство с именем “CC41-A” меня заинтересовало и не зря.
После подключения к устройству нам становится доступен список его сервисов (рис. 3). Вряд ли мы найдём что-то интересное в “Device information”, так что смело жмём в “Unknown service”.
Рис. 3 (Список сервисов устройства)
На скриншоте ниже (рис. 4) можно заметить самое главное для нас: запись в характеристику и её чтение.
Когда я решал задачу, описанную выше, то попробовал отправить в характеристику значение «2». В результате чего моя пара светодиодов начала гореть зелёным цветом. Почти успех. Теперь надо сделать тоже самое, но не через мобильное приложение, а через браузер.
Рис. 4 (Unknown характеристика)
Вот список данных, которые мы получили из приложения для продолжения выполнения задачи:
Прежде чем начать писать JavaScript-код, стоит оговорить несколько моментов:
Работа с Web Bluetooth API построена на Promise. Ниже я буду приводить поэтапные примеры кода. Полный исходный код можно будет найти в репозитории, на который будет оставлена ссылка.
Для начала нам необходимо подключиться к устройству. Мы запрашиваем устройства и в фильтре передаём имя устройства и UID сервиса, с которыми будем работать. Если не указать сервис заранее, то в дальнейшем с ним нельзя будет взаимодействовать.
navigator.bluetooth.requestDevice({
filters:
[
{ name: MY_BLUETOOTH_NAME },
{ services: [SEND_SERVICE] },
]
})
После того как мы нажмём на кнопку “Connect”, у нас откроется окно (рис. 5), в котором необходимо выбрать устройство и нажать на кнопку подключения.
Рис. 5 (Окно с доступным к подключению устройством)
При подключении возвращается Promise, содержащий “device”, к которому можно подключиться. Окей, давайте запишем его в переменную и создадим соединение.
.then(device => {
myDevice = device;
return device.gatt.connect();
})
После этого нам возвращается Promise, содержащий “server”. Затем мы у “server” запрашиваем “service”, передавая туда UID сервиса (который мы подсмотрели через приложение). Затем нам возвращается Promise, содержащий “service”, у которого мы запрашиваем “characteristic”, передавая её UID (который мы тоже подсмотрели через приложение).
.then(server => server.getPrimaryService(SEND_SERVICE))
.then(service => service.getCharacteristic(SEND_SERVICE_CHARACTERISTIC))
И вот только теперь мы можем уже начинать что-то делать. Например, я запоминаю характеристику в переменную и вешаю обработчики кликов на кнопки. В своих data-атрибутах они содержат код, который будет записан в характеристику при клике.
В обработчиках кликов по кнопкам содержится следующий код:
const code = Number(event.target.dataset.code);
if (code === 1) {
toggleLigthCharacteristic.writeValue(Uint8Array.of(code));
return;
}
toggleLigthCharacteristic.readValue()
.then(currentCode => {
const convertedCode = currentCode.getUint8(0);
toggleLigthCharacteristic.writeValue(
Uint8Array.of(convertedCode === code ? 0 : code)
);
});
В характеристику необходимо передавать массив uint8, поэтому для преобразования кода, который будет передан в неё, необходимо использовать Uint8Array.
По задумке, код 1 заставляет светодиоды мигать тремя цветами и затем гаснуть. Но как погасить светодиод, если в него был передан код 3 и светодиод всё ещё горит? Или включить другой цвет?
Я считываю значение, лежащее в характеристике, преобразую его с помощью getUint8 и, если код совпадает, отправляю любое невалидное значение (например 0). Если же значение валидное, то преобразую его в массив unit8 и записываю в характеристику.
Для окончательного решения поставленной задачи необходимо всего лишь научиться отключаться от устройства. У нас уже есть eventListener на кнопке “Disconnect”, в котором происходит отключение от bluetooth-устройства, снимаются eventListeners, кнопки управления прячутся, а в переменные записывается undefined.
myDevice.gatt.disconnect();
toggleItemsEventListeners('removeEventListener');
toggleButtonsVisible();
toggleLigthCharacteristic = undefined;
myDevice = undefined;
Мы создали простую web-страницу, с помощью которой можно подключаться к bluetooth-устройству и управлять им. Как видите, это довольно просто. А устройства, которые вы можете собирать и управлять таким образом, ограничены лишь вашей фантазией!
Автор: Виктор Пасынок
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/285514
Ссылки в тексте:
[1] Репозиторий с рабочим приложением: https://github.com/binjospookie/web-bluetooth-api
[2] Видео с рабочим приложением: https://binjo.ru/iot/demo.mp4
[3] Статья на Google Developers: https://developers.google.com/web/updates/2015/07/interact-with-ble-devices-on-the-web
[4] Спецификация от Web Bluetooth Community Group: https://webbluetoothcg.github.io/web-bluetooth/
[5] Больше информации про GATT: https://www.bluetooth.com/specifications/gatt/generic-attributes-overview
[6] Вадим Макеев с докладом «Я и ИоТ»: https://www.youtube.com/watch?v=l9GQbpVwR6A
[7] Поддержка Web Bluetooth API на Can I Use: https://caniuse.com/#search=bluetooth
[8] Источник: https://habr.com/post/416579/?utm_source=habrahabr&utm_medium=rss&utm_campaign=416579
Нажмите здесь для печати.