До настоящего момента мы изучали работу ESP32-S3 с проводными протоколами связи, такими как UART, I²C и SPI . Эти протоколы являются важными инструментами в арсенале разработчика встроенных систем. Они позволяют нам расширять возможности микроконтроллера, добавлять внешние датчики, взаимодействовать с дисплеями и соединять несколько микроконтроллеров вместе по общей шине.
Однако проводная связь вносит существенные ограничения:
- Ограниченная мобильность: устройства должны оставаться физически соединенными между собой.
- Протоколы ближнего действия: протоколы, такие как I²C и SPI, предназначены для передачи данных на короткие расстояния (обычно на одной печатной плате). Передача данных по длинным проводам приводит к появлению шума и ухудшению качества сигнала.
- Масштабируемость и стоимость: прокладка физических проводов между десятками датчиков окружающей среды, разбросанных по зданию, является дорогостоящим и непрактичным решением.
Протоколы беспроводной связи решают эти проблемы, передавая и принимая данные с помощью радиочастотных (РЧ) волн по воздуху. Это устраняет необходимость в физических кабелях, обеспечивая настоящую мобильность, большую дальность действия и упрощая развертывание сложных сенсорных сетей. Двумя наиболее распространенными беспроводными протоколами в области встраиваемых систем являются Wi-Fi (работу с ним мы изучали в прошлом уроке), отлично подходящий для высокоскоростного подключения к интернету, и Bluetooth, идеально подходящий для маломощной связи между устройствами.
Bluetooth — это стандарт беспроводной связи ближнего радиуса действия, работающий в радиодиапазоне ISM (промышленный, научный и медицинский) 2,4 ГГц. Он предназначен для обмена данными между устройствами на коротких расстояниях с использованием маломощной радиосвязи.
Вместо передачи непрерывного сигнала Bluetooth разделяет данные на небольшие блоки, называемые пакетами. Эти пакеты передаются по воздуху с использованием метода, называемого скачкообразным переключением частот, при котором радиомодуль быстро переключается между различными частотами в диапазоне 2,4 ГГц. Это уменьшает помехи от других устройств, таких как Wi-Fi-роутеры и микроволновые печи, работающие в том же диапазоне.
Диапазон 2,4 ГГц разделен на несколько каналов. Bluetooth Classic использует 79 каналов, расположенных на расстоянии 1 МГц друг от друга, в то время как Bluetooth Low Energy (BLE) использует 40 каналов, расположенных на расстоянии 2 МГц друг от друга. Во время связи устройства следуют общей последовательности переключения каналов и передают каждый пакет по отдельному каналу в этой последовательности.
Для обмена данными Bluetooth обычно использует архитектуру «центр-периферия»:
- Периферийное устройство (сервер): устройство, которое сообщает о своем присутствии и хранит данные.
- Центральный узел (клиент): устройство, которое сканирует периферийные устройства, подключается к ним и запрашивает или отправляет данные.
Когда устройства подключаются через Bluetooth, они образуют крошечную, самоорганизующуюся сеть, называемую пикосетью. В пикосети устройства выполняют определенные функции:
- Ведущее устройство (Master): устройство, инициирующее соединение и определяющее последовательность и синхронизацию переключения частот (например, ваш смартфон).
- Подчиненные (ведомые) устройства (Slave): устройства, которые следуют правилам Главного устройства и синхронизируются с его часами (например, ваши беспроводные наушники и умные часы).
В одной пикосети может быть одновременно подключен одно ведущее и до семи активных ведомых устройств. Ведущее устройство общается с ведомыми, но ведомые не общаются напрямую друг с другом; вся информация передается через ведущее устройство.

Скаттернеты (Scatternets)
Для скаттернетов также используют следующие названия:
- Рассеянные сети
- Децентрализованные пико-сети
- Объединенные пикосети
Скаттернет формируется, когда несколько пикосетей соединяются через устройства, участвующие более чем в одной пикосети, что позволяет более крупной сети бесперебойно функционировать.
В скаттернете устройство может быть ведомым (Slave) в одном пикосети, но выступать в качестве ведущего (Master) в другом, создавая сеть взаимосвязанных беспроводных узлов.
Для того чтобы два устройства могли установить сеть и обмениваться данными, они проходят определенный процесс подключения:
- Запрос (Inquiry): Если устройство хочет найти другие устройства, оно отправляет запрос на поиск. Устройство, которое хочет быть найденным, должно находиться в «режиме обнаружения», то есть активно отслеживать эти запросы и отвечать на них.
- Пейджинг (Paging): После того, как устройства обнаружат друг друга, они устанавливают соединение. Это включает в себя синхронизацию их тактовых сигналов и согласование схемы скачкообразного изменения частоты.
- Сопряжение (безопасность) (Pairing): Чтобы предотвратить случайное подключение соседа к вашим колонкам, устройства обычно требуют процесса сопряжения. Они генерируют и обмениваются защищенным цифровым ключом (часто проверяемым путем ввода PIN-кода или подтверждения запроса). После сопряжения устройства запоминают этот ключ и могут автоматически подключаться в будущем, используя зашифрованные сигналы, обеспечивая безопасность данных от прослушивания.
По мере развития Bluetooth был представлен новый, важный вариант, призванный устранить критическое ограничение: энергопотребление.
Оригинальный Bluetooth, часто называемый Bluetooth Classic или BR/EDR (Basic Rate / Enhanced Data Rate), предназначен для непрерывной потоковой передачи данных. Он обеспечивает скорость передачи данных до 3 Мбит/с и идеально подходит для таких приложений, как потоковая передача аудио (наушники, колонки) или быстрая передача файлов. Однако он потребляет относительно много энергии, что является проблемой для небольших устройств с батарейным питанием, таких как фитнес-браслеты или умные датчики, которым необходимо работать в течение нескольких месяцев от батарейки-таблетки.
Технология Bluetooth Low Energy (BLE), представленная в Bluetooth 4.0 (2010), была разработана с нуля с приоритетом на энергоэффективность. BLE обеспечивает значительно меньшее энергопотребление благодаря ряду конструктивных решений:
- Короткие пакеты передачи: вместо поддержания непрерывного соединения устройства BLE большую часть времени находятся в спящем режиме и пробуждаются лишь на короткое время для отправки или получения небольших пакетов данных.
- Меньшее количество каналов: BLE использует всего 40 каналов (каждый шириной 2 МГц), из которых 3 являются выделенными рекламными каналами, используемыми для обнаружения.
- Упрощенный процесс подключения: соединения BLE устанавливаются и завершаются быстрее.
- Оптимизированная структура пакетов: пакеты BLE меньше по размеру и проще.
Устройство на основе технологии BLE может работать месяцами или даже годами от небольшой батарейки-таблетки, что делает его идеальным для:
- фитнес-трекеры и умные часы;
- медицинские датчики (пульсометры, глюкометры);
- устройства для умного дома (замки, освещение, термостаты);
- технология маяков (геолокационные сервисы в магазинах)
- датчики промышленного интернета вещей.
Bluetooth — это не один протокол, а набор протоколов, организованных по уровням. Каждый уровень обрабатывает определенную часть связи, от физической радиопередачи до приложения, с которым взаимодействует пользователь.
Протокол Bluetooth состоит из двух основных частей: стека хоста и стека контроллера.
Стек контроллеров управляет операциями на аппаратном уровне и низкоуровневым управлением каналами связи. Он включает в себя:
Физический уровень (радио)
В самом низу стека находится радиоуровень. Это собственно аппаратная часть: антенна, которая передает и принимает радиоволны, и схемы, которые выполняют модуляцию и демодуляцию. Этот уровень обрабатывает передачу битов по воздуху с использованием модуляции GFSK и FHSS.
Непосредственно над физическим радиомодулем находится базовый уровень. Этот уровень управляет синхронизацией и структурой группировки и передачи битов. Он отвечает за:
- Формирование пакетов: данные группируются в пакеты (небольшие группы), заголовки которых содержат адресную и управляющую информацию.
- Обнаружение ошибок: для обнаружения ошибок передачи используются такие методы, как CRC (циклическая избыточность).
- Синхронизация: часы ведущего устройства используются для синхронизации всех устройств в пикосети.
- Типы соединений: Bluetooth поддерживает два типа соединений:
- SCO (Synchronous Connection-Oriented): используется для передачи аудио в реальном времени, где допустима некоторая потеря данных, но синхронизация должна быть точной; применяется, например, для телефонных звонков.
- ACL (асинхронный бессоединительный протокол): используется для передачи данных общего назначения, при которой данные не могут быть потеряны; применяется для передачи файлов, датчиков.
Протокол управления каналами связи (LMP) отвечает за установление и управление Bluetooth-соединениями. Он обрабатывает:
- Сопряжение и аутентификация: проверка того, что оба устройства действительно являются теми, за кого себя выдают.
- Шифрование: кодирование данных таким образом, чтобы они не могли быть прочитаны посторонними лицами.
- Управление энергопотреблением: переключение в режим сна с низким энергопотреблением для экономии заряда батареи.
- Переключение ролей: при необходимости устройство может запросить переключение с ведомого на ведущее устройство.
Интерфейс HCI (Host Controller Interface) — это стандартизированная граница между аппаратным обеспечением Bluetooth (радио + базовая полоса + LMP) и программным обеспечением, работающим на процессоре хоста, обычно микроконтроллере или ЦП. Он определяет набор команд, которые хост может отправлять контроллеру, и событий, которые контроллер отправляет обратно.
Такое разделение означает, что модуль Bluetooth может представлять собой отдельный чип, взаимодействующий с основным процессором через простой интерфейс, такой как UART или USB.
L2CAP — это уровень в Bluetooth, который позволяет различным приложениям совместно использовать одно и то же Bluetooth-соединение. Он работает как промежуточный слой между приложением и нижестоящей системой Bluetooth.
Его основная задача — мультиплексирование, что означает, что он позволяет нескольким потокам данных использовать одно соединение одновременно, не смешивая их. Каждое приложение получает свой собственный логический канал.
L2CAP также обрабатывает разделение и объединение пакетов. Если данные слишком велики, он разбивает их на более мелкие части перед отправкой. На стороне получателя он объединяет эти части, чтобы исходные данные были восстановлены корректно.
Он также поддерживает качество обслуживания (QoS), которое помогает определять, как следует обрабатывать данные в зависимости от приложения. Например, для передачи аудио требуется быстрая доставка, а для передачи файлов — более высокая точность.
Поверх уровня L2CAP Bluetooth использует несколько протоколов верхнего уровня, которые предоставляют различные коммуникационные услуги, такие как последовательная связь, передача файлов, доступ в Интернет, потоковая передача аудио и телефония. Эти протоколы позволяют устройствам Bluetooth поддерживать множество типов приложений и сервисов.
RFCOMM — это протокол Bluetooth, который служит простой заменой последовательному кабелю. Он имитирует традиционную последовательную связь (RS-232), поэтому старые приложения, разработанные для проводных последовательных портов, могут легко работать через Bluetooth. Он работает поверх L2CAP и широко используется в таких устройствах, как модули Bluetooth в проектах на микроконтроллерах, GPS-устройства и простые беспроводные датчики. Он также основан на стандарте ETSI TS 07.10, который определяет, как обрабатывается последовательная связь.
OBEX (Object Exchange) используется для передачи объектов, таких как файлы, изображения и контакты, между устройствами. Он часто встречается в функциях обмена файлами и синхронизации контактов.
Протокол WAP (Wireless Application Protocol) использовался в первых мобильных устройствах для доступа к базовым интернет-сервисам через Bluetooth и другие беспроводные сети, хотя сейчас он в основном устарел.
Протокол TCS (Telephony Control Protocol) используется для управления услугами голосовой связи, такими как установление и завершение вызовов, и в основном применяется в беспроводных телефонных системах и голосовых шлюзах.
К другим протоколам этого уровня относятся:
- BNEP (Bluetooth Network Encapsulation Protocol): протокол для организации сети по Bluetooth.
- AVDTP (Audio/Video Distribution Transport Protocol): для потоковой передачи аудио.
- AVCTP: для дистанционного управления аудио/видео.
На вершине стека находятся профили. Профиль — это спецификация, которая точно определяет, какие протоколы и функции должно поддерживать устройство для выполнения определенной задачи. Профили обеспечивают совместимость: если два устройства реализуют один и тот же профиль, гарантируется их совместная работа.
К числу важных профилей Bluetooth относятся:
| Профиль | Сокращение | Использование |
| Serial Port Profile (профиль последовательного порта) | SPP | Беспроводное последовательное соединение |
| Hands-Free Profile (профиль "Без рук") | HFP | Телефонные звонки через автомобильную аудиосистему или гарнитуру |
| Advanced Audio Distribution Profile (расширенный профиль распределения аудиосигнала) | A2DP | Высококачественная потоковая передача стереозвука |
| Audio/Video Remote Control Profile (профиль дистанционного управления аудио/видео) | AVRCP | Управление воспроизведением мультимедиа (воспроизведение, пауза, пропуск) |
| Human Interface Device Profile (профиль устройства пользовательского интерфейса) | HID | Клавиатуры, мыши, игровые контроллеры |
| File Transfer Profile (профиль передачи файлов) | FTP | Передача файлов между устройствами |
| Health Device Profile (профиль медицинского устройства) | HDP | Данные медицинских датчиков (измерение артериального давления, уровня глюкозы в крови) |
Как видим, состав профилей достаточно обширный.
Bluetooth Low Energy (BLE) вносит ряд улучшений и модификаций по сравнению с Bluetooth Classic, особенно на уровне хоста, благодаря определению собственной облегченной и энергоэффективной структуры протокола. BLE специально разработан для беспроводной связи с низким энергопотреблением, используемой в устройствах IoT, таких как датчики, интеллектуальные переключатели, носимые устройства и медицинские приборы.
Архитектура BLE разделена на несколько уровней, каждый из которых отвечает за определенные функции связи. Уровень хоста включает в себя важные протоколы, такие как:
- SMP (Security Manager Protocol) для обеспечения безопасности и сопряжения.
- GAP (Generic Access Profile) — профиль общего доступа для обнаружения устройств и управления подключениями.
- ATT/GATT (Attribute Protocol / Generic Attribute Profile) — протокол атрибутов для организации и обмена данными.
- Механизмы обнаружения сервисов для выявления доступных сервисов и их характеристик.
ESP32-S3 поддерживает только Bluetooth Low Energy (BLE). Общая реализация BLE аналогична той, что мы обсуждали ранее, но фреймворк ESP-IDF предоставляет два встроенных стека для хоста, упрощающих разработку (Bluedroid и NimBLE). Кроме того, ESP-IDF предлагает несколько готовых к использованию профилей и сервисов BLE, таких как BluFi, HID и ESP-BLE-MESH, которые можно использовать поверх этих стеков для ускорения разработки приложений.

ESP-Bluedroid — это стек Bluetooth по умолчанию, предоставляемый ESP-IDF. Он основан на стеке Android Bluedroid и поддерживает как классический Bluetooth, так и Bluetooth Low Energy (BLE) на совместимых устройствах ESP. Для ESP32-S3, который поддерживает только BLE, ESP-Bluedroid предоставляет полную реализацию BLE-хоста с поддержкой GAP, GATT, функций безопасности и различных профилей BLE. Он обладает богатым функционалом и хорошо интегрирован с экосистемой ESP-IDF, что делает его подходящим для сложных BLE-приложений.
ESP-NimBLE — это легковесный и ресурсоэффективный стек BLE-хостинга, доступный в ESP-IDF. Он основан на проекте Apache NimBLE и оптимизирован для низкого потребления памяти и повышения производительности по сравнению с Bluedroid. ESP-NimBLE поддерживает стандартные функции BLE, такие как GAP, GATT, реклама, сканирование и защищенные соединения, потребляя при этом меньше системных ресурсов. Благодаря своим компактным размерам и эффективности, он часто предпочтителен для встраиваемых приложений, где важны такие параметры, как память и энергопотребление.
Над стеками хоста находятся реализации профилей от Espressif, а также некоторые распространенные профили. В зависимости от вашей конфигурации, эти профили могут работать на ESP-Bluedroid или ESP-NimBLE.
ESP-BLE-MESH — это платформа для создания ячеистых сетей на основе Bluetooth Low Energy, предоставляемая ESP-IDF. Она позволяет нескольким устройствам BLE взаимодействовать друг с другом в топологии «многие ко многим», обеспечивая передачу сообщений по большой сети узлов. Это делает ESP-BLE-MESH подходящим для таких приложений, как «умный дом», промышленная автоматизация, сенсорные сети и интеллектуальные системы освещения. Платформа поддерживает инициализацию, безопасную связь, передачу сообщений и управление узлами на основе официального стандарта Bluetooth Mesh. Используя ESP-BLE-MESH, разработчики могут создавать масштабируемые и надежные сети IoT с расширенным диапазоном связи, выходящим за рамки стандартных соединений BLE «точка-точка».
BluFi — это запатентованный профиль Bluetooth Low Energy, разработанный компанией Espressif для упрощения настройки Wi-Fi для устройств ESP. Он позволяет смартфону или другому устройству с поддержкой BLE безопасно передавать учетные данные Wi-Fi, такие как SSID и пароль, на устройство ESP по BLE-соединению. После получения учетных данных устройство ESP может автоматически подключиться к целевой сети Wi-Fi. BluFi широко используется в продуктах IoT для обеспечения простого и удобного процесса настройки без необходимости использования временной точки доступа или ручной конфигурации. ESP-IDF включает встроенную поддержку профиля BluFi, что упрощает интеграцию для разработчиков.
Теперь, когда мы знаем основы, давайте создадим простой пример управления светодиодом с помощью Bluetooth.
Схема проекта
Сначала соберем схему. Для этого проекта нам понадобится только один светодиод и один резистор на 220 Ом. Мы подключим короткий вывод (катод) светодиода к GND, длинный вывод (анод) светодиода к одному из концов резистора на 220 Ом, а другой конец резистора — к выводу GPIO 1.

Структура проекта
|
1 2 3 4 5 6 |
ble_led_control/ ├── CMakeLists.txt ├── main/ │ ├── CMakeLists.txt │ └── main.c └── sdkconfig (генерируется автоматически) |
Файл main/main.c
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
#include <stdio.h> #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "driver/gpio.h" #include "esp_bt.h" #include "esp_bt_main.h" #include "esp_bt_device.h" #include "esp_gap_bt_api.h" #include "esp_spp_api.h" // Имя устройства Bluetooth #define DEVICE_NAME "ESP32_S3_LED_Control" // GPIO пин светодиода (согласно схеме - GPIO 1) #define LED_GPIO_PIN GPIO_NUM_1 // Теги для логирования static const char *TAG = "BLED_LED_Control"; // Флаги состояния static bool led_state = false; // Буфер для приема данных static char receive_buffer[64]; static int buffer_index = 0; // Прототипы функций static void spp_callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param); static void gap_callback(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param); static void process_command(char *cmd); /** * @brief Обработчик событий SPP (Serial Port Profile) */ static void spp_callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) { switch (event) { case ESP_SPP_INIT_EVT: ESP_LOGI(TAG, "SPP инициализирован"); // Регистрация сервиса SPP esp_spp_start_srv(ESP_SPP_SEC_NONE, ESP_SPP_ROLE_SLAVE, 0, "SPP_LED_Server"); break; case ESP_SPP_DISCOVERY_COMP_EVT: ESP_LOGI(TAG, "Поиск устройств завершен"); break; case ESP_SPP_OPEN_EVT: ESP_LOGI(TAG, "Bluetooth соединение установлено с %s", param->open.rem_bda); break; case ESP_SPP_CLOSE_EVT: ESP_LOGI(TAG, "Bluetooth соединение закрыто"); buffer_index = 0; memset(receive_buffer, 0, sizeof(receive_buffer)); break; case ESP_SPP_START_SRV_EVT: ESP_LOGI(TAG, "SPP сервер запущен. Ожидание подключения..."); break; case ESP_SPP_DATA_IND_EVT: ESP_LOGI(TAG, "Получено %d байт данных", param->data_ind.len); // Обработка полученных данных for (int i = 0; i < param->data_ind.len; i++) { char c = param->data_ind.data[i]; if (c == '\n' || c == '\r') { if (buffer_index > 0) { receive_buffer[buffer_index] = '\0'; process_command(receive_buffer); buffer_index = 0; memset(receive_buffer, 0, sizeof(receive_buffer)); } } else if (buffer_index < sizeof(receive_buffer) - 1) { receive_buffer[buffer_index++] = c; } } break; case ESP_SPP_WRITE_EVT: ESP_LOGD(TAG, "Данные отправлены"); break; default: ESP_LOGD(TAG, "SPP событие: %d", event); break; } } /** * @brief Обработчик GAP (Generic Access Profile) событий */ static void gap_callback(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) { switch (event) { case ESP_BT_GAP_AUTH_CMPL_EVT: if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { ESP_LOGI(TAG, "Аутентификация успешна: %s", param->auth_cmpl.device_name); } else { ESP_LOGE(TAG, "Ошибка аутентификации: %d", param->auth_cmpl.stat); } break; default: ESP_LOGD(TAG, "GAP событие: %d", event); break; } } /** * @brief Отправка сообщения через Bluetooth */ static void send_message(const char *message) { uint32_t spp_handle = 0; // В реальном приложении нужно хранить handle соединения // Упрощенная отправка - для полной функциональности нужно хранить handle из ESP_SPP_OPEN_EVT ESP_LOGI(TAG, "Отправка: %s", message); } /** * @brief Обработка текстовых команд */ static void process_command(char *cmd) { ESP_LOGI(TAG, "Обработка команды: '%s'", cmd); // Удаляем пробелы в начале и конце while (*cmd == ' ' || *cmd == '\t') cmd++; char *end = cmd + strlen(cmd) - 1; while (end > cmd && (*end == ' ' || *end == '\t' || *end == '\n' || *end == '\r')) end--; *(end + 1) = '\0'; // Преобразуем в нижний регистр для простоты for (int i = 0; cmd[i]; i++) { cmd[i] = tolower(cmd[i]); } // Обработка команд if (strcmp(cmd, "on") == 0 || strcmp(cmd, "1") == 0) { led_state = true; gpio_set_level(LED_GPIO_PIN, 1); ESP_LOGI(TAG, "СВЕТОДИОД ВКЛЮЧЕН"); send_message("OK: LED ON"); } else if (strcmp(cmd, "off") == 0 || strcmp(cmd, "0") == 0) { led_state = false; gpio_set_level(LED_GPIO_PIN, 0); ESP_LOGI(TAG, "СВЕТОДИОД ВЫКЛЮЧЕН"); send_message("OK: LED OFF"); } else if (strcmp(cmd, "status") == 0 || strcmp(cmd, "?") == 0) { char status_msg[32]; sprintf(status_msg, "LED is %s", led_state ? "ON" : "OFF"); send_message(status_msg); ESP_LOGI(TAG, "Статус: %s", status_msg); } else if (strcmp(cmd, "help") == 0) { send_message("Commands: ON, OFF, STATUS, HELP"); ESP_LOGI(TAG, "Показана справка"); } else if (strlen(cmd) > 0) { ESP_LOGW(TAG, "Неизвестная команда: '%s'", cmd); send_message("ERROR: Unknown command. Try: ON, OFF, STATUS, HELP"); } } /** * @brief Инициализация Bluetooth стека */ static void bluetooth_init(void) { ESP_LOGI(TAG, "Инициализация Bluetooth..."); // Инициализация контроллера Bluetooth esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_mem_release(ESP_BT_MODE_BTDM); esp_err_t ret = esp_bt_controller_init(&bt_cfg); if (ret != ESP_OK) { ESP_LOGE(TAG, "Ошибка инициализации контроллера Bluetooth: %s", esp_err_to_name(ret)); return; } ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); if (ret != ESP_OK) { ESP_LOGE(TAG, "Ошибка включения контроллера Bluetooth: %s", esp_err_to_name(ret)); return; } // Инициализация Bluedroid стека ret = esp_bluedroid_init(); if (ret != ESP_OK) { ESP_LOGE(TAG, "Ошибка инициализации Bluedroid: %s", esp_err_to_name(ret)); return; } ret = esp_bluedroid_enable(); if (ret != ESP_OK) { ESP_LOGE(TAG, "Ошибка включения Bluedroid: %s", esp_err_to_name(ret)); return; } // Установка имени устройства esp_bt_dev_set_device_name(DEVICE_NAME); // Регистрация callback функций esp_bt_gap_register_callback(gap_callback); esp_spp_register_callback(spp_callback); // Инициализация SPP esp_spp_init(ESP_SPP_MODE_CB); // Настройка discoverability и connectability esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); ESP_LOGI(TAG, "Bluetooth инициализирован. Имя устройства: %s", DEVICE_NAME); ESP_LOGI(TAG, "Подключитесь через Bluetooth Serial и отправляйте команды: ON, OFF, STATUS"); } /** * @brief Инициализация GPIO для светодиода */ static void led_init(void) { gpio_config_t io_conf = { .pin_bit_mask = (1ULL << LED_GPIO_PIN), .mode = GPIO_MODE_OUTPUT, .intr_type = GPIO_INTR_DISABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .pull_up_en = GPIO_PULLUP_DISABLE, }; ESP_ERROR_CHECK(gpio_config(&io_conf)); // Начальное состояние - выключен gpio_set_level(LED_GPIO_PIN, 0); ESP_LOGI(TAG, "GPIO %d инициализирован как выход для светодиода", LED_GPIO_PIN); } /** * @brief Главная задача приложения */ void app_main(void) { ESP_LOGI(TAG, "=== Bluetooth LED Control для ESP32-S3 ==="); // Инициализация светодиода led_init(); // Инициализация Bluetooth bluetooth_init(); // Мигание светодиодом при запуске (индикация готовности) for (int i = 0; i < 3; i++) { gpio_set_level(LED_GPIO_PIN, 1); vTaskDelay(pdMS_TO_TICKS(200)); gpio_set_level(LED_GPIO_PIN, 0); vTaskDelay(pdMS_TO_TICKS(200)); } ESP_LOGI(TAG, "Система готова. Ожидание Bluetooth подключения..."); ESP_LOGI(TAG, "Доступные команды:"); ESP_LOGI(TAG, " ON - Включить светодиод"); ESP_LOGI(TAG, " OFF - Выключить светодиод"); ESP_LOGI(TAG, " STATUS - Показать статус"); ESP_LOGI(TAG, " HELP - Показать справку"); // Основной цикл - здесь можно добавить дополнительную логику while (1) { vTaskDelay(pdMS_TO_TICKS(1000)); } } |
Файл main/CMakeLists.txt
|
1 2 |
idf_component_register(SRCS "main.c" INCLUDE_DIRS ".") |
Файл CMakeLists.txt (корневой)
|
1 2 3 |
cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(ble_led_control) |
Настройка через idf.py menuconfig
Перед сборкой выполните конфигурацию:
|
1 |
idf.py menuconfig |
Обязательно проверьте или настройте следующие параметры:
-
Bluetooth включен:
-
Component config → Bluetooth → Bluetooth controller mode → BR/EDR only -
Или выберите
Bluetooth enable
-
-
Выбор чипа:
-
Component config → ESP32-S3 Specific → Target ESP32-S3
-
-
Размер ОЗУ и кэша:
-
Убедитесь, что настройки соответствуют вашей версии ESP32-S3.
-
Сборка и прошивка
|
1 2 3 4 5 6 7 8 |
# Сборка проекта idf.py build # Прошивка на устройство idf.py -p /dev/ttyUSB0 flash # Замените на ваш порт # Мониторинг (для просмотра логов) idf.py -p /dev/ttyUSB0 monitor |
Подключение и использование
-
На телефоне:
-
Включите Bluetooth
-
Найдите устройство
ESP32_S3_LED_Control -
Подключитесь к нему
-
Используйте любое Bluetooth Serial приложение (например: "Serial Bluetooth Terminal" для Android)
-
-
Доступные команды:
-
ONили1- включить светодиод -
OFFили0- выключить светодиод -
STATUSили?- узнать текущий статус -
HELP- показать справку
-
-
При подключении:
-
ESP32-S3 будет виден как последовательный Bluetooth порт
-
Отправляйте команды через терминал
-
Важные замечания
1. ESP32-S3 требует явного указания target при первом использовании:
|
1 |
idf.py set-target esp32s3 |
2. Пин GPIO 1 может использоваться для Serial логирования на некоторых платах - убедитесь, что это не конфликтует
3. Для стабильной работы убедитесь, что антенна ESP32-S3 подключена (на некоторых dev-платах нужен внешний разъем)
Код включает полную обработку команд, логирование и индикацию запуска светодиодом. Устройство будет видимо для любых Bluetooth устройств и принимает текстовые команды для управления LED.
1 просмотров





