BMP-Bilder von SD-Karte auf Arduino 2,4″ TFT-LCD-Shield anzeigen
Komponenten und Zubehör
| Komponente | Menge |
|---|---|
| Arduino UNO | 1 |
| 2,4″ TFT-LCD-Touchscreen-Shield (z. B. SPFD5408/ILI9341) | 1 |
| Micro-SD-Karte (FAT32 formatiert) | 1 |
Projektbeschreibung
Dieses Tutorial baut auf zwei vorherigen Artikeln auf: Interfacing und Touch-Probleme beheben sowie Grafikfunktionen und Touch-Buttons. Hier geht es darum, 24-Bit-BMP-Bilder (240×320 oder 320×240 Pixel) von der SD-Karte zu lesen und auf dem Display darzustellen.
Vorbereitung der SD-Karte
- SD-Karte am PC als FAT32 formatieren.
- Bilder als 24-Bit-BMP speichern (kein PNG/JPG).
- Auflösung: 240×320 (Hochformat,
setRotation(0)) oder 320×240 (Querformat,setRotation(1)). - Dateinamen notieren (z. B.
Img1.bmp,Logo.bmp). - Karte in den Shield-Slot stecken.
Bibliothek
Verwendete Bibliothek: SPFD5408_Adafruit_GFX + SPFD5408_Adafruit_TFTLCD + SPFD5408_TouchScreen (für Code 2). Falls Beispiel-Codes einen weißen Bildschirm zeigen, eine andere Bibliotheksversion testen.
Code 1: Einfache Bildershow
Lädt nacheinander drei Bilder (Logo.bmp, Img2.bmp, Img3.bmp) mit 2 Sekunden Pause.
/* 2,4" TFT LCD Touch Screen Shield – BMP von SD-Karte anzeigen
* Referenz: 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)) {
Serial.println("SD init 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.print("Loading image '"); Serial.print(filename); Serial.println("'");
if ((bmpFile = SD.open(filename)) == NULL) {
Serial.println("File not found");
return;
}
if(read16(bmpFile) == 0x4D42) { // BMP-Signatur
Serial.print("File size: "); Serial.println(read32(bmpFile));
read32(bmpFile); // Creator bytes ignorieren
bmpImageoffset = read32(bmpFile);
Serial.print("Image Offset: "); Serial.println(bmpImageoffset);
Serial.print("Header size: "); Serial.println(read32(bmpFile));
bmpWidth = read32(bmpFile);
bmpHeight = read32(bmpFile);
if(read16(bmpFile) == 1) { // Planes = 1
bmpDepth = read16(bmpFile);
Serial.print("Bit Depth: "); Serial.println(bmpDepth);
if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 24-bit, unkomprimiert
goodBmp = true;
Serial.print("Image size: "); Serial.print(bmpWidth); Serial.print('x'); Serial.println(bmpHeight);
rowSize = (bmpWidth * 3 + 3) & ~3; // 4-Byte-Ausrichtung
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);
Serial.print("Loaded in "); Serial.print(millis() - startTime); Serial.println(" ms");
}
}
}
bmpFile.close();
if(!goodBmp) Serial.println("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;
}
Code 2: Touch-gesteuerte Bildnavigation
Zwei unsichtbare Buttons (links/rechts) auf dem Touchscreen blättern durch Bilder x1.bmp … x4.bmp.
/* Touch-gesteuerte Slideshow – 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)) { Serial.println("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) { // Links
Serial.println("Left");
x[1]--;
bmpDraw(x, 0, 0);
delay(300);
} else if(p.y > 200 && p.y < 320) { // Rechts
Serial.println("Right");
x[1]++;
bmpDraw(x, 0, 0);
delay(300);
}
}
}
// bmpDraw(), read16(), read32() identisch zu Code 1
Schaltplan
Es handelt sich um ein Shield – alle Verbindungen sind auf der Platine vorgegeben. Siehe Bild im Originalartikel.
Herstellungsprozess
- Die Grußkartenindustrie: Geschichte, Produktion und Zukunftstrends
- Kreditkarte: Geschichte, Design, Fertigung und Zukunftstrends
- Flüssigkristall-Display (LCD): Technologie, Fertigung und Zukunftsaussichten
- DATA MODUL bringt 23,1″ Ultra-Slim TFT Display mit Smart Wi-Fi Control
- Distec stellt Ortustechs 7-Zoll-Transflektives TFT-Display vor: Robust, Sonnenlichttauglich, Niedrigenergetisch
- Nuvo-7160GC: Rugged GPU-PC liefert 6 TFLOPS, 120W GPU Support und 4K Output für Machine Vision, VR und Automation
- Primal Display: Raspberry Pi LCD-Temperaturmonitor mit DHT11 bauen
- Kuman 3,5″ TFT Display auf RetroPie installieren – Schritt-für-Schritt-Anleitung
- KI generiert realistische Gerichtsbilder aus textbasierten Rezepten
- Arduino LCD-Projekt: 16×2 Display mit Tastern & Widerständen selbst bauen