О том как подключают дисплейные модули к контроллеру ESP32, с лирическими отступлениями и неожиданным окончанием. Сравнительный анализ вариантов, более детально рассмотрен T-Display S3 на контроллере ESP32 S3. Много текста, без картинок. Актуально на конец 2022 года, сейчас, вероятно, уже что-то изменилось.

Исходная цель

Хотелось заиметь небольшую плату для прототипирования с напаянным дисплеем и контроллером с упором на программирование и контактами для подключения своих компонентов по разным интерфейсам.

Не Arduino-подобную — без штырьков 2.54, а с пайкой, поскольку для испытаний поделки планировалось носить. Но и не Flipper Zero: там тоже штырьковые контакты, плюс некислая цена.

На процессоре ESP32, так как Microchip (Atmel) AVR несколько слабоваты, а для STM32 нужных вариантов маловато. Есть, правда, варианты с контроллером от GigaDevice.

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

Хотя изучение различных вариантов тоже заняло немало времени.

Как вообще подключаются дисплеи

Для того чтобы двигаться дальше, хотелось бы сперва рассмотреть вопрос с точки зрения электрических соединений и интерфейсов подключения.

Как правило, на дисплейном модуле есть отдельный специализированный контроллер, который управляет свечением каждого пикселя, в соответствии с командами/данными, полученными от внешнего контроллера.

Соответственно, должен быть какой-то интерфейс взаимодействия с основным управляющим контроллером. Можно выделить следующие (которые «знает» ESP32):

  • i2c — всего два сигнальных провода и не очень большая скорость обмена. При этом полноценный интерфейс обмена командами и данными с адресацией (т.е. с несколькими ведомыми устройствами), чтением-записью и подтверждением получения переданных данных.

  • SPI — минимум два, обычно три-четыре провода и большая скорость обмена.

  • 8080 (i80) — параллельный 8-битный. 8 бит передаются одновременно по 8 проводам, плюс 2-3 служебных сигнала для синхронизации.

  • SPI Octal — также 8 бит данных одновременно, но другая логика работы.

  • 16 bit — одновременно 16 бит данных/команд, плюс куча служебных сигналов.

  • RGB — только данные о цвете разрядностью 16 (дисплеи позволяют 24) бита передаются попиксельно, столбцами и строчками, под управлением сигналов строчной и кадровой синхронизации. Команды подаются по дополнительному интерфейсу i2c. Аппаратную поддержку такого интерфейса имеет ESP32-S3, но не более древние модели ESP32.

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

Отдельно стоит отметить интерфейс для определения прикосновений (touch) пользователя к поверхности дисплея. Это могут быть как и аналоговые сигналы непосредственно с контактов на поверхности, так и встроенный контроллер, который имеет интерфейс i2c или SPI.

Сигналы с этого интерфейса обычно выведены на отдельный шлейф, но иногда бывают и в общем.

Для удобства макетирования дисплейные модули размещают на отдельной переходной плате с контактами с шагом 2,54мм, добавляют слот для карт памяти... Логичное продолжение — размещение управляющего контроллера на этой же плате.

Возможные варианты

Конструкций с дисплеем и контроллером на общей плате предлагается очень много.
Для рассматриваемой задачи придется отбросить изделия от STONE, Nextion, DWIN. Они, конечно, позволят вообще абстрагироваться от задач отображения информации и взаимодействия с пользователем. Интерфейс для них можно «нарисовать» в специализированном графическом редакторе вообще без знаний программирования, вся графика будет храниться «внутри» этого дисплея, и контроллер напаян мощный. Только вот какие-нибудь датчики, периферию обслуживать он, вероятно, не очень обучен. Впору ставить еще один контроллер, что несколько усложняет конструкцию.

Ну и цена STONE и Nextion не шибко радует. DWIN может стоить сопоставимо с предлагаемыми ниже вариантами.

Варианты эти — изделия, известные под названием WT32-SC01 и WT32-SC01 Plus от Wireless-Tag Technology, а также ассортимент от Shenzhen Jingcai Intelligent.

Первый производитель не имеет официального магазина на Aliexpress, и торгует им несколько продавцов. Изделия второго продаются в магазине, имеющем явную направленность на дисплейные модули.

В обоих случаях сервис для конечного пользователя довольно типичный: вот куцая документация, почти без схем/распиновок, вот какие то примеры — программируй.
И надо сказать — программируют. Для WT32-SC01 (Plus) есть примеры от пользователей, плюс некая визуальная среда разработки онлайн (требует пароль) http://8ms.xyz/login. Относительно подробная документация находится поиском, не на родном сайте.
WT32-SC01 использует более старую версию ESP32, дисплей подключен по SPI, много сигналов выведено на «гребенку» снизу.

На WT32-SC01 Plus уже используется ESP32-S3, дисплей на шине 8080, и немножко сигналов выведено на специфичные разъемы, которые, в общем-то, где-то надо взять.
Примерно то же самое обстоит с девайсами от второго производителя. Всякие ESP32-4827S043, ESP32-8048S050, ESP32-8048S070 имеют несколько модификаций с разным размером, типом дисплея и сенсорного датчика. Модели с диагональю 4.3, 5, 7 дюймов имеют подключение дисплея по интерфейсу RGB, а также несколько разъемов для подключения к интерфейсам, которыми оснащен набортный ESP32-S3. А также архивы с документацией и примерами, которые достаточно несложно скачиваются с сайта производителя. Одна проблемка: в архив положили только 1 лист со схемой, а их там 2 или 3!

Благо, распиновка разъемов подписана сразу на плате, остается только заиметь ответные части к этим самым разъемам.

Заметно лучше с документацией и примерами дело обстоит у производителя, известного как LilyGo (Shenzhen Xinyuan Electronic Technology).

К ним есть более проработанная документация, схемы, примеры. И выбор богатый. Есть с ePaper разных размеров, есть круглой формы, прямоугольные IPS/OLED дисплеи, все довольно небольших размеров.

Схемы нам, конечно же, нужны, чтобы понять, к каким именно выводам ESP32 подключена периферия. Тут сразу надо отметить что в ESP32 (а также в других современных контроллерах) сигнал с (почти) любого цифрового интерфейса можно цифровым образом с коммутировать на (почти) любой выбранный вывод микросхемы при помощи сложной системы маршрутизации сигналов GPIO matrix. Это позволяет упростить трассировку печатной платы.

Поэтому разработчики печатных плат упомянутых выше дисплейных модулей не особо напрягались и использовали удобные им выводы, а все проблемы должен был решать программист при помощи GPIO matrix. Более того, в документации на ESP32 высокоскоростные интерфейсы, даже UART (!), рекомендуется пускать в обход GPIO matrix через более простой коммутатор IO MUX, который позволяет использовать для каждого интерфейса только строго заданные выводы, но на максимальной скорости.

Особо занятно вышло с круглым дисплеем от LilyGo: там некоторые выводы вообще не заняты, однако на шине i2c висит микросхема-расширитель портов с восемью дискретными входами-выходами. Это еще бы и ничего, но эти дискретные выходы при помощи ПО на ESP32 имитируют упрощенный интерфейс i2c, к которому уже подключен дисплей. К счастью, это только командный интерфейс. Данные RGB о цвете передаются при помощи 18-ти разрядной шины данных, причем 2 бита из них вырезаются программным образом, т.е. соединение есть, но софтово не используется: два вывода ESP32 заняты впустую. И это чудо схемотехники как-то работает, но оставляет странное впечатление.

Плату T-Display-S3, похоже, разрабатывали другие люди: на ней данный аспект реализован максимально корректно, однако все это должно учитываться и в программном обеспечении; о нем и пойдет дальнейший разговор.

Но сперва необходимо отметить ценовой аспект. «Улучшенная» поддержка от LilyGo заметно отражается на цене, да и остальные упомянутые платы стоят совсем не копеечно.
Немаловажно, что существуют две версии T-Display-S3 c сенсорным экраном и без — это два разных товара, и цена их отличается очень заметно. Оба используют экран на шине i80 c контроллером ST7789. Марку сенсорного контроллера практически замалчивают, вероятно это CST328, на который документацию не так-то просто найти, возможно, он совместим с FT5x06.

Да и сам дисплейный модуль не указан, известна только марка разъема для плоского шлейфа, к которому он подключается.

В общем, экономически покупка рассматриваемой платы не очень оправдана, но будет экономия времени и некоторые удобства. Антиподом всех этих штуковин выступает небольшая безымянная плата на ESP-C3 и с очень небольшим дисплейчиком Air 10X. Стоит раз в пять дешевле аналога от LilyGo, картинка с распиновкой есть в комплекте.

Как же это всё программировать

Как уже можно понять, речь пойдет про программирование микросхем серии ESP32 фирмы Espressif Systems.

Для подкованных профессиональных программистов предлагается Espressif IoT Development Framework — сокращенно ESP-IDF. Это довольно сложный многокомпонентный комплекс на основе Python, Cmake, Ninja, GIT, а также некоторых других утилит из мира Linux. Поставить его можно из-под Windows, но официально — только Windows 10 и 11. 7ку все уже официально предали забвению, поэтому все связанное с Windows 7 будет прокомментировано отдельно.

В состав ESP-IDF входит огромное количество библиотек, тестов, драйверов, а также примеров, включая работу с дисплеями. Правда, есть примеры работы только с несколькими контроллерами дисплеев: ST7789, ILI934, SSD1306, NT35510 и тремя сенсорными контроллерами: GT911, TT21100, FT5x06. Т.е. для рассматриваемой платы понадобится сторонняя библиотека.

В декабре 2022 года появилась ESP-IDF v5.0, вполне допустимо использовать v.4.4.3, да и множество проектов рассчитано на v4.x. Для Windows можно скачать как online инсталлятор ESP-IDF, который сам скачает все нужное из сети, так и offline, который, если интернет обнаружит, то все-таки докачает пару сотен мегабайт и поставит все нужное в указанную папку. Есть также отдельная сборка с графической средой разработки на основе Eclipse.

Пользователи Linux/MAC традиционно должны поставить некоторое количество пакетов, скачать ESP-IDF из GIT, и запустить install.sh, который докачает некоторое количество компиляторов и утилит.

Такой путь допустим и для Windows, поскольку install.bat и install.ps1 есть и работают, но инсталлятором воспользоваться гораздо проще. Кстати, он без проблем заработал и под Windows 7, несмотря на предупреждающие надписи.

В результате этих манипуляций на диске появится папка размером более 3Гб, в которой содержится набор утилит, причем необходимо вызывать их из командной строки. Что совсем не порадует многих как начинающих, так и опытных программистов.

Например, обширные настройки в готовых проектах редактируются командой «idf.py menuconfig». Чтобы несколько осовременить процесс, можно использовать графическую оболочку, подробнее об этом рассказано далее.

Для начинающих та же самая Espressif предлагает воспользоваться Arduino. Возможно, не всем известно, но это не только маленькие платки, но и объемная программная среда, в рассматриваемом случае созданная на основе той же ESP-IDF.

Оную ESP-IDF упаковали в библиотечные файлы, добавили библиотеки, позволяющие делать сложные вещи «парой строк», а настройки «железа» упакованы в компактное меню, ну и файлы конфигурации тоже есть.

Что немаловажно — происходит сильное абстрагирование от портов контроллера, пользователь манипулирует номерами выводов, подписанными на плате. Что, в общем-то, отлично укладывается в концепцию GPIO matrix, и выводы по умолчанию тоже предусмотрены.

Принцип компиляции исходных текстов в arduino несколько упрощен. С одной стороны, arduino «самостоятельно» не скачивает необходимые библиотеки, только по команде. Однако не нужно указывать, где что лежит, все найдется «само» (а может, и не найдется).
Самое неудобное в arduino то, что все файлы, полученные после компиляции, временные и исчезают после закрытия ПО arduino.

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

Неказистая оболочка, написанная на java, может подвисать в некоторых случаях, нет возможности отладки — частично это решается новой Arduino IDE, но есть и другие варианты.

Для быстрых тестов Arduino 1.8 вполне достаточно, единственное, в случае Windows 7 надо отключить подробный вывод результатов компиляции в настройках. Также можно воспользоватся arduino-cli, которая «соберет» проект на Arduino, не запуская графическую оболочку. Но все многочисленные параметры придется указывать в командной строке.

И никаких GIT, Python, все работает и почти не просит интернета.

Сложные примеры для T-Display S3 в arduino не могут скомпилироваться (хотя все дело во вложенных папках) поэтому LilyGo рекомендует пользоваться Platformio, и это часто встречается в проектах на ESP32.

Platformio представляет собой набор скриптов на Python, которые самостоятельно скачивают все нужное для компиляции проекта. «Все нужное» может быть как ESP-IDF и Arduino, так и куча других сред разработки для самых разных контроллеров. Точнее, используются компиляторы, библиотеки, а вот система сборки проекта у platformio своя. Ну и опять же — рассчитано все на командную строку, но для конфигурации проекта можно запустить вебинтерфейс Platformio Home и настроить проект в браузере.

Ну а чтобы «рулить по-взрослому», не мудря в командной строке, существует полновесная бесплатная среда разработчика Visual Studio Code. В ней уже имеются расширения для работы с ESP-IDF, Platformio и Arduino.

Другими словами, по паре кликов мышкой среда сама загрузит все, что нужно, откомпилирует и позволит отладить. Причем загрузит она сотни мегабайт файлов из Интернета и распакует их в несколько гигабайт файлов в домашней папке пользователя.

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

Для Windows 7 поддержка закончилась на версии 1.70.3, но скачать можно только версию 1.70.2 и в ней обновиться на 1.70.3 Более того, можно скачать более свежие версии в .zip, распаковать и запустить их без инсталляции. Для более новых Windows есть готовая сборка Portable VSC/Platformio/Python for Windows.

Для любителей MicroPython делают поддержку в том числе и рассматриваемого девайса.

Как пройти в библиотеку

Теперь ближе к отрисовке всяких изображений и графического интерфейса. Как вообще нарисовать кнопку на экране и определить, что пользователь что-то нажал? Для этого есть множество специализированных библиотек, но не все так просто.

Как уже говорилось выше, существует много интерфейсов подключения, много контроллеров с разными форматами команд и данных, а их комбинаций не сосчитать. Условно можно сказать, что изначально (скажем, для первой Arduino на Atmega 8) были разработаны комплексные библиотеки, которые через конкретный интерфейс управляли конкретным дисплейным модулем с конкретными параметрами. Т.е. были готовые функции для рисования примитивных фигур, отрисовки текста, а взаимодействие с пользователем — дело отдельное.

Поскольку платформа сильно расширялась, библиотеки стали сложнее, с конфигурированием под разные контроллеры, дисплеи. Те библиотеки, которые существовали давно, могли сильно измениться со временем.

Можно выделить несколько задач, которые решаются графическими библиотеками:

  1. реализация интерфейса обмена с дисплейным модулем

  2. взаимодейcтвие с контроллером дисплея, подача команд

  3. отрисовка примитивов

  4. отрисовка конструкций из примитивов (меню)

  5. взаимодейcтвие с пользователем: опрос кнопок, сенсора, обработка.

В зависимости от библиотеки эти задачи могут решаться либо одной библиотекой одновременно, либо несколькими совместно.

Если исходить от истоков в лице ESP-IDF, то там можно найти код для реализации задач 1,2, частично 5, но не 3 или 4. В библиотеках ESP-IDF с расчетом именно на ESP32 реализованы интерфейсы с использованием, так сказать, аппаратного ускорения (DMA). Для Arduino эти функции были собраны в библиотеку liblcd.

И в том, и другом случае для отрисовки интерфейса с пользователем предлагается использовать LVGL. Эта библиотека отрисовывает различные меню в буфере (оперативной памяти), а за передачу их на конкретный контроллер дисплея отвечает отдельный «driver».

Для ESP32 (а также множества других систем) существует отдельная сборка ("port"), в ней поддерживается много дисплейных контроллеров, но только на интерфейсах i2c и SPI.

В случае с T-Display S3 базовый пример использования (factory и lv_demos) также использует дисплей при помощи liblcd и рисует там меню LVGL в собственный буфер экрана.

Есть также пример с использованием библиотеки Arduino_GFX. Эта библиотека тоже использует liblcd для организации интерфейса, но она «знает» больше контроллеров и «умеет» много функций для отрисовки примитивов.

С библиотекой TFT_eSPI несколько сложнее. С ESP32 работать данная библиотека умеет, причем без участия liblcd, и не очень быстро, без «аппаратного ускорения». Конкретно для T-Display S3 эта библиотека была обработана так называемым micky_commit.patch, в котором не только прописываются нужные номера GPIO, но и ускорена работа с ними. TFT_eSPI также умеет рисовать в буфер в памяти, причем он может быть разных размеров (и в пикселях, и в байтах) и вообще называется спрайтом. Возможности этой библиотеки очень богаты, несколько шрифтов в комплекте, есть даже алгоритм сглаживания линий. Наверное, поэтому для этой библиотеки сторонними разработчиками создано много красивых примеров.

Библиотека Lovyan GFX приспособлена неизвестным программистом (настройки опубликованы на AliExpress), внутри нее — также вызовы liblcd. Тоже имеет множество функций для рисования, умеет и примитивы, и шрифты, и спрайты.

Для обработки прикосновений к дисплею создатели T-Display S3 предлагают использовать https://github.com/mmMicky/TouchLib от того же Micky, нужно это в случае версии с сенсорным экраном.

Заводская прошивка T-Display S3 реализована на базе библиотек Arduino, графика реализована LVGL с драйвером в liblcd, той же TouchLib, плюс опрашиваются кнопки библиотекой OneButton. Стартовая анимация сделана показом анимированой gif-картинки.

При старте плата пытается просканировать WiFi сети и подключиться к точке доступа с жестко заданным SSID, ну, точнее, в своей прошивке. Вы его сможете поменять. Если только случайно не найдется сеть с именем "xinyuandianzi", то прошивка предложит запустить утилиту EspTouch, доступную для Android и IOS.

Про отладку

На ESP32 есть JTAG, и есть софт для отладки, который интегрируется в ту же VSCode, а также, например, Eclipse. Однако JTAG в случае ESP32 выведен на строго определенные выводы микросхемы, которые вместо этого могут быть использованы и под другие нужды. Надо ли говорить, что в случае T-Display S3 так и случилось. Нужные выводы заняты подключением к дисплею.

К счастью, ESP32 поддерживает отладку через USB. Но у этого решения есть как минимум два минуса: драйвера и то, что при нажатии кнопки RST на плате она программно отключается от USB (пропадает в «Диспетчере устройств») и отладочный софт приходит в большое недоумение.

Драйверы же нужно поставить, только вот под Windows 7 якобы нельзя. На самом деле, драйвера входят в состав ESP-IDF и их можно скачать и поставить вручную (через «Диспетчер устройств»). И отладка даже будет работать.

Но не будет работать отладочный вывод через виртуальный COM-порт. Для 7-ки были созданы отдельные драйвера, через которые работает JTAG, и отладочный вывод посмотреть можно (любой терминальной программой, умеющей работать с COM-портом). Заводская прошивка дублирует вывод и на этот порт, так что можно подключиться и посмотреть выводимый текст.

Работу отладочного интерфейса быстро можно проверить командой (в командной строке):

openocd -f board/esp32s3-builtin.cfg

Для этого нужно иметь в том или ином виде openocd с поддержкой ESP32, можно скачать отдельно, также она входит в состав ESP-IDF, platformio. Вывод будет примерно такой:

Open On-Chip Debugger v0.11.0-esp32-20221026 (2022-10-26-14:48)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Info : esp_usb_jtag: VID set to 0x303a and PID to 0x1001
Info : esp_usb_jtag: capabilities descriptor set to 0x2000
Warn : Transport "jtag" was already selected
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : esp_usb_jtag: serial
Info : esp_usb_jtag: Device found. Base speed 40000KHz, div range 1 to 255
Info : clock speed 40000 kHz
Info : JTAG tap: esp32s3.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : JTAG tap: esp32s3.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : starting gdb server for esp32s3.cpu0 on 3333
Info : Listening on port 3333 for gdb connections
Info : [esp32s3.cpu0] Target halted, PC=0x420A85FA, debug_reason=00000000
Info : [esp32s3.cpu0] Reset cause (1) - (Power on reset)
Info : [esp32s3.cpu1] Target halted, PC=0x420A85FA, debug_reason=00000000
Info : [esp32s3.cpu1] Reset cause (1) - (Power on reset)

Неожиданный финал

И тут мне стало скучно. При отладке в Vscode возникали какие-то вылеты openocd, я погуглил тексты ошибок, но нашел только разовые упоминания, без решений. Вероятно, стоит попробовать делать все под Linux или Win10. Без наличия практической необходимости я этим заниматься не планирую.

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


  1. rever50
    20.07.2023 06:29

    Arduino ide прекрасно сохраняет bin файлы. Никуда они не пропадают.


    1. NutsUnderline Автор
      20.07.2023 06:29

      bin не пропадают, но там еще куча промежуточных файлов типа .o которые для того и придуманы чтобы не перекомпилировать все файлы с исходниками каждый раз


  1. NutsUnderline Автор
    20.07.2023 06:29

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

    https://habr.com/ru/articles/748198/ практический пример использования упомянутого здесь ESP32-8048S070

    https://habr.com/ru/companies/epam_systems/articles/522730/ подробно про программирование ESP32