Как использовать круглый сенсорный дисплей Waveshare RP2040 1.28»
В этом руководстве мы покажем, как управлять этой LCD-платой на базе RP2040 с диагональю 1.28» с помощью MicroPython, включая работу с ёмкостным сенсорным дисплеем.
Вам может быть полезно ознакомиться с нашими предыдущими руководствами по программированию графики и текста на дисплеях Waveshare LCD, поскольку этот дисплей очень похож на 240x240, рассмотренный там, — только со скруглёнными углами!
Все процедуры и методы из тех руководств работают на этом дисплее и были использованы в проекте часов, который мы демонстрируем.
Что вам понадобится
Предполагается, что вы уже установили Thonny на компьютер и настроили Raspberry Pi Pico с актуальной прошивкой MicroPython (UF2). Если нет — ознакомьтесь с руководством по началу работы с Raspberry Pi Pico, где это подробно описано.
Вам понадобится:
RP2040 1.28» Round Touch LCD
Кабель USB-C
Дополнительно (опционально):
Потенциометр 10 кОм
Введение в аппаратное обеспечение
Эта плата на базе RP2040 от Waveshare с дисплеем 1.28» предоставляет разработчикам множество функций для экспериментов и использования в проектах. Все возможности легко доступны через MicroPython и включают:
Круглый IPS-дисплей 240x240 пикселей
65K цветов
Ёмкостный сенсор касания с режимами точки и жестов
Мощный инерциальный измерительный модуль (IMU) — акселерометр и гироскоп
4 МБ Flash-памяти
12-контактный соединительный кабель к незадействованным GPIO-пинам RP2040
Поддержка аккумулятора LiPo (разъём MX1.25 с шагом 1,25 мм)
Настройка платы
Если вы подключите кабель USB-C к разъёму на плате и запитаете её от компьютера, вы обнаружите, что на ней установлен демонстрационный файл UF2. Он демонстрирует некоторые графические элементы, работу IMU и показывает фотографию водопада.
Нам нужно заменить установленный UF2 на актуальный файл MicroPython для RP2040 (версия Pico), который можно скачать с официального сайта MicroPython и установить по инструкции на той же странице.
Программирование платы
Получение демо-кода
Наши примеры основаны на демонстрационном коде для платы, доступном на Wiki. Waveshare предоставили обширную документацию для этой платы в Wiki (стоит прочитать её перед тем, как продолжать).
Перейдите по ссылке выше, затем прокрутите страницу вниз до раздела ресурсов и скачайте демонстрационный файл.
Это загрузит zip-архив с именем RP2040-Touch-LCD-Code. После его распаковки вы получите программу на MicroPython, содержащую все необходимые драйверы и демонстрацию. Это незаменимый инструмент и основа для наших собственных программ.
Запуск демо
Откройте демонстрационный файл в Thonny, подключите плату по USB-C, затем выберите правильный порт и запустите демонстрацию. Она должна пройти следующим образом:
На первом экране отображаются данные от IMU. Если помахать устройством, вы увидите, как меняются показания акселерометра и гироскопа.
Следуйте инструкциям и осторожно приложите палец к дисплею и удерживайте несколько секунд — это долгое нажатие для сенсора касания.
Программа переходит к демонстрации распознавания жестов — свайпов. Следуйте инструкциям на экране, проводя пальцем в указанном направлении.
В конце вы попадёте на экран с белым квадратом, разделённым на 4 цветных сегмента. Красный, зелёный и синий сегменты меняют цвет рисования при касании. В белой области можно писать или рисовать. Чёрный сегмент очищает экран.
Нас впечатлила скорость и точность рисования!
Написание собственного кода
Waveshare не предоставляет отдельно именованных библиотек MicroPython, а вместо этого включает драйверы в демонстрационный код (описан выше). Вы можете удалить ненужные разделы и добавить другие по мере необходимости. Код хорошо документирован и имеет несколько комментариев в ключевых местах.
Если вы просмотрите демо-программу, вы найдёте следующие разделы (демо-код может измениться — номера строк актуальны на момент публикации):
1–20 — Импорт библиотек и назначение GPIO-пинов
21–402 — Драйвер дисплея
403–495 — Драйвер сенсора касания
496–569 — Драйвер IMU
570–633 — Процедуры рисования и вывода текста
634–679 — Демо процедура жестов касания
680–716 — Демо IMU
717 — до конца — Основная программа
При написании собственных программ вам потребуются драйверы. Для следующих примеров удалите только основную программу и замените её кодом, который мы предоставляем.
Пример 1: Касание и простая графика
В этой программе пять областей экрана являются сенсорными:
Маленькая «H»: останавливает программу (никогда не запускайте то, что нельзя остановить!)
Кнопки U, D, L и R
Up и Down увеличивают или уменьшают число в центре на 1 — диапазон от 0 до 9
Left и Right меняют цвет числа в центре
Маленькое чёрное число — значение указателя цвета, диапазон от 0 до 8
Скопируйте код в Thonny, попробуйте, а затем читайте дальше о том, как он работает:
# ========== Main starts here ============
# Demonstrates Touch control
# U = increase number, D = decrease
# L & R control foreground colour
# Tony Goodhew 20 July 2023
# Set up LCD display screen and Touch sensor
LCD = LCD_1inch28()
LCD.set_bl_pwm(65535)
Touch=Touch_CST816T(mode=1,LCD=LCD) # Touch ON - mode 1
def colour(R,G,B): # Convert RGB888 to RGB565
return (((G&0b00011100)<<3) +((B&0b11111000)>>3)<<8) + (R&0b11111000)+((G&0b11100000)>>5)
def button(xx,yy,txt,bc,fc): # Square button at (xx, yy) with txt in colour fc and background colour bc
LCD.rect(xx,yy,70,70,bc,True) # Background square
LCD.write_text(txt,xx+8,yy+10,7,fc) # Large character
# Set up colours
w = colour(255,255,255)
r = colour(255,0,0)
g = colour(0,255,0)
b = colour(0,0,255)
y = colour(255,255,0)
c = colour(0,255,255)
m = colour(255,0,255)
g = colour(100,100,100)
o = colour(255,128,30)
colours = [r,y,g,c,b,m,w,o,g] # List of colours, 0 to 8
mode = 1
Touch.Set_Mode(mode)
def draw_buttons(n,cp):
LCD.fill(w)
button(85,10,"U",colour(0,0,255),colour(255,255,0))
button(85,160,"D",colour(0,0,255),colour(255,255,0))
button(10,85,"L",colour(255,0,0),colour(0,255,0))
button(160,85,"R",colour(255,0,0),colour(0,255,0))
button(85,85,str(n),colour(0,0,0),colours[cp])
LCD.write_text(str(cp),165,170,3,0) # Colour pointer
LCD.write_text("H",50,170,3,r) # Colour pointer
LCD.show()
n = 5 # Central number counter
cp = 5 # Colour pointer
draw_buttons(n,cp)
running = True
try:
while running:
if (Touch.X_point > 85 and Touch.X_point < 160) and (Touch.Y_point > 15 and Touch.Y_point < 90): # U touched
Touch.X_point = 0 # Clear Touch
n = n + 1
if n > 9: n = 9
elif (Touch.X_point > 85 and Touch.X_point < 160) and (Touch.Y_point > 160 and Touch.Y_point < 235): # D touched
Touch.X_point = 0 # Clear Touch
n = n - 1
if n < 0: n = 0
elif (Touch.X_point > 208 and Touch.X_point < 240) and (Touch.Y_point > 85 and Touch.Y_point < 160): # R touched
Touch.X_point = 0 # Clear Touch
cp = cp + 1
if cp > 8: cp = 8
elif (Touch.X_point > 0 and Touch.X_point < 160) and (Touch.Y_point > 85 and Touch.Y_point < 160): # L touched
Touch.X_point = 0 # Clear Touch
cp = cp - 1
if cp < 0: cp = 0
elif (Touch.X_point > 0 and Touch.X_point < 80) and (Touch.Y_point > 165 and Touch.Y_point < 240): # H touched = HALT
running = False
break
draw_buttons(n,cp)
# print(Touch.X_point,Touch.Y_point)
Touch.X_point = 0
Touch.Y_point = 0
time.sleep(0.4) # Delay to untouch - Debounce
except KeyboardInterrupt:
pass
# Tidy up after CTRL-C / KeyboardInterrupt
LCD.fill(0)
LCD.show()
Как это работает
Структура кода выглядит следующим образом, по порядку:
Начинаем с инициализации дисплея и сенсоров касания
Определяем процедуру смешения цветов — colour(R, G, B) допускает 65K цветов
Определяем, как рисовать кнопку
Определяем несколько удобных цветов и сохраняем их в список
Устанавливаем режим сенсора касания на касание и позицию, mode = 1
Определяем процедуру для отрисовки всех пяти кнопок на экране
Задаём начальные значения центрального счётчика и указателя цвета
Основной цикл управляется переменной running. Цикл выполняется, пока она равна True, и мы можем остановить его, установив значение False.
В цикле мы проверяем, регистрирует ли сенсор касание в пределах каждой из четырёх внешних кнопок или области HALT. Если кнопка нажата, мы обновляем значения n или cp, либо сбрасываем переменную running, чтобы остановить цикл.
Позиция касания использует те же координаты экрана (x, y).
Touch.X_point — значение x, Touch.Y_point — значение y.
Следующие инструкции очищают текущее указание касания:
Touch.X_point = 0 # Clear Touch
Touch.Y_point = 0 # Clear Touch
В конце цикла мы приводим всё в порядок, очищая экран.
Это работало довольно хорошо, с лишь несколькими случаями «дребезга кнопки», когда числа менялись на два, а не на один.
Пример 2: Жесты и простая графика
Этот пример работает аналогичным образом, но мы используем свайп по экрану, а не касание.
Свайп вверх или вниз меняет центральное число, а свайп влево или вправо меняет центральный цвет. Двойное нажатие или долгое нажатие останавливают программу.
Замените раздел MAIN программы следующим кодом, а затем читайте о том, как он работает:
# ========== Main starts here ============
# Demonstrates Touch control
# U = increase number, D = decrease
# L & R control foreground colour
# Tony Goodhew 20 July 2023
# Set up LCD display screen and Touch sensor
LCD = LCD_1inch28()
LCD.set_bl_pwm(65535)
Touch=Touch_CST816T(mode=0,LCD=LCD) # Touch ON - mode 1
def colour(R,G,B): # Convert RGB888 to RGB565
return (((G&0b00011100)<<3) +((B&0b11111000)>>3)<<8) + (R&0b11111000)+((G&0b11100000)>>5)
def button(xx,yy,txt,bc,fc): # Square button at (xx, yy) with txt in colour fc and background colour bc
LCD.rect(xx,yy,70,70,bc,True) # Background square
LCD.write_text(txt,xx+8,yy+10,7,fc) # Large character
def up():
x = 0
for y in range(10,40):
x = x + 1
LCD.hline(120-x, y,2*x,r)
def down():
x = 0
for y in range(229,199, -1):
x = x + 1
LCD.hline(120-x, y,2*x,r)
# Set up colours
w = colour(255,255,255)
r = colour(255,0,0)
g = colour(0,255,0)
b = colour(0,0,255)
y = colour(255,255,0)
c = colour(0,255,255)
m = colour(255,0,255)
g = colour(100,100,100)
o = colour(255,128,30)
colours = [r,y,g,c,b,m,w,o,g] # List of colours, 0 to 8
mode = 0
Touch.Set_Mode(mode)
def draw_buttons(n,cp):
LCD.fill(0)
up()
down()
button(85,85,str(n),colour(0,0,0),colours[cp])
LCD.write_text(str(cp),180,180,2,0) # Colour pointer
LCD.show()
n = 5 # Central number counter
cp = 5 # Colour pointer
draw_buttons(n,cp)
running = True
try:
while running:
if Touch.Gestures == 0x01: # UP
Touch.Gestures = 0 # Clear the current gesture
n = n + 1
if n > 9: n = 9
elif Touch.Gestures == 0x02: # Down
Touch.Gestures = 0 # Clear the current gesture
n = n - 1
if n < 0: n = 0
elif Touch.Gestures == 0x04: # Right
Touch.Gestures = 0 # Clear the current gesture
cp = cp + 1
if cp > 8: cp = 8
elif Touch.Gestures == 0x03: # Left
Touch.Gestures = 0 # Clear the current gesture
cp = cp - 1
if cp < 0: cp = 0
# Double tap or Long Press to HALT
elif (Touch.Gestures == 0x0C) or (Touch.Gestures == 0x0B):
running = False
break
draw_buttons(n,cp)
time.sleep(0.4) # Delay to untouch - Debounce
except KeyboardInterrupt:
pass
# Tidy up after CTRL-C / KeyboardInterrupt or HALT Gesture
LCD.fill(0)
LCD.show()
Как это работает
Сенсор касания в режиме 0 распознаёт шесть различных жестов:
Свайп ВВЕРХ — 0x01
Свайп ВНИЗ — 0x02
Свайп ВПРАВО — 0x03
Свайп ВЛЕВО — 0x04
Долгое нажатие — 0x0B
Двойное нажатие — 0x0C
Они проверяются с помощью следующего формата инструкции:
if Touch.Gestures == 0x01: # UP
Инструкция Touch.Gestures = 0 используется для ожидания следующего жеста.
Остальная часть программы очень похожа на предыдущую. Верхняя и нижняя кнопки заменены индикативными красными стрелками с помощью инструкции hline(x, y, l, c), которая рисует горизонтальную линию от точки (x, y) длиной l и цветом c.
Стрелки определены в процедурах up() и down().
Метод жестов работал абсолютно надёжно с точным пошаговым изменением как числа, так и цветов. Отлично!
Что ещё можно попробовать
Добавьте синие стрелки, указывающие влево и вправо, используя инструкцию vline(x, y, l, c)
Изучите руководство по графике и попробуйте рисовать наклонные линии, треугольники, сетки, окружности и кольца на вашем дисплее
Пример 3: Бонусный проект — Стимпанк-манометр!
Вот интересный проект для вас! Мы будем использовать дисплей вместе с потенциометром 10 кОм, чтобы создать манометр на экране.
Посмотрите видео ниже, а затем читайте инструкции и код:
Подключите поставляемый кабельный жгут GPIO к разъёму на задней панели платы.
Примечание
Обратите внимание: цвета могут быть в обратном порядке — серый конец может оказаться рядом с кнопкой RESET. Красный и чёрный провода могут быть подключены не к Power и GND!
Изучите схему распиновки в Wiki и подключите потенциометр 10 кОм к плате следующим образом:
GND — к оранжевому
3.3v — к коричневому
Wiper (ползунок) — к зелёному (GPIO 26 = ADC0)
Код довольно длинный, поэтому файл MicroPython доступен для скачивания по ссылке. Удачи!