ИТ

LilyGo T-Connect Pro: продакшн-прошивка ESP32-S3 с LVGL-консолью на тачскрине

Платы, которые позиционируются как «мультипротокольные», обычно идут с набором разрозненных Arduino-скетчей — по одному на каждый периферийный модуль, ни один из которых не готов к продакшену. Вы получаете мигающие светодиоды и вывод в Serial, но ничего, что одновременно работает с LoRa, Ethernet, CAN и BLE на одной SPI-шине и при этом поддерживает отзывчивый сенсорный интерфейс. Путь от демо-прошивки вендора до рабочего firmware — это месяцы интеграции: управление конкуренцией на общей шине, асинхронные пробы, персистентное состояние и поворот дисплея без артефактов.

Эта прошивка LilyGo T-Connect Pro ESP32-S3 закрывает этот разрыв. Проект на PlatformIO превращает плату T-Connect Pro V1.0 в полноценную тач-консоль диагностики на LVGL с одиннадцатью живыми страницами — Wi-Fi, BLE, LoRa, Ethernet (W5500), CAN/TWAI, RS232, RS485, IMU, управление реле и системные настройки. Все шесть проводных и беспроводных протоколов работают параллельно на общей SPI-шине, FreeRTOS-задачи обрабатывают асинхронные пробы достижимости, а все пользовательские настройки сохраняются в NVS между перезагрузками. Репозиторий приватный — доступ по запросу.

Содержание
  1. Зачем нужна эта прошивка
  2. Архитектура железа
  3. Распиновка и разделение шины
  4. Распределение памяти
  5. Программный стек
  6. Организация кода
  7. Последовательность инициализации
  8. Одиннадцать страниц LVGL-консоли
  9. Системные страницы
  10. Страницы сенсоров и ввода
  11. Страницы протоколов
  12. Страницы управления и настроек
  13. Детали реализации протоколов
  14. LoRa: SX1262 через RadioLib
  15. Ethernet: W5500 вне lwIP
  16. CAN: TWAI в классическом режиме
  17. BLE: отложенный Bluedroid-сканер
  18. Асинхронные пробы достижимости
  19. Персистентное состояние и NVS
  20. Дисплей и тач
  21. Верхняя панель и навигация
  22. OTA-обновления и синхронизация времени
  23. Сборка, прошивка и настройка
  24. Вендорированные библиотеки и лицензирование
  25. Связанные проекты
  26. Часто задаваемые вопросы
  27. Репозиторий открытый?
  28. Прошивка поддерживает CAN-FD?
  29. Можно использовать другую частоту LoRa?
  30. Почему BLE инициализация отложена?
  31. Какие варианты платы поддерживаются?
  32. Как Ethernet сосуществует с Wi-Fi?

Зачем нужна эта прошивка

Изображение статьи — wp-image-11026
Изображение статьи — wp-image-11006

LilyGo T-Connect Pro собирает на одной плате ESP32-S3-R8 (16 МБ флеш, 8 МБ PSRAM), ёмкостный тач-дисплей 222×480, радиомодуль LoRa SX1262, Ethernet-контроллер W5500, трансивер CAN-FD, RS232 и RS485 трансиверы, акселерометр BMA423 и реле на 10 А. Официальный репозиторий LILYGO содержит фрагментарные примеры, инициализирующие каждый периферийный модуль отдельно. Ни один из них не обрабатывает общую SPI-шину корректно при одновременной работе нескольких устройств, и ни один не предоставляет интерфейс кроме Serial-вывода.

Прошивка LilyGo T-Connect Pro ESP32-S3 создавалась для одновременной валидации всей периферии, как приёмочный тест платы и как продакшен-готовая основа для OEM-проектов. Вместо двенадцати отдельных скетчей — одна прошивка, которая грузится в отполированную LVGL-консоль с одиннадцатью страницами менее чем за три секунды.

Архитектура железа

T-Connect Pro V1.0 работает на ESP32-S3-R8 с тактовой частотой 240 МГц и 8 МБ PSRAM. На плате шесть коммуникационных протоколов сосредоточены на одной SPI-шине, которую разделяют дисплей ST7796, модуль LoRa SX1262 и Ethernet-контроллер W5500 — каждый изолирован выделенной линией chip-select на GPIO 21, 14 и 10 соответственно.

Распиновка и разделение шины

Архитектура общей SPI-шины — ключевое проектное ограничение. Все три линии CS должны быть подтянуты к HIGH перед любой SPI-транзакцией, чтобы предотвратить перекрёстные помехи. Прошивка делает это в самом начале peripheralsBegin() — до инициализации дисплея, до LoRa, до Ethernet. Одна линия CS, «провисающая» в LOW во время транзакции другого устройства, тихо повреждает оба трансфера.

ПериферияИнтерфейсОсновные GPIO
Дисплей ST7796SPI (общая)CS=21, DC=45, RST=42, BL=46
LoRa SX1262SPI (общая)CS=14, RST=41, BUSY=40, DIO1=39
Ethernet W5500SPI (общая)CS=10, RST=9, INT=13
Тач CST226SEI2C (400 кГц)SDA=15, SCL=16, RST=48, INT=11
IMU BMA423I2C (общая)Addr 0x18 или 0x19
CAN (TWAI)Нативный TWAITX=6, RX=7
RS232UART1TX=4, RX=5
RS485UART2TX=17, RX=18
РелеGPIOGPIO=8 (active HIGH)

Распределение памяти

Внутренняя DRAM ESP32-S3 сильно загружена при одновременной работе Wi-Fi, BLE и lwIP. Прошивка направляет все выделения LVGL в PSRAM через кастомный аллокатор, высвобождая примерно 96 КБ внутренней DRAM для стеков FreeRTOS-задач. Два буфера отрисовки дисплея (по 222×60×2 байт, около 52 КБ суммарно) тоже в PSRAM. Виджеты создаются однократно при загрузке и почти не освобождаются, поэтому латентность PSRAM допустима — горячих путей выделения памяти в цикле рендеринга нет.

Программный стек

Прошивка LilyGo T-Connect Pro ESP32-S3 собирается в PlatformIO на фреймворке Arduino (платформа espressif32 6.5.0, ядро Arduino-ESP32 2.0.14). Используется LVGL 8.4.0 для UI, RadioLib 7.1.2 для LoRa и вендорированная библиотека Ethernet 2.0.0 для W5500 — намеренно отделённая от lwIP, чтобы избежать конфликтов маршрутизации с нативным Wi-Fi стеком ESP32.

Организация кода

Вся кодовая база — примерно 2700 строк в четырёх исходных файлах и пяти заголовках. Разделение принципиальное: драйверы железа никогда не вызывают функции UI, а UI никогда не блокируется на I/O.

ФайлСтрокОтветственность
main.cpp36Оркестрация: peripheralsBegin → probesBegin → uiBegin, затем цикл тиков
peripherals.cpp511Все драйверы железа, стеки протоколов, NVS-персистенция
ui.cpp1481Инит LVGL, 11 билдеров страниц, навигация, верхняя панель
probes.cpp173FreeRTOS-воркер проб — ICMP и TCP проверки достижимости

Последовательность инициализации

Загрузочная последовательность строго линейная — без параллельной инициализации. Это намеренно: периферия на общей шине требует детерминированных состояний CS, а стек Bluedroid в BLE требует завершения первичной ассоциации Wi-Fi-радио прежде чем Bluetooth-коэксистенция стабилизируется. Полная последовательность выполняется за ~2.5 секунды при холодной загрузке.

  • Подтяжка всех SPI CS линий к HIGH (дисплей, LoRa, Ethernet)
  • Загрузка NVS namespace «tcpro» — состояние реле, ротация, яркость, счётчик загрузок, лучший аптайм
  • Инициализация GPIO реле из сохранённого состояния
  • Дисплей ST7796 с поворотом и ШИМ-подсветкой
  • RS232 и RS485 UART на 115200 бод
  • I2C-шина 400 кГц — инит тача CST226SE, полный скан шины (0x08–0x77), проба BMA423
  • SPI-шина — SX1262 LoRa (868 МГц, SF9, +10 дБм), W5500 сброс + DHCP
  • TWAI-драйвер (500 кбит/с, normal mode)
  • Wi-Fi STA подключение, сканирование точек доступа
  • Отложенная задача BLE: ожидание WL_CONNECTED или 8-секундный таймаут, потом 1.5 с, потом Bluedroid
  • FreeRTOS-задача асинхронных проб
  • LVGL с PSRAM-аллокатором, 11 страниц, привязка дисплея и тача

Одиннадцать страниц LVGL-консоли

Консоль — основной интерфейс. Каждая страница обновляется каждые 250 мс из фонового состояния — никаких блокирующих I/O в UI-цикле. Навигация работает горизонтальным свайпом, стрелками в верхней панели или физической кнопкой BOOT (GPIO 0). Индекс текущей страницы сохраняется в NVS — прошивка возвращается точно туда, где остановились, после выключения питания.

Системные страницы

CHIP — модель CPU, размеры флеш и PSRAM, свободная куча, версия SDK, MAC-адрес, температура процессора, причина сброса, счётчик загрузок (NVS за всё время), лучший аптайм (гранулярность записи 5 минут), количество точек доступа из загрузочного сканирования, индикатор яркости подсветки.

WIFI — SSID, состояние подключения, уровень RSSI, канал, IP-адрес, шлюз, DNS, BSSID, статус OTA. Три ICMP-пробы каждые 3 секунды пока страница видима: шлюз, DNS-сервер и 1.1.1.1. Пробы останавливаются при переходе на другую страницу.

BLE 5 — режим стека Bluedroid, счётчик рекламных пакетов, количество уникальных устройств (до 32), последнее обнаруженное устройство и список по убыванию RSSI. Сканер BLE стартует с намеренной задержкой после Wi-Fi для предотвращения сбоев радио-коэксистенции.

Страницы сенсоров и ввода

TOUCH — ID контроллера CST226SE, количество пальцев, координаты X/Y, полоса давления. Полезно для проверки калибровки тача и мультитач-детекции ёмкостной панели.

IMU — акселерометр BMA423: живые значения X, Y, Z, магнитуда вектора, температура чипа. Также показывает полную инвентаризацию I2C-шины (все отвечающие адреса), независимо от физического наличия BMA423. Обновление каждые 100 мс при обнаруженном сенсоре.

Страницы протоколов

LoRa — конфигурация SX1262 (868 МГц, SF9, 125 кГц, +10 дБм), счётчик TX-маяков, счётчик RX-пакетов, состояние CAD и последний принятый пакет с RSSI и SNR. Радио передаёт маяк каждые 5 секунд и запускает CAD-сканирование каждые 2 секунды.

ETH — результат пробы W5500, состояние линка, IP от DHCP, шлюз, DNS, MAC (локально администрируемый, производный от Wi-Fi MAC). TCP-пробы к шлюзу и DNS каждые 3 секунды пока страница видима. Пробы используют W5500-стек напрямую — не lwIP — потому что Ethernet-контроллер работает вне нативного TCP/IP стека ESP32.

CAN — трансивер TD501MCANFD, состояние TWAI-драйвера, состояние шины (error-active, error-passive, bus-off), счётчики TX/RX/TX-fail, последний принятый фрейм с ID и данными в HEX. Heartbeat-фрейм (ID 0x123, 8 байт с счётчиком и таймстемпом) отправляется каждую секунду.

UART — RS232 (TD501D232H) и RS485 (TD501D485H-A) рядом: чип трансивера, распиновка, бодрейт, счётчики TX/RX, последний принятый байт. Оба порта передают heartbeat-символ (*) каждую секунду и непрерывно читают входящие буферы.

Страницы управления и настроек

RELAY — управляет реле на 10 А (GPIO 8). Персистентный переключатель сохраняет состояние в NVS мгновенно — реле возвращается в последнее состояние после любого выключения. Также ведёт счётчик переключений.

SETTINGS — поворот дисплея (0°/90°/180°/270° с живой перестройкой макета), интервал автопереключения страниц (OFF, 10, 15, 20, 30, 60 секунд), инверсия цветов, ступенчатая регулировка яркости (20–255, шаг 15, живой превью). Все изменения пишутся в NVS сразу.

Детали реализации протоколов

LoRa: SX1262 через RadioLib

SX1262 настроен на 868 МГц, spreading factor 9, полоса 125 кГц, coding rate 4/7, приватное sync word (0x14). Мощность TX +10 дБм. Прошивка реализует простой протокол маяков: каждые 5 секунд передаётся строка «TCpro #<counter>», а между передачами выполняется Channel Activity Detection каждые 2 секунды для обнаружения входящих пакетов.

Критический момент — разделение SPI-шины. Перед каждой транзакцией RadioLib линии CS дисплея и Ethernet должны быть подтянуты к HIGH. RadioLib управляет своим CS самостоятельно, но если дисплейный драйвер оставил CS в LOW после незавершённого DMA-трансфера, LoRa-транзакция будет повреждена. Прошивка гарантирует подтяжку CS при инициализации и полагается на Arduino_GFX для корректного отключения после каждой дисплейной операции.

Ethernet: W5500 вне lwIP

W5500 работает на вендорированной библиотеке Ethernet 2.0.0, намеренно отделённой от lwIP-стека ESP32. Это проектное решение: если бы W5500 был интегрирован в lwIP, конфликты таблицы маршрутизации между Wi-Fi и Ethernet интерфейсами привели бы к непредсказуемому пути пакетов. Отдельный стек гарантирует, что Wi-Fi трафик идёт через нативный netif ESP32, а Ethernet — через собственный сокетный слой W5500.

W5500 требует аппаратный сброс перед инициализацией — особенность интеграции на плате. Прошивка подаёт импульс сброса на GPIO 9 длительностью 50 мс, затем генерирует локально администрируемый MAC из Wi-Fi MAC ESP32 и запускает DHCP. TCP-пробы на странице ETH используют EthernetClient.connect() W5500, а не esp_ping, поскольку ICMP недоступен на не-lwIP стеке.

CAN: TWAI в классическом режиме

На плате стоит трансивер TD501MCANFD с поддержкой CAN-FD, но прошивка использует нативный TWAI-контроллер ESP32-S3 в режиме классического CAN на 500 кбит/с. CAN-FD требует отдельную, более высокую скорость фазы данных — возможность, которую TWAI-периферия ESP32-S3 аппаратно не поддерживает. Прошивка устанавливает TWAI-драйвер в normal mode, отправляет heartbeat-фрейм с ID 0x123 каждую секунду и непрерывно читает очередь RX.

BLE: отложенный Bluedroid-сканер

Инициализация BLE — самый тонкий момент. На ESP32-S3 Wi-Fi и Bluetooth разделяют один 2.4 ГГц PHY. Запуск Bluedroid до завершения первичной ассоциации Wi-Fi вызывает сбои радио-арбитража, которые проявляются как отключения Wi-Fi или крэши Bluetooth. Прошивка решает это запуском FreeRTOS-задачи, которая ждёт WL_CONNECTED (или 8-секундный таймаут при невалидных Wi-Fi-креденшелах), затем выдерживает 1.5-секундную паузу перед инициализацией Bluedroid в режиме «только сканер».

Сканер работает в активном режиме (интервал 160 мс, окно 150 мс) и отслеживает до 32 уникальных устройств по MAC-адресу, сохраняя имя и RSSI для каждого. Никаких подключений или сопряжений — только пассивный мониторинг окружения.

Асинхронные пробы достижимости

Пробы сетевой достижимости по своей природе блокирующие — ICMP-пинг ждёт ответа или таймаута, TCP-connect либо успешен, либо висит несколько секунд. Запуск их в основном цикле заморозил бы LVGL UI. Прошивка обрабатывает это выделенной FreeRTOS-задачей probeWorker со стеком 4 КБ, которая потребляет запросы проб из очереди FreeRTOS.

Основной цикл проверяет, какая страница сейчас видима. Если это WIFI и Wi-Fi подключён, ставятся в очередь ICMP-пробы к шлюзу, DNS-серверу и 1.1.1.1. Если это ETH и Ethernet линк активен — TCP-connect пробы к шлюзу и DNS по Ethernet. Когда пользователь свайпает на другую страницу, новые пробы не ставятся — воркер дочитывает очередь и засыпает.

Wi-Fi ICMP-пробы привязаны к WIFI_STA_DEF netif, чтобы ядро не маршрутизировало их через W5500. Без этой привязки таблица маршрутизации ESP32 могла бы отправить ICMP-пакеты через Ethernet, если оба интерфейса подключены, — давая ложноположительные результаты на Wi-Fi странице.

Персистентное состояние и NVS

Прошивка использует единый NVS namespace (tcpro) для сохранения пользовательских настроек и операционных счётчиков между перезагрузками:

  • Состояние реле ON/OFF и суммарный счётчик переключений
  • Уровень подсветки дисплея (20–255)
  • Поворот дисплея (0°, 90°, 180°, 270°)
  • Интервал автопереключения страниц (OFF или 10–60 секунд)
  • Флаг инверсии цветов
  • Индекс последней видимой страницы
  • Счётчик загрузок за всё время
  • Лучший аптайм (записывается с гранулярностью 5 минут для снижения износа флеш)

Записи в NVS дросселированы где возможно. Лучший аптайм записывается во флеш только каждые 5 минут, а не каждый тик. Состояние реле и изменения настроек записываются немедленно — намерение пользователя не должно теряться, если питание отключится секундой позже.

Дисплей и тач

Дисплей ST7796 работает с разрешением 222×480, ШИМ-подсветка на LEDC-канале 1 на 2 кГц. Поддерживаются все четыре режима поворота. При смене поворота в настройках дисплейный драйвер переключает вывод, матрица трансформации координат тача обновляется, и макет страницы перестраивается — полуширинные строки переключаются между 48% и 100% в зависимости от ландшафтной или портретной ориентации.

Ёмкостный тач CST226SE работает на I2C-шине 400 кГц. Драйвер тача LVGL читает координаты только при наличии пальца на экране (детекция по прерыванию). Контроллер поддерживает мультитач и детекцию давления — обе возможности отображаются на странице TOUCH.

Верхняя панель и навигация

Верхняя панель занимает две строки. Первая: кнопки «назад/вперёд», индекс и название текущей страницы, шоткат в настройки. Вторая: живые бейджи статуса — Wi-Fi (цветокод по состоянию подключения), состояние Ethernet-линка, количество уникальных BLE-устройств, счётчик LoRa TX, часы (синхронизация SNTP через pool.ntp.org и time.google.com после подключения Wi-Fi — до синхронизации показывает --:--:--).

Навигация отвечает на горизонтальные свайпы по всему экрану, кнопки со стрелками в верхней панели и физическую кнопку BOOT (GPIO 0 — переход на следующую страницу). Опциональный таймер автопереключения ротирует страницы с настраиваемым интервалом — удобно, когда плата смонтирована как пассивный мониторинговый дисплей.

OTA-обновления и синхронизация времени

ArduinoOTA стартует после подключения Wi-Fi с hostname t-connect-pro.local. Статус OTA отображается на странице WIFI. SNTP-синхронизация запрашивает pool.ntp.org и time.google.com, часовой пояс настраивается через state.tz_offset_sec в app_state.h (по умолчанию UTC+3). После синхронизации часы отображаются в верхней панели.

Сборка, прошивка и настройка

Проект использует PlatformIO с кастомным описанием платы (boards/esp32s3_flash_16MB.json) для ESP32-S3 на 240 МГц с 16 МБ QIO флеш и 8 МБ OPI PSRAM. Скорость загрузки 921600 бод.

git clone https://github.com/ilia-ae/lilygo-t-connect-pro.git
cd lilygo-t-connect-pro
cp include/secrets.h.example include/secrets.h
# Отредактируйте secrets.h — укажите данные Wi-Fi
pio run -t upload
pio device monitor

Wi-Fi-креденшелы хранятся в include/secrets.h (gitignored). Если файл отсутствует, прошивка компилируется с плейсхолдерами и выдаёт предупреждение компилятора — она загрузится и покажет все страницы, но Wi-Fi и синхронизация времени работать не будут. Для восстановления после неудачной прошивки удерживайте BOOT при нажатии на Reset, затем перепрошейте. Репозиторий приватный — доступ по запросу через форму обратной связи для тех, кого интересует прошивка LilyGo T-Connect Pro ESP32-S3.

Вендорированные библиотеки и лицензирование

Две библиотеки вендорированы в каталоге lib/. Ethernet 2.0.0 (LGPL-2.1+) — для изоляции от lwIP W5500 стека, который включают некоторые board-пакеты ESP32. Arduino_DriveBus (GPL-3.0, приватная библиотека LILYGO) — инициализация тача CST226SE и операции с I2C-шиной, недоступная в публичном реестре PlatformIO. RadioLib, LVGL, Arduino_GFX и SensorLib подтягиваются как стандартные зависимости. Полные детали лицензирования в THIRD_PARTY_NOTICES.md.

Связанные проекты

Если вы работаете с ESP32 и BLE-маяками, проект BLE.KZ — экосистема трекинга присутствия описывает комплементарный подход на ESPHome с двумя протоколами маяков и Flutter-приложением. Для интеграции e-ink дисплея с ESPHome, проект M5Paper — дашборд умного дома демонстрирует другую дисплейную технологию на платформе ESP32. А если интересует безопасное управление инфраструктурой с Go-агентами, проект GoLauncher покрывает серверную телеметрию и контроль доступа с другого ракурса.

Часто задаваемые вопросы

Репозиторий открытый?

Репозиторий приватный. Доступ по запросу — напишите через форму обратной связи с кратким описанием вашего кейса.

Прошивка поддерживает CAN-FD?

Трансивер TD501MCANFD на плате поддерживает CAN-FD, но TWAI-контроллер ESP32-S3 аппаратно поддерживает только классический CAN. Прошивка работает на 500 кбит/с в режиме классического CAN. Для CAN-FD с переключением скорости фазы данных нужен внешний CAN-FD контроллер.

Можно использовать другую частоту LoRa?

Прошивка настроена на 868 МГц. Переход на 433 или 915 МГц требует изменения константы частоты в peripherals.cpp и, возможно, согласующей антенной цепи на плате. SX1262 поддерживает широкий диапазон, но модуль HPD16A настроен под конкретный региональный бенд.

Почему BLE инициализация отложена?

ESP32-S3 разделяет одно 2.4 ГГц радио между Wi-Fi и BLE. Запуск Bluedroid до завершения первичной ассоциации Wi-Fi вызывает сбои радио-арбитража. Прошивка ждёт подключения Wi-Fi (или 8-секундный таймаут), затем выдерживает 1.5-секундную паузу перед инициализацией Bluedroid.

Какие варианты платы поддерживаются?

Только SKU V1.0 с дисплеем, тачем и LoRa. Варианты без экрана или без LoRa-модуля имеют другую распиновку и требуют отдельный pin map header. Прошивка не пытается детектировать отсутствующую периферию в рантайме, за исключением опционального IMU BMA423.

Как Ethernet сосуществует с Wi-Fi?

W5500 работает на собственном TCP/IP стеке (вендорированная Ethernet 2.0.0), а не через lwIP ESP32. Это предотвращает конфликты таблицы маршрутизации. Wi-Fi ICMP-пробы явно привязаны к WIFI_STA_DEF netif, чтобы не маршрутизироваться случайно через Ethernet.

Оцените статью