DIY Графический Планшет на Arduino и TFT Дисплее

15 февраля 2024

Создайте графический планшет на Arduino и TFT-дисплее, передавайте рисунки на компьютер в реальном времени с использованием Python.

Всем привет! Сегодня рассмотрим интересный проект в дополнение к нашей старой статье про TFT дисплей от компании Mcufriend.

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

В прошлой статье мы научились передавать данные с Arduino на компьютер посредством распространённого языка программирования Python. В этот раз сделаем также, задействовав последовательный порт для связи.

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

#include <MCUFRIEND_kbv.h>  // Подключаем официальные библиотеки
#include <TouchScreen.h>
// Константы калибровки
#define XP 7
#define XM A1
#define YP A2
#define YM 6
#define TS_LEFT 896
#define TS_RT 134
#define TS_TOP 952
#define TS_BOT 165
// Объекты
MCUFRIEND_kbv tft;
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
// Используемые цвета, их можно заменить или добавить больше
#define BLACK 0x0000
#define WHITE 0xFFFF
int pixel_x, pixel_y;
void setup() {
  // Запускаем Serial порт на максимальной скорости для уменьшения задержки при рисовании
  Serial.begin(2000000);
  uint16_t ID = tft.readID();
  if (ID == 0xD3D3) ID = 0x9341;
  tft.begin(ID);
  tft.setRotation(1);     // Ориентация экрана
  tft.fillScreen(BLACK);  // Заполняем черным
  Serial.println("C");    // Флаг перезагрузки
}
void loop() {
  if (Touch_getXY()) {
    // Если приходят координаты, выводим их в порт
    Serial.print(pixel_x);
    Serial.print(",");
    Serial.print(pixel_y);
    Serial.println();
    tft.drawPixel(pixel_x, pixel_y, WHITE);  // Ставим пиксель
  }
}
// Функция получения точек касания
bool Touch_getXY(void) {
  TSPoint p = ts.getPoint();
  pinMode(YP, OUTPUT);
  pinMode(XM, OUTPUT);
  digitalWrite(YP, HIGH);
  digitalWrite(XM, HIGH);
  bool pressed = (p.z > 200 && p.z < 1000);  // Сила нажатия
  if (pressed) {
    if (tft.width() <= tft.height()) {
      pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width());
      pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
    } else {
      pixel_x = map(p.y, TS_TOP, TS_BOT, 0, tft.width());
      pixel_y = map(p.x, TS_RT, TS_LEFT, 0, tft.height());
    }
  }
  return pressed;
}

Загружаем код в Arduino, и теперь с помощью стилуса можно рисовать на экране.

К сожалению, дисплей не поддерживает мультитач, поэтому можно использовать только один стилус.

Теперь нужна программа на Python для компьютера, которая будет получать координаты и отображать их.

import pygame
import serial
import sys
serial_port = 'COM4'  # Укажите свой порт
baud_rate = 2000000
# Открываем последовательный порт
ser = serial.Serial(serial_port, baud_rate)
pygame.init()  # Инициализируем pygame
# Размеры экрана и холста
original_width, original_height = 320, 240
scale_factor = 1  # Масштаб
width, height = original_width * scale_factor, original_height * scale_factor
canvas = pygame.Surface((width, height))
# Цвета
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
# Создаем холст
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Canvas')
clock = pygame.time.Clock()
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    # Получаем данные из последовательного порта
    line = ser.readline().decode('utf-8').strip()
    # Если получен флаг перезагрузки, очищаем холст
    if line == 'C':
        canvas.fill(BLACK)
        continue
    try:
        x, y = map(int, line.split(','))
        # Масштабирование координат
        x *= scale_factor
        y *= scale_factor
        pygame.draw.circle(canvas, WHITE, (x, y), 1)  # Рисуем точки на холсте
    except ValueError:
        pass
    screen.fill(BLACK)
    # Масштабирование холста
    scaled_canvas = pygame.transform.scale(canvas, (width, height))
    screen.blit(scaled_canvas, (0, 0))
    pygame.display.flip()
    clock.tick(0)  # Устанавливаем значение 0, чтобы отключить ограничение кадров в секунду

Этот код позволяет получать координаты касаний через последовательный порт и отображать их на холсте с использованием библиотеки Pygame. Если Arduino перезагружается с помощью кнопки на дисплее, очищаем экран, получая флаг 'C'. Если вы столкнетесь с ошибкой при запуске кода на Python, убедитесь, что порт не открыт в Arduino IDE или в другом месте.

- В модуле TFT есть слот для SD-карты, и вы можете сохранять рисунки на карту для последующего просмотра.

- Добавление разноцветной палитры цветов.

- Реализация автоматического обнаружения подключенного Arduino планшета.

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

Спасибо за внимание и удачи в ваших проектах!


Данная статья является собственностью Amperkot.ru. При перепечатке данного материала активная ссылка на первоисточник, не закрытая для индексации поисковыми системами, обязательна.


Поделиться: