0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

480x320タッチディスプレイで各種描画機能を詰め込んだお絵かきソフトを試作

Posted at

 先に「迷路作成」を投稿しましたが、その後 800x480 ディスプレイ パラレル接続での作品を教えていただきました。ありがとうございます。

 今回は、ILI9488 480x320 ディスプレイモジュールのタッチ機能を利用したお絵かきソフトを作ってみたので投稿します。
KIMG0479.JPG
点や線、三角形、楕円(塗りつぶしも)、四角形(塗りつぶしも)までの描画機能を盛り込みました。工夫したポイントは

1.タッチ感度や精度を手懐けられるか
2.3点めまでのタッチ入力を可能にするために loop() を上手に中断させられるか
3.タッチパネルとしての座標と描画の座標が合わず変換が必要

なのですが、うまくできたりできなかったり。次のように loop() を中断させています。

  pressed = false;
  while (!pressed) {
    t_x = 0;
    t_y = 0;
    pressed = tft.getTouch(&t_x, &t_y);
    delay(1);
  }

付属のペンでタッチしますがパネルサイズも小さいですし、タクトスイッチでのチャタリングみたいなのが発生し、loop()が意図しない形で進んでしまうようです。タッチが強すぎるとLoopが進みますし、弱すぎると認識しないし。軽やかなステップを踏むように(笑)タッチ!
 第3点めについては、

tft.setRotation(1)

のとき最も簡単になります。
9488座標.jpg
 TFT_eSPIの設定は先に投稿した「迷路作成」を見て頂くことにして、ここでは新たなタッチ機能部の結線について示します。

ESP32(V_SPI) ILI9488(display) ILI9488(touch panel)
MOSI 23 SDI(MOSI) T_DIN
MISO 19 T_DO
SCK 18 SCK T_CLK
CS 5 CS
4 T_CS
27 DC/RS
32 RESET
3V3 LED
3V3 VCC
GND GND

 以下に Arduino IDE 2.1.0 で確認したコードを示します。

9488_TouchPaint.ino
#include <TFT_eSPI.h>  // Hardware-specific library

TFT_eSPI tft = TFT_eSPI();  // Invoke custom library

char KindLabel[8][12] = { "Clear.Scr", "Free Dot",
                          "Draw Line", "D.Triangl",
                          "D.Ellipse", "F.Ellipse",
                          "D.Rectang", "F_Rectang" };
uint8_t Shape[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
uint16_t Color[8] = { TFT_BLACK, TFT_MAGENTA, TFT_RED, TFT_YELLOW,
                      TFT_GREEN, TFT_BLUE, TFT_CYAN, TFT_WHITE };

void setup() {
  Serial.begin(115200);
  tft.init();  // DisplayとTouchは同じVSPIを使用
               // T_DOのみMISOと接続。SDIはMISOと接続しない。
  tft.setRotation(1);
  InitScreen();
}

void InitScreen() {
  // Clear the screen
  tft.fillScreen(TFT_WHITE);

  for (int x = 0; x < 8; x++) {
    if (x % 2 == 1) {
      tft.fillRect(60 * x, 0, 60, 25, TFT_DARKGREY);
      tft.setTextColor(TFT_WHITE);
    } else {
      tft.fillRect(60 * x, 0, 60, 25, 0xF777);  // Light Grey
      tft.setTextColor(TFT_BLACK);
    }
    tft.drawRect(60 * x, 0, 60, 25, TFT_WHITE);
    tft.drawString(KindLabel[x], 60 * x + 2, 4, 2);
    tft.fillRect(60 * x, 25, 60, 25, Color[x]);
  }

  tft.setTextColor(TFT_WHITE);
  tft.drawString("Black", 12, 29, 2);

  tft.drawRect(420, 25, 60, 25, TFT_BLACK);
  tft.setTextColor(TFT_BLACK);
  tft.drawString("White", 432, 29, 2);
}

int pCol;
int shapeK;
uint16_t t_x;  // To store the touch coordinates
uint16_t t_y;
bool pressed;

uint16_t x2;
uint16_t y2;
bool pressed2;

uint16_t x3;
uint16_t y3;
bool pressed3;

void loop(void) {
  // Pressed will be set true as there is a valid touch on the screen
  pressed = false;
  while (!pressed) {
    t_x = 0;
    t_y = 0; // 後から y1 に変更しようとしたらエラーになったのでこのまま
    pressed = tft.getTouch(&t_x, &t_y);
    delay(1);
  }
  delay(10);
  Serial.printf("First Point\r\n");

  if (t_y >= 319 - 25) {  // shape choose & clear screen
    shapeK = t_x / 60;    // shape kind
    if (shapeK == 0) InitScreen();
  }

  if (t_y < 319 - 25 && t_y >= 319 - 25 * 2) {  // color choose
    pCol = Color[t_x / 60];
  }

  if (t_y < 319 - 25 * 2 - 5) {
    if (shapeK == 1) {
      tft.fillEllipse(t_x, 319 - t_y, 3, 3, pCol);
    } else {
      tft.fillEllipse(t_x, 319 - t_y, 2, 2, pCol);

      x2 = 0;
      y2 = 319;
      pressed2 = false;
      while (!pressed2 && y2 > 319 - 25 * 2 - 5) {
        pressed2 = tft.getTouch(&x2, &y2);
        delay(1);
      }
      delay(10);
      Serial.printf("  Second Point\r\n");
      if (y2 < 319 - 25 * 2 - 5) {
        switch (shapeK) {
          case 2:
            tft.drawLine(t_x, 319 - t_y, x2, 319 - y2, pCol);
            break;
          case 3:
            x3 = 0;
            y3 = 319;
            pressed3 = false;
            while (!pressed3 && y3 > 319 - 25 * 2 - 5) {
              pressed3 = tft.getTouch(&x3, &y3);
              delay(1);
            }
            delay(10);
            Serial.printf("    Third Point\r\n");

            tft.drawTriangle(t_x, 319 - t_y, x2, 319 - y2, x3, 319 - y3, pCol);
            break;
          case 4:
            tft.drawEllipse(t_x, 319 - t_y, abs(x2 - t_x), abs(y2 - t_y), pCol);
            break;
          case 5:
            tft.fillEllipse(t_x, 319 - t_y, abs(x2 - t_x), abs(y2 - t_y), pCol);
            break;
          case 6:
            tft.drawRect(min(t_x, x2), min(319 - t_y, 319 - y2), abs(x2 - t_x), abs(y2 - t_y), pCol);
            break;
          case 7:
            tft.fillRect(min(t_x, x2), min(319 - t_y, 319 - y2), abs(x2 - t_x), abs(y2 - t_y), pCol);
            break;
          default:
            break;
        }
      }
    }
  }
}

 何かお気づきの点がございましたらお教えください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?