Как использовать круглый сенсорный дисплей Waveshare RP2040 1.28»

Круглый сенсорный дисплей 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 мм)

Задняя сторона Waveshare RP2040 Round Display

Настройка платы

Если вы подключите кабель 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 доступен для скачивания по ссылке. Удачи!