Bodmer / TFT_eSPI

Arduino and PlatformIO IDE compatible TFT library optimised for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips
Other
3.84k stars 1.1k forks source link

Image pixelation when using TJpg_Decoder with ST7796 SD ESP32 #658

Closed sonnyk88 closed 4 years ago

sonnyk88 commented 4 years ago

I'm using ESP32 to interface ST7796S LCD & SDCARD with SPI.

The JPG image was stored in SDCARD and using TJpg_Decoder to display image onto LCD.

The code is working fine with ILI9488 but when I recompiled the code with ST7796S. The image has pixelation. st7796s_sd_pixelation

Bodmer commented 4 years ago

It looks like some MCU blocks are not being drawn or only partially drawn. Have you tried a lower SPI clock rate for the TFT?

Bodmer commented 4 years ago

Do the other examples provided with the library work OK?

Bodmer commented 4 years ago

Assumed stale.

Tszul commented 2 years ago

Alguien lo solucionó?, tengo exactamente el mismo problema...

Bodmer commented 2 years ago

Post an example sketch that is failing along with full details of the hardware setup (boards, display type, connections etc).

Do the other examples provided with TJpg_Decoder work OK?

Tszul commented 2 years ago

Primero debo mostrar que conseguí realizar el ejemplo de imágenes JPEG en un TFT shield para Arduino ILI9486 de 3,5" a 480x320 pixeles; así como para un display ST7735 de 1,8" a 160x128 pixeles. Se pueden observar en las dos primeras imágenes. En concreto es natural que sé modificar el archivo de usuario para las configuraciones de los tipos de pantalla que admiten la librería. Al intentar realizar los mismos pasos rutinarios para un display ST7796S de 4" a 480x320 pixeles muestra los mismos problemas que el compañero que abrió éste hilo. Cabe mencionar que al dibujar íconos de imágenes BMP descompuestas en cadenas de bytes en archivos con extensión .h no sucede lo mismo. 1 2 3 4

Tszul commented 2 years ago

Omití mencionar que estoy trabajando con ESP32-WROOM32, en el IDE de Arduino. Para no extenderme en mi comentario anterior, coloqué aquí el código de ejemplo que me ha venido funcionando.

include

TFT_eSPI tft = TFT_eSPI();

include

include

include

include

include

define BL 12 // BL = BACK LIGHT. ONLY ST7796

//////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////// void showTime(uint32_t msTime) { tft.setCursor(0, 0); tft.setTextFont(1); tft.setTextSize(2); //Stft.setTextColor(TFT_YELLOW, TFT_BLACK); tft.setTextColor(TFT_RED); tft.print(F(" JPG DRAWN IN: ")); tft.print(msTime); tft.println(F(" ms ")); } //#################################################################################################### // Draw a JPEG on the TFT, images will be cropped on the right/bottom sides if they do not fit //#################################################################################################### // This function assumes xpos,ypos is a valid screen coordinate. For convenience images that do not // fit totally on the screen are cropped to the nearest MCU size and may leave right/bottom borders. void jpegRender(int xpos, int ypos) { uint16_t pImg; uint16_t mcu_w = JpegDec.MCUWidth; uint16_t mcu_h = JpegDec.MCUHeight; uint32_t max_x = JpegDec.width; uint32_t max_y = JpegDec.height; bool swapBytes = tft.getSwapBytes(); tft.setSwapBytes(true); // Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs) // Typically these MCUs are 16x16 pixel blocks // Determine the width and height of the right and bottom edge image blocks uint32_t min_w = jpg_min(mcu_w, max_x % mcu_w); uint32_t min_h = jpg_min(mcu_h, max_y % mcu_h); // save the current image block size uint32_t win_w = mcu_w; uint32_t win_h = mcu_h; // record the current time so we can measure how long it takes to draw an image uint32_t drawTime = millis(); // save the coordinate of the right and bottom edges to assist image cropping // to the screen size max_x += xpos; max_y += ypos; // Fetch data from the file, decode and display while (JpegDec.read()) { // While there is more data in the file pImg = JpegDec.pImage ; // Decode a MCU (Minimum Coding Unit, typically a 8x8 or 16x16 pixel block) // Calculate coordinates of top left corner of current MCU int mcu_x = JpegDec.MCUx mcu_w + xpos; int mcu_y = JpegDec.MCUy mcu_h + ypos; // check if the image block size needs to be changed for the right edge if (mcu_x + mcu_w <= max_x) win_w = mcu_w; else win_w = min_w; // check if the image block size needs to be changed for the bottom edge if (mcu_y + mcu_h <= max_y) win_h = mcu_h; else win_h = min_h; // copy pixels into a contiguous block if (win_w != mcu_w) { uint16_t cImg; int p = 0; cImg = pImg + win_w; for (int h = 1; h < win_h; h++) { p += mcu_w; for (int w = 0; w < win_w; w++) { cImg = (pImg + w + p); cImg++; } } } // calculate how many pixels must be drawn //uint32_t mcu_pixels = win_w win_h; // 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.pushImage(mcu_x, mcu_y, win_w, win_h, pImg); else if ( (mcu_y + win_h) >= tft.height()) JpegDec.abort(); // Image has run off bottom of screen so abort decoding } tft.setSwapBytes(swapBytes); showTime(millis() - drawTime); // These lines are for sketch testing only } //#################################################################################################### // Draw a JPEG on the TFT pulled from SD Card //#################################################################################################### // xpos, ypos is top left corner of plotted image void drawSdJpeg(const char filename, int xpos, int ypos) { // Open the named file (the Jpeg decoder library will close it) File jpegFile = SD.open( filename, FILE_READ); // or, file handle reference for SD library // Use one of the following methods to initialise the decoder: bool decoded = JpegDec.decodeSdFile(jpegFile); // Pass the SD file handle to the decoder, //bool decoded = JpegDec.decodeSdFile(filename); // or pass the filename (String or character array) if (decoded) { // print information about the image to the serial port //jpegInfo(); // render the image onto the screen at given coordinates jpegRender(xpos, ypos); } else { tft.setTextSize(1); tft.setTextColor(TFT_WHITE, TFT_RED); tft.setCursor(100, 5); tft.print(F("JPG FILE FORMAT NO SUPPORTED")); } } void setup() { tft.begin(); pinMode(BL, OUTPUT); // BL = BACK LIGHT. ONLY ST7796 digitalWrite(BL, HIGH); // BL = BACK LIGHT. ONLY ST7796 SPI.begin(14, 2, 15, 13); //SCK, MISO, MOSI,SS SD.begin(13, SPI, 8000000); tft.fillScreen(TFT_BLACK); } void loop() { tft.setRotation(1); drawSdJpeg("/A.jpg", 0, 0); // THIS DRAWS A JPG PULLED OFF THE SD CARD. delay(5000); drawSdJpeg("/B.jpg", 0, 0); delay(5000); drawSdJpeg("/C.jpg", 0, 0); delay(5000); drawSdJpeg("/D.jpg", 0, 0); delay(5000); drawSdJpeg("/E.jpg", 0, 0); delay(5000); drawSdJpeg("/F.jpg", 0, 0); delay(5000); drawSdJpeg("/G.jpg", 0, 0); delay(5000); drawSdJpeg("/H.jpg", 0, 0); delay(5000); drawSdJpeg("/I.jpg", 0, 0); delay(5000); drawSdJpeg("/J.jpg", 0, 0); delay(5000); drawSdJpeg("/K.jpg", 0, 0); delay(5000); //while(1); // WAIT HERE. }

Bodmer commented 2 years ago

See #898. If your ST7796 board has a diode fitted then it will need to be bypassed with a shorting link.

Tszul commented 2 years ago

Es una maravilla, realmente funciona. Muchas gracias senior developer Bodmer. Quedó perfecto... IMG_20220127_203936

Bodmer commented 2 years ago

Great, glad it is fixed.

Jc096 commented 1 year ago

Hello great bodmer and anyone who can help me solve my fault, I have the same 320x480 ST7796 screen, I already replaced the diode with a bridge and changed the working speeds of the screen and my fault remains the same, I would appreciate any advice a lot, I attach a video of the failure and my pin configuration.

define TFT_MISO 19

define TFT_MOSI 23

define TFT_SCLK 18

define TFT_CS 5 // Chip select control pin

define TFT_DC 4 // Data Command control pin

define TFT_RST 17 // Reset pin (could connect to RST pin)

Alguien que tenga algun consejo para solucionar esta falla se los agradezco! ya realice todos los pasos de este post y mi falla sigue igual. puente1

https://github.com/Bodmer/TFT_eSPI/assets/143748869/aee685e0-9c74-4e65-b46a-64e6cdddb358

puente