BMP-afbeeldingen van SD-kaart Tonen op Arduino 2,4″ TFT LCD Shield
Onderdelen en Benodigdheden
| Onderdeel | Aantal |
|---|---|
| Arduino UNO | 1 |
Over dit Project
Deze tutorial is een vervolg op eerdere handleidingen over de 2,4″ TFT LCD Shield met Arduino UNO. De eerste behandelde het interfaceren en het oplossen van touch-problemen en omgekeerde assen; de tweede ging over het tekenen van vormen en het maken van touch-knoppen.
Vandaag richten we ons op het inlezen van afbeeldingen van een SD-kaart en het tonen ervan op het scherm.
Voorbereiding SD-kaart
- Formateer de SD-kaart als FAT32 op je computer.
- Zet je afbeeldingen erop – ze moeten BMP-formaat zijn, 24-bits Bitmaps.
- Voor correcte weergave: resolutie 240×320 pixels.
Kies wat bij jou past: schermrotatie of afbeeldingsrotatie op de PC. Noteer de bestandsnamen (bijv. Img1.bmp) en steek de SD-kaart in de shield.
Bibliotheek
De bibliotheek die voor mij werkte: Download hier. Als je met de voorbeeldcodes een wit scherm krijgt, zoek dan een bibliotheek die bij jouw shield past.
Code
Hieronder de twee codes uit de video (in .ino formaat). Vergeet niet de bestandsnamen aan te passen aan jouw afbeeldingen.
- Code 1: Basis diavoorstelling
- Code 2: Touch-gecontroleerde diavoorstelling
Code 1: Basis Diavoorstelling (TFT_Shield_SD_1.ino)
/* Deze code is voor 2,4" TFT LCD touch screen shield, leest BMP-afbeeldingen van SD-kaart
* en toont ze op het scherm. Zie SurtrTech.com voor details. */
#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 handtekening
progmemPrint(PSTR("File size: ")); Serial.println(read32(bmpFile));
(void)read32(bmpFile); // Skip creator bytes
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) { // Planes = 1
bmpDepth = read16(bmpFile);
progmemPrint(PSTR("Bit Depth: ")); Serial.println(bmpDepth);
if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 24-bit, uncompressed
goodBmp = true;
progmemPrint(PSTR("Image size: "));
Serial.print(bmpWidth); Serial.print('x'); Serial.println(bmpHeight);
rowSize = (bmpWidth * 3 + 3) & ~3; // 4-byte boundary padding
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();
}
Code 2: Touch-gecontroleerde Diavoorstelling (TFT_Shield_SD_2.ino)
/* Voor 2,4" TFT LCD touch shield met UNO.
* Maakt een diavoorstelling die verandert op basis van waar je op het scherm drukt.
* Afbeeldingen worden van SD-kaart gelezen. Zie 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
// Let op: als touch niet werkt, probeer (A1, A2, 7, 6)
#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"; // Array voor bestandsnamen (x1, x2, x3, x4)
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());
// Scherm is geroteerd (setRotation(1)), dus Y-as gebruikt voor knoppen
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);
}
}
}
// De bmpDraw-functie is identiek aan Code 1 (zie bovenaan)
Schema's
Het is een shield – geen complex schema nodig.

Productieproces
- De Kaartjesindustrie: Geschiedenis, Productie en Toekomsttrends
- Creditcard: Geschiedenis, Ontwerp, Productie en Toekomsttrends
- Vloeistofkristal Display (LCD): Technologie, Productie en Toekomstperspectief
- Primal Display: Een Raspberry Pi LCD-temperatuurmonitor bouwen
- Hoe de Kuman 3,5″ TFT-display op RetroPie te Installeren – Stap-voor-stap Handleiding
- Professionele gids voor bitmap-animatie op de ILI9341 2,4″ TFT Touchscreen Shield
- DIY Arduino LCD-project: Bouw met weerstanden, drukknop en 16x2 display
- AI genereert realistische maaltijdafbeeldingen vanuit tekstuele recepten
- DATA MODUL lanceert 23,1″ ultra‑slank TFT-display met slimme Wi‑Fi‑besturing
- Distec introduceert Ortustech's 7-inch transflectieve TFT-display: robuust, zonlicht-leesbaar, laag-vermogen
- Nuvo-7160GC: robuuste GPU-PC met 6 TFLOPS, 120W GPU-ondersteuning en 4K-output voor machine-vision, VR en automatisering