Go Down

Topic: 3.5 SPI Display problem of displaying Jpeg images (Read 568 times) previous topic - next topic

ketineni

Hi,  I have a strange problem,  where the  jpeg displayed  shows distortion at the area where there is plain color,  problem is specific to this display. 

Using  Jpegdecoder,  TFT_ESPI   

Using 3.5 inch SPI display  MSP3520 ,  with ILI9488 driver

User_Setup.h  file , selected  ILI9488,  ESP8266 Setup default pins specified. 

Attaching the pictures original and as displayed on the display. If the picture has lot of things in it, it is displayed properly or as if looks like it is in proper condition,  however if there is a region where there is plain color or color gradient such as sky,  it shows like some compressed image within that area .  example a color gradient button is displayed as rectangles of color patches instead of smooth button. The problem  happens with ILI9488 with 3.5 SPI,  the  problem does not exist with 2.8SPI ILI9341 same graphic files.

Looking for a solution
Thank you.

ketineni

If it helps, 

I have created a button with color gradient,  and converted the file to C array,  used this file to display (drawArrayJpeg) and it works fine,  the same  jpg file if I store it in SPIFF,  and if i use  drawJpeg  it displays distorted image.

david_prentice

Yes,  it renders in very low resolution for ILI9488.
It works fine on ILI9341.

Most controllers use 2 SPI bytes per pixel.
The ILI9488 requires 3 SPI bytes per pixel.

I suspect that it is pushRect().   Bodmer will investigate.

David.

david_prentice

I am too idle to fix the library.   But this should get you going:

Replace the pushRect() statement with this sequence:
Code: [Select]

    // draw image MCU block only if it will fit on the screen
    if ( ( mcu_x + win_w) <= tft.width() && ( mcu_y + win_h) <= tft.height())
    {
//      tft.pushRect(mcu_x, mcu_y, win_w, win_h, pImg);
      tft.setAddrWindow(mcu_x, mcu_y, win_w, win_h);  //new Adafruit
      uint32_t mcu_pixels = win_w * win_h;
      while (mcu_pixels--) {
        uint16_t color = *pImg++;
        color = (color >> 8) | (color  << 8);
        tft.pushColor(color);
      }
    }


Unzip the attachment into your sketch directory.
You can use ESP8266 Sketch Data Upload to put all the sample JPG files into SPIFFS
Then run the sketch.

David.

ketineni

Hello David, 

Am very thankful for your time, and the Code fix has worked, pictures are showing up much better now, for a minute thought i was doing some mistake in some setting.

What I have is in place of pushRect()

//  tft.pushImage(mcu_x, mcu_y, win_w, win_h, pImg);

replaced this line with your code. 

So is this like something specific that was required for ili9488 chip.

David or Bodmer

Please answer only when free, it was taking 350ms max to display full image on 2.8 display, but with 3.5 inch display, it's taking 1200ms to display full image, is this normal, both cases spi is operating at 27Mhz

Thank you very much.

david_prentice

ILI9488 needs 320x480x3 SPI bytes.
ILI9341 needs 240x320x2 SPI bytes e.g. 350ms.

This means 1050ms for the bigger picture.    Purely because of more SPI traffic.

Obviously a fixed pushImage() will be faster than the individual pushColor() calls in my kludge.

There is plenty of scope for optimisation.   Actually the SPI traffic maths calculation is naive.    The bulk of the time is spent decoding JPG and creating the 16-bit or 24-bit pixel.

David.

ketineni

Thanks David,  actually  it was taking 1.7 to 2.2 seconds,  depending on picture, but 1.686 is minimum on Esp32, The spi  frequency change did not make much of difference hardly 100ms. so looks like it is taking lot of cpu for jpeg decode conversion. Well  It should be ok for now.   

david_prentice

#7
May 18, 2019, 11:55 am Last Edit: May 18, 2019, 12:02 pm by david_prentice
I have found the problem.   Edit TFT_eSPI.h
from
Code: [Select]

  // Convert swapped byte 16 bit colour to 18 bit and write in 3 bytes
  #define tft_Write_16S(C) spi.transfer(C & 0xF8); \
                           spi.transfer((C & 0xE0)>>11 | (C & 0x07)<<5); \
                           spi.transfer((C & 0x1F00)>>5)

to:
Code: [Select]

  // Convert swapped byte 16 bit colour to 18 bit and write in 3 bytes
  #define tft_Write_16S(C) spi.transfer(C & 0xF8); \
                           spi.transfer((C & 0xE000)>>11 | (C & 0x07)<<5); \
                           spi.transfer((C & 0x1F00)>>5)

It makes little difference using pushRect(), pushImage(), pushColors(..., false) or pushColor() in a loop.
sunfl.jpg takes 2293ms, 2293ms, 2287ms, 2293ms on an ESP8266

Most of the time is spent in decoding JPEG.
ESP32 will be faster than ESP8266.

There might be optimisations for the JPEG decode algorithm.

Personally,  I find the convenience of SPIFFS to be impressive.   You can get lots of JPEGS into a 1MB SPIFFS.   Of course an SD card gives you unlimited quantity of pictures and you can use RAW pixel dumps.

On balance,  a compressed JPG avoids the SPI transfer time of a RAW file from SD.
The ESP32 supports QSPI SD card.   I have never tried QSPI.

David.

ketineni

David, am  gonna try that fix  first in the morning, yes am using SPIFFS only,  and 1MB is enough to rotate like 10 pics, and any supported graphic files.  SD card  is not required at this point,   The time taken for JPEG C Array is at 700ms so the important one file am gonna call from Array for now and rest from SPIFFS, that would solve the time issue.

ketineni

I have removed the old fix and applied new one by changing the below line ,  the images are fine , displaying normally,  the jpeg which was taking 2.2 sec is now taking   just one second,  this has lot of detail etc.
Thank you again, the problem is solved.
 
spi.transfer((C & 0xE000)

david_prentice

I am impressed.   I only ran it on ESP8266.   I would not expect such a big difference.

If you tried the ZIP that I had attached,   it reports files found on SPIFFS.   And the rendering time for each file that matches the strstr() line.   e.g. strstr("sunfl.jpg")

In other words.   You could quote the actual number of milliseconds for "sunfl.jpg"
We could compare the same JPEG image.

David.

ketineni

David, the  kbv code required changes  to run on esp32,  so I have used the old same sketch to display sunfl.jpg  ,  SPIFFS_Jpeg  sketch from examples of jpegdecoder  ,  the performance difference between esp32 and esp8266 should not be that much but  the time is  700ms

===========================
Drawing file: /sunfl.jpg
===========================
===============
JPEG image info
===============
Width      :320
Height     :480
Components :1
MCU / row  :20
MCU / col  :30
Scan type  :4
MCU width  :16
MCU height :16
===============

Total render time was    : 730 ms
=====================================

bodmer

I have found the problem.   Edit TFT_eSPI.h

...

Library has been updated, thanks David.

david_prentice

#13
May 19, 2019, 01:05 pm Last Edit: May 19, 2019, 02:09 pm by david_prentice
This is the result from the ESP8266 using ESP8266 v2.4.2 Core
Code: [Select]

NodeMCU decoder test!

Initialisation done.

SPIFFS files found:
=====================================
  File name               Size
=====================================
/Baboon40.jpg            24384 bytes
/waterlily.jpg           44762 bytes
/bapa.jpg                26797 bytes
/betty_8.jpg             17422 bytes
/chinese_girl.jpg        46034 bytes
/woof.jpg                19000 bytes
/dog.jpg                 18163 bytes
/EagleEye.jpg            20838 bytes
/flower.jpg              23879 bytes
/flower3.jpg             32385 bytes
/flower4.jpg             30836 bytes
/hibiscus.jpg            26372 bytes
/lena20k.jpg             19414 bytes
/tiger_320x200x24.jpg    29484 bytes
/marilyn_240x240.jpg     9402 bytes
/MOTO_CORRIDA.jpg        18450 bytes
/Mouse480.jpg            6609 bytes
/Parrot2.jpg             17393 bytes
/Penguins.jpg            29719 bytes
/purple.jpg              32042 bytes
/rose.jpg                9243 bytes
/sunfl.jpg               32187 bytes
/tiger.jpg               31171 bytes
/angry_16.jpg            18267 bytes
=====================================

  1: /Baboon40.jpg        320x480 2320 ms
  2: /waterlily.jpg       400x300 2052 ms
  3: /bapa.jpg            250x315 1245 ms
  4: /betty_8.jpg         204x252 823 ms
  5: /chinese_girl.jpg    320x480 2502 ms
  6: /woof.jpg            240x320 1218 ms
  7: /dog.jpg             284x177 824 ms
  8: /EagleEye.jpg        300x300 1336 ms
  9: /flower.jpg          240x320 1261 ms
 10: /flower3.jpg         320x240 1329 ms
 11: /flower4.jpg         320x240 1310 ms
 12: /hibiscus.jpg        240x320 1282 ms
 13: /lena20k.jpg         320x480 2247 ms
 14: /tiger_320x200x24.jpg 320x200 1154 ms
 15: /marilyn_240x240.jpg 240x240 861 ms
 16: /MOTO_CORRIDA.jpg    320x240 1211 ms
 17: /Mouse480.jpg        480x320 2078 ms
 18: /Parrot2.jpg         261x200 875 ms
 19: /Penguins.jpg        320x240 1305 ms
 20: /purple.jpg          240x320 1333 ms
 21: /rose.jpg            176x220 611 ms
 22: /sunfl.jpg           320x480 2292 ms
 23: /tiger.jpg           320x240 1330 ms
 24: /angry_16.jpg        240x320 1179 ms

I had already updated ESP32 to ESP32 Core v1.0.2
I had to amend the SPIFFS calls to suit v1.0.2
and this is the result for ESP32 using ESP32 Core v1.0.2 @ 240MHz SPI=27MHz
Code: [Select]

NodeMCU decoder test!

Initialisation done.
Listing directory: /
  FILE: /angry_16.jpg SIZE: 18267
  FILE: /Baboon40.jpg SIZE: 24384
  FILE: /bapa.jpg SIZE: 26797
  FILE: /betty_8.jpg SIZE: 17422
  FILE: /chinese_girl.jpg SIZE: 46034
  FILE: /dog.jpg SIZE: 18163
  FILE: /EagleEye.jpg SIZE: 20838
  FILE: /flower.jpg SIZE: 23879
  FILE: /flower3.jpg SIZE: 32385
  FILE: /flower4.jpg SIZE: 30836
  FILE: /hibiscus.jpg SIZE: 26372
  FILE: /lena20k.jpg SIZE: 19414
  FILE: /marilyn_240x240.jpg SIZE: 9402
  FILE: /MOTO_CORRIDA.jpg SIZE: 18450
  FILE: /Mouse480.jpg SIZE: 6609
  FILE: /Parrot2.jpg SIZE: 17393
  FILE: /Penguins.jpg SIZE: 29719
  FILE: /purple.jpg SIZE: 32042
  FILE: /rose.jpg SIZE: 9243
  FILE: /sunfl.jpg SIZE: 32187
  FILE: /tiger.jpg SIZE: 31171
  FILE: /tiger_320x200x24.jpg SIZE: 29484
  FILE: /waterlily.jpg SIZE: 44762
  FILE: /woof.jpg SIZE: 19000
  1: /angry_16.jpg        240x320 394 ms
  2: /Baboon40.jpg        320x480 771 ms
  3: /bapa.jpg            250x315 453 ms
  4: /betty_8.jpg         204x252 273 ms
  5: /chinese_girl.jpg    320x480 868 ms
  6: /dog.jpg             284x177 275 ms
  7: /EagleEye.jpg        300x300 445 ms
  8: /flower.jpg          240x320 418 ms
  9: /flower3.jpg         320x240 478 ms
 10: /flower4.jpg         320x240 473 ms
 11: /hibiscus.jpg        240x320 463 ms
 12: /lena20k.jpg         320x480 750 ms
 13: /marilyn_240x240.jpg 240x240 287 ms
 14: /MOTO_CORRIDA.jpg    320x240 401 ms
 15: /Mouse480.jpg        480x320 695 ms
 16: /Parrot2.jpg         261x200 289 ms
 17: /Penguins.jpg        320x240 470 ms
 18: /purple.jpg          240x320 479 ms
 19: /rose.jpg            176x220 203 ms
 20: /sunfl.jpg           320x480 802 ms
 21: /tiger.jpg           320x240 477 ms
 22: /tiger_320x200x24.jpg 320x200 415 ms
 23: /waterlily.jpg       400x300 712 ms
 24: /woof.jpg            240x320 403 ms

Note that the ESP32 was faster than ESP8266 but I did not get 730 ms
Code: [Select]

 20: /sunfl.jpg           320x480 802 ms

I updated my ESP8266 installation to v2.5.1 but could not get any TFT_eSPI examples to compile.
I will try installing v2.5.0.  Otherwise I will have to go back to v2.4.2

David.

Edit.  Woo-hoo.  ESP8266 v2.5.0 will compile and run but it is very SLOW.  e.g. sunfl.jpg: 3677 ms @ 160MHz.  4418 ms @ 80MHz   ( SPI=27MHz )
Code: [Select]

Using library JPEGDecoder at version 1.8.0 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\JPEGDecoder
Using library SD at version 1.0.5 in folder: C:\Users\David Prentice\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\libraries\SD
Using library SPI at version 1.0 in folder: C:\Users\David Prentice\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\libraries\SPI
Using library TFT_eSPI at version 1.4.9 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\TFT_eSPI
"C:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-3-20ed2b9/bin/xtensa-lx106-elf-size" -A "C:\\Users\\DAVIDP~1\\AppData\\Local\\Temp\\arduino_build_573353/TFT_SPIFFS_Jpeg_kbv.ino.elf"
Sketch uses 332688 bytes (31%) of program storage space. Maximum is 1044464 bytes.
Global variables use 31364 bytes (38%) of dynamic memory, leaving 50556 bytes for local variables. Maximum is 81920 bytes.

ketineni

#14
May 19, 2019, 02:27 pm Last Edit: May 19, 2019, 02:45 pm by ketineni
Sorry,  my spi is at 40Mhz,  at some point I was testing and left it there,  that's why 730ms.

Same sketch and same jpeg  retested at 27Mhz, it matches now.

===========================
Drawing file: /sunfl.jpg
===========================
===============
JPEG image info
===============
Width      :320
Height     :480
Components :1
MCU / row  :20
MCU / col  :30
Scan type  :4
MCU width  :16
MCU height :16
===============

Total render time was    : 801 ms
=====================================

Go Up