TFT_eSPI: работа с русским текстом

TFT_eSPI — самая лучшая библиотека для работы с дисплеями в среде Arduino IDE, на момент написания данной статьи. Она отличается высоким быстродействием и поддержкой множества популярных контроллеров TFT дисплеев.

На этом уроке мы научимся выводить текст на дисплей, менять его цвет и координаты. А также, подключим русский шрифт!

Для экспериментов используем контроллер Графит-32S и 2-дюймовый дисплей с IPS матрицей. Всё это есть в интернет-магазине RobotClass.

В корзину
В корзину
В корзину
В корзину

Подключение

Дисплей подключается к контроллеру по 4-контактной шине SPI.

Графит-32S (ESP32-S)3V3Gnd142223518
Дисплей IPS 2.0VCCGCSRSTRSSCKMOBK

Контакт BK отвечает за подсветку матрицу. Для выключения подсветки этот контакт можно соединить с землёй, но мы его оставим в покое.

Программа

Для правильной работы библиотеки TFT_eSPI сначала необходимо настроить файл конфигурации. Это нужно сделать вручную, открыв в текстовом редакторе файл:

путь_к_библиотекам\Arduino\libraries\TFT_eSPI-master\User_Setup.h

Можно удалить всё содержимое этого файла и оставить только следующие строки:

#define USER_SETUP_INFO "User_Setup"

#define ST7789_2_DRIVER

#define TFT_RGB_ORDER TFT_RGB

#define TFT_WIDTH  240
#define TFT_HEIGHT 320

#define TFT_INVERSION_ON

#define TFT_MOSI 18
#define TFT_SCLK 5
#define TFT_CS   15
#define TFT_DC   27
#define TFT_RST  33

#define LOAD_GLCD

#define SPI_FREQUENCY  27000000
#define SPI_READ_FREQUENCY  20000000
#define SPI_TOUCH_FREQUENCY  2500000

Установка кириллицы

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

1. Сначала подменим коллекцию символов GLCD. Символы шрифта хранятся в файле:

путь_к_библиотекам\Arduino\libraries\TFT_eSPI-master\Fonts\glcdfont.c

Заменяем этот файл на русифицированный, за авторством Вячеслава Загайнова (ссылка в конце урока). В отличие от оригинала, новый файл содержит как оригинальную таблицу ASCII так и блок кириллических символов таблицы UTF-8. Так что в коде программы просто пишем русский текст, и он будет выводиться на дисплей без всяких дополнительных ухищрений.

2. Затем, внесём небольшое изменение в код библиотеки, а именно в файл TFT_eSPI.cpp. Нужно найти и удалить (или закомментировать) такую строку:

if (c > 255) return;

Это ограничение не даёт библиотеке извлекать из коллекции символы с кодом больше 255.

Готово, теперь пишем первую программу.

Вывод текста

В качестве первого примера выведем на экран текст «Привет!».

#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();

void setup() {
    tft.init(); // инициализация дисплея
    tft.setRotation(2); // вращение на 180 градусов
    tft.fillScreen(TFT_BLACK); // заливка фона чёрным цветом


    tft.setCursor(60, 150); // x,y координаты текста
    tft.setTextColor(TFT_WHITE); // цвет текста - белый
    tft.setTextSize(2); // размер текста - №2 (7*2 = 14 точек)
    tft.print("Привет!"); // вывод текста
}

void loop() {
}

Загружаем программу на контроллер и наблюдаем русский текст, написанный шрифтом из крупных пикселей.

Русский текст на TFT IPS дисплее с библиотекой TFT_eSPI

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

Цвет текста задаётся функцией setTextColor. В библиотеке TFT_eSPI есть несколько констант со стандартными цветами: TFT_WHITE, TFT_BLACK, TFT_BLUE, TFT_RED и т.п. Их можно посмотреть в файле TFT_eSPI.h. Либо можно указать любой доступный цвет с помощью числа от 0 до 65535. Об этом подробнее в следующем примере.

Всего имеется 7 размеров шрифта. 1 — самый маленький текст размером 5*7 точек. 2 — увеличенный в 2 раза. И т.д. Размер шрифта устанавливается функцией setTextSize.

Для вывода текста можно использовать либо функцию print, либо println. Вторая, автоматически переводит строку, как и в случае роботы с Serial.

Вывод цветного текста

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

#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();

uint16_t color24to16( uint8_t r, uint8_t g, uint8_t b ){
    uint16_t c = ((r & 0xF8)<<8) | ((g & 0xFC)<<3) | ((b & 0xF8)>>3);
    Serial.println(c, HEX);
    return c;
}

void setup() {
    Serial.begin(115200);

    color24to16(0xC8, 0x8C, 0x1E);
  
    tft.init();
    tft.setRotation(2);
    tft.fillScreen(TFT_BLACK);

    //tft.setCursor(0, 0);
    tft.setTextSize(3);
    tft.setTextColor( color24to16(255,0,0) );
    tft.println("каждый");
    tft.setTextColor( color24to16(255,128,0) );
    tft.println("охотник");
    tft.setTextColor( color24to16(255,255,0) );
    tft.println("желает");
    tft.setTextColor( color24to16(0,255,0) );
    tft.println("знать");
    tft.setTextColor( color24to16(0,255,255) );
    tft.println("где");
    tft.setTextColor( color24to16(0,0,255) );
    tft.println("сидит");
    tft.setTextColor( color24to16(255,0,255) );
    tft.println("фазан");
}

void loop() {
}

В этой программе есть функция color24to16 которая преобразует 24-разрядное RGB представление цвета в 16-разрядное.

Дело в том, что многие дисплейные модули, используемые в DIY, работают только с 16-разрядным цветом (65K цветов). При этом используется схема: 565, в которой красный цвет кодируется 5 битами, зелёный — 6 битами и синий снова 5 битами.

Уверен, что большинству читателей привычнее использовать 24-разрядное представление, в котором на каждую компоненту цвета приходится 1 байт — число от 0 до 255. Так что функция color24to16 используется для удобства программиста, не более того.

Загружаем программу на контроллер и наблюдаем цветной текст.

Русский текст на TFT IPS дисплее с библиотекой TFT_eSPI

К размышлению

На данном уроке мы научились выводить текст самым простым шрифтом, в котором каждый символ имеет размер всего 5*7 точек. При увеличении в 3 и более раз он выглядит уже неприлично, и понравится разве что любителям Pixel Art.

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

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

Полезные ссылки

Файл glcdfont.c с кириллицей:
https://download.robotclass.ru/Arduino/glcdfont.c

Репозиторий GitHub библиотеки TFT_eSPI:
https://github.com/Bodmer/TFT_eSPI


Изменено:

TFT_eSPI: работа с русским текстом: 9 комментариев

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

  2. Здравствуйте!
    Ссылка в конце статьи на кириллический фонт не содержит сам фонт, приложена просто заглушка glcdfont.c. Можете поделиться рабочим файлом?
    Спасибо!

  3. Здравствуйте!
    Скачал файл glcdfont.c, заменил в папке ..\.pio\libdeps\esp32doit-devkit-v1\TFT_eSPI\Fonts\.
    Закомментировал строку «if (c > 255) return;» в файле TFT_eSPI.cpp.
    Русские символы появились, но их последовательность перепутана.
    Вместо :
    А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я
    выводится следующее:
    Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я а
    Понятно что идёт смещение, но разбираться было лень, а написал может кому пригодится.

    • то же самое. открыл файл редактором скопировал и добавил строчку перед тем как начинаються русские буквы и все работает

      • Здравствуйте, подскажите что и в каком файле редактировал? Тоже имею такую проблему Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я а

  4. В догонку к предыдущему комментарию.
    Хотел сделать красивый шрифт, например растеризовать тот же Times New Roman, НО! Задавила жаба отдавать место под шрифт )))
    Поэтому стал разбираться с glcdfont.c и оказалось что всё очень просто.
    То ли сам случайно удалил строчку, но надо вставить в строку 1125 (это буква Ё) строку
    0x00, 0x00, 0x00, 0x00, 0x00,
    И будет всем счастье)))
    На всякий случай положил исправленный файлик сюда:
    https://drive.google.com/file/d/13F4GlNWATGLXO3ld7wQpaJaJCVglySu0/view?usp=sharing

  5. Слишком сложно и неюзабельно.
    Русификация делается и используется гораздо проще, чем в представленных примерах.
    При этом используются шрифты TrueType а не примитивный glcdfont.c

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.