I really had this desire to build a digital photoframe from last three ,Until This January when i got this tft lcd touch module .I was excited but when i looked on the internet found very few (sorry none) help regarding it only JoaoLopesF instructable was there but the bitmap sketch had not been working so i cracked it as a challenged debugged it and made a working sketch .

Digital photo frame are quite popular now days.
but cost a hell lot of money with this DIY it cost less 25 $ to make one .
Most importantly its easy to add new file and even with a 1 gb card i can store more 5k photos.

Also like my page for support

Step 1: Incredients

I still give the items you shall be needing

Step 2: What Is TFT LCD ?

TFT LCD stands for thin-film-transistor liquid-crystal display.It is a variant of a liquid-crystal display (LCD) that uses thin-film transistor (TFT) technology to improve image qualities such as addressability and contrast. A TFT LCD is an active-matrix LCD, in contrast to passive-matrix LCDs or simple, direct-driven LCDs with a few segments.

When no voltage is applied, the molecule structures are in their natural state and twisted by 90 degrees. The light emitted by the back light can then pass through the structure.

If a voltage is applied, i.e. an electric field is created, the liquid crystals are twisted so that they are vertically aligned. The polarized light is then absorbed by the second polarizer. Light can therefore not leave the TFT display at this location.

Step 3: Using Th SD Card Shield and Code

Its good to have a SD card shield when you have a lot of file to read or write,
The 2.4 inch LCD touchscreen module has a inbuilt SD card module .
The SD card uses the SPI bus for interfacing with the arduino.
For the working of the SD card you need to call the SD library

Formatting the SD card

If you bought an SD card, chances are it's already pre-formatted with a FAT filesystem. However you may have problems with how the factory formats the card, or if it's an old card it needs to be reformatted. The Arduino SD library we use supports both FAT16 and FAT32 filesystems. If you have a very small SD card, say 8-32 Megabytes you might find it is formatted FAT12 which isn't supported. You'll have to reformat these card. Either way, it's always good idea to format the card before using, even if it's new! Note that formatting will erase the card so save anything you want first.


Connect the 5V pin to the 5V pin on the Arduino

Connect the GND pin to the GND pin on the Arduino

Connect CLK to pin 13 or 52Connect DO to pin 12 or 50

Connect DI to pin 11 or 51Connect CS to pin 10 or 53


Thanks to adafruit for its library and JoaoLopesF for the modified library
all his sketch work except the bitmap once i corrected it

Step 4: Setting Up the Bitmap Image

Arduino supports bitmap images so i needed to convert my jpeg into bmp files.
You can do these easily with Photoshop any version

  • Open Photoshop
  • Create a canvas of 240 x 320
  • drag the image you want in the Photoshop
  • adjust it
  • Save it as .bmp file
  • the bitrate should be 24

Once saved the file should be moved in the sd card

<p>is there anyway to make it display multiple images?</p>
<p>STM32 based BMP Display on TFT LCD http://stm32photoframe.blogspot.com/</p>
<p>Please upload the libraries you have used</p>
<p>2.4&quot; is pretty small; any way to scale this up? I happen to have access to several larger displays, 7&quot; and 10.1&quot; that I have procured...any ideas how to adapt the project to these?</p>
<p>they have 7 inch lcd shield work the same ways just need the proper library</p>
cool, thanks! I actually was thinking of making my own shield....and I really have a lot more 10.1 and 10.2&quot; LCDs....looks like I'll have a bit of work to do to figure this out! Great idea though; been wanting to do this for a while (as long as I have had those spare LCDs), but this is the kick in the pants I needed to start.
<p>let me know how it looked :)</p>
<p>Did u use SDcard shield OR just insert the SDcard into SDcard module in TFT LCD? Thx sir.</p>
<p>I use the SD card on the TFT display with a 32 gb card. Next up is to add jpeg support and image scaling..</p>
<p>the shield comes with a pre board sd card reader </p>
Nice work
<p>Thanks bro</p>
<p>Thanks bro</p>
<p>I found the TFT screen and Uno on Banggood.com about a month ago and over the weekend I was messing with the pair and found the tftbmp draw code in the demo.. I extended it with the ability to read any bmp file on the SD card.. so all you do is put your bitmaps on the SD and plug it in.. Having to add/edit/recompile/reload the Uno everytime is BS... Here is my code:</p><p>// BMP-loading example specifically for the TFTLCD breakout board.<br>// If using the Arduino shield, use the tftbmp_shield.pde sketch instead!<br>// If using an Arduino Mega make sure to use its hardware SPI pins, OR make<br>// sure the SD library is configured for 'soft' SPI in the file Sd2Card.h.<br><br>#include &lt;Adafruit_GFX.h&gt; // Core graphics library<br>#include &lt;Adafruit_TFTLCD.h&gt; // Hardware-specific library<br>#include &lt;SD.h&gt;<br>#include &lt;SPI.h&gt;<br><br>int COMM = 19200; // Speed of our comm port - SET THIS to match your setup<br>int SLEEP = 5000; // Sleep time in milliseconds between pictures - Set this to make you happy..<br><br>// For Arduino Uno/Duemilanove, etc<br>// connect the SD card with DI going to pin 11, DO going to pin 12 and SCK going to pin 13 (standard)<br>// Then pin 10 goes to CS (or whatever you have set up)<br><br>// In the SD card, place 24 bit color BMP files (be sure they are 24-bit!)<br>// There are examples in the sketch folder<br><br>/* * SD card attached to SPI bus as follows: */<br>#define MOSI 11 // Not used yet in this code <br>#define MISO 12 // Not used yet in this code<br>#define SCLK 13 // Not used yet in this code<br>#define SD_CS 10 // Set the chip select line to whatever you use (10 doesnt conflict with the library)<br><br>// The control pins for the LCD can be assigned to any digital or<br>// analog pins...but we'll use the analog pins as this allows us to<br>// double up the pins with the touch screen (see the TFT paint example).<br>#define LCD_CS A3 // Chip Select goes to Analog 3<br>#define LCD_CD A2 // Command/Data goes to Analog 2<br>#define LCD_WR A1 // LCD Write goes to Analog 1<br>#define LCD_RD A0 // LCD Read goes to Analog 0<br><br>// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:<br>// For the Arduino Uno, Duemilanove, Diecimila, etc.:<br>// D0 connects to digital pin 8 (Notice these are<br>// D1 connects to digital pin 9 NOT in order!)<br>// D2 connects to digital pin 2<br>// D3 connects to digital pin 3<br>// D4 connects to digital pin 4<br>// D5 connects to digital pin 5<br>// D6 connects to digital pin 6<br>// D7 connects to digital pin 7<br>// For the Arduino Mega, use digital pins 22 through 29<br>// (on the 2-row header at the end of the board).<br><br><br>// our TFT wiring<br>Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, A4);<br><br>File root;<br><br>// This function opens a Windows Bitmap (BMP) file and<br>// displays it at the given coordinates. It's sped up<br>// by reading many pixels worth of data at a time<br>// (rather than pixel by pixel). Increasing the buffer<br>// size takes more of the Arduino's precious RAM but<br>// makes loading a little faster. 20 pixels seems a<br>// good balance.<br><br>#define BUFFPIXEL 20<br><br>void bmpDraw(char *filename, int x, int y) {<br><br> File bmpFile;<br> int bmpWidth, bmpHeight; // W+H in pixels<br> uint8_t bmpDepth; // Bit depth (currently must be 24)<br> uint32_t bmpImageoffset; // Start of image data in file<br> uint32_t rowSize; // Not always = bmpWidth; may have padding<br> uint8_t sdbuffer[3*BUFFPIXEL]; // pixel in buffer (R+G+B per pixel)<br> uint16_t lcdbuffer[BUFFPIXEL]; // pixel out buffer (16-bit per pixel)<br> uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer<br> boolean goodBmp = false; // Set to true on valid header parse<br> boolean flip = true; // BMP is stored bottom-to-top<br> int w, h, row, col;<br> uint8_t r, g, b;<br> uint32_t pos = 0, startTime = millis();<br> uint8_t lcdidx = 0;<br> boolean first = true;<br><br> if((x &gt;= tft.width()) || (y &gt;= tft.height())) return;<br><br> int i = 0;<br> int j = 0;<br> tft.setRotation(i);<br> tft.fillScreen(j);<br><br> Serial.println();<br> Serial.print(F(&quot;Loading image '&quot;));<br> Serial.print(filename);<br> Serial.println('\'');<br> // Open requested file on SD card<br> if ((bmpFile = SD.open(filename)) == NULL) {<br> Serial.println(F(&quot;File not found&quot;));<br> return;<br> }<br><br> // Parse BMP header<br> if(read16(bmpFile) == 0x4D42) { // BMP signature<br> Serial.print(F(&quot;File size: &quot;)); Serial.println(read32(bmpFile));<br> (void)read32(bmpFile); // Read &amp; ignore creator bytes<br> bmpImageoffset = read32(bmpFile); // Start of image data<br> Serial.print(F(&quot;Image Offset: &quot;)); Serial.println(bmpImageoffset, DEC);<br>// Read DIB header<br> Serial.print(F(&quot;Header size: &quot;)); Serial.println(read32(bmpFile));<br> bmpWidth = read32(bmpFile);<br> bmpHeight = read32(bmpFile);<br> if(read16(bmpFile) == 1) { // # planes -- must be '1'<br> bmpDepth = read16(bmpFile); // bits per pixel<br> Serial.print(F(&quot;Bit Depth: &quot;)); Serial.println(bmpDepth);<br> if((bmpDepth == 24) &amp;&amp; (read32(bmpFile) == 0)) { // 0 = uncompressed<br><br> goodBmp = true; // Supported BMP format -- proceed!<br> Serial.print(F(&quot;Image size: &quot;));<br> Serial.print(bmpWidth);<br> Serial.print('x');<br> Serial.println(bmpHeight);<br><br> // BMP rows are padded (if needed) to 4-byte boundary<br> rowSize = (bmpWidth * 3 + 3) &amp; ~3;<br><br> // If bmpHeight is negative, image is in top-down order.<br> // This is not canon but has been observed in the wild.<br> if(bmpHeight &lt; 0) {<br> bmpHeight = -bmpHeight;<br> flip = false;<br> }<br><br> // Crop area to be loaded<br> w = bmpWidth;<br> h = bmpHeight;<br> if((x+w-1) &gt;= tft.width()) w = tft.width() - x;<br> if((y+h-1) &gt;= tft.height()) h = tft.height() - y;<br><br> // Set TFT address window to clipped image bounds<br> tft.setAddrWindow(x, y, x+w-1, y+h-1);<br><br> for (row=0; row&lt;h; row++) { // For each scanline...<br> // Seek to start of scan line. It might seem labor-<br> // intensive to be doing this on every line, but this<br> // method covers a lot of gritty details like cropping<br> // and scanline padding. Also, the seek only takes<br> // place if the file position actually needs to change<br> // (avoids a lot of cluster math in SD library).<br> if(flip) // Bitmap is stored bottom-to-top order (normal BMP)<br> pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;<br> else // Bitmap is stored top-to-bottom<br> pos = bmpImageoffset + row * rowSize;<br> if(bmpFile.position() != pos) { // Need seek?<br> bmpFile.seek(pos);<br> buffidx = sizeof(sdbuffer); // Force buffer reload<br> }<br><br> for (col=0; col&lt;w; col++) { // For each column...<br> // Time to read more pixel data?<br> if (buffidx &gt;= sizeof(sdbuffer)) { // Indeed<br> // Push LCD buffer to the display first<br> if(lcdidx &gt; 0) {<br> tft.pushColors(lcdbuffer, lcdidx, first);<br> lcdidx = 0;<br> first = false;<br> }<br> bmpFile.read(sdbuffer, sizeof(sdbuffer));<br> buffidx = 0; // Set index to beginning<br> }<br><br> // Convert pixel from BMP to TFT format<br> b = sdbuffer[buffidx++];<br> g = sdbuffer[buffidx++];<br> r = sdbuffer[buffidx++];<br> lcdbuffer[lcdidx++] = tft.color565(r,g,b);<br> } // end pixel<br> } // end scanline<br> // Write any remaining data to LCD<br> if(lcdidx &gt; 0) {<br> tft.pushColors(lcdbuffer, lcdidx, first);<br> } <br> Serial.print(F(&quot;Loaded in &quot;));<br> Serial.print(millis() - startTime);<br> Serial.println(&quot; ms&quot;);<br> } // end goodBmp<br> }<br> }<br><br> bmpFile.close();<br> if(!goodBmp) Serial.println(F(&quot;BMP format not recognized.&quot;));<br>}<br><br>// These read 16- and 32-bit types from the SD card file.<br>// BMP data is stored little-endian, Arduino is little-endian too.<br>// May need to reverse subscript order if porting elsewhere.<br><br>uint16_t read16(File f) {<br> uint16_t result;<br> ((uint8_t *)&amp;result)[0] = f.read(); // LSB<br> ((uint8_t *)&amp;result)[1] = f.read(); // MSB<br> return result;<br>}<br><br>uint32_t read32(File f) {<br> uint32_t result;<br> ((uint8_t *)&amp;result)[0] = f.read(); // LSB<br> ((uint8_t *)&amp;result)[1] = f.read();<br> ((uint8_t *)&amp;result)[2] = f.read();<br> ((uint8_t *)&amp;result)[3] = f.read(); // MSB<br> return result;<br>}<br><br>void setup()<br>{<br><br> // Open serial communications and wait for port to open:<br> Serial.begin(COMM);<br> while (!Serial) {<br> ; // wait for serial port to connect. Needed for native USB port only<br> }<br><br> Serial.print(&quot;Initializing SD card...&quot;);<br><br> if (!SD.begin(SD_CS)) {<br> Serial.println(&quot;initialization failed!&quot;);<br> return;<br> }<br> Serial.println(&quot;initialization done.&quot;);<br><br> tft.reset();<br><br> uint16_t identifier = tft.readID();<br><br> if(identifier == 0x9325) {<br> Serial.println(F(&quot;Found ILI9325 LCD driver&quot;));<br> } else if(identifier == 0x9328) {<br> Serial.println(F(&quot;Found ILI9328 LCD driver&quot;));<br> } else if(identifier == 0x7575) {<br> Serial.println(F(&quot;Found HX8347G LCD driver&quot;));<br> } else if(identifier == 0x9341) {<br> Serial.println(F(&quot;Found ILI9341 LCD driver&quot;));<br> } else if(identifier == 0x8357) {<br> Serial.println(F(&quot;Found HX8357D LCD driver&quot;));<br> } else {<br> Serial.print(F(&quot;Unknown LCD driver chip: &quot;));<br> Serial.println(identifier, HEX);<br> Serial.println(F(&quot;If using the Adafruit 2.8\&quot; TFT Arduino shield, the line:&quot;));<br> Serial.println(F(&quot; #define USE_ADAFRUIT_SHIELD_PINOUT&quot;));<br> Serial.println(F(&quot;should appear in the library header (Adafruit_TFT.h).&quot;));<br> Serial.println(F(&quot;If using the breakout board, it should NOT be #defined!&quot;));<br> Serial.println(F(&quot;Also if using the breakout, double-check that all wiring&quot;));<br> Serial.println(F(&quot;matches the tutorial.&quot;));<br> return;<br> }<br><br> tft.begin(identifier);<br> delay(1000);<br>}<br><br>void printDirectory(File dir) {<br>int k = 0;<br><br>dir.rewindDirectory();<br><br>while (true) {<br> File entry = dir.openNextFile();<br> if (! entry) {<br> // no more files<br> Serial.println(&quot;Last File Reached&quot;);<br> entry.close();<br> break;<br> }<br> if (entry.isDirectory()) {<br> Serial.println(&quot;/&quot;);<br> }<br> bmpDraw(entry.name(),k,k);<br> entry.close();<br> delay(SLEEP);<br> }<br>}<br><br>void loop()<br>{<br>while (true) {<br> root = SD.open(&quot;/&quot;);<br> printDirectory(root);<br>// Serial.println(&quot;End&quot;); // Loop Debug to console<br> }<br>}</p>
<p>Great show us a pic would be awesome.</p>

About This Instructable




Bio: So basically i am a crazy person, who loves to think the most odd way ever possible,who makes what he thinks and also let ... More »
More by geekrex:$10 DIY Dremel /RotaryTool $10 DIY Flexible Soldering Helping Hand $5 Powerful DIY Fume Extractor  
Add instructable to: