TFT-дисплей ILI9341 и ST7789: подключение к Arduino по SPI
TFT-дисплей подключается к Arduino по шине SPI и требует не двух проводов, как OLED, а шести-восьми: CS, DC, RESET, MOSI, MISO, SCK, плюс питание, земля и подсветка. ILI9341 даёт экран 240×320, ST7789 встречается в 135×240 и 240×320.
Разница для новичка не в картинке, а в памяти платы: полноэкранный буфер 240×320 занимает 153 600 байт, а у Uno оперативной памяти всего 2 КБ.
Первый TFT я брал с расчётом, что это OLED, только цветной. Получил чёрный экран: на плате модуля было написано 3,3 V, а я подключил 5 В от Uno.
ILI9341 и ST7789: в чём разница
Оба контроллера говорят по SPI и рисуют примитивами, но отличаются размером матрицы, наличием флеша на модуле и ценой.
| Параметр | ILI9341 | ST7789 |
|---|---|---|
| Разрешение | 240×320 | 135×240 или 240×320 |
| Диагональ | 2,8-3,2 дюйма | 1,3-2,0 дюйма |
| Флеш на модуле | 4 МБ, у части есть слот для карты | обычно нет |
| Буфер в плате | нужен 153 600 байт | 96 000 байт при 135×240 |
| Цена | 550-1100 ₽ | 350-700 ₽ |
Флеш на модуле ILI9341 это отдельная микросхема, куда кладутся картинки. Многие модули держат её в режиме PROGMEM, и тогда библиотека рисует прямо из флеша: на картинки не тратится ни байта оперативной памяти. У дешёвых ST7789 флеша нет.
Распиновка: что куда втыкать
Подписи на модуле зависят от производителя, но набор выводов у всех один и тот же.
- VCC и GND это питание: голый ILI9341 рассчитан на 3,3 В, модуль с преобразователем берёт 5 В.
- CS это выбор адресата на шине, DC переключает команду и данные, RESET сбрасывает контроллер.
- MOSI несёт данные к дисплею, SCK это такт шины, MISO нужен для чтения из флеша.
- BL это подсветка, часто с отдельным выводом.
На Uno аппаратные SPI-пины фиксированы: MOSI это D11, MISO D12, SCK D13. Остальные выводы можно пересаживать на свободные пины, но CS, DC и RESET лучше не назначать на D0 и D1: там сидит Serial. Карта выводов Uno в лендинге про распиновку.
Две библиотеки: Adafruit_ST7789 и TFT_eSPI
Универсальной библиотеки для TFT нет, есть две. Для новичка разница сводится к одному вопросу: готовы ли вы перед первой прошивкой отредактировать файл конфигурации.
- Adafruit_ST7789 и Adafruit_ILI9341 ставятся через менеджер, настраиваются в begin() и выдают внятные ошибки.
- TFT_eSPI ставится zip-файлом в папку libraries, пины и модель описываются в User_Setup.h до компиляции.
- TFT_eSPI быстрее: у него свой контроллер буфера, а на ESP32 ещё и DMA.
- Цена настройки TFT_eSPI: ошибка в конфиге даёт невнятный чёрный экран.
Первый экран и учебные задачи это Adafruit: установка в два клика, скорости для меню и графика хватает. TFT_eSPI я беру, когда проект перерос: анимация, картинки из флеша или плата ESP32.
#include <Adafruit_ST7789.h>#include <Adafruit_GFX.h> int cs = 10, dc = 9, rst = 8;Adafruit_ST7789 tft = Adafruit_ST7789(cs, dc, rst); void setup() { tft.init(240, 320); // dlya ST7789 135x240 pishite init(135, 240) tft.setRotation(0); tft.fillScreen(ST77XX_BLACK); tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK); tft.setTextSize(2); tft.setCursor(10, 20); tft.print("TFT zhiv"); tft.setTextColor(ST77XX_YELLOW); tft.setCursor(10, 60); tft.print("SPI 40 MHz");} void loop() {}Память: почему Uno не тянет TFT
Это главные грабли, и виноват не дисплей, а арифметика. Один пиксель в RGB565 занимает 2 байта. Экран 240×320 это 76 800 пикселей, то есть 153 600 байт на кадр. У Uno оперативной памяти 2 048 байт.
| Плата | Оперативная память | Кадр 240×320 |
|---|---|---|
| Arduino Uno и Nano | 2 048 байт | не помещается |
| Arduino Mega 2560 | 8 192 байта | не помещается |
| Arduino Due | 96 КБ | помещается |
| ESP32 | 520 КБ SRAM | помещается |
| ESP8266 | 80 КБ | помещается |
На Uno TFT не рисуют целиком: рисуют строку, кнопку, иконку и обновляют только изменившуюся часть экрана. Это влезает в две килобайта. Работают текст, линии, рамки, заливки и графики: ломаная на 240 точек это 480 байт. А картинка из массива не влезает никогда.
Шрифты и картинки в PROGMEM
Во флеш Arduino можно положить шрифт или картинку и не тратить на них оперативную память. Строка с макросом PROGMEM или F() живёт во флеше, а не в SRAM. На TFT это важно: крупные шрифты в оперативной памяти дороги.
- Конвертер шрифтов Adafruit GFX Font Converter собирает глифы в массив байтов для блока PROGMEM.
- Свой bitmap: картинка превращается в массив по 1 или 16 бит на пиксель.
- Флеш на модуле ILI9341: файл заливается в память модуля, а библиотека читает его оттуда.
TFT против OLED SSD1306 и LCD 1602
Выбирать экран надо не по красоте, а по задаче. Разница между ними не в цвете, а в том, сколько данных вы на него выведете и сколько проводов у вас останется.
| Критерий | TFT ILI9341 | OLED SSD1306 | LCD 1602 |
|---|---|---|---|
| Разрешение | 240×320 | 128×64 | 16 знакомест |
| Цвет | 65 тысяч цветов | монохром | монохром |
| Интерфейс | SPI, 6-8 проводов | I2C, 4 провода | параллельный или I2C |
| Память Arduino | нужен большой запас | 1 КБ буфер | почти не нужна |
| Цена | 550-1100 ₽ | 250-500 ₽ | 150-400 ₽ |
Если задача укладывается в «показать две цифры и стрелку», OLED SSD1306 будет дешевле и съест меньше проводов: у него шина I2C, всего два сигнальных провода. TFT оправдан там, где нужна карта, меню с иконками или график за сутки. Сравнение в уроке про OLED против LCD.
Что сначала не получилось
Первый TFT я брал с мыслью, что это OLED, только цветной. Не вышло. Экран был чёрный, а монитор порта показывал, что скетч работает: библиотека отвечала, begin() отрабатывал без ошибок. Я перебрал распиновку, питание и версию библиотеки. Помогло то, что было написано на плате рядом с выводом VCC.
Второй тупик был на Mega, куда я перенёс проект после первого провала. Экран заработал, но скетч не собрался: компилятор написал, что не хватает памяти для массива картинки 240×320. Это был тот самый буфер, про который я знал по статьям, но не подумал, что приду за ним с картинкой в скетче. Уменьшил её до 240×160 и вынес в PROGMEM.
Третий раз я уже не мучился: перед покупкой прочитал даташит и проверил объём флеша и преобразователь уровней. У моего ILI9341 на 2,8 дюйма флеша не было, а подсветка шла через транзистор на вывод BL.
Личный опыт: термостат с цветным экраном
Первое устройство с TFT у меня было настенным термостатом: ESP32, датчик температуры, реле и экран 2,8 дюйма вместо LCD 1602. Задача была не в красоте, а в том, чтобы родственница из другого города могла позвонить и понять температуру в квартире.
Что я понял по ходу. Память ESP32 расходуется не только кадром: стек WiFi, буферы TLS и сам кадр вместе дали мне около 200 КБ из 520 доступных. На Uno такой проект не собрался бы. А перерисовка экрана на дефолтной частоте SPI занимала около 40 мс, и при обновлении графика это было видно как подёргивание.
Авторская позиция: что взять новичку
Первый TFT новичку я бы посоветовал не покупать. Если задача укладывается в текст и пару цифр, OLED SSD1306 у дешёвого TFT выигрывает по всем осям: два провода, килобайт памяти, в три раза дешевле.
TFT стоит брать, когда проект упирается в монохромный экран: интерфейс с иконками, карта, графики. И берите ESP32, если проект серьёзный: разница в цене с Uno меньше, чем разница в нервах, когда скетч не собирается.
Не берите самый дешёвый модуль, не прочитав маркировку. Разница между двумя одинаковыми по виду платами ILI9341 в наличии преобразователя уровней, флеша и токе подсветки. Десять минут чтения надписи экономят вечер.