아두이노 나노로 2.8" TFT SPI 디스플레이에 JPEG 사진·RGB565 동영상 재생하기
부품 및 소모품
| 아두이노 나노 R3 |
1개 |
| 2.8" 320x240 SPI TFT 디스플레이 (터치스크린 내장) |
1개 |
| 마이크로 SD카드 (1GB 이상, FAT32 포맷) |
1개 |
| 아두이노 나노용 TFT 쉴드 (브레이크아웃 보드) |
1개 |
프로젝트 개요
아두이노 나노와 2.8" TFT SPI 디스플레이로 JPEG 이미지와 RGB565 포맷 동영상을 재생하는 미니 미디어 플레이어를 만듭니다. 터치스크린으로 재생/일시정지/정지 제어 가능.
하드웨어 구성
아두이노 나노 + TFT 쉴드 + 디스플레이를 결합하고 SD카드를 장착합니다. 이전 글 TFT 쉴드 제작기를 참고하세요.
소프트웨어 준비
SD카드 준비
- FAT32 포맷 필수
- JPEG 이미지: 최대 2560x1920 해상도 권장, 별도 변환 불필요
- 동영상: ffmpeg로 RGB565 포맷 변환 필요
동영상 변환 명령어 (ffmpeg)
ffmpeg -i input.avi -s 320x240 -pix_fmt rgb565 output.rgb
필수 라이브러리
YATFT 라이브러리 설치 필요 (TFT 쉴드 전용)
메인 코드 (PhotoAndVideoPlay.ino)
#include
#include
#include
#include
YATFT tft(0);
SDC sdc;
#define CS_PIN A0
XPT2046_Touchscreen ts(CS_PIN);
uint16_t frame = 0;
uint32_t total_time = 0;
bool f_first = true;
uint8_t mode = 0;
void setup() {
Serial.begin(115200);
tft.begin(0x4391, -8);
tft.SetColor(BLACK);
tft.ClearDevice();
ts.begin();
SPI.end();
uint8_t state = sdc.FSInit();
sdc.currentFileType = DEMO_FILE_TYPE_RGB;
total_time = millis() + 500;
}
void loop() {
if (total_time < millis()) {
total_time = millis() + 2000;
if (f_first) {
if (-1 != sdc.FindFirst("*.*", ATTR_ARCHIVE, &sdc.nextFile))
f_first = false;
else total_time = 0;
} else {
// JPEG 이미지 재생
if (sdc.GetFileType(sdc.nextFile.filename) == DEMO_FILE_TYPE_JPEG) {
if (sdc.currentFileType != DEMO_FILE_TYPE_JPEG) {
tft.SetColor(0x007F); tft.ClearDevice(); tft.SetYUV();
sdc.currentFileType = DEMO_FILE_TYPE_JPEG;
}
// JPEG 디코딩 및 표시
FSFILE *jpeg_file = sdc.FSfopen(sdc.nextFile.filename, "r");
JPEG_DECODE jpeg_decode;
jpeg_decode.stream = (void*)jpeg_file;
sdc.JPEGReadFromSD(&jpeg_decode, 0, 0, GetMaxX()+1, GetMaxY()+1);
sdc.FSfclose(jpeg_file);
frame++; frame &= 0xF;
total_time = millis() + 2000;
}
// RGB565 동영상 재생
else if (sdc.GetFileType(sdc.nextFile.filename) == DEMO_FILE_TYPE_RGB) {
if (sdc.currentFileType != DEMO_FILE_TYPE_RGB) {
tft.SetColor(BLACK); tft.ClearDevice(); tft.SetRGB();
sdc.currentFileType = DEMO_FILE_TYPE_RGB;
}
FSFILE *pFile = sdc.FSfopen(sdc.nextFile.filename, "rb");
tft.SetColor(BLACK); tft.ClearDevice();
sdc.RGBReadFromSD(pFile, &ScanTouch); // 터치 콜백으로 제어
mode = 0;
tft.SetColor(BLACK); tft.ClearDevice();
sdc.FSfclose(pFile);
total_time = millis() + 1000;
}
if (-1 == sdc.FindNext(&sdc.nextFile))
f_first = true;
}
}
}
// 터치스크린 콜백: 재생/일시정지/정지 버튼 처리
uint8_t ScanTouch(void) { ... }
터치 제어
- 왼쪽 영역 터치: 정지
- 가운데 영역 터치: 일시정지 (재생/일시정지 아이콘 표시)
- 오른쪽 영역 터치: 재생
라이브러리 및 참고 자료