Вывод BMP‑изображений с SD‑карты на TFT LCD Shield 2.4″ для Arduino
Компоненты и материалы
| Arduino UNO | 1 |
О проекте
Это руководство — продолжение двух предыдущих уроков по TFT LCD Shield 2.4″ с Arduino UNO. Первый урок охватывал подключение и исправление сенсорного экрана (инвертированные оси), второй — рисование фигур и создание сенсорных кнопок. Сегодня речь пойдёт о чтении изображений с SD‑карты и их отображении на экране.
Подготовка SD‑карты
- Отформатируйте SD‑карту в FAT32.
- Перенесите изображения в формате BMP 24‑бит.
- Разрешение изображений должно соответствовать ориентации экрана:
- При
setRotation(0)(стандартная ориентация) — 240×320 пикселей. - При
setRotation(1)(поворот на 90°) — 320×240 пикселей.
- При


Выберите удобный вариант: либо поворачивайте экран программно, либо поворачивайте изображения на компьютере. Запомните имена файлов (например, Img1.bmp), вставьте карту в шилд.

Библиотека
Использовалась библиотека SPFD5408_Adafruit_GFX и SPFD5408_Adafruit_TFTLCD. Если при запуске примеров появляется белый экран — попробуйте другую версию библиотеки, совместимую с вашим шилдом.
Коды
Два примера кода (в формате .ino) приведены ниже. Не забудьте заменить имена файлов на свои. Подробности смотрите в видео‑уроке.
Код 1: Последовательный показ изображений
/* This code is to use with 2.4" TFT LCD touch screen shield, it reads bmp images stored on SD card
* and shows them on the screen
* Refer to SurtrTech.com for more details */
#include <SPFD5408_Adafruit_GFX.h> // Core graphics library
#include <SPFD5408_Adafruit_TFTLCD.h> // Hardware-specific library
#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 signature
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= 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: Слайд‑шоу с управлением касанием
/* This code is meant for the 2.4" TFT LCD touch screen shield with UNO board
* It creates a little slide show of images that changes depending on where you pressed on the screen
* The images are read from SD card
* Refer to SurtrTech.com for more details */
#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 (приведена выше для полноты)
#define BUFFPIXEL 20
void bmpDraw(char *filename, int x, int y) {
// ... (тот же код отрисовки BMP)
}
// Вспомогательные функции read16, read32, progmemPrint, progmemPrintln — те же, что в коде 1
Схемы
Это шилд, схема простая: он просто надевается на Arduino UNO.

Производственный процесс
- Промышленность открыток: история, производство и будущие тренды
- Кредитная карта: история, дизайн, производство и будущие тренды
- Жидкокристаллические дисплеи (LCD): технология, производство и перспективы
- DATA MODUL запускает 23,1″ ультратонкий TFT-дисплей с умным Wi-Fi-управлением
- Distec представляет 7‑дюймовый трансфлективный TFT‑дисплей Ortustech: надежный, читаемый на солнце, низкое потребление
- Nuvo-7160GC: Rugged GPU-ПК с 6 TFLOPS, поддержкой 120 Вт GPU и 4K выводом для машинного зрения, VR и автоматизации
- Primal Display: создайте монитор температуры на Raspberry Pi с LCD
- Установка дисплея Kuman 3.5″ TFT на RetroPie — Пошаговое руководство
- ИИ генерирует реалистичные фото блюд по текстовым рецептам
- DIY-проект Arduino LCD: сборка с резисторами, кнопкой и дисплеем 16x2