im doing job project on arduino that is reading .bmp pictures on sdcard and writing it on 320x240 tft color display whit ILI9341 driver.
The pictures(even small, like 60x60) load visually slow(line after line), but when writing some complex multicolored shapes of same dimensions(60x60 rainbow, composed by strings) it is almost instantaneous.
So from this i assume that problem is that speed of reading from the SD card is not fast enought to keep up whit writing down the pictures itself on the screen.
Is there anyway to speed up the SD card file read?
I also tried pararell mode instead of SPI mode, the shapes draw even faster, but the .bmp files still draw slowly whit same speed.
In the attachement is bitmap read from SDcard sketch. I use adafruit ili9341+adafruit gfx library.
you should read the BMP file at once into memory as a blob and do the decoding from memory.
Now you are reading one byte at the time and that is very inefficient.
Note that this reading might use quite some RAM.
As sectors on an SD card are typically 512 bytes you could start with a buffer of 512 bytes. And only reread from disk when needed. A buffer of 256 or 128 bytes should improve performance also. Try change BUFFPIXEL to 50.
Never did it on an Arduino, but it was common practice previous century when reading from floppies..
klemko:
So from this i assume that problem is that speed of reading from the SD card is not fast enought to keep up whit writing down the pictures itself on the screen.
Is there anyway to speed up the SD card file read?
The solution to speed things up would be: Handle as much bytes as possible in one chunk.
Your TFT is also using SPI, isn't it?
Currently you code does that:
switch SPI bus to SD card, read one pixel from SD card
switch SPI bus to TFT, push one pixel to TFT
This is the slowest possibility.
If I'd make a guess, this would speed up things very much:
switch SPI bus to SD card, read 20 pixels from SD card in one chunk
switch SPI bus to TFT, push 20 pixels to TFT
I'm guessing this will be possibly 10 times faster than what you are doing now.
Switching the SPI bus from device to device is done in your libraries code, so speeding up your code would mean: Reduce the number of read/write commands and instead of "single byte read/write commands" use "blockread/blockwrite commands" where your libraries allows.
If i raise buffpixel to 50, the time to draw 300x200 picture goes from 4,7 to 4,1sec. If i raise it above 50 the processors runs out of memory and only displays black screen or some random vertical lines.
So i assume i need to wire in and program pararel ram chip if i want to draw faster?
I also thought about modifing the bmpDraw function to ignore black dots(background color) and only read the others. That would reduce the number of dots to read significantly but i dont know if that is possible since dots stil needs to be read for program to see the color. But still if it is black it would not be written to atmegas328 memory.
Im thinking of converting the bmp files to native/rgb code on laptop and then load those files to the sdcard, so i could only call those files from sd card and write directly to display(no need for conversion of 24bit files to rgb that is done on atmega currently and takes long time to do it).
But in that case i need to modifiy my bmpDraw function to call hex code and display it.
What is an option is to gather run lengths of the same colour on a line and then print them with a tft.line command. That would reduce the # tft calls.
I did manage to optimise the spitftbitmap sketch to a point that i can draw pictures 100x100 or smaller in under 100ms and 50x50 under 30ms which is all i needed
When i get some time to spare, i will also try to make this library work whit bitmaps in HEX code, that could speed it up, we will see.