산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

아두이노 2.4″ TFT LCD 실드에 SD카드 BMP 이미지 표시하기

부품 및 소모품

아두이노 UNO 1

프로젝트 소개

이 튜토리얼은 아두이노 UNO용 2.4″ TFT LCD 실드 시리즈의 세 번째 편입니다. 앞선 두 편에서는 터치 기능 수정, 축 반전 문제 해결, 도형 그리기 및 터치 버튼 만들기를 다뤘습니다. 이번에는 SD카드에서 BMP 이미지를 읽어 화면에 표시하는 방법을 설명합니다.

사전 준비

  1. SD카드를 컴퓨터에 연결해 FAT32로 포맷
  2. 이미지는 24비트 BMP(Bitmap) 형식이어야 함
  3. 해상도는 화면 회전 설정에 맞춰 준비:
    • setRotation(0) (기본): 240×320 픽셀
    • setRotation(1) (90도 회전): 320×240 픽셀
  4. 이미지 파일명을 기억해 두세요(예: Img1.bmp)
아두이노 2.4″ TFT LCD 실드에 SD카드 BMP 이미지 표시하기
setRotation(0) - 240×320
아두이노 2.4″ TFT LCD 실드에 SD카드 BMP 이미지 표시하기
setRotation(1) - 320×240
아두이노 2.4″ TFT LCD 실드에 SD카드 BMP 이미지 표시하기
SD카드 내 BMP 파일명 예시

라이브러리

제가 사용해 성공한 라이브러리: SPFD5408_Adafruit_GFX / SPFD5408_Adafruit_TFTLCD / SPFD5408_TouchScreen
예제 코드 실행 시 흰 화면만 나온다면, 본인의 실드에 맞는 라이브러리를 찾아야 합니다.

소스 코드

두 가지 예제 코드를 제공합니다. 사용 중인 이미지 파일명으로 수정해 업로드하세요.

예제 1: 이미지 슬라이드쇼 (자동 전환)

/* 2.4" TFT LCD 터치 실드용 - SD카드 BMP 이미지 읽어 표시
 * SurtrTech.com 참고 */
#include <SPFD5408_Adafruit_GFX.h>
#include <SPFD5408_Adafruit_TFTLCD.h>
#include <SPI.h>
#include <SD.h>

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define SD_CS 10

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, A4);

void setup() {
  Serial.begin(9600);
  tft.reset();
  uint16_t identifier = tft.readID();
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  tft.begin(identifier);
  if (!SD.begin(SD_CS)) {
    progmemPrintln(PSTR("failed!"));
    return;
  }
}

void loop() {
  bmpDraw("Logo.bmp", 0, 0);
  delay(2000);
  bmpDraw("Img2.bmp", 0, 0);
  delay(2000);
  bmpDraw("Img3.bmp", 0, 0);
  delay(2000);
}

#define BUFFPIXEL 20

void bmpDraw(char *filename, int x, int y) {
  File bmpFile;
  int bmpWidth, bmpHeight;
  uint8_t bmpDepth;
  uint32_t bmpImageoffset;
  uint32_t rowSize;
  uint8_t sdbuffer[3*BUFFPIXEL];
  uint16_t lcdbuffer[BUFFPIXEL];
  uint8_t buffidx = sizeof(sdbuffer);
  boolean goodBmp = false;
  boolean flip = true;
  int w, h, row, col;
  uint8_t r, g, b;
  uint32_t pos = 0, startTime = millis();
  uint8_t lcdidx = 0;
  boolean first = true;

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

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

  if ((bmpFile = SD.open(filename)) == NULL) {
    progmemPrintln(PSTR("File not found"));
    return;
  }

  if(read16(bmpFile) == 0x4D42) { // BMP 시그니처
    progmemPrint(PSTR("File size: ")); Serial.println(read32(bmpFile));
    (void)read32(bmpFile);
    bmpImageoffset = read32(bmpFile);
    progmemPrint(PSTR("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
    progmemPrint(PSTR("Header size: ")); Serial.println(read32(bmpFile));
    bmpWidth = read32(bmpFile);
    bmpHeight = read32(bmpFile);
    if(read16(bmpFile) == 1) {
      bmpDepth = read16(bmpFile);
      progmemPrint(PSTR("Bit Depth: ")); Serial.println(bmpDepth);
      if((bmpDepth == 24) && (read32(bmpFile) == 0)) {
        goodBmp = true;
        progmemPrint(PSTR("Image size: "));
        Serial.print(bmpWidth); Serial.print('x'); Serial.println(bmpHeight);
        rowSize = (bmpWidth * 3 + 3) & ~3;
        if(bmpHeight < 0) { bmpHeight = -bmpHeight; flip = false; }
        w = bmpWidth; h = bmpHeight;
        if((x+w-1) >= tft.width()) w = tft.width() - x;
        if((y+h-1) >= tft.height()) h = tft.height() - y;
        tft.setAddrWindow(x, y, x+w-1, y+h-1);
        for (row=0; row<h; row++) {
          if(flip) pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
          else pos = bmpImageoffset + row * rowSize;
          if(bmpFile.position() != pos) {
            bmpFile.seek(pos);
            buffidx = sizeof(sdbuffer);
          }
          for (col=0; col<w; col++) {
            if (buffidx >= sizeof(sdbuffer)) {
              if(lcdidx > 0) {
                tft.pushColors(lcdbuffer, lcdidx, first);
                lcdidx = 0; first = false;
              }
              bmpFile.read(sdbuffer, sizeof(sdbuffer));
              buffidx = 0;
            }
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            lcdbuffer[lcdidx++] = tft.color565(r,g,b);
          }
        }
        if(lcdidx > 0) tft.pushColors(lcdbuffer, lcdidx, first);
        progmemPrint(PSTR("Loaded in "));
        Serial.print(millis() - startTime);
        Serial.println(" ms");
      }
    }
  }
  bmpFile.close();
  if(!goodBmp) progmemPrintln(PSTR("BMP format not recognized."));
}

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

uint32_t read32(File f) {
  uint32_t result;
  ((uint8_t *)&result)[0] = f.read();
  ((uint8_t *)&result)[1] = f.read();
  ((uint8_t *)&result)[2] = f.read();
  ((uint8_t *)&result)[3] = f.read();
  return result;
}

void progmemPrint(const char *str) {
  char c;
  while(c = pgm_read_byte(str++)) Serial.print(c);
}

void progmemPrintln(const char *str) {
  progmemPrint(str); Serial.println();
}

예제 2: 터치로 이미지 넘기기 (슬라이드쇼 제어)

/* 2.4" TFT LCD 터치 실드 + UNO - 터치로 이미지 전환
 * SurtrTech.com 참고 */
#include <SPFD5408_Adafruit_GFX.h>
#include <SPFD5408_Adafruit_TFTLCD.h>
#include <SPI.h>
#include <SD.h>
#include <SPFD5408_TouchScreen.h>

#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif

#define YP A3
#define XM A2
#define YM 9
#define XP 8
#define TS_MINX 176
#define TS_MINY 159
#define TS_MAXX 921
#define TS_MAXY 884
#define MINPRESSURE 10
#define MAXPRESSURE 1000

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define SD_CS 10

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, A4);
char x[] = "x1.bmp";  // 파일명 배열로 관리 (숫자 부분만 변경)

void setup() {
  Serial.begin(9600);
  tft.reset();
  uint16_t identifier = tft.readID();
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  tft.begin(identifier);
  if (!SD.begin(SD_CS)) {
    progmemPrintln(PSTR("failed!"));
    return;
  }
  tft.setRotation(1);
  bmpDraw(x, 0, 0);
}

void loop() {
  if(x[1] < 49) x[1] = 49;
  if(x[1] > 52) x[1] = 52;

  TSPoint p = ts.getPoint();
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);

  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    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(p.y > 0 && p.y < 100) {  // 좌측 영역 터치 → 이전 이미지
      Serial.println("Left");
      x[1] = x[1] - 1;
      bmpDraw(x, 0, 0);
      delay(300);
    } else if(p.y > 200 && p.y < 320) {  // 우측 영역 터치 → 다음 이미지
      Serial.println("Right");
      x[1] = x[1] + 1;
      bmpDraw(x, 0, 0);
      delay(300);
    }
  }
}

// bmpDraw 함수는 예제 1과 동일 (생략)

회로도

실드 형태라 별도 배선도가 필요 없습니다. 실드 사진 참조.

아두이노 2.4″ TFT LCD 실드에 SD카드 BMP 이미지 표시하기

제조공정

  1. 그리팅 카드 산업: 역사, 생산, 미래 트렌드
  2. 신용카드: 역사, 설계, 제조, 미래 트렌드
  3. 액정 표시장치(LCD): 기술, 제조 및 미래 전망
  4. 데이터 모듈, 스마트 와이파이 제어 탑재 23.1인치 울트라 슬림 TFT 디스플레이 출시
  5. Distec, Ortustech 7인치 트랜스플렉티브 TFT 디스플레이 출시: 견고함, 햇빛 가독성, 저전력
  6. Nuvo-7160GC: 6 TFLOPS, 120W GPU 지원, 4K 출력의 러기드 GPU-PC로 머신 비전, VR, 자동화 구현
  7. Primal Display: 라즈베리 파이 LCD 온도 모니터 만들기
  8. RetroPie에 Kuman 3.5″ TFT 디스플레이 설치하기 - 단계별 가이드
  9. 텍스트 레시피에서 실사 음식 이미지 생성하는 AI 개발
  10. DIY Arduino LCD 프로젝트: 저항, 푸시버튼, 16x2 디스플레이로 축구 게임 만들기