Интро


Уже сравнительно давно микроконтроллер ESP32 стал неким стандартом для множества DIY проектов. И действительно, возможность работы с Wi-Fi, Bluetooth, встроенная энергонезависимая память, а так же большое число выводов позволяют сделать массу интересных проектов.

В этой статье, мы поговорим про управление конроллером с помощью BLE используя доступные в AppStore приложения. А в следующей, если она будет, про создание собственного приложения для iOS.

На основе непосредственно контроллера, существует множество плат, с различными интегрируемыми модулями: экраном, модулем для карт памяти и тд. Одной из самых удобных для новичков, которым интересно именно программирование, а не возня с кучей проводков — платформа M5Stack.

image

Это устройство, в базовой комплектации, включает в себя LCD-дисплей, кардридер, аккумулятор, и три кнопки. Кроме этого, к нему существует множество модулей, подключаемых по принципу «бутерброда».

Не смотря на то, что в данной статье программирование микроконтроллера будет в Arduino IDE, его так же можно программировать с помощью MicroPython, а так же собственной блоковой среды разработки — UiFlow.

Инструкцию по настройке ArduinoIDE, для работы с M5Stack можно найти здесь.

Немного про то, что же такое BLE


BLE — Bluetooth Low Energy, это протокол, который, в отличии от обычного Bluetooth, постоянно находится в спящем режиме, кроме тех случаев, когда идёт непосредственная передача данных. За счёт этого, тратится примерно в 100 раз меньше энергии, что очень важно при использовании встраиваемых устройств с аккумуляторами.

Когда мы используем протокол BLE, мы работаем с сервисами и характеристиками. Это очень напоминает протокол MQTT, где есть топики. У каждого сервиса, есть как минимум одна характеристика. Каждый сервис это просто объем информации: например состояние датчика. Характеристика включает в себя описание себя (что она умеет: читать, писать, является Broadcast-ом) и непосредственно значение.

Каждый элемент, с которым мы работаем: сервис, характеристика должен иметь свой UUID (Universally unique identifier).

Подробнее про BLE можно почитать тут.

В Ардуино, система работа с BLE примерно такая: есть сервер — это само устройство, у сервера есть сервис, а у сервиса уже есть характеристики, в которые и поступают данные. У каждого из них могут быть Callback функции.

Выводим сообщение на экран


Чтобы работать с BLE и M5Stack из Arduino IDE необходимо подключить библиотеки.

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <M5Stack.h>

Затем сгенерировать как минимум два UUID: один для сервиса, а один для характеристики. Для генерации можно использовать UUID generator.


#define SERVICE_UUID              "9a8ca9ef-e43f-4157-9fee-c37a3d7dc12d" // ID сервиса
#define ELEM_UUID              "cc46b944-003e-42b6-b836-c4246b8f19a0" // ID характеристики

#define DEVINFO_UUID              (uint16_t)0x180a
#define DEVINFO_MANUFACTURER_UUID (uint16_t)0x2a29
#define DEVINFO_NAME_UUID         (uint16_t)0x2a24
#define DEVINFO_SERIAL_UUID       (uint16_t)0x2a25

#define DEVICE_MANUFACTURER "M5Stack" // Имя "Производителя"
#define DEVICE_NAME         "M5Stack_BLE" // Имя устройства

Создадим сервер и сервис.



// Создание Callback функции для сервера. 
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      // Обработка подключения телефона к устройству
      M5.Lcd.println("Connected");
    };

    void onDisconnect(BLEServer* pServer) {
      // Обработка отключения
      M5.Lcd.println("Disconnected");
    }
};


  // Код размещённый ниже - помещается в функцию setup()
  String devName = DEVICE_NAME; 
  String chipId = String((uint32_t)(ESP.getEfuseMac() >> 24), HEX);
  devName += '_';
  devName += chipId;

  BLEDevice::init(devName.c_str());  // Инициализация девайса 
  BLEServer *pServer = BLEDevice::createServer(); // Создание сервера
  pServer->setCallbacks(new MyServerCallbacks()); // Подключение Callback-а


  BLEService *pService = pServer->createService(SERVICE_UUID); // Cоздание сервиса


Для создания какой-либо характеристики необходимо сделать следующее:

  1. Объявить характеристику.

    BLECharacteristic *pElem;
  2. Объявить класс Callback Функция onWrite вызывается, когда в данную характеристику поступает информация. В нашем случае, информация просто выводится на экран.

    class ElemCallbacs : public BLECharacteristicCallbacks {
      void onWrite(BLECharacteristic *pCharacteristic) {
          std::string value1 = pCharacteristic->getValue();
          M5.Lcd.clear(BLACK);
          M5.Lcd.setCursor(3, 35);
          M5.Lcd.print("Get value: ");
          M5.Lcd.println(value1.c_str());
      }
    };
  3. И добавить новую характеристику к уже существующему сервису, с указанием свойств. Это тоже делается внутри функции setup()

     pElem = pService->createCharacteristic(ELEM_UUID,BLECharacteristic::PROPERTY_READ| BLECharacteristic::PROPERTY_WRITE);
      pElem->setCallbacks(new ElemCallbacs());

После добавления всех характеристик, важно не забыть запустить сервис, а после этого запустить Advertising.


  pService->start();


  // ----- Advertising

  BLEAdvertising *pAdvertising = pServer->getAdvertising();

  BLEAdvertisementData adv;
  adv.setName(devName.c_str());
  pAdvertising->setAdvertisementData(adv);

  BLEAdvertisementData adv2;
  adv2.setCompleteServices(BLEUUID(SERVICE_UUID));
  pAdvertising->setScanResponseData(adv2);

  pAdvertising->start();

Полностью исходный код представлен на гитхабе.

Тестируем


Для тестирования была использована программа BLE scanner. В ней можно выбрать устройство, выбрать характеристику и отправить на неё данные в текстовом или байтовом формате.

При запуске необходимо выбрать наше устройство, затем выбрать ту характеристику, с которой мы хотим работать и отправить в неё информацию.



А что же происходит на устройстве? При загрузке на нём отображается такие сообщения:



После подключения телефона — добавляется соответствующая строка:



А когда отправляется сообщение — экран выглядит так:



Заключение


Используя предложенный пример, можно достаточно легко сделать собственный функционал. А с учётом возможностей M5Stack, часть проектов не потребует никакого дополнительного оборудования. Но постоянно использовать BLE scanner или аналогичные программы — не удобно. Так что скоро мы разберём, как написать приложение под iOS, со своим функционалом.

P.S. Пользователи Android, не обижайтесь, что я не сказал про вас ни слова. У вас тоже есть возможность работы с BLE и даже приложение BLE Scanner доступно в PlayMarket.

Комментарии (1)


  1. virtualsys
    26.10.2019 19:30

    Огромное спасибо, что рассказали про платформу M5Stack. Как-то до этого не привелось про нее прочитать. Сходил на али — там все в порядке, есть из чего выбрать. Очень интересное направление для обучения.