Использование Bluetooth Low Energy (BLE) в ESP32 для соединения с фитнес браслетом


Согласитесь, как было бы замечательно, если бы свет в каждой комнате вашего дома (квартиры) зажигался бы автоматически когда вы в нее входите. И в данной статье мы рассмотрим создание подобной системы. Мы будем использовать модуль ESP32 в качестве BLE клиента, а фитнес браслет (fitness band) – в качестве BLE сервера. И когда человек с данным фитнес браслетом будет оказываться в зоне действия Bluetooth модуля ESP32, то модуль будет обнаруживать это и включать свет в комнате. Также вместо фитнес браслета в данном проекте можно использовать любое Bluetooth устройство, которое может выступать в роли BLE сервера.

Внешний вид проекта использования Bluetooth Low Energy (BLE) в ESP32

В предыдущей статье на нашем сайте мы уже рассматривали основы использования технологии Bluetooth в модуле ESP32 и там мы говорили, что данный модуль поддерживает две технологии – и классический (classic) Bluetooth, и BLE (Bluetooth Low Energy – Bluetooth с низким энергопотреблением). При этом классический Bluetooth можно использовать для передачи песен или других файлов, а BLE полезен в приложениях с оптимизацией энергопотребления батареи: фитнес браслеты, умные часы и т.д. Также модуль ESP32 можно использовать как serial (последовательный) Bluetooth наподобие модулей HC-05 или HC-06 в различных электронных проектах.

Общие принципы работы проекта

Технология BLE в модуле ESP32 может использоваться в двух режимах: в качестве сервера и в качестве клиента. В данном проекте мы BLE в модуле ESP32 будем использовать в качестве клиента и будем подключать его к фитнес браслету, который будет выступать в качестве сервера.

Все BLE серверы, включая и фитнес браслет в нашем проекте, находятся постоянно в режиме вещания, поэтому BLE всегда их могут обнаружить, сканируя диапазон передачи. В данном проекте мы фитнес браслет будем использовать в качестве "датчика близости" (proximity switch) – поскольку он всегда находится на руке человека, то обнаружив фитнес браслет в непосредственной близости от нашего BLE клиента, мы можем считать, что человек также находится недалеко от нашего клиента.

Мы будем программировать модуль ESP32 для функционирования в качестве BLE клиента, который будет постоянно сканировать BLE устройства. Если в процессе сканирования мы будем обнаруживать фитнес браслет в диапазоне нашего действия, мы будем пытаться подключиться к нему. Если подключение будет успешным, мы будем включать электрическую лампу, подавая соответствующий управляющий сигнал на один из контактов модуля ESP32. Наш метод обнаружения нужного нам устройства можно считать достаточно надежным, поскольку каждый BLE сервер (в нашем случае это фитнес браслет) имеет уникальный аппаратный идентификатор (unique hardware ID) и поэтому у двух разных BLE серверов не может быть двух одинаковых идентификаторов.

Прежде чем приступать к изучению данного проекта советуем прочитать статью по программированию модуля ESP32 с помощью Arduino IDE и основы применения классического Bluetooth в модуле ESP32.

Необходимые компоненты

  1. Модуль ESP32 (купить на AliExpress).
  2. Модуль реле (купить на AliExpress).
  3. Нагрузка переменного тока (в нашем случае лампа).

Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158

Схема проекта

Схема проекта для демонстрации использования BLE в модуле ESP32 представлена на следующем рисунке.

Схема проекта для демонстрации использования BLE в модуле ESP32

Модуль ESP32 в нашей схеме будет управлять включением/выключением лампы при обнаружении сигнала Bluetooth или его пропадании. Для переключения лампы с помощью модуля ESP32 мы будем использовать модуль реле, срабатывающий от напряжения 3.3V. Данный модуль реле вы можете сконструировать самостоятельно, используя транзистор BC548, как показано на приведенной схеме.

Предупреждение: в схеме предусмотрена работа с напряжением 220 В переменного тока, которое является опасным для жизни человека. Поэтому будьте внимательны и избегайте коротких замыканий.

Причина, по которой мы использовали в схеме транзистор BC548 (также подойдут BC547 или 2N2222), заключается в том, что для срабатывания его перехода эмиттер-база достаточно небольшого напряжения, а модуль ESP32 может выдавать на своих контактах только 3.3V. Реле, которое мы использовали в схеме, работает от 5V, поэтому его необходимо запитать от контакта Vin модуля (на данном контакте он получает напряжение 5V по кабелю, подключенном к компьютеру).

Резистор 1 кОм используется для ограничения тока через базу транзистора. Фазовый провод сети подключен к контакту NO реле, а общий провод реле подключен к нагрузке, второй контакт нагрузки подключен к нейтральному проводу сети. Вы можете поменять позиции фазового и нейтрального проводов в данном проекте, только ни в коем случае не соединяйте эти два провода вместе (опасность короткого замыкания!). Переменный ток всегда должен проходить через нагрузку. Автор проекта (ссылка на оригинал приведена в конце статьи) использовал готовый модуль реле на 3.3V, поэтому собранная им конструкция проекта выглядит следующим образом:

Внешний вид собранной конструкции проекта

Также в целях тестирования работы проекта вы можете вместо включения/выключения лампы переменного тока управлять переключением встроенного светодиода, подключенного к контакту 2 модуля ESP32.

Получение Bluetooth адреса сервера (адреса фитнес браслета)

Как мы уже говорили, модуль ESP32 в нашем проекте будет работать в качестве клиента (аналогично смартфону) и подключаться к серверу, которым в нашем случае будет фитнес браслет (Lenovo HW-01). Чтобы клиент мог подключиться к серверу, он должен знать его Bluetooth адрес. Каждый сервер в технологии BLE имеет свой собственный постоянный уникальный адрес. Это примерно как MAC адрес вашего компьютера или ноутбука.

Для получения Bluetooth адреса сервера (адреса фитнес браслета) мы будем использовать приложение nRF connect от компании Nordic semi-conductors. Оно бесплатно для пользователей платформ IOS и Android. Скачайте это приложение, установите и запустите его на выполнение. Затем в приложении запустите поиск Bluetooth устройств, находящихся поблизости. Приложение покажет список обнаруженных BLE устройств, среди них должен быть и ваш фитнес браслет. В нашем случае приложение обнаружило его под именем HW-01 как показано на рисунке ниже. Снизу под именем устройства высветится его аппаратный адрес.

Определение аппаратного адреса фитнес браслета с помощью приложения nRF connect

Таким образом, в нашем случае мы получили аппаратный BLE адрес равный C7:F0:69:F0:68:81. В вашем случае адрес будет другой, но такого же формата. Его в дальнейшем необходимо будет использовать в программе для модуля ESP32.

Определение услуг и характеристик UUID сервера

Для осуществления взаимодействия с BLE сервером необходимо знать предоставляемые им услуги и характеристики UUID (Universally Unique Identifier, универсальный уникальный идентификатор). Для их получения мы также будем использовать выше указанное приложение nRF connect.

В этом приложении нажмите на кнопку connect и выполните поиск этих характеристик (write characteristics). В результате этого приложение покажет вам service UUID и characteristic UUID для вашего устройства. В нашем случае мы на экране смартфона получили следующую картину:

Определение услуг и характеристик UUID сервера с помощью приложения nRF connect

В нашем случае Service UUID и Characteristic UUID оказались одинаковыми, но в общем случае они не обязаны быть одинаковыми. Запишем и сохраним их в отдельном месте.

Не обязательно использовать именно эти характеристики (write characteristics), вы можете использовать любые корректные услуги и характеристики UUID сервера (service and characteristic UUID), которые показаны в приложении.

Объяснение программы для модуля ESP32

Основная идея программы для модуля ESP32 состоит в том, чтобы сделать его Bluetooth клиентом, который будет постоянно сканировать эфир на наличие Bluetooth устройств и когда он будет находить наш сервер (фитнес браслет), он будет проверять его аппаратный идентификатор (hardware ID) и если он правильный, то он будет включать лампу при помощи подачи соответствующего сигнала на свой контакт 13.

На первый взгляд все кажется просто, но проблема здесь заключается в том, что радиус действия всех BLE серверов составляет примерно 10 метров, что сравнительно много для нашего проекта – ведь при такой дальности свет в комнате будет включаться когда мы будем находиться в другой комнате.

Для уменьшения радиуса действия сервера BLE мы будем использовать опцию связывания/"спаривания" (pairing option). BLE сервер и BLE клиент считаются связанными ("спаренными") только когда расстояние между ними не превышает 3-4 метров. А это расстояние уже хорошо подходит для нашего проекта. То есть в программе для модуля ESP32 мы будем выполнять не только сканирование пространства на наличие BLE сервера, мы также будем соединяться с ним и "спариваться" с ним (paired). Пока наши BLE сервер и клиент будут оставаться "спаренными" лампа переменного тока будет гореть. Как только расстояние между ними будет превышать радиус "спаривания" лампа будет выключаться.

Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.

После подключения в коде программы необходимых библиотек мы указываем в программе адрес BLE, Service и characteristic UUID, которые мы ранее получили с помощью приложения nRF connect.

Далее внутри функции setup мы инициализируем последовательную связь и включаем BLE в модуле ESP на сканирование эфира. После того как сканирование будет завершено для каждого обнаруженного устройства будет вызываться функция MyAdvertisedDeviceCallbacks.

Активное сканирование эфира мы будем использовать когда мы будем запитывать модуль ESP32 от стационарного источника питания, при питании от батарейки мы будем его отключать в целях экономии энергопотребления. Контакт trigger реле подключен к контакту 13 модуля, поэтому для этого контакта мы установим режим работы на вывод данных.

Внутри функции MyAdvertisedDeviceCallbacks мы будем выводить в окно монитора последовательной связи имя и другую информацию о BLE устройствах, которые мы обнаружили. Нам необходим будет аппаратный идентификатор (hardware ID) обнаруженного устройства – его мы будем сравнивать с заранее определенным значением (то есть с тем, которое нам нужно). Таким образом, мы будем использовать переменную Server_BLE_Address для получения адреса устройства и затем преобразовывать тип BLEAddress в строку.

Внутри функции loop мы будем производить сканирование эфира в течение 3-х секунд и помещать результат сканирования в объект foundDevices, который является объектом класса BLEScanResults. Если мы обнаружим одно или более устройств в процессе сканирования, мы будем проверять соответствие BLE адресов этих устройств тому адресу, который нам нужен. Если адреса совпадают, но устройства еще не "спарены" ранее (not paired), мы будем пытаться их "спарить" с помощью функции connectToserver. Также часть информации мы будем выводить в окно монитора последовательной связи в целях отладки.

Внутри функции connectToserver мы будем использовать UUID для связывания/"спаривания" наших BLE сервера и клиента. В качестве клиента у нас выступает модуль ESP32, поэтому мы создаем его в программе с помощью функции createClient() и затем соединяемся с адресом BLE сервера. Далее мы осуществляем поиск служб (service) и характеристик (characteristic) используя значения UUID и пытаемся осуществить соединение. Когда соединение будет успешно установлено функция будет возвращать true, а если соединение не будет установлено, то оно будет возвращать false. Заметьте, что не обязательно знать service и characteristic UUID чтобы произвести "спаривание" с сервером, мы здесь это использовали в образовательных целях.

Если соединение будет успешно установлено, то на контакт 13 мы будем подавать уровень high и управление мы будем передавать за пределы функции loop используя команду break. Логическая переменная paired при этом будет устанавливаться в true.

После того как "спаривание" (pairing) устройств прошло успешно и контакт 13 установлен в high, нам необходимо будет проверять находиться ли устройство в радиусе нашего действия. Поскольку устройства у нас уже "спарены", то сканирование BLE устройств уже не сможет увидеть устройство. Мы сможем найти его с помощью сканирования только когда пользователь с браслетом покинет область нашего действия. Таким образом, нам будет необходимо проверять этот факт и если мы обнаружим что BLE сервер находится за пределами области действия нашего модуля ESP32, мы будем устанавливать контакт 13 в low, а переменной paired присваивать значение false.

Тестирование работы проекта

После того как аппаратная часть проекта будет у вас готова загрузите код программы в модуль ESP32 и приступите к тестированию проекта.

Тестирование работы проекта

Вы должны заметить что лампа будет включаться когда фитнес браслет (сервер) осуществит "спаривание" с модулем ESP32. Вы можете проверить это увидев символ Bluetooth соединения на вашем фитнес браслете. После того как "спаривание" будет произведено отойдите с браслетом на 3-4 метра от модуля ESP32 – вы увидите что символ Bluetooth на браслете исчезнет и соединение будет потеряно. Лампа при этом должна выключиться. Когда вы с браслетом снова подойдете близко к модулю ESP32, устройства снова "спарятся" и лампа включится. Более подробно работу проекта вы можете посмотреть на видео, приведенном в конце статьи.

Исходный код программы (скетча)

Видео, демонстрирующее работу проекта

Источник статьи

(Проголосуй первым!)
Загрузка...
3 083 просмотров

Комментарии

Использование Bluetooth Low Energy (BLE) в ESP32 для соединения с фитнес браслетом — 14 комментариев

  1. Если нужно просто обычное определение находится ли браслет с нужным Mac-адресом в поле обнаружения, то самый хороший вариант это думаю следующий код:

    #include

    #define out_pin 22 // Пин светодиода на плате
    #define time_sleep 3 // Время сканирования устройств
    #define level_RSSI -75 // Уровень сигнала при достижении которого плата будет считать что браслет вне зоны доступа

    String My_BLE_Address = "ff:ff:ff:ff:ff:ff"; //Mac-адрес фитнес браслета

    BLEScan* pBLEScan;
    BLEScanResults *foundDevices;
    static BLEAddress *Server_BLE_Address;
    String Scaned_BLE_Address;
    String Scaned_BLE_RSSI;

    boolean paired = false;

    class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks
    {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
    //Serial.printf("Scan Result: %s \n", advertisedDevice.toString().c_str()); // Вывод списка обнаруженных устройств со сведениями
    Server_BLE_Address = new BLEAddress(advertisedDevice.getAddress());
    Scaned_BLE_Address = Server_BLE_Address->toString().c_str();
    Scaned_BLE_RSSI = advertisedDevice.getRSSI();
    if (Scaned_BLE_Address == My_BLE_Address && Scaned_BLE_RSSI.toInt() > level_RSSI) {
    //Serial.println(Scaned_BLE_RSSI); // Вывод текущего уровня сигнала если он не превышает лимит
    paired = true;
    }
    }
    };
    void setup() {
    Serial.begin(115200);
    BLEDevice::init("SonZMoon");
    pBLEScan = BLEDevice::getScan();
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true);
    pinMode (out_pin, OUTPUT);
    digitalWrite (out_pin, HIGH);
    }
    void loop() {
    paired = false;
    foundDevices = pBLEScan->start(time_sleep);
    if (paired == true) {
    digitalWrite (out_pin, LOW);
    } else {
    digitalWrite (out_pin, HIGH);
    }
    }

    При обнаружении нужного Mac-адреса в радиусе действия при условии что уровень сигнала соответствует загорается светодиод на плате, при потере сигнала или если его уровень падает ниже заданного светодиод гаснет. Просто и весьма надёжно

  2. подскажите а как сделать что бы при обнаружении устройство давало просто импульс на секунду например

    • Устанавливаете контакт в состояние high, потом задержка на секунду, и после этого контакт в состояние low

  3. На скриншоте nrf connect uuid не одинаковы. Посмотрите внимательнее и не вводите людей в заблуждение.

        • Да, опечатку вижу, но рисунок поправить уже не могу. Там снизу под рисунком в описании указано, что UUID у сервиса и у характеристики могут быть как одинаковыми, так и разными.

  4. Скетч требует доработки.Взаимоисключающие операторы в цикле будут постоянно включать и выключать пин с задержкой на сканирование.
    вопрос по времени коммуникации - есть ли способ снизить время подключения браслета (без учета снижения времени сканирования)?

    • К сожалению я этот проект лично не собирал, поэтому "сложные" вопросы подсказать по нему не могу. Если у вас получится его доработать, то будем признательны если поделитесь здесь в комментариях своими решениями с посетителями нашего сайта, которых также заинтересует этот проект

  5. Здравствуйте. ""В результате этого приложение покажет вам service UUID и characteristic UUID для вашего устройства" у меня показывает не такой длинный uuid!
    20:48

    58%

    =

    Devices

    DISCONNECT

    ADVERTISER

    REALME...2 PRO C4:2B:3D:90:41:50

    CONNE...

    CLIENT

    SERVE

    R

    BONDED

    Unknown Service

    UUID: 0xA700

    PRIMARY SERVICE

    Unknown Characteristic

    UUID: 0xA701

    Properties: INDICATE

    Descriptors:

    Client Characteristic

    Configuration UUID: 0x2902

    Value: Indications enabled

    Unknown Characteristic

    UUID: 0xA702

    Properties: WRITE

    Unknown Characteristic

    UUID: 0xA703

    Properties: WRITE NO RESPONSE

    Unknown Service

    UUID: 0xFCCO

    PRIMARY SERVICE

    Что то не так видимо делаю, подскажите пожалуйста

    • Если еще интересен вопрос по UUID/ Что тут странного - он бывает в формате 16 или 128 бит

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *