# ESP32 BLE

<p align="center"><img src="https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge" /></p>

## Введение в проект

Проект исследования и обучения низкоэнергетического Bluetooth (BLE) для MicroPython на плате ESP32.

## Определение терминологии

Терминология написана хаотично, поэтому требуется стандартизация:

* BLE — низкоэнергетический Bluetooth (Bluetooth Low Energy, Bluetooth LE)
* Peripheral, BLE устройство, внешнее устройство, устройство — представляет собой `плату ESP32`
* Central, центральное устройство — представляет собой `телефон, компьютер и т. п.` устройства, способные подключаться к Bluetooth периферии

## Цели проекта

Используя BLE реализовать функцию управления Bluetooth клавиатурой, то есть создание Bluetooth (малой) клавиатуры (HID).

Для создания малой Bluetooth клавиатуры необходимо выполнить следующие функции:* Плата должна реализовать функцию HID, то есть работать как внешнее устройство, которое может быть сканировано и подключено центральным устройством.
* Создать схему малой клавиатуры, написать драйвер клавиатуры, чтобы обеспечить возможность ввода данных через плату ESP32 на центральное устройство.
* Также аппаратная часть включает световые эффекты, управляемые одним кнопочным переключателем:
    * Выключение всех светодиодов (по умолчанию)
    * Включение всех светодиодов
    * Дыхательный режим свечения
    * ~~Клик по кнопке для свечения~~
* Проектирование таблицы символьной отображаемости для унификации и удобства соответствия кнопкам и введенным данным.## Прогресс проекта

* [Видео демонстрация](https://www.bilibili.com/video/av91982504/)
* Успешно реализована функциональность платы как внешнего устройства, которая может быть сканирована и подключена телефоном и используется для ввода некоторых букв и цифр
* Разработана схема малой клавиатуры, жду подходящего времени для производства печатной платы, имеются два варианта
* Несколько попыток изготовления платы завершились неудачей, текущий уровень аппаратуры — `v0.2.5`, готовлюсь к новым тестам
* На данный момент [`v0.2.6`](https://gitee.com/walkline/esp32-ble/tree/master/hardware/v026) аппаратная часть кнопок успешно протестирована, теперь можно продолжать дальнейшее развитие...

## Знанные проблемы

* ~~При первом успешном соединении BLE устройства, при повторном подключении после сброса устройства или закрытия Bluetooth функции на центральном устройстве, устройство остаётся в состоянии "подключено", но центральное устройство никак не реагирует, ни успешно подключившись, ни потеряв соединение. Предположительно это связано с отсутствием настройки тайм-аута соединения, однако текущая версия прошивки устройства не поддерживает установку этого значения~~

* ~~На системах Windows 10 устройство BLE может быть найдено и подключено, но вскоре появляется сообщение "Ошибка драйвера", решение пока не найдено~~* Причиной вышеуказанных проблем является то, что `MicroPython ubluetooth` **не поддерживает** операции парирования и привязывания между устройствами; эта проблема требует решения...* Я попробовал добавить функцию сопряжения в прошивку, тестирование на `iOS` завершилось успешно.

### Ветвные проекты

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

* [Библиотека MicroPython Beacon](https://gitee.com/walkline/micropython-beacon-library): Эта библиотека предназначена для реализации двух типов маяков — Google Eddystone и Apple iBeacon, а также включает приближенную систему измерения расстояния до маяка.
* [ESP32 BLE - Дистанционное управление](https://gitee.com/walkline/ESP32-BLE-Remote_Controller): Этот проект предназначен для создания беспроволочного кнопочного управления, однако пока не поддерживает устройства Apple.
* [ESP32 BLE - Чтение данных температуры и влажности от Mi Temperature Humidity 2](https://gitee.com/walkline/ESP32-BLE-MI_Temperature_Humidity_2_Reader): Этот проект немного скучный, он предназначен для чтения данных о температуре и влажности с устройства Xiaomi Temperature Humidity 2.

* [Библиотека MicroPython BLE](https://gitee.com/walkline/micropython-ble-library): На основе ранее изученной информации о работе с Bluetooth Low Energy в MicroPython были созданы модульные классы, чтобы использовать их в будущем.

* [ESP32 BLE - Механическая клавиатура](https://gitee.com/walkline/ESP32-BLE-Mechanical_Keypad): Основной проект, создание механической клавиатуры.* [ESP32 BLE - UART](https://gitee.com/walkline/esp32-ble-uart): Использование `UART` для передачи данных между устройствами

### Знания о BLE

> Для непрофессионалов, ниже приведены мои личные выводы, если есть ошибки, буду рад получить замечания

* Устройства BLE следуют за спецификацией HOGP (HID over GATT Profile)
* `Профиль` состоит из множества `Услуг`
* `Услуги` состоят из множества `Характеристик`
* `Характеристики` состоят из множества `Дескрипторов`

	Например, беспроволочный клавиатурный профиль включает в себя как минимум три `Услуги`:

	* `Услуга аккумулятора`
	* `Информация о устройстве`
	* `Услуга HID`

	`Услуга аккумулятора` включает одну `Характеристику`:

	* `Уровень заряда аккумулятора`

	`Уровень заряда аккумулятора` может включать один `Дескриптор`:

	* `Клиентский конфигурационный дескриптор характеристики`

### Программная часть

Сначала, используя спецификацию `HOGP`, настроим все `Услуги`, `Характеристики` и `Дескрипторы`.

BLE устройство работает как `Периферийное устройство (GATT Сервер)`, регистрируется все `Услуги` локально, генерирует `payload`, ждет соединения `Центрального устройства (GATT Клиента)`.

Затем, как `Передающее устройство`, отправляет `payload` в радиоканал, включая:* Локальное имя (отображаемое имя)
* Все `services`
* Внешний вид (иконка рядом с отображаемым именем)`Централизованное устройство` анализирует содержание после получения броадкастового сообщения, отображает его, и при нажатии пользователем на отображаемое содержание начинается процесс привязки с `периферийным устройством`. Затем происходит чтение информации `характеристик` и `дескрипторов`, хранящихся локально в BLE устройстве, что завершает соединение и готовит устройство к получению данных.В данном процессе мы занимаемся только разработкой `периферийного устройства (GATT сервер)`.

### Раздел аппаратной части (кнопки)

Разработано два варианта схемы для маленького клавиатурного блока:

* Схема АЦП выборки
* Схема матрицы клавиш

#### Схема АЦП выборки

Схема АЦП выборки использует последовательное соединение одинаковых по модели сопротивлений, как показано на рисунке:

![Схема работы АЦП](images/screenshot_01.png)

Преимущества:

* Небольшое количество необходимых входов/выходов (IO), один IO может обслуживать минимум десять кнопок (не проверено)
* Удобство управления закупками благодаря использованию однотипных сопротивлений

Недостатки:

* Последовательное соединение позволяет обнаружить только одно нажатие кнопки за раз, то есть одновременно можно обнаружить только одну кнопку

Этот метод имеет две возможные области применения:

* Как маленькая клавиатура, так как она не требует возможности одновременного нажатия нескольких кнопок
* В сочетании с двумя каналами АЦП, одним из которых управляет основные клавиши (например Ctrl, Alt, Shift), а вторым используется для простой вводной информации

#### Схема матрицы клавиш

Схема матрицы клавиш представляет собой обычную схему клавиатуры, которая соединена следующим образом:

![Схема работы матрицы клавиш](images/screenshot_02.png)Преимущества:

* Полностью бесконфликтная работа всех клавиш
* Простая схема, использующая только кнопки

Недостатки:

* Большое количество необходимых входов-выходов (IO), где количество IO равно сумме колонок и строк, например, для 20-клавишной клавиатуры размером 4x5 требуется 9 IO

### Раздел аппаратной части (эффекты светодиодов)

Эффекты светодиодов также будут использовать схему матрицы (ожидается подтверждение) и использовать кнопки для переключения между четырьмя различными эффектами свечения

![Схема работы матрицы клавиш](images/screenshot_03.png)

### Связанные ссылки

* [Проект Walkline Hardware](https://gitee.com/walkline/walkline-wardware): Все открытые проекты аппаратной части, включая производственные файлы и BOM таблицы, будут доступны здесь, включая три рассматриваемые в этом проекте схемы

* [Загрузка пользовательского прошивочного файла ESP32](https://gitee.com/walkline/esp32_firmware)

### Ссылки на материалы

* [Официальная документация MicroPython](http://docs.micropython.org/en/latest/library/ubluetooth.html)

* [Примеры проектов MicroPython](https://github.com/micropython/micropython/tree/master/examples/bluetooth)

* Bluetooth GATT

	* [Услуги](https://www.bluetooth.com/specifications/gatt/services/)
	
		* [Устройства человек-машина](https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Services/org.bluetooth.service.human_interface_device.xml)
		
		* [Услуга аккумулятора](https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Services/org.bluetooth.service.battery_service.xml)* [Информация о устройстве](https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Services/org.bluetooth.service.device_information.xml)

* [Характеристики](https://www.bluetooth.com/specifications/gatt/characteristics/)

* [Дескрипторы](https://www.bluetooth.com/specifications/gatt/descriptors/)

* [Общие атрибуты](https://www.bluetooth.com/specifications/gatt/)
    * [Профиль HOGP](https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=245141): спецификация HOGP

* [Таблица внешнего вида](https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.gap.appearance.xml): таблица соответствия внешнего вида Bluetooth устройств

* [Таблица использования USB HID](http://www.freebsddiary.org/APC/usb_hid_usages): таблица соответствия значений кнопок клавиатуры

* [Инструмент дескриптора HID](https://www.usb.org/document-library/hid-descriptor-tool): используется для генерации данных `Report Map`

### Рекомендованная литература

* [Парсинг пакетов рассылки (Автор: сильный луч света)](https://www.cnblogs.com/aikm/p/5022502.html)
* [Запросы сканирования и ответы на запросы сканирования (Автор: сильный луч света)](https://www.cnblogs.com/aikm/p/5144209.html)

### Обмен информацией и сотрудничество

* Электронная почта для связи: <walkline@163.com>
* Группы для общения через QQ:
    * Walkline IoT: 163271910
    * BigIoT: 31324057

<p align="center"><img src="https://gitee.com/walkline/WeatherStation/raw/docs/images/qrcode_walkline.png" width="300px" alt="Walkline IoT"><img src="https://gitee.com/walkline/WeatherStation/raw/docs/images/qrcode_bigiot.png" width="300px" alt="BigIoT"></p>