Arduino ILI9341 display RGB pictures fast

Go To Last Post
20 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

im using adafruit GFX and ILI9341 library. I am reading BMP pictures from SD card, convert them to RGB and then push to TFT display.

This process takes 2 to 3,5 seconds to finish, but i want the image to be displayed almost instantaneously. I tried raising the chunks of bits being porcessed but the atmegas328 memory jsut isnt big enought to make big difference so i need to get rid of the conversion from 24bit to rgb format, which takes most of the time required for the process.

So is it possible to convert all my pictures and icons(about 40 of them) and convert them to raw rgb/hex file and put that on the SD card, so i could just make program to read them and write to ILI9341 driver directly, whithout wasting time for slow conversion from 24bit gmp to rgb?

 

Example sketch is in the attachement.

Attachment(s): 

This topic has a solution.

Last Edited: Tue. Dec 29, 2015 - 07:22 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

short yes

 

How big are your pictures?

You have to find out how the convertion are made so take a look at :

 tft.pushColor(tft.color565(r,g,b));

And if you can find out how many clk's it take, it will help to find your bottleneck.

It should not take many clk's but it depends of the lib.(in ASM it would be able to feed the SPI port)

If you use SPI at about 5MHz, a 240x320 will take in the ballpark of 1/3 of a sec.

 

But it will be faster in the tft format (than BMP) because the file will be smaller  , do you want to do the conversion with the AVR or your PC?

 

Do you run many ISR's at the same time?

 

 

Last Edited: Mon. Dec 28, 2015 - 01:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I want to do the conversion on my PC, so the AVR(arduino 328) only has to read the files from SD card and send them to TFT LCD ILI9341 driver as fast as possible.

I dont run any ISR(in system interrupt), because this microprocessor is only here for displaying specific images on lcd according to signals it gets from my main avr.

Yea i tried to find info about that tft.pushcolor command in lib files, but i cant find any info on it, so now im doing some experimentating whit it. 

 

Last Edited: Mon. Dec 28, 2015 - 01:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Think about it. You have to read 240x320 pixel colors from your SD card by SPI. i.e. 154kB
And blit them to the TFT by SPI. i.e. 154kB.

So it is physically impossible to do anything faster than 308ms with 8MHz SCK.

Sevaral SD libraries will only go at 4MHz. And they might be reading sectors and copying them elsewhere.
And the typical Arduino user will probably choose to bit bang SPI rather than use the hardware.
The mega SPI peripheral cannot run without gaps.
The USART_MSPI peripheral can achieve maximum throughput but you probably use the USART for Serial comms.

Yes, you can do the BMP to RAW conversion and store this on SD card.

Or use the Xmega DMA. Which could run at 16MHz with no gaps.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks. 99% of the time im actually writing 60x60 and 20x30 icons.

I tested writing(via library drawRectangle command) some shapes of 60x60 size via SPI and they load instantaneusly to a naked eye, while when i use same BMP of same sizes and color, that same picture and then write it via conversion and takes around 3 seconds. So the SPI itself is fast enought to write small icons fast enought, but i just need to get rid of conversion on atmega itself.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If your icons are simple, just draw them with graphics primitives.
Yes, 30x30 is a lot faster than 240x320.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

they are still multicolored(bottles whit logs on, sun, etc....) so i need to keep the, on sd card. But even 30x30 pictures are so slow that user can see it being loaded line by line. I will try to tomdify and optimise the ILI9341 adafruit library first and see to what speed i can get it and then i will also try to modify it so it will load raw instead of bmp files from sd card.

At the moment time takes to write 320x240 or 30x30 image is pretty much the same, so im sure there is a bottleneck somewhere in the program itself. I will study this example code and then try to come up whit my own one and hopefully that one will work faster.

Last Edited: Mon. Dec 28, 2015 - 02:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You must be doing something wrong. I use the pushColors() method. I was surprised to see that Adafruit changed the API for their 9341 SPI library.
You simply use setAddrWindow() for the 30x30 box, and blit 900 pixels via pushColors().

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What do you mean by pushColors method?

Sorry but i really dont ahve any experience using any displays on avrs.

Last Edited: Mon. Dec 28, 2015 - 02:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Adafruit_TFTLCD.h library has pushColors() method.
Adafruit_ILI9341.h library has pushColor() method.

I implement the pushColors() method but they both do the same thing.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I suspect that you are using Adafruit's SPI software emulator to transfer data to the ILI9341 instead of the Arduino's hardware SPI.  Check if the TFT constructor in the .ino file is sending a value for the SCK, MISO, and MOSI pins along with the value for the CS, DC, and RESET pins.   The fast version of the TFT constructs looks like this:

 

Adafruit_ILI9340 tft = Adafruit_ILI9340(_cs, _dc, _rst);  //[ I use the Adafruit_ILI9340 library for the 2.2" 320x240 TFT (no touchscr) as it seems to be more stable.]

 

You don't need to be concerned about the speed of the conversion of the BMP file's R_G_B to the 16-bit format that Arduino sends to the ILI9341.  Each pixel's conversion takes only about 5-10 microseconds.  The function is taking the most significant five bits of the Red and Blue values and the six MSB bits of the Green value and shifting them into a single 16-bit value.  This does alter the color balance of the BMP image on the TFT screen because colors have only 32 levels instead of 256 levels.

 

The Adafruit draw-pixel function is designed to be flexible and reliable instead of fast.   For each pixel, the function makes a screen "window" that is only one pixel is size. Then the 16-bit pixel is written to that "window".   For screen clears and fill_Rectangles, the screen window is set only once to be the size of the entire screen or the rectangle size.  Then a constant pixel color value is sent thousands of times to the TFT.  The ILI9341 places each pixel value received onto the LED screen adjacent to the previous pixel displayed and adjusts into internal screen memory pointer.

 

The Arduino TFT  2.2" 320x240 should fill with a BMP screen in about 2 seconds using the default Adafruit libraries.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

pushColors() is the multi-colour equivalent of a single colour fillRect().

i.e. it will fill the rectangle set by setAddrWindow() with 16-bit colours from a block of memory.

 

It should take a similar time to draw different colours as to fill an area with a single colour.

 

However there is a trick with the 16-bit parallel interface where you can load the 16-bit PORT with a single colour once and just strobe the write line.   This is not applicable to the AVR 8-bit SPI interface.    It is applicable to a 16-bit SPI with DMA.

 

David.

Last Edited: Mon. Dec 28, 2015 - 09:20 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I checked and it uses hardware ISP. The write speed to TFT is fast enought for instantaneous appear effect, but not when reading bmp from sdcard. Now i get some random picture raw hex code and pasted that to sd card and modified library example to call hex instead of bmp and it works great and fast. Thanks for all the help :DD

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi I want to report that your sketch is not working for me, I onle get my screen blue.

What can be wrong?

My code is the same as yours, but I added the line 

//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are using a TFT with a SPI interface.  The fastest that it can transfer data from both the SD to the CPU buffer, and then from that CPU buffer to the TFT is about 10-15 microseconds per pixel.  Then there is all the background work to set up the pixel's position, etc...

 

Consider switching to a TFT with a parallel port interface (8080-interface).  They are the same price yet interface ten times faster.  You use the MCUFRIEND library instead of the AdaFruit one. 

 

Most parallel-port TFTs are sold on ebay as touch screens.  And some have actual working touch screens that can be made functional.  These TFTs often have the pads for installing a SOIC 8-pin 32Kx8 Serial SPI SRAM that can be used as cache memory.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am just worried because it is not working. No image is loaded to my screen. By now I don't care about speed.

What it can be?

Thanks for your answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Post a link to the actual screen that you have bought.   e.g. the Ebay sale.

 

Alternatively post a photo of the pcb side of the display.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi here are the pictures. I cant make it work for the SD.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have a regular SPI ILI9341 board.

 

It needs 3.3V GPIO levels on the logic pins.   5V on VCC pin (which feeds the onboard LDO regulator)

Ideally you use a proper 3.3V Arduino like Zero or Due.

Otherwise use external level converters if you are determined to use 5V GPIO.

 

Install/Update Adafruit_ILI9341 and Adafruit_GFX  via Arduino Library Manager.

Always use full-fat constructors i.e. with TFT_RST argument

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);

The library examples should all work (if you have TFT_RST argument).

 

I have the same board as you.  I can confirm it works very well with Zero, Due, ESP8266, ESP32, STM32, Xmega, 3.3V AVRs

Post a pencil sketch of your schematic if you want help.

 

Oh,   every third party SPI ILI9341 library works fine with your display.

Quote library version numbers with any question.

 

David.

Last Edited: Fri. Jan 18, 2019 - 03:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sdanielpaz88 wrote:
Hi here are the pictures. I cant make it work for the SD.

It looks like you need to add a 4 pin connector to access the SD card, just a guess.

 

Jim

 

 

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...