고급 예제

다양한 도구들을 가지고 마음껏 응용해보세요.

2.8'' Touch LCD Shield

2014-10-02 15:13:17

그림판을 만들어 봅시다,

이 글을 읽기 전에 2.8'' Touch LCD Shield를 사용해 봅시다.(1)을 읽고 오시기 바랍니다.

이 컨텐츠에서는 이전 컨텐츠(2.8'' Touch LCD Shield를 사용해 봅시다.(1))를 읽었다고 가정하고 작성했습니다.



2.8'' Touch LCD Shield를 이용해서 6가지 색상으로 그림을 그릴수 있는 그림판을 만들어 봅시다.

미리보기 동영상

소프트웨어 코드

* 이 소스는 스케치를 이용하여 작성 / 업로드 합니다. 스케치에 대한 사용법은 링크를 참고하시기 바랍니다.

 

/***************************************************
  This is our touchscreen painting example for the Adafruit ILI9341 Shield
  ----> http://www.adafruit.com/products/1651

  Check out the links above for our tutorials and wiring diagrams
  These displays use SPI to communicate, 4 or 5 pins are required to
  interface (RST is optional)
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
 ****************************************************/


#include <Adafruit_GFX.h>    // Core graphics library
#include <SPI.h>
#include <Wire.h>      // this is needed even tho we aren't using it
#include <Adafruit_ILI9341.h>
#include <Adafruit_STMPE610.h>

// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

// The STMPE610 uses hardware SPI on the shield, and #8
#define STMPE_CS 8
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);

// The display also uses hardware SPI, plus #9 & #10
#define TFT_CS 10
#define TFT_DC 9
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// Size of the color selection boxes and the paintbrush size
#define BOXSIZE 40
#define PENRADIUS 3
int oldcolor, currentcolor;

void setup(void) {
 // while (!Serial);     // used for leonardo debugging
 
  Serial.begin(9600);
  Serial.println(F("Touch Paint!"));
  
  tft.begin();

  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("Touchscreen started");
  
  tft.fillScreen(ILI9341_BLACK);
  
  // make the color selection boxes
  // 색깔 박스를 화면에 그려줍니다.
  tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
  tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
  tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
  tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
  tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
  tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
 
  // select the current color 'red'
  tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
  currentcolor = ILI9341_RED;  // 처음 기본 색깔은 빨간색으로 합니다.
}


void loop()
{
  // See if there's any  touch data for us
  if (ts.bufferEmpty()) {
    return;
  }
  /*
  // You can also wait for a touch
  if (! ts.touched()) {
    return;
  }
  */

  // Retrieve a point  
  TS_Point p = ts.getPoint();  // 터치한곳의 좌표를 받아옵니다.
  
 /*
  Serial.print("X = "); Serial.print(p.x);
  Serial.print("\tY = "); Serial.print(p.y);
  Serial.print("\tPressure = "); Serial.println(p.z);  
 */
 
  // Scale from ~0->4000 to tft.width using the calibration #'s
  p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
  p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
  // 터치한 곳의 x좌표와, y좌표를 touch LCD 화면 크기에 맞게 재분배 해줍니다.

  /*
  Serial.print("("); Serial.print(p.x);
  Serial.print(", "); Serial.print(p.y);
  Serial.println(")");
  */

  if (p.y < BOXSIZE) {  // 터치한 곳의 좌표가 색깔 선택하는 박스 안이면 터치한 위치의 색깔에 맞게 붓의 색깔을 바꿔줍니다.
                        // y좌표값을 통해 선택한 좌표가 색깔 박스 안에 있는지 확인을 하고,
                        // x좌표값을 이용해 어떤 색을 선택햇는지 확인합니다.
     oldcolor = currentcolor;

     if (p.x < BOXSIZE) { 
       currentcolor = ILI9341_RED; 
       tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*2) {
       currentcolor = ILI9341_YELLOW;
       tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*3) {
       currentcolor = ILI9341_GREEN;
       tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*4) {
       currentcolor = ILI9341_CYAN;
       tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*5) {
       currentcolor = ILI9341_BLUE;
       tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*6) {
       currentcolor = ILI9341_MAGENTA;
       tft.drawRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     }

     if (oldcolor != currentcolor) { // 전에 골랐던 색과 현재 선택한 색이 달랐을 경우 붓의 색깔을 바꿔줍니다.
        if (oldcolor == ILI9341_RED) 
          tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
        if (oldcolor == ILI9341_YELLOW) 
          tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
        if (oldcolor == ILI9341_GREEN) 
          tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
        if (oldcolor == ILI9341_CYAN) 
          tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
        if (oldcolor == ILI9341_BLUE) 
          tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
        if (oldcolor == ILI9341_MAGENTA) 
          tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
     }
  }
  if (((p.y-PENRADIUS) > BOXSIZE) && ((p.y+PENRADIUS) < tft.height())) { // 빈공간에 터치했을 경우 해당 좌표에 작은 원을 그려줍니다.
    tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
  }
}

// 출처 : adafruit_ILI9341 예제 - touchpaint

 

 

소프트웨어 설명

 

void setup(void) {
 // while (!Serial);     // used for leonardo debugging
 
  Serial.begin(9600);
  Serial.println(F("Touch Paint!"));
  
  tft.begin();

  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("Touchscreen started");
  
  tft.fillScreen(ILI9341_BLACK);
  
  // make the color selection boxes
  // 색깔 박스를 화면에 그려줍니다.
  tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
  tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
  tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
  tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
  tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
  tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
 
  // select the current color 'red'
  tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
  currentcolor = ILI9341_RED;  // 처음 기본 색깔은 빨간색으로 합니다.
}

처음 시작 화면을 세팅해 주는 부분입니다. LCD화면을 검은색으로 채우고, 그위에 넓이 40, 높이 40의 색깔 박스를 6개 그려 줍니다.
(각 박스의 x좌표값을 박스 크기만큼 늘려주어 가로 일렬로 나열합니다.)

그 후 기본 색깔을 빨간색으로 선택해 줍니다.
 

  TS_Point p = ts.getPoint();  // 터치한곳의 좌표를 받아옵니다.
  
  p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
  p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
  // 터치한 곳의 x좌표와, y좌표를 touch LCD 화면 크기에 맞게 재분배 해줍니다.

터치된 곳의 좌표값을 받아오는 부분입니다. p에 터치된 x,y좌표값이 다 들어가며, p.x p.y로 x좌표 y좌표 값을 알수 있습니다.

이렇게 받아온 좌표값을 LCD화면 크기에 맞게 map()을 이용해서 재분배 해주셔서 사용하면 됩니다.
 

if (p.y < BOXSIZE) {  // 터치한 곳의 좌표가 색깔 선택하는 박스 안이면 터치한 위치의 색깔에 맞게 붓의 색깔을 바꿔줍니다.
                        // y좌표값을 통해 선택한 좌표가 색깔 박스 안에 있는지 확인을 하고,
                        // x좌표값을 이용해 어떤 색을 선택햇는지 확인합니다.
     oldcolor = currentcolor;

     if (p.x < BOXSIZE) { 
       currentcolor = ILI9341_RED; 
       tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*2) {
       currentcolor = ILI9341_YELLOW;
       tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*3) {
       currentcolor = ILI9341_GREEN;
       tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*4) {
       currentcolor = ILI9341_CYAN;
       tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*5) {
       currentcolor = ILI9341_BLUE;
       tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*6) {
       currentcolor = ILI9341_MAGENTA;
       tft.drawRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     }

     if (oldcolor != currentcolor) { // 전에 골랐던 색과 현재 선택한 색이 달랐을 경우 붓의 색깔을 바꿔줍니다.
        if (oldcolor == ILI9341_RED) 
          tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
        if (oldcolor == ILI9341_YELLOW) 
          tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
        if (oldcolor == ILI9341_GREEN) 
          tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
        if (oldcolor == ILI9341_CYAN) 
          tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
        if (oldcolor == ILI9341_BLUE) 
          tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
        if (oldcolor == ILI9341_MAGENTA) 
          tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
     }
  }
  if (((p.y-PENRADIUS) > BOXSIZE) && ((p.y+PENRADIUS) < tft.height())) { // 빈공간에 터치했을 경우 해당 좌표에 작은 원을 그려줍니다.
    tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
  }


터치한 좌표를 이용해서 색깔 박스안의 색깔과 캔버스를 구별합니다.

우선 y좌표 값을 이용하여 터치한 좌표의 값이 색깔 박스인지 캔버스 인지 구별을 합니다.


선택한 곳이 색깔 박스일 경우 x좌표값에 따라 색깔을 정해 줍니다.

이렇게 선택된 색깔과 이전의 선택된 색깔을 비교하여 바꼇을 경우 선택된 색깔을 붓의 색깔로 정해줍니다.
(바뀌지 않았으면 그대로 사용합니다.)

선택한 곳이 캔버스일 경우 현재 선택된 색깔에 맞는 점을 그립니다.

터치로 그림을 바꿔봅시다.




이번엔 SD카드에 여러 bmp파일을 저장해 두고, 터치된 위치에 따라 그림 앞, 뒤로 바꿔봅시다.

 

 

미리 보기 동영상


 

 

 

소프트웨어 코드

* 이 소스는 스케치를 이용하여 작성 / 업로드 합니다. 스케치에 대한 사용법은 링크를 참고하시기 바랍니다.

 

/***************************************************
 This is our Bitmap drawing example for the Adafruit ILI9341 Breakout and Shield
 ----> http://www.adafruit.com/products/1651
 
 Check out the links above for our tutorials and wiring diagrams
 These displays use SPI to communicate, 4 or 5 pins are required to
 interface (RST is optional)
 Adafruit invests time and resources providing this open source code,
 please support Adafruit and open-source hardware by purchasing
 products from Adafruit!
 
 Written by Limor Fried/Ladyada for Adafruit Industries.
 MIT license, all text above must be included in any redistribution
 ****************************************************/


#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ILI9341.h> // Hardware-specific library
#include <Adafruit_STMPE610.h>
#include <SPI.h>
#include <SD.h>
#include <Wire.h> 

// TFT display and SD card will share the hardware SPI interface.
// Hardware SPI pins are specific to the Arduino board type and
// cannot be remapped to alternate pins.  For Arduino Uno,
// Duemilanove, etc., pin 11 = MOSI, pin 12 = MISO, pin 13 = SCK.

#define TFT_DC 9
#define TFT_CS 10
#define STMPE_CS 8

#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);

TS_Point p;
int i = 1;
boolean pageState = 0;

#define SD_CS 4

void setup(void) {
  Serial.begin(9600);

  tft.begin();
  tft.fillScreen(ILI9341_BLUE);
  ts.begin();

  Serial.print("Initializing SD card...");
  if (!SD.begin(SD_CS)) {
    Serial.println("failed!");
  }
  Serial.println("OK!");

  drawPicture(i); // 시작화면은 temp1.bmp파일을 열어줍니다.
}

void loop() {
  if (ts.bufferEmpty()) {  // 터치를 하고 손을 들면 그때 그림을 이동한다.
    if(pageState == 1){
      pageMove(p);
      pageState = 0;
    }
    return;
  }
  
  // 터치된곳의 좌표값을 받아온다.
  p = ts.getPoint();

  // 받아온 좌표값을 LCD 화면의 크기에 맞게 재분배 해준다.
  p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
  p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());

  if(ts.touched()){  // 터치된 좌표의 정확성을 높이기 위해 상태값을 주어 터치되었을 때의 좌표값을 받아 온다.
    pageState = 1;
  }

  Serial.print("("); 
  Serial.print(p.x);
  Serial.print(", "); 
  Serial.print(p.y);
  Serial.println(")");
}

void drawPicture(int num) { // LCD화면에 그릴 비트맵 파일을 선택하여 출력하는 함수
  String temp = String(i);
  temp = "temp" + temp + ".bmp";

  char *fname = new char[temp.length() + 1];
  strcpy(fname, temp.c_str());
  bmpDraw(fname, 0, 0);
  delete [] fname;
}

void pageMove(TS_Point t){ // 터치된 좌표의 x값에 따라 앞, 뒤의 사진으로 이동하는 함수
  if(t.x > 120){ // 터치된 좌표의 x값이 120보다 클 경우 앞의 사진으로 이동
      if(i != 4)
        i++;
      else           // temp4.bmp파일일 경우 temp1.bmp파일로 이동합니다.
        i = 1;
          
      drawPicture(i);
    }
    else{ // 120보다 작을 경우 뒤의 사진으로 이동
      if(i != 1)
        i--;
      else           // temp1.bmp파일일 경우 temp4.bmp파일로 이동합니다.
        i = 4;
          
      drawPicture(i);
    }
}

// This function opens a Windows Bitmap (BMP) file and
// displays it at the given coordinates.  It's sped up
// by reading many pixels worth of data at a time
// (rather than pixel by pixel).  Increasing the buffer
// size takes more of the Arduino's precious RAM but
// makes loading a little faster.  20 pixels seems a
// good balance.

#define BUFFPIXEL 20

void bmpDraw(char *filename, uint8_t x, uint16_t y) { // 비트맵 파일을 LCD화면에 그리는 함수

  File     bmpFile;
  int      bmpWidth, bmpHeight;   // W+H in pixels
  uint8_t  bmpDepth;              // Bit depth (currently must be 24)
  uint32_t bmpImageoffset;        // Start of image data in file
  uint32_t rowSize;               // Not always = bmpWidth; may have padding
  uint8_t  sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
  uint8_t  buffidx = sizeof(sdbuffer); // Current position in sdbuffer
  boolean  goodBmp = false;       // Set to true on valid header parse
  boolean  flip    = true;        // BMP is stored bottom-to-top
  int      w, h, row, col;
  uint8_t  r, g, b;
  uint32_t pos = 0, startTime = millis();

  if ((x >= tft.width()) || (y >= tft.height())) return;

  Serial.println();
  Serial.print(F("Loading image '"));
  Serial.print(filename);
  Serial.println('\'');

  // Open requested file on SD card
  if ((bmpFile = SD.open(filename)) == NULL) {
    Serial.print(F("File not found"));
    return;
  }

  // Parse BMP header
  if (read16(bmpFile) == 0x4D42) { // BMP signature
    Serial.print(F("File size: ")); 
    Serial.println(read32(bmpFile));
    (void)read32(bmpFile); // Read & ignore creator bytes
    bmpImageoffset = read32(bmpFile); // Start of image data
    Serial.print(F("Image Offset: ")); 
    Serial.println(bmpImageoffset, DEC);
    // Read DIB header
    Serial.print(F("Header size: ")); 
    Serial.println(read32(bmpFile));
    bmpWidth  = read32(bmpFile);
    bmpHeight = read32(bmpFile);
    if (read16(bmpFile) == 1) { // # planes -- must be '1'
      bmpDepth = read16(bmpFile); // bits per pixel
      Serial.print(F("Bit Depth: ")); 
      Serial.println(bmpDepth);
      if ((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed

        goodBmp = true; // Supported BMP format -- proceed!
        Serial.print(F("Image size: "));
        Serial.print(bmpWidth);
        Serial.print('x');
        Serial.println(bmpHeight);

        // BMP rows are padded (if needed) to 4-byte boundary
        rowSize = (bmpWidth * 3 + 3) & ~3;

        // If bmpHeight is negative, image is in top-down order.
        // This is not canon but has been observed in the wild.
        if (bmpHeight < 0) {
          bmpHeight = -bmpHeight;
          flip      = false;
        }

        // Crop area to be loaded
        w = bmpWidth;
        h = bmpHeight;
        if ((x+w-1) >= tft.width())  w = tft.width()  - x;
        if ((y+h-1) >= tft.height()) h = tft.height() - y;

        // Set TFT address window to clipped image bounds
        tft.setAddrWindow(x, y, x+w-1, y+h-1);

        for (row=0; row<h; row++) { // For each scanline...

          // Seek to start of scan line.  It might seem labor-
          // intensive to be doing this on every line, but this
          // method covers a lot of gritty details like cropping
          // and scanline padding.  Also, the seek only takes
          // place if the file position actually needs to change
          // (avoids a lot of cluster math in SD library).
          if (flip) // Bitmap is stored bottom-to-top order (normal BMP)
            pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
          else     // Bitmap is stored top-to-bottom
          pos = bmpImageoffset + row * rowSize;
          if (bmpFile.position() != pos) { // Need seek?
            bmpFile.seek(pos);
            buffidx = sizeof(sdbuffer); // Force buffer reload
          }

          for (col=0; col<w; col++) { // For each pixel...
            // Time to read more pixel data?
            if (buffidx >= sizeof(sdbuffer)) { // Indeed
              bmpFile.read(sdbuffer, sizeof(sdbuffer));
              buffidx = 0; // Set index to beginning
            }

            // Convert pixel from BMP to TFT format, push to display
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            tft.pushColor(tft.color565(r, g, b));
          } // end pixel
        } // end scanline
        Serial.print(F("Loaded in "));
        Serial.print(millis() - startTime);
        Serial.println(" ms");
      } // end goodBmp
    }
  }

  bmpFile.close();
  if (!goodBmp) Serial.println(F("BMP format not recognized."));
}

// These read 16- and 32-bit types from the SD card file.
// BMP data is stored little-endian, Arduino is little-endian too.
// May need to reverse subscript order if porting elsewhere.

uint16_t read16(File &f) {
  uint16_t result;
  ((uint8_t *)&result)[0] = f.read(); // LSB
  ((uint8_t *)&result)[1] = f.read(); // MSB
  return result;
}

uint32_t read32(File &f) {
  uint32_t result;
  ((uint8_t *)&result)[0] = f.read(); // LSB
  ((uint8_t *)&result)[1] = f.read();
  ((uint8_t *)&result)[2] = f.read();
  ((uint8_t *)&result)[3] = f.read(); // MSB
  return result;
}
// 출처 : adafruit_ILI9341 spitftbitmap, touchpaint 두 소스를 참고하여 kocoaFab에서 만들었습니다.

 

 

소프트웨어 설명



이 소스에서는 위의 4가지 그림을 순서대로 사용했습니다.(파일명 temp1~4.bmp, 순서대로 소닉 -> 앵그리버드 -> 스펀지밥 -> 캡틴 아메리카)

 

 

 

  // 터치된곳의 좌표값을 받아온다.
  p = ts.getPoint();

  // 받아온 좌표값을 LCD 화면의 크기에 맞게 재분배 해준다.
  p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
  p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());

터치된 곳의 좌표값을 받아오는 부분입니다. p에 터치된 x,y좌표값이 다 들어가며, p.x p.y로 x좌표 y좌표 값을 알수 있습니다.

이렇게 받아온 좌표값을 LCD화면 크기에 맞게 map()을 이용해서 재분배 해주셔서 사용하면 됩니다.

 

 

 

 

void drawPicture(int num) { // LCD화면에 그릴 비트맵 파일을 선택하여 출력하는 함수
  String temp = String(i);
  temp = "temp" + temp + ".bmp";

  char *fname = new char[temp.length() + 1];
  strcpy(fname, temp.c_str());
  bmpDraw(fname, 0, 0);
  delete [] fname;
}

위의 소스에 이용된 bmp파일은 temp1~4.bmp 입니다. 그림을 이동할 때 기준을 파일명의 숫자로 정해서 이동하기 때문에 파일명 끝을 숫자로 합니다.(순서대로)

다른 파일 명을 쓰실거면 temp = "temp" + temp + ".bmp"; 부분에서 "temp" 에서 쌍따옴표 안의 문자를 수정하시면 됩니다.
(SD카드 안에 있는 bmp파일명과 같아야 합니다.)

drawPicture()함수는 LCD에 그릴 bmp파일을 선택하여 출력하는 함수 입니다. SD카드에 temp1~4.bmp 파일로 저장해 놓고, drawPicture(int) 함수에 int값에 따라(1~4) 해당 그림을 선택하여 파일명을 bmpDraw()함수로 보내줍니다.

입력 받은 인트 값을 스트링으로 바꿔서 temp.bmp 와 합쳐서 그림파일 명을 정하고, 이것을 char* 형태로 바꿔서 bmpDraw()함수로 보내줍니다.
(String을 char*로 변환해주는 방법은 링크에서 참고했습니다.)

 

 

 

 

void pageMove(TS_Point t){ // 터치된 좌표의 x값에 따라 앞, 뒤의 사진으로 이동하는 함수
  if(t.x > 120){ // 터치된 좌표의 x값이 120보다 클 경우 앞의 사진으로 이동
      if(i != 4) 
        i++;
      else           // temp4.bmp파일일 경우 temp1.bmp파일로 이동합니다.
        i = 1;
          
      drawPicture(i);
    }
    else{ // 120보다 작을 경우 뒤의 사진으로 이동
      if(i != 1)
        i--;
      else           // temp1.bmp파일일 경우 temp4.bmp파일로 이동합니다.
        i = 4;
          
      drawPicture(i);
    }
}

터치된 좌표값의 x좌표값에 따라 그림을 앞, 뒤로 이동시킬지 정하는 함수 입니다. 

가로 길이가 240이므로 120을 기준으로 잡고, 터치된 좌표값이 120이 넘었을 경우 앞의 그림으로, 120보다 작을 경우 뒤의 그림으로 이동시키는 함수입니다.

LCD에 출력할 그림은 파일명에 숫자로 구분 하기 때문에 앞에 그림으로 이동하고 싶으면 숫자를 1 증가 시켜주고(temp4.bmp일경우는 temp1.bmp로 이동), 뒤의 그림으로 이동하고 싶으면 숫자를 1 감소 시켜줍니다.(temp1.bmp일 경우 temp4.bmp로 이동)
 

 

 

kocoafabeditor

항상 진취적이고, 새로운 것을 추구하는 코코아팹 에디터입니다!

Touch LCD, 기타

박종훈 2019-05-19 17:24:47

위에 touchpaint를 하고 있는데 잘 안됩니다.. 컴파일 에러는 안뜨고, 잘 되는데
시리얼 모니터를 보니
Touch Paint!
Couldn't start touchscreen controller
이란 문구만 뜨고 하얀 화면이 계속 나오네요.. 왜 그런 걸까요