Go Down

Topic: speeding up displaying bitmaps (Read 320 times) previous topic - next topic


Hi there,
           I am a newbie to arduino.I make sci fi models and i want to use an arduino uno with a 1.8 inch tft display to make some control panels for a model cockpit.My goal is to have the display cycle though a series of bitmaps to replicate a cockpit with LCD panels. I bought the ardafruit 1.44 tft display with the microSD card and used the program in their tutorial to display the images.The only problem is the images load slowly onto the screen.it looks like a curtain effect where the image gradually appears on the screen from the top down. I have been reading lots about how to speed up the image but I am a bit confused as to how to do it. Can anyone guide me through how to write a sketch that would make the images appear quicker on the lcd without the curtain effect or point me towards an easy to follow tutorial ?



Your 128x160 display is small.

1.  use the hardware SPI constructor.
2.  convert 24-bit .BMP image into raw 16-bit pixels with a PC program.
3.  copy the raw image directly from SD to the display in big lumps.

It is generally quicker to draw a graphic from scratch than to load from SD.

Obviously a photo can only load from SD.

If you have a mega2560, Zero, Due, ... there is sufficient Flash to store several images in Flash.
And they have sufficient SRAM to decode JPEG images.    You can fit many more JPG images than RAW images in Flash memory.

An ESP8266 can give you dramatic results.   For storage, decoding, performance, ...



Thanks David,
                     I saw a project on next-hack where they modified a tft to enable 20fps video by doing exactly what you decribed.I guess I could use that hack and put a delay in .I want the images to appear instantly instead of slowly loading onto the tft. I am trying to understand how it works but the code is quite complex.Currently it takes about 800ms to load an image on a 1.44 inch adafruit tft screen so it would likely be over a second on a 1.8tft whcih is the one I want to use.

Are there example sketches that show how to load raw files from the SD card to display? Using the ardafruit bitmap loader from their example library and using the arduino library SD reader is VERY slow.



Code: [Select]

/* An AVR can do SPI @ 8MHz but with gaps.
 * most TFT have a Pixel Write Cycle = 100ns
 * most TFT and SD can operate SPI @ 24MHz
 * theoretical times. allow x1.5 for overhead, gaps etc
 * 8080-8 400ns per pixel.   8080-16 200ns per pixel
 * 128x160 = 20480 pixels
 * RAW: SD:x2  TFT:x2 SPI =  82ms
 * BMP: SD:x3  TFT:x2       103ms
 * BGR: SD:x3  TFT:x3       123ms
 * 240x320 = 76800 pixels
 * RAW: SD:x2  TFT:x2 SPI = 308ms 8080-8 = 154+31ms
 * BMP: SD:x3  TFT:x2       384ms          192+31ms
 * BGR: SD:x3  TFT:x3       461ms          231+31ms
 * 240x400 = 96000 pixels
 * RAW: SD:x2  TFT:x2 SPI = 384ms 8080-8 = 192+39ms
 * BMP: SD:x3  TFT:x2       480ms          240+39ms
 * BGR: SD:x3  TFT:x3       576ms          288+39ms

Note that these are theoretical figures.   

AVR hardware SPI can run at 8MHz with F_CPU @ 16MHz.
The absolute best SPI throughput is actually 18 cycles rather than 16 cycles.
However the USART_MSPI can manage 16 cycles.    (USART unavailable because it is used for Serial).
And the nice people that designed the Mega2560 ensured that none of the XCKn pins are accessible.

So there is no way that you can have an instant picture on a 128x160.

Arduino SPI libraries are not the fastest.    Not too bad for Uno, Mega.
Zero is appalling.   STM32 from ST is worse than appalling.

So if you want the best performance you would need to write custom code.

It would make life much easier if you posted JPG, PNG, link, example, ... of the images you want to display.    How many.   How often.   ...



Have You thinked to increase the scale of your project?

Two screens would help you:

NHD 3.5" (FT813, 320x240 px)
EVE2-38G of Matrix Orbital (FT813, 480x116 px)

The MCU could be the teensy 3.6


Mar 19, 2019, 02:48 pm Last Edit: Mar 19, 2019, 02:51 pm by david_prentice
Please post a typical image.   

I don't know how you get 800ms to load a 128x128 BMP image.
I get about 1200ms for 128x160 with Adafruit_ST7735_and_ST7789_Library.

The theoretical "best" would be 103ms.
I suspect that I could get 200ms with Adafruit if I tried hard.

If you used ESP8266 you could get much better times and avoid the SD card.



Mar 19, 2019, 03:29 pm Last Edit: Mar 19, 2019, 03:30 pm by darbyvet
Thanks guys,
                   here is a pictures of the set up.I cant use a bigger tft because it wont fit inside the model.The 1.8 inch screen is the perfect size.I have also included the bmps I want to display on the screen.I can put the arduino behind the screen.

800ms was what the serial monitor output recorded after loading a file, but that was on a 1.44 inch screen

200ms would be fine. I know something about arduino.I dont know anything about ESP8266.


All your images are monochrome.   In fact they look as if they are two 64x64 images side-by-side.

This makes a massive difference.   You can store ten 64x64 monochrome images in 5120 bytes of Flash memory.   You could probably fit another twenty 64x64 monochrome images in a Uno.

Mind you,  E.png is not going to render very well in 64x64 pixels.   When you have an image like that it looks better if it is "anti-aliased".   i.e. you don't have just Blue or White pixels.   A thin line would use a Blue-White colour.    Your eyes will imagine more detail than actually exists.   e.g.  it will look like text from a distance.   As you get closer you realise it is just a blur.

Experiment with your PNG images on the PC.   You can make them larger or smaller.   The text will still be unreadable.



The images I uploaded were converted to .png because the forum wouldnt accept them as 24 bit bmp images for upload.In the sketch I use bmpDraw.

So are you saying I could store the images in the Arduino RAM so I dont have the delay in loading them from the SD card? If I did that I could they still be stored as .bmp files?  I could also just redraw the 2 64 by 64 areas rather than the whole screen

The details on the BMPS are not really critical.You will be viewing them through an open door in the model so you wont be able to get up close to them.

I think I will try using the bmpDraw and have it place the 2 64 by 64 images on the tft and see how fast that is.

FWIW here is a pic of the pod from 2001.I have a 1/8 model kit of the pod and want the screens to look like the ones in the picture.The model kit comes with decals of the different screens.I thought it would look cool to have the screens cycle through a few of the different screens and that is what I am trying to achieve .


Another question.The arduino bitmap drawing example has code in to write to the serial monitor to give upload times for the bmpDraw routine.if I delete that code would it speed things up any? I assume it must take some processing time to send data through the serial port to the PC.


Where did you get the original images?
Do you intend to use the TFT as 160x128 Landscape?

i.e. with 80x80 images
or with 64x64 images on a 128x160 or 128x128 Portrait?
set_up.jpg implies Portrait.
it also implies glazing bars around each image.   So they would be 60x60 rather than 64x64.
does your screen have a microSD holder?

You probably want to replace individual images rather than a pair.
The Adafruit spitftbmp.ino example will work fairly swiftly with smaller .BMP images.

And your PC will create a colour .BMP when you reduce the .PNG to the actual size that you want.
This will be anti-aliased and look better than a plain monochrome.

Sorry for the questions.    But if you are going to make a nice model it is worth getting these things correct from the start.



the original images were taken by my iphone from a sheet of decals supplied with the model kit.I plan on taking better pictures and resizing them once I have the software figured out

I intend to use the tft in landscape mode.The only reason they are in portrait is the wires from the breadboard interfere with the panel piece.When I make the actual pieces all the wires will come out of the back of the tft and wont interfere with the panel.

I plan on the images filling the whole of the windows in the panel so they would need to be about 70 by 70 pixels-I have to play around with the size to make them fill the window

Yes the screen has a micro SD card reader on the back.

I am going to try using the bmpDraw to place a 64 by 64 image onto the screen and see how quickly that works. I can do it so that only one of the 2 panels changes at once and that should speed things up too.

My first priority is to see if I can get the panels to draw quickly, then I will make sure they are exactly the right size to fit the panels and finally I will wire up the tft so it can be mounted directly behind the model kit part.

I want the rest of the screen to be white so it will illuminate the buttons on the panel.

Thanks for your help with this.If I can get it to work I think it will make a really cool model



OK so the pictures need to be 80 pixels by 80 pixels.I used bmpDraw to draw them on the screen.The draw time was now 380 ms per picture .I made a video and it is pretty good. I guess the only way to make it faster would be to write custom code which is beyond my skill level. I guess there in no way to post a video on this forum? Would removing the serial monitoring output in the sketch make any difference in the speed?


Go Up