Bodmer / TJpg_Decoder

Jpeg decoder library based on Tiny JPEG Decompressor
Other
228 stars 43 forks source link

Corrupted image-display on ESP32 with 4” ST7796 SPI-TFT-inc-SD (small white boxes on .jpg photo) #57

Closed Rob58329 closed 1 year ago

Rob58329 commented 1 year ago

When using “TJpgDec.drawSdJpg(0,0,path);” for a 240x320 jpg photo stored on the SD card, with this ST7796 TFT I get about 10 small white boxes on the displayed photo, I suspect caused by SD-card read errors: (I suspect that reading the SD card too soon after the TFT is written to often causes errors for this SD-mounted-on-the-TFT.) (Note this does NOT happen if using my other Adafruit-TFT-Dispays-inc-SDcard.)

This can be solved by adding a “delay(5);” in the “tjpgd.c” file before the “rc = mcu_load(jd)” line as shown below:

delay(5); // 4ms does not seem enough!
rc = mcu_load(jd)

(as well as the associated pre-definition “void delay(unsigned int);” at the top of the file somewhere).

This has the disadvantage that the photo now takes about 5seconds to fully display (approx 5ms*925), however for my application this is OK.

This display-time could possibly be reduced by increasing the size of the chunks of data read-in/processed (fewer chunks causes fewer delay(5)s).

A better option would probably be to modify “mcu_load()” to check the validity of the SD data read in, and if invalid then re-read it, but I haven’t tried this as for my application the above delay(5) fix is adequate.

PS1. I also note that for this TFT display you also often need to add a delay between a “time-consuming command” and the following command, as otherwise the following command is often incorrectly received, eg.

tft.fillScreen(TFT_BLACK);
delay(50); // necessary otherwise following command gets corrupted/misinterpreted
tft.setCursor(0,0); // top

PS2: I’m using the arduino-IDE v1.8.19 with a ESP32 DEVKITV1 with:

#define TFT_DC 2
#define TFT_CS 15
#define TFT_RST 16
#define SD_CS 4
#include "FS.h"
#include <SD.h>
#include <SPI.h>
SPIClass MySPI(HSPI);
Adafruit_ST7796S_kbv tft=Adafruit_ST7796S_kbv(&MySPI, TFT_DC, TFT_CS, TFT_RST);
tft.begin();
SD.begin(SD_CS,MySPI);

(I note the Touch-Screen usage for this TFT display is also mentioned in https://github.com/Bodmer/TFT_eSPI/issues/655, but this does not cover the above issue.)

UPDATE: removing/shorting D1 as suggested (below) by Bodmer seems to have solved my issues (ie. the above delay(5) and delay(50) are no longer necessary in my code!

Bodmer commented 1 year ago

Does your display have the diode described here: https://github.com/Bodmer/TFT_eSPI/discussions/898#discussioncomment-254870

It may be the cause of the problem and make the delay necessary.

Rob58329 commented 1 year ago

Bodmer: very many thanks for the above suggestion. You are spot on – shoring out D1 removed the need for both my suggested delay(5) [and my suggested delay(50)].

However, I am a little concerned that D1 might have been introduced because the “matrix_CS” requires a lower voltage than 3.3V. Did you ever put a meter on the “matrix_CS” pin of the 48pin FPC to see what voltage level it was operating at before removing D1?

Bodmer commented 1 year ago

Normally the diode is not present. The CS line is a standard 3.3V logic input, just like the MOSI, DC and SCK lines, so shorting the diode is not a problem.