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). ![_Ihn3JM3X3o](https://hackmd.io/_uploads/B1igQlqJbe.jpg) **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.