Here’s a reliable way to show pictures from a microSD on a 3.2" TFT for [Arduino Mega 2560](https://www.ampheo.com/product/a000067-25542697). I’ll cover the two common setups:
* A parallel Mega shield (most 3.2" modules) → use MCUFRIEND_kbv
* An SPI TFT (e.g., ILI9341/ILI9488) → use Adafruit_ILI9341 + Adafruit_GFX
If you’re not sure which you have: if it plugs directly on the Mega’s headers and uses many pins, it’s the parallel shield (use the first sketch).

**A) Parallel 3.2" Mega shield (MCUFRIEND_kbv)**
**1) Prep**
* Install libraries: MCUFRIEND_kbv, SD (built-in), SPI (built-in).
* Format the card FAT/FAT32.
* Save images as 24-bit, uncompressed BMP (no alpha). Size them to your panel (most 3.2" are 480×320; some are 320×240).
**2) Full working sketch (draws /test.bmp full-screen)**
```
#include <SPI.h>
#include <SD.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
const uint8_t SD_CS_CANDIDATES[] = {10, 4, 53}; // try common CS pins (shield variants)
uint8_t sdCS = 10;
bool initSD() {
for (uint8_t i = 0; i < sizeof(SD_CS_CANDIDATES); i++) {
uint8_t cs = SD_CS_CANDIDATES[i];
pinMode(cs, OUTPUT); digitalWrite(cs, HIGH);
if (SD.begin(cs)) { sdCS = cs; return true; }
}
return false;
}
uint16_t read16(File &f){ uint16_t r; f.read((uint8_t*)&r, 2); return r; }
uint32_t read32(File &f){ uint32_t r; f.read((uint8_t*)&r, 4); return r; }
void drawBMP(const char *filename, int16_t x, int16_t y) {
File bmpFile;
uint32_t bmpImageoffset;
int32_t bmpWidth, bmpHeight;
uint16_t planes, bitDepth;
uint32_t compression;
bool flip = true;
if ((bmpFile = SD.open(filename)) == false) return;
if (read16(bmpFile) == 0x4D42) { // 'BM'
(void)read32(bmpFile); // file size (unused)
(void)read32(bmpFile); // creator bytes
bmpImageoffset = read32(bmpFile); // pixel data offset
// DIB header
(void)read32(bmpFile); // DIB header size
bmpWidth = (int32_t)read32(bmpFile);
bmpHeight = (int32_t)read32(bmpFile);
planes = read16(bmpFile);
bitDepth = read16(bmpFile);
compression = read32(bmpFile);
if (planes == 1 && bitDepth == 24 && compression == 0) {
// If height < 0, data is top-down
if (bmpHeight < 0) { bmpHeight = -bmpHeight; flip = false; }
// Clip to screen
int16_t w = bmpWidth, h = bmpHeight;
if ((x >= tft.width()) || (y >= tft.height())) { bmpFile.close(); return; }
if ((x + w) > tft.width()) w = tft.width() - x;
if ((y + h) > tft.height()) h = tft.height() - y;
// Each scanline is padded to 4-byte boundary
uint32_t rowSize = (bmpWidth * 3 + 3) & ~3;
uint8_t sdbuf[3*32]; // SD read buffer (96 bytes)
static uint16_t line[480]; // enough for up to 480 px wide (Mega has RAM)
tft.setAddrWindow(x, y, x + w - 1, y + h - 1);
for (int16_t row = 0; row < h; row++) {
uint32_t pos;
int16_t yrow = flip ? (y + h - 1 - row) : (y + row);
pos = bmpImageoffset + (flip ? (bmpHeight - 1 - row) : row) * rowSize;
bmpFile.seek(pos);
int32_t col = 0;
int32_t toRead = w * 3;
int32_t out = 0;
while (toRead > 0) {
int32_t n = toRead;
if (n > (int32_t)sizeof(sdbuf)) n = sizeof(sdbuf);
bmpFile.read(sdbuf, n);
for (int i = 0; i < n; i += 3) {
uint8_t b = sdbuf[i+0];
uint8_t g = sdbuf[i+1];
uint8_t r = sdbuf[i+2];
// RGB888 -> RGB565
line[out++] = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}
toRead -= n;
}
tft.pushColors(line, w, true);
}
}
}
bmpFile.close();
}
void setup() {
Serial.begin(115200);
uint16_t id = tft.readID();
if (id == 0xD3D3) id = 0x9486; // common fallback for some 3.2" shields
tft.begin(id);
tft.setRotation(1); // try 1 or 3 for landscape
tft.fillScreen(0x0000);
if (!initSD()) {
tft.setCursor(10,10); tft.setTextColor(0xFFFF); tft.setTextSize(2);
tft.print("SD init failed"); // check CS pin / card format
return;
}
// Draw full-screen BMP at (0,0). Ensure your BMP matches your panel size.
drawBMP("/test.bmp", 0, 0);
}
void loop() { }
```
**How to use:**
* Put a 24-bit BMP named test.bmp in the SD card root.
* If the image is rotated or clipped, change tft.setRotation() and/or resize the BMP to your display resolution.
**B) SPI TFT (Adafruit ILI9341/ILI9488 + SD on SPI)**
If your 3.2" module uses SPI (fewer wires, separate CS lines), install Adafruit_ILI9341 and Adafruit_GFX. Wire to the Mega’s SPI pins:
* Mega SPI: SCK=52, MISO=50, MOSI=51, plus CS pins of TFT and SD (e.g., TFT_CS=10, SD_CS=4).
* Use the example File → Examples → Adafruit_ILI9341 → spitftbitmap.
* It reads 24-bit BMP from SD and draws it—change pins and filename to match your wiring.
**File & format tips**
* Use 24-bit, uncompressed BMP (Windows BMP). Other formats (PNG/JPG) need extra decoders.
* For 480×320 images, a Class-10 card helps.
* If drawing is slow, reduce SPI clock (for reliability) or pre-scale images to screen size.
**Hardware gotchas (important)**
* Voltage levels: [Arduino Mega](https://www.ampheoelec.de/product/a000067-25542697) is 5 V; many bare TFT/SD modules are 3.3 V only. If it’s not a shield with onboard level shifting, add level shifters (e.g., [74LVC245](https://www.onzuu.com/search/74LVC245)) and a 3.3 V regulator.
* SD CS pin: Shields often use CS=10 or CS=4. If SD.begin() fails, try the other.
* Identify your controller: Common 3.2" chips are ILI9341, ILI9481/9486/9488, HX8357. MCUFRIEND_kbv auto-detects; for SPI you must choose the matching library/driver.