Цветной IPS дисплей 1.14, 135×240 AlashEd
Дисплей IPS 1.14 ST7789
Различные виды жидкокристаллических дисплеев часто применяются в DIY проектах для отображения символьной и графической информации. И если самые простые дисплеи умеют отображать только чёрное и белое, то более продвинутые могут работать с цветом.
Матрицы, используемые в ЖК дисплеях (TFT) бывают разных типов: TN, VA, IPS и пр. За этими буквами скрывается технология организации жидких кристаллов, от которой зависят разные параметры дисплея. Так, дисплеи с IPS матрицей отличаются большими углами обзора, более высоким уровнем контраста и точной цветопередачей.
В этой инструкции мы будем работать как раз с таким дисплейным модулем от AlashEd. В основе модуля — матрица IPS с диагональю 1,14 дюйма (около 29 мм).
Характеристики
Примечание
напряжение питания: от 3,3 до 5 В;
интерфейс: 4-проводной SPI;
разрешение: 135 x 240 точек;
контроллер: ST7789V2;
размеры матрицы: 14,864 x 24,912 мм (1,14 дюйма по диагонали);
размеры модуля: 32 x 28,5 мм.
Важно
Контроллер ST7789, как и большинство его аналогов, может работать только с 16-разрядным цветом. Этот факт накладывает ограничение на отображение привычных 24-разрядных цветов.
Список необходимых компонентов
Для выполнения всех экспериментов в данном уроке, кроме самого модуля IPS дисплея, потребуются: отладочная плата UNO2, либо любая другая Arduino-совместимая плата. Отладочная плата с CircuitPython для примера на python. Беспаечная макетная плата и немного проводов вилка-розетка.
Подключение
Дисплей подключается по интерфейсу SPI4, а значит нужно соединить четыре сигнальные линии, две линии питания и выключатель подсветки:
SCK — синхроимпульс;
MOSI — данные от контроллера (Master Out) к устройству (Slave In);
CS — выбор устройства (Chip Select);
RS(D/C) — линия для передачи команд устройству;
RST — сброс памяти дисплея;
VCC — питание;
GND — земля;
BK — контакт для контроля подсветки.
Примечание
В наших экспериментах мы не управляем подсветкой, так что этот контакт никуда подключать не будем.
Подключение к плате UNO2 (Atmega328)
UNO2 — это аналог классической Arduino Uno R3, так что для SPI используем стандартные контакты: MOSI-11, MISO-12, SCK-13. Остальные контакты дисплея можно подключить к любым свободным GPIO контактам отладочной платы.
UNO2 |
5V |
G |
10 |
9 |
8 |
13 |
11 |
— |
|---|---|---|---|---|---|---|---|---|
Дисплей IPS 1.14 AlashEd |
VCC |
G |
CS |
RST |
RS |
SCK |
MO |
BK |
Подключение к Графит-S3 (ESP32)
Аналогичным образом дисплей подключается к отладочной плате Графит-S3. У данной платы SPI интерфейс, по умолчанию, привязан к контактам: MISO-2, MOSI-9, SCK-10.
Графит-S3 |
3.3 |
Gnd |
6 |
5 |
4 |
10 |
9 |
— |
|---|---|---|---|---|---|---|---|---|
Дисплей IPS 1.14 AlashEd |
VCC |
G |
CS |
RST |
RS |
SCK |
MO |
BK |
Arduino IDE
Для работы с дисплеем будем использовать библиотеку Adafruit-ST7735-Library (ссылка в конце статьи). Эта библиотека описывает протокол обмена сразу с двумя распространёнными контроллерами дисплеев: ST7735 и ST7789. Нам будет интересен последний из них.
Пусть первая программа выведет в центре дисплея текст «Hello world!».
Сразу после подключения библиотеки, создадим объект класса Adafruit-ST7789 с именем tft. При создании объекта укажем номера контактов отладочной платы, к которым мы ранее подключили линии CS, RS и RST дисплея:
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_RS, TFT_RST);
При запуске программы необходимо инициализировать дисплей. Делаем это при помощи функции tft.init. У функции два аргумента: ширина и высота матрицы в пикселах. Для нашего дисплея они будут равны 240 и 280:
tft.init(135, 240);
Изначально все подобные дисплеи ориентированы так, что ширина у них меньше, чем высота. Чтобы повернуть изображения можно использовать функцию setRotation с одним аргументом: 0 — не поворачивать, 1 — на 90 градусов, 2 — на 180, 3 — на 270.
Далее можем вызывать разные функции объекта tft, для построения графики или вывода текста на дисплей. Полный код программы:
#include <Adafruit_ST7789.h>
#define TFT_CS 10
#define TFT_RST 9
#define TFT_RS 8
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_RS, TFT_RST);
void setup(void) {
tft.init(135, 240);
tft.setRotation(1);
tft.fillScreen(ST77XX_BLACK);
tft.setTextSize(2);
tft.setTextColor(ST77XX_MAGENTA);
tft.setCursor(45, 55);
tft.print("Hello world!");
}
void loop() {
}
Загружаем программу на UNO2 и получаем вывод:
Геометрия и цвета
В следующей программе изобразим палитру. Используем функцию fillRect, которая рисует закрашенный прямоугольник.
В начале программы определим 12 цветов. Помним, что контроллер ST7789 использует только 16 разрядов для хранения цвета точки, следовательно, нам потребуется переменная типа uint16_t, а вернее массив таких переменных.
Затем строим в цикле двенадцать прямоугольников с заданными в массиве цветами.
#include <Adafruit_ST7789.h>
#define TFT_CS 10
#define TFT_RST 9
#define TFT_RS 8
#define BOX_HEIGHT 135/2
#define BOX_WIDTH 240/6
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_RS, TFT_RST);
uint16_t colors[12] = {
0x0000, // чёрный
0xFFFF, // белый
0xBDF7, // светло серый
0x7BEF, // серый
0xF800, // красный
0xFFE0, // жёлтый
0xFBE0, // оранжевый
0x79E0, // коричневый
0x7E0, // зелёный
0x7FF, // голубой
0x1F, // синий
0xF81F // розовый
};
void setup(void) {
tft.init(135, 240);
tft.setRotation(1);
tft.fillScreen(ST77XX_BLACK);
byte color = 0;
for(byte y=0; y<2; y++){
for(byte x=0; x<6; x++){
tft.fillRect(2+x*BOX_WIDTH, 2+y*BOX_HEIGHT, BOX_WIDTH, BOX_HEIGHT, colors[color]);
color++;
}
}
}
void loop() {
}
Загружаем программу на UNO2 и получаем такую картину:
CircuitPython
Примеры для CircuitPython будем запускать на отладочной плате Графит-S3.
Для работы с дисплеем используем библиотеку adafruit_st7789, которую можно скачать по ссылке в конце урока. Всё, что нам нужно сделать для её установки — это скопировать файл adafruit_st7789.mpy в папку lib на накопителе CIRCUITPY.
Совет
Более подробно о работе с библиотеками CircuitPython можно узнать в уроке «Библиотеки для CircuitPython».
Установка зависимостей
Для работы примеров понадобятся вспомогательные библиотеки, которые помогают работать с текстом и графикой:
adafruit_display_text
adafruit_display_shapes
Все эти библиотеки есть в сборнике от Adafruit. Точно также, копируем их на накопитель CIRCUITPY.
Вывод текста
Для составления программы используем среду разработки Mu.
Пусть, самая первая наша программа будет выводить текст «Hello world!». Начнём с подключения всех необходимых библиотек. Помним, что в python это делается с помощью команды import.
Кроме adafruit_st7789 и adafruit_display_text нам будут нужны еще несколько библиотеки:
board — предоставляет интерфейс для работы с периферией отладочной платы;
terminalio — отсюда возьмем стандартный шрифт;
displayio — нужна для работы с графическими абстрактами.
import board
import terminalio
import displayio
from displayio import FourWire
from adafruit_display_text import label
from adafruit_st7789 import ST7789
Обязательно вызываем функцию release_displays для освобождения шины:
displayio.release_displays()
Теперь инициализируем шину SPI и дисплей. Особое внимание следует обратить на аргументы конструктора ST7789: ширина матрицы — 135 точек, высота — 240 точек. Значение аргументов rowstart и colstart определяется особенностями конкретного дисплея. Также здесь можно передать четвертый аргумент — rotation, который укажет поворот дисплея в градусах (90, 180, 270).
spi = board.SPI()
tft_cs = board.D6
tft_dc = board.D4
tft_rst = board.D5
display_bus = FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=tft_rst)
display = ST7789(display_bus, width=240, height=135, rowstart=40, colstart=53, rotation=90)
А теперь приступим к выводу текста.
Графическая библиотека displayio, которая часто используется в CircuitPython, работает не совсем привычно. Она требует, чтобы все графические объекты были организованы в иерархию. Такой подход может показаться более сложным, чем обычный процедурный. В действительности, это сильно упрощает работу со сложной графикой, такой как, например, в играх.
# создание коревой группы
splash = displayio.Group()
display.root_group = splash
# создание группы для размещения текста
text_group = displayio.Group(scale=2, x=45, y=65)
text = "Hello World!"
text_area = label.Label(terminalio.FONT, text=text, color=0xFF00FF)
text_group.append(text_area) # размещаем текст в его группе
splash.append(text_group) # размещаем текстовую группу в корневой группе
Вся программа целиком:
import board
import terminalio
import displayio
from displayio import FourWire
from adafruit_display_text import label
from adafruit_st7789 import ST7789
displayio.release_displays()
spi = board.SPI()
tft_cs = board.D6
tft_dc = board.D4
tft_rst = board.D5
display_bus = FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=tft_rst)
display = ST7789(display_bus, width=240, height=135, rowstart=40, colstart=53, rotation=90)
splash = displayio.Group()
display.root_group = splash
text_group = displayio.Group(scale=2, x=45, y=65)
text = "Hello World!"
text_area = label.Label(terminalio.FONT, text=text, color=0xFF00FF)
text_group.append(text_area)
splash.append(text_group)
while True:
pass
Сохраняем программу на Графит и смотрим результат.
Геометрия и цвета (CircuitPython)
В следующей программе изобразим палитру. Используем функцию Rect из библиотеки adafruit_display_shapes, которая рисует закрашенный прямоугольник.
В начале программы определим 12 цветов. В circuitpython мы задаём их как 24 разрядные числа в шестнадцатеричном формате: #FF00FF. Однако, помним, что контроллер ST7789 использует только 16 разрядов для хранения цвета точки, так что эти 24-разрядные цвета позже будут конвертированы в 16-разрядные с потерей информации.
Затем строим в цикле двенадцать прямоугольников с заданными в массиве цветами. Каждый прямоугольник обязательно добавляем в корневую группу.
import time
import board
import terminalio
import displayio
from displayio import FourWire
from adafruit_display_text import label
from adafruit_display_shapes.rect import Rect
from adafruit_st7789 import ST7789
displayio.release_displays()
spi = board.SPI()
tft_cs = board.D6
tft_dc = board.D4
tft_rst = board.D5
display_bus = FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=tft_rst)
display = ST7789(display_bus, width=240, height=135, rowstart=40, colstart=53, rotation=90)
# Make the display context
splash = displayio.Group()
display.root_group = splash
# определяем палитру из 12 цветов
palette = displayio.Palette(12)
palette[0] = 0x000000 #чёрный
palette[1] = 0xFFFFFF #белый
palette[2] = 0xC0C0C0 #светло серый
palette[3] = 0x808080 #серый
palette[4] = 0xFF0000 #красный
palette[5] = 0xFFFF00 #жёлтый
palette[6] = 0xFF8000 #оранжевый
palette[7] = 0x804000 #коричневый
palette[8] = 0x00FF00 #зелёный
palette[9] = 0x00FFFF #голубой
palette[10] = 0x0000FF #синий
palette[11] = 0xFF00FF #маджента
BOX_HEIGHT = int(135/2-2)
BOX_WIDTH = int(240/6-4)
# генерируем 12 прямоугольников с разными цветами из палитры
color_idx = 0
for y in range(2):
for x in range(6):
rect = Rect(x=2+x*(BOX_WIDTH+4), y=2+y*(BOX_HEIGHT+4), width=BOX_WIDTH, height=BOX_HEIGHT, fill=palette[color_idx])
splash.append(rect)
color_idx += 1
while True:
pass
Сохраняем программу на отладочную плату и смотрим результат.
Схемы
Принципиальная схема модуля.