За 20 секунд: ST7735 — популярный контроллер цветных TFT-дисплеев размером от 0,96 до 1,8 дюйма. Модуль общается по SPI, а не по I2C, даже если контакты подписаны
SDAиSCL. Для запуска нужны пять сигналов:SCK,SDA/MOSI,CS,DCиRST, плюс питание и подсветкаBL. Подключается к Arduino Uno/Nano и ESP32 через аппаратный SPI, работает с библиотеками Adafruit GFX и «Adafruit ST7735 and ST7789». Главные подводные камни: логика 3,3 В у дешёвых модулей, неправильная таблица инициализации (смещение картинки и обрезанные края) и белый экран при ошибке в подключении.
ST7735 — один из самых дешёвых способов добавить в проект цветной экран. На нём строят домашние метеостанции, мини-терминалы, индикаторы станций с ЧПУ, часы, плееры и портативные измерительные приборы. Модуль стоит дешевле стакана кофе, занимает мало места и рисует текст, графику и растровые картинки.
Но у новичков он регулярно вызывает вопросы. Экран остаётся белым. Картинка сдвинута, и по краям видны полосы. Красный и синий поменялись местами. Надписи SDA и SCL сбивают с толку — их хочется подключать к I2C. А на модуле 80×160 с таб-вариантом Mini вообще ничего не отображается, пока не выбран правильный вариант инициализации.
Разберём всё по порядку.
Что такое ST7735
ST7735 — контроллер ЖК-дисплеев от компании Sitronix. Он управляет матрицей, содержит память кадра (GRAM), встроенный контроллер питания и последовательный интерфейс. Сам по себе чип — не экран, а «мозг» модуля. Дисплейная панель с матрицей и breakout-плата с колодкой контактов образуют готовый модуль, который вы держите в руках.
Контроллер рассчитан на матрицы до 132×162 пикселя. Реальные модули используют распространённые панели:
| Модуль | Разрешение | Диагональ | Типичный вариант инициализации |
|---|---|---|---|
| 1,8" | 128×160 | 1,8 дюйма | INITR_BLACKTAB или INITR_GREENTAB/INITR_REDTAB |
| 1,44" | 128×128 | 1,44 дюйма | INITR_144GREENTAB |
| 0,96"–1,0" | 80×160 | 0,96–1,0 дюйма | INITR_MINI160x80 |
Разрешение 128×160 означает 128 пикселей по ширине и 160 по высоте в портретной ориентации. Экран показывает 18-битный цвет, который в коде передаётся как 16-битное значение RGB565. Цвета в библиотеках Adafruit задаются константами ST77XX_BLACK, ST77XX_RED, ST77XX_GREEN, ST77XX_BLUE, ST77XX_YELLOW, ST77XX_WHITE и так далее.
Почему SDA и SCL — это не I2C
На многих платах контакты подписаны SDA и SCL или даже SDA/MOSI и SCL/SCK. Это часто путает.
Внутри ST7735 используется только SPI. Исторические подписи взялись от модулей, где один и тот же контакт разводился под оба стандарта. На практике:
SDAна плате ST7735 — это линия данных SPI, то естьMOSI(Master Out, Slave In). Данные контроллер только принимает, отдельной линии чтенияMISOу модуля нет.SCLилиSCK— это тактирующий сигнал SPI.
Пытаться подключать такой экран к I2C-шине I2C-сканером бесполезно: адреса у него нет, и в списке устройств он не появится.
Распиновка модуля
Типичная плата 1,8 дюйма имеет восемь контактов:
| Контакт на плате | Альтернативные подписи | Назначение |
|---|---|---|
VCC | VDD, 3.3V | Питание логики и матрицы |
GND | VSS | Общий провод |
CS | TFT_CS | Выбор чипа SPI (Chip Select), активный LOW |
RESET | RST, RES | Аппаратный сброс контроллера, активный LOW |
A0 | DC, RS, D/C | Data/Command: выбор между командой и данными |
SDA | MOSI, DIN | Данные SPI от контроллера к экрану |
SCK | SCL, CLK | Тактовый сигнал SPI |
LED | BL, BLC, BK | Подсветка; чаще всего уже подключена к питанию через транзистор на плате |
У модулей 0,96" и 1,44" подписи почти те же, но порядок контактов может отличаться. Перед подключением всегда сверяйтесь с маркировкой именно вашей платы.
Пин A0/DC — самый важный для понимания. По SPI в экран идут и команды («установить адрес окна», «начать запись в память»), и данные (значения пикселей). Логический уровень на DC говорит контроллеру, что именно сейчас передаётся: LOW — команда, HIGH — данные. Именно поэтому для дисплея нужны пять сигналов, а не три, как для простых SPI-датчиков.
Питание и логические уровни
Здесь кроется главный практический вопрос: можно ли питать модуль от 5 В?
- Дешёвые «голые» модули без стабилизатора рассчитаны на питание 3,3 В. Их логические входы тоже ожидают уровни около 3,3 В.
- Часть модулей (включая оригинальные breakout-платы Adafruit) имеет встроенный стабилизатор и согласование уровней, и производитель прямо заявляет совместимость и с 5 В, и с 3,3 В логикой.
- Маркировка продавца «5V» на карточке товара не всегда отражает реальную схему платы.
Практические рекомендации:
- Для ESP32 и RP2040 всё просто: питайте модуль от 3,3 В и подключайте сигналы напрямую.
- Для Arduino Uno/Nano с 5-вольтовой логикой самый надёжный вариант — модуль с подтверждённой поддержкой 5 В. Если модуль без стабилизатора, используйте преобразователь уровней на линиях
SCK,SDA,CS,DC,RST. - Многие дешёвые модули 1,8" годами работают от 5 В без преобразователя, но это выходит за рамки спецификации чипа. Решение «подключил напрямую — работает» не гарантирует стабильность на другой партии плат.
- Подсветка
LED/BLна большинстве модулей управляется транзистором и допускает прямое подключение к питанию. Если подсветку нужно включать и выключать программно, проверьте схему своей платы: на некоторых модуляхBLуже подтянут к питанию, и разрывать её пином нельзя.
Подключение к Arduino Uno/Nano
Используем аппаратный SPI. На Uno и Nano он жёстко закреплён за выводами 11 (MOSI) и 13 (SCK). Остальные сигналы можно назначить на любые свободные цифровые пины.
ST7735 1.8" Arduino Uno/Nano
───────────── ────────────────
VCC ─────── 3.3V (или 5V, если модуль поддерживает)
GND ─────── GND
CS ─────── D10
RESET ─────── D8
A0/DC ─────── D9
SDA ─────── D11 (MOSI)
SCK ─────── D13 (SCK)
LED ─────── 3.3V / 5V (или пин с PWM для регулировки)
Номера пинов CS = 10, DC = 9, RST = 8 выбраны не случайно — они совпадают с примерами библиотеки Adafruit, поэтому чужие скетчи из интернета заработают без правок.
Подключение к ESP32
На ESP32 удобнее всего использовать шину VSPI с выводами по умолчанию: SCK = GPIO18, MOSI = GPIO23. Сигналы CS, DC и RST можно повесить на любые свободные GPIO.
ST7735 1.8" ESP32 DevKit
───────────── ─────────────────
VCC ─────── 3V3
GND ─────── GND
CS ─────── GPIO5 (VSPI CS по умолчанию)
RESET ─────── GPIO4
A0/DC ─────── GPIO2
SDA ─────── GPIO23 (VSPI MOSI)
SCK ─────── GPIO18 (VSPI SCK)
LED ─────── 3V3
Ничего паять не нужно: все сигналы у ESP32 уже 3,3-вольтовые. Не забудьте только, что GPIO2 участвует в процедуре загрузки ESP32 — если экран мешает прошивке, перенесите DC на другой пин, например GPIO16. Подробнее о безопасных выводах — в статье про .
Установка библиотек
Нужны две библиотеки от Adafruit:
- Adafruit GFX Library — графический движок: линии, прямоугольники, круги, текст, шрифты.
- Adafruit ST7735 and ST7789 Library — драйвер конкретно этого контроллера. Раньше она называлась Adafruit-ST7735-Library, сейчас объединена с поддержкой ST7789.
Установка через Arduino IDE:
- Меню Скетч → Подключить библиотеку → Управлять библиотеками.
- В поиске введите
ST7735. - Установите «Adafruit ST7735 and ST7789 Library».
- Arduino IDE предложит установить зависимости — согласитесь, среди них будет Adafruit GFX.
Для PlatformIO добавьте в platformio.ini:
lib_deps =
adafruit/Adafruit GFX Library
adafruit/Adafruit ST7735 and ST7789 LibraryПервый скетч: проверка экрана
Скетч заливает экран цветом, рисует рамку и выводит текст. Ничего лишнего, но по нему сразу видно, правильно ли выбрана таблица инициализации.
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
// Пины для Arduino Uno/Nano
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8
// Для ESP32 закомментируйте строки выше и используйте:
// #define TFT_CS 5
// #define TFT_DC 2
// #define TFT_RST 4
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
void setup() {
Serial.begin(9600);
Serial.println("ST7735 test");
// Для модуля 1.8" 128x160 начните с этого варианта:
tft.initR(INITR_BLACKTAB);
// Альтернативы для других модулей:
// tft.initR(INITR_GREENTAB); // 1.8", старые партии
// tft.initR(INITR_REDTAB); // 1.8", ещё один вариант
// tft.initR(INITR_144GREENTAB); // 1.44" 128x128
// tft.initR(INITR_MINI160x80); // 0.96"/1.0" 80x160
Serial.println("Initialized");
uint16_t time = millis();
tft.fillScreen(ST77XX_BLACK);
time = millis() - time;
Serial.print("fillScreen: "); Serial.print(time); Serial.println(" ms");
// Крупный текст
tft.setTextColor(ST77XX_YELLOW);
tft.setTextSize(2);
tft.setCursor(10, 20);
tft.println("ARDULOVE");
tft.setTextColor(ST77XX_GREEN);
tft.setTextSize(1);
tft.setCursor(10, 50);
tft.println("ST7735 128x160 TFT");
// Рамка по краям — проверка, что ничего не обрезано
tft.drawRect(0, 0, tft.width(), tft.height(), ST77XX_RED);
}
void loop() {
// Мигание цветом, чтобы убедиться, что экран обновляется
tft.invertDisplay(true);
delay(500);
tft.invertDisplay(false);
delay(500);
}Если на экране появился чёрный фон, жёлтая надпись, зелёная строка и красная рамка ровно по краям — модуль подключён правильно.
Функция tft.invertDisplay() меняет местами чёрный и белый и удобна для быстрой проверки, что картинка живая, а не зависла.
Таблицы инициализации: почему картинка сдвинута
ST7735 выпускается в разных версиях для разных панелей, и в памяти контроллера окно вывода может начинаться не с нуля. Библиека Adafruit учитывает это набором «табов» — вариантов инициализации. Если таб не совпал с реальной панелью, симптомы такие:
- картинка сдвинута на несколько пикселей, у одного края цветная полоса;
- углы рамки обрезаны, рамка «уехала» за край;
- изображение есть, но по краям видны полосы мусора;
- у Mini-модуля 80×160 при неправильном табе экран остаётся пустым или показывает мусор.
Решение — перебрать варианты initR():
| Модуль | Что пробовать |
|---|---|
| 1,8" 128×160 | INITR_BLACKTAB, затем INITR_GREENTAB, затем INITR_REDTAB |
| 1,44" 128×128 | INITR_144GREENTAB |
| 0,96"/1,0" 80×160 | INITR_MINI160x80 |
Правильный таб — тот, при котором рамка из скетча выше видна целиком, без сдвигов и обрезания.
Цвета перепутаны: красный стал синим
Ещё одна особенность партий ST7735 — порядок цветовых каналов. У части панелей формат BGR вместо RGB. Внешне это выглядит так: вы рисуете красный, а на экране синий, и наоборот; жёлтый и голубой тоже меняются местами.
Часто правильный таб из предыдущего раздела заодно решает и проблему цвета. Если нет, в новых версиях библиотеки есть функция:
tft.setRGB(true); // RGB-порядок
// или
tft.setRGB(false); // BGR-порядокЕсли ваша версия библиотеки эту функцию не знает, обновите библиотеку или используйте функцию invertDisplay() для инверсии — но учтите, что инверсия меняет все цвета, а не только порядок каналов.
Поворот экрана
Экран можно повернуть программно на 90° шагами:
tft.setRotation(0); // портрет, 128x160
tft.setRotation(1); // пейзаж, 160x128
tft.setRotation(2); // портрет вверх ногами
tft.setRotation(3); // пейзаж вверх ногамиПосле setRotation() функции tft.width() и tft.height() возвращают актуальные размеры, поэтому код отрисовки не нужно переписывать под каждую ориентацию.
Русский текст
Штатный шрифт Adafruit GFX содержит только ASCII, поэтому tft.print("Привет") выведет каракули или ничего. Варианты решения:
- Свой шрифт с кириллицей. Сгенерируйте GFX-шрифт из TTF/OTF-файла онлайн-конвертером (например, font converter от Adafruit или DIY-инструменты на Python/PIL), выбрав нужную кодировку Unicode, и подключите через
tft.setFont(&my_cyrillic_font);. Это самый правильный путь: шрифт влезает во flash, а не в RAM. - Библиотеки с готовыми кириллическими шрифтами. В экосистеме Arduino есть сборники GFX-шрифтов с русскими глифами — можно взять готовый вместо конвертации своего.
- Транслит или английский. Для приборных экранов иногда проще вывести
TEMP 23.5C, чем возиться со шрифтами.
Для ESP32 есть и альтернативная библиотека TFT_eSPI — она быстрее за счёт DMA, поддерживает спрайты и загрузку шрифтов с кириллицей. Если проект перерастает Adafruit GFX, посмотрите в её сторону.
Обновление чисел без мерцания
Классическая задача: метеостанция раз в секунду выводит температуру. Если просто вызывать tft.print() поверх старого значения, цифры будут накладываться друг на друга.
Простейшее решение — стирать область перед выводом:
void printValue(int x, int y, float value) {
tft.fillRect(x, y, 80, 16, ST77XX_BLACK); // стираем зону числа
tft.setTextColor(ST77XX_WHITE);
tft.setTextSize(2);
tft.setCursor(x, y);
tft.print(value, 1);
}Более продвинутый способ — двойная буферизация через спрайты (в TFT_eSPI) или частичная перерисовка только изменившихся символов. Для большинства любительских приборов достаточно fillRect().
Вывод картинок
Растровое изображение нужно перевести в массив RGB565 и хранить во flash. Стандартный инструмент — image2cpp (веб-конвертер) или LCD Assistant:
- Подготовьте картинку нужного размера, например 128×128.
- Конвертируйте в массив
uint16_tв формате RGB565. - Поместите массив в PROGMEM.
- Выведите через
tft.drawRGBBitmap(x, y, bitmap, w, h);.
Учитывайте объём: картинка 128×128 занимает 32 КБ flash. Полноэкранная 128×160 — 40 КБ. Для Uno с её 32 КБ это уже не влезет, а для ESP32 — без проблем.
Совместное использование с microSD
Многие модули 1,8" выпускаются со слотом microSD на той же плате. Карта и дисплей сидят на одном SPI: общие SCK и MOSI, но отдельные CS. Пока вы обращаетесь к дисплею, его CS низкий, а CS карты высокий, и наоборот. Дисплей не использует MISO — чтение идёт только с карты.
Типичная схема для Uno:
Дисплей: CS=D10, DC=D9, RST=D8, SDA=D11, SCK=D13
Карта: CS=D4, MOSI=D11, MISO=D12, SCK=D13В коде перед работой с картой не забывайте завершать транзакции с дисплеем — при использовании стандартных библиотек SPI.beginTransaction()/endTransaction() это происходит автоматически.
Диагностика проблем
Экран белый и ничего не показывает
Белый экран с работающей подсветкой означает, что матрица жива, но контроллер не получает команды. Проверьте:
- питание
VCCиGND— частая ошибка при подключении к макетке; - все пять сигналов:
SCK,SDA,CS,DC,RST; - не перепутаны ли местами
DCиRST— это самая частая ошибка; - правильность пинов в
#define— особенно если скетч писался для другой платы; - общий GND между экраном и контроллером.
Подсветка не светится, картинка вроде есть
Проверьте контакт LED/BL. Если он не подключён, подсветка выключена, и изображение можно разглядеть только под ярко направленным светом под углом. Подключите BL к питанию.
Картинка сдвинута, у края полоса
Неверный таб инициализации. Переберите варианты initR() из таблицы выше.
Красный и синий поменялись местами
Порядок цветовых каналов панели. Попробуйте другой таб или setRGB().
Экран работает, но медленно перерисовывается
Убедитесь, что используется аппаратный SPI, а не программный. При создании объекта Adafruit_ST7735(CS, DC, RST) библиотека сама использует аппаратный SPI. Конструктор с явной передачей MOSI и SCK включает медленный программный SPI — избегайте его без необходимости.
Модуль 80×160 показывает мусор
Используйте INITR_MINI160x80. У этих панелей другое начальное смещение окна, и обычные табы 128×160 не подходят.
Что запомнить
- ST7735 — SPI-дисплей. Подписи
SDA/SCLна плате означаютMOSIиSCK, а не I2C. - Для работы нужны пять сигналов:
SCK,SDA,CS,DC,RST, плюс питание и подсветка. - Дешёвые модули — 3,3-вольтовые. Для Uno/Nano либо модуль с поддержкой 5 В, либо преобразователь уровней. Для ESP32 — прямое подключение к 3V3.
- Для Uno удобно:
CS=10,DC=9,RST=8,MOSI=11,SCK=13. Для ESP32:CS=5,DC=2,RST=4,MOSI=23,SCK=18. - Белый экран — почти всегда ошибка в подключении или в
#defineпинов. - Сдвиг картинки и полосы по краям лечатся подбором
initR()-таба:BLACKTAB,GREENTAB,REDTAB,144GREENTAB,MINI160x80. - Перепутанные красный и синий — особенность порядка каналов панели, а не поломка.
- Кириллица требует собственного GFX-шрифта; штатный шрифт — только ASCII.
- microSD на том же модуле спокойно делит SPI с экраном через отдельный
CS.
Проверь себя
- На плате дисплея есть контакты
SDAиSCL. Значит ли это, что экран подключается по I2C? - Экран светится белым, но ничего не показывает. Какие две самые частые причины?
- Рамка из тестового скетча обрезана справа, а слева видна цветная полоса. Что нужно поменять в коде?
- Почему для дешёвого 3,3-вольтового модуля не стоит напрямую подключать сигналы от Arduino Uno?
Показать ответы
- Нет. У ST7735 только SPI.
SDAна плате — это линия данных SPI (MOSI),SCL— тактовый сигнал (SCK). I2C-адреса у экрана нет, и I2C-сканер его не найдёт. - Первая — ошибка в подключении или в
#defineпинов, особенно перепутанныеDCиRST. Вторая — отсутствие общего GND или питания. Сама белая подсветка говорит, что питание и LED в порядке, проблема в сигнальных линиях. - Выбран неверный вариант инициализации. Нужно перебрать табы
initR(): для 1,8" попробоватьINITR_BLACKTAB,INITR_GREENTABиINITR_REDTAB, пока рамка не встанет ровно по краям. - Логика Uno работает на 5 В, а входы дешёвого модуля рассчитаны на 3,3 В. Прямое подключение выходит за спецификацию чипа и может привести к нестабильной работе или повреждению. Нужен модуль с подтверждённой поддержкой 5 В либо преобразователь уровней.
Источники
- Adafruit 1.8" Color TFT LCD Display Guide — официальное руководство по подключению и библиотекам
- Adafruit ST7735 and ST7789 Library на GitHub — исходный код, варианты инициализации и примеры
- Adafruit GFX Library на GitHub — графический движок, шрифты и примитивы
- image2cpp — онлайн-конвертер картинок в массивы для Arduino