Zonnestroompanelen in Nederland

duurzaamheid achter de meter

(56) Arduino digital photo frame with parallel TFT display

by Floris Wouterlood — The Netherlands —  February 2, 2022

Here we describe the following setups: 1. Arduino Uno with mounted on it a TFT display shield, 2. Arduino Nano with a separate SD card reader and driving the same (parallel) TFT display. Both combinations comfortably support a digital photo frame. The library MCUFRIEND_kbv.h (David Prentice) is required.

A TFT display offers in width, height, pixels and color depth an attractive medium to display pictures. The assemblies described here are capable of showing sequences of pictures stored on SD card. Most simple is to mount a TFT shield onto an Arduino Uno and, with the proper sketch, display images. The Arduino Uno or its little brother Nano can also be used in combination with with a separate SD card reader and a TFT display, for instance in situations where it is difficult if not impossible to reach the shields SD card reader. We have tested a selection of TFT displays. Some form of external data storage is always necessary with the original Arduinos because the internal memory of these microcontrollers is far too small to hold color image frames. The Arduino serves in a photo frame assembly as an engine that reads image files stored on SD card pixel for pixel and transfers them fast and in a proper way to the display. The result is that a digital photo frame can be created fast and with very modest means.

1. Compact: TFT shield mounted directly on top of an Arduino Uno

This configuration needs:
• microcontroller board: Arduino Uno,
• TFT shield with on-board SD card reader,
• library: MCUFRIEND_kbv.h (created by David Prentice).

2. Assembly: parallel TFT display, SD card reader and Arduino Nano

This configuration needs:
• microcontroller board: Arduino Nano,
• TFT display. We use the same TFT display as in the ‘compact’ option
• a separate SD card reader,
• a handful of jumper wires,
• library: MCUFRIEND_kbv.h (created by David Prentice).

1. The compact way: TFT shield mounted directly on top of an Arduino Uno

The idea of a shield is very simple and very clever: Just stick the device properly onto an Arduino UNO, insert the SD card loaded with pictures, upload a sketch and you’re in business. Let’s go through this procedure.

figure 1. Left: 3.5’ 320*480 pixel parallel TFT shield, front – a micro SD card sticks out of the SD card slot. Right: Arduino UNO. basically: just stick the shield onto the UNO, stick a micro SD card with picture files in the card reader slot, load the sketch and go!

Shields: The market supplies a range of shields between 2.4’ and 3.95’ display diagonal and with resolutions of 320*240 and 320*480. Display controllers are ILI9341, ILI9481, ILI9486 and ILI9488. This range of displays suits the purpose of creating a photo frame. My favorite photo frame display is a 3.5’ 320*480 display shield with ILI9481 controller. The MCUFRIEND_kbv.h library supports all these controllers.

SD card: The world of SD cards is rapidly changing. Some years ago all TFT displays on the market came equipped with a standard SD card slot, accepting cards with capacities in the MB range. Current SD card slots are in the micro format while the market is flooded with micro-SD cards with enormous capacities. At the same time ‘low-capacity’ SD cards are increasingly hard to get. The micro SD card used here has a capacity of 8 GB. Note that cards need to be formatted in FAT32 and that it is most handy to have all images stored in the root directory.
SD card technology works with 3.3V control logic while an Arduino UNO works with 5V control logic. The voltage requirements for a card reader integrated in a TFT shield is taken care of by the voltage regulator and level shifters of the shield, so don’t worry.

figure 2. left: the back of the 3.5’ TFT shield of figure 1 – all pins visible. Four pins (marked ‘SD_xx’) support the SD card reader while the remaining pins provide power and serve (marked LCD_xx) the parallel interface of the display. Displays with an ILI9341, ILI9481, or ILI 9486 controller are fully supported by the MCUFRIEND_kbv.h library.

Images: The only format recognized by Arduino is Microsoft’s BMP format. BMP is an uncompressed format that exists in several color depths: 2, 4, 8, 16, 24 and 32 bit. The 24-bit color depth (R8G8B8), designated in Windows as ‘True Color’ is the only format accepted by the Arduino. The file system on the SD cards works with eight-character filenames that reminisces good old DOS times long ago, when short file names were the norm. Names longer than 8 characters become shorthanded with the ~ sign.

Image dimensions: My photo frame image collection contains pictures with different dimensions and different positions (portrait, landscape). The screen dimensions of my favorite photo frame however, are fixed: 320*480 pixels. What happens to pictures whose dimensions exceed those of the screen? I have tested this by taking a picture of my favorite dog, called ‘Bastien’. The original picture dimensions (landscape) was scaled to 1600*1200 pixels and exported as 24-bit BMP: bastien1.bmp. Further downscaling was done to 800*600, 400*300 and 200*150 pixels. The resulting pictures were exported to SD card as BMPs: bastien2.bmp, bastien3.bmp and bastien4.bmp. Three of these pictures (bastien2, 3 and 4) were perfectly displayed on screen (figure 2). The 1600*1200 image was shown garbled. The sketch does not scale, it just transfers the image from the SD card to the display. The display acts as a kind of keyhole giving access to the entire picture. Keyholes work as long as pictures are no larger than the keyhole. With pictures larger than the keyhole the upper left part of the content is shown, e.g., that of bastien2.bmp (800*600; fig 3C) and the remaining is invisible beyond the edges of the display. This makes one wonder what the maximum pixel format is that is supported by the controller. In case of this display with an ILI9481 controller some experimenting learned that all images with conventional image formats up to 1280*1024 pixels are supported. It does not matter whether this format is in portrait or landscape. beyond these dimensions the pcitures become garbled on screen. On-card file size of the 1280*1024 pixel images is 3.9 MB which makes it attractive to believe that maximum allowed file size is 4 MB.

library: MCUFRIEND_kbv.h is an extremely flexible library that is meticulously kept up to date by David Prentice, its creator. Thanks to this library most Arduino display shields on the market are supported. David provides assistance via the Arduino forum – https://forum.arduino.cc.

figure 3. Image dimensions test. The same image scaled and then exported. Three dimension formats: 150*200, 300*400 and 600*800 pixels. The images in A and B are within the display dimensions of 320 pixels high and 480 pixels wide and are shown in all their glory on screen where pixel (0,0) is in the upper left corner of the display. The dimensions of the image in C (bastien2.bmp; 800*600 pixels) exceed the display dimensions; the left upper part of the image is shown while the remaining is off screen.

2. The Assembly way: parallel TFT display, SD card reader and Arduino Nano

With a bare Arduino Nano it is very well possible to connect parallel displays. In several previous projects (*, **) this has been achieved. The only barrier is that a parallel TFT needs, apart from two power wires and GND, five control wires and 8 data wires to provide a working, stable interface. This wiring can be acchieved with Dupont jumper wires . However to get rid of what easily becomes a massive tangle of wires and to have permanently at hand a reliable, stable assembly I constructed some time ago a ‘Nano-parallel TFT display bench’ (*) that suits a range of parallel-interface TFT shields. On this bench I mounted the TFT display previously used with the UNO and connected the bench with an external SD card reader. The sketch used with the Arduino UNO worked perfectly with this assembly. Modification of the sketch was not necessary.

Wiring the shield to the Nano
A table listing the pins of the Nano necessary for wiring the TFT display is shown, together with a wiring diagram, in figure 4.


figure 4. Wiring diagram and pin wire out for an Arduino Nano connected to an Arduino UNO-style TFT display shield.

Wiring the card reader to the Nano
A table listing the pins of the Nano necessary for wiring the TFT display is shown, together with a wiring diagram, in figure 5. Card readers standard have four control pins: MISO, CLS, MOSI and CS. These need to be wired to pins 12, 13, 11 and 10 of the Nano. Note that card reader technology works with 3.3V control logic while a Nano has 5-volt control logic so verify that your SD card reader is 5V compliant. The card reader used here is 3.3V-5V compliant, as witnessed by the presence of pins for 3.3V and 5V power plus an on-board voltage regulator. Both voltages (as power supply to the card reader) were tested, and there were no differences in performance.


figure 5. Wiring diagram and pin wireout for an Arduino Nano connected to a standalone SD card reader. Notice that SD cards are 3.3V devices. The card reader usually has an on-board voltage regulator.

figure 6. Complete wiring diagram and pin wireout for an Arduino Nano connected to a standalone SD card reader and to a parallel-interface TFT display (e.g. UNO shield).

Wiring both TFT shield and card reader to the Nano
Figure 6 shows the complete wiring diagram for all components. I previously built a Nano-TFT bench (*). This bench was used in the present project. Figure 7 shows a working assembly consisting of the Nano-TFT bench connected to an external SD card reader.

figure 7. The same display as in figure 1 now on a bench powered by a Nano (left). The bench has the advantage that free pins have been wired to a row pin headers below the display. The image on display is the 1280*1024 version of the ‘bastien’ picture. The SD card reader receives here power from the Nano’s 3.3V pin.

Results and discussion
Both options: UNO with TFT shield and Nano-TFT shield-separate card reader, work fine. Pictures are shown with vivid colors and great brightness on screen. With large pictures (320*480 or larger) the line-for-line transfer of the bitmap from card to display is evident, reminiscent of the old days with slow computers and low-capacity graphic cards. Just as in the old days the best performance of a slide show is obtained when all pictures in the show have the same dimensions, preferably pixel dimensions that match those of the display: 320*240 or 320*480. As 320*480 needs twice the number of pixels as 320*240, loading speed of the smaller images can be anticipated twice as fast as that of the bigger pictures.


*) Floris Wouterlood – Arduino test bench with a 3.5 inch TFT displaying in analog fashion. Thesolaruniverse, February 25, 2021.

**) Floris Wouterlood – Construction of a desk display with a 3.5″ 320×480 TFT screen for multi temperature-humidity sensing with an Arduino Nano. Thesolaruniverse, June 1, 2021.

The zip file ‘UNO_TFT_photoframe.ino contains the sketch that runs a slide show on the UNO-TFT shield as well as on the Nano-TFT-shield-separate SD card reader. Note that this sketch is a slightly modified version of the example ‘showBMP_kbv_Uno’ provided with the MCUFRIEND_kbv.h library created by David Prentice. All credits to David. Of course you have to prepare yourself a SD card loaded with .BMP ‘True Color’ formatted color pictures with dimensions matching those of your display

UNO_TFT_photoframe.ino – packed as zip file.