Strange behaviour Crow Panel HMI Advanced 7inch Lesson4 - displaced sccreen

Hello.
I'll say right away - I'm a complete beginner..
I have a Crow Panel Advanced HMI 7 inch panel in my tests.
During lesson 4 - photos from SD CARD - the photos are loaded but the image is shifted a few dozen pixels to the left. I hope you can see it well in the photos I'm attaching.
The panel resolution is set correctly - I'm attaching the code
Second thing - with the standard parameter
cfg.freq_write = 21000000; the image flickers when loading - it's like it's waving.
After setting cfg.freq_write = 14000000; - everything is ok
Setting below 14 only causes a white screen

SD_CrowPanel_ESP32_Advance_HMI_4_3_5_0_7_0.ino

    #include "pins_config.h"
    #include "LovyanGFX_Driver.h"
    #include <Wire.h>
    #include <SPI.h>
    #include <FS.h>
    #include <SD.h>
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_GFX.h>

    /* Expand IO */
    #include <TCA9534.h>
    TCA9534 ioex;

    #define SD_MOSI 6
    #define SD_MISO 4
    #define SD_SCK 5
    #define SD_CS 0 //The chip selector pin is not connected to IO

    // The image name you stored on the SD card
    #define IMAGE_1 "/1.bmp"
    #define IMAGE_2 "/2.bmp"
    #define IMAGE_3 "/3.bmp"
    #define IMAGE_4 "/4.bmp"
    // #define IMAGE_5 "/5.bmp"

    SPIClass SD_SPI = SPIClass(HSPI);
    LGFX gfx;

    // Display text on the screen
    void show_test(int lcd_w, int lcd_h, int x, int y, const char * text) {
      gfx.fillScreen(TFT_BLACK);
      gfx.setTextSize(3);
      gfx.setTextColor(TFT_RED);
      gfx.setCursor(x, y);
      gfx.print(text); 
    }

    void setup()
    {
      Serial.begin(115200); // set baud rate

     // Init Display
      gfx.init();
      gfx.initDMA();
      gfx.startWrite();
      gfx.fillScreen(TFT_BLACK);
      delay(500);

      Wire.begin(15, 16);
      delay(50);
      ioex.attach(Wire);
      ioex.setDeviceAddress(0x18);
      ioex.config(1, TCA9534::Config::OUT);
      /* Turn on backlight */Serial.println("Refreshing image...5");

      ioex.output(1, TCA9534::Level::H);

      if (SD_init() == 0)
      {
        Serial.println("TF_Card initialization succeeded");
        show_test(LCD_H_RES, LCD_V_RES, 800, 480, "SD_Card OK");
        delay(3000);
      } else {
        Serial.println("TF card initialization failed");
        show_test(LCD_H_RES, LCD_V_RES, 800, 480, "SD_Card failed");
        delay(3000);
      }
      gfx.setRotation(2);
      gfx.fillScreen(TFT_BLACK);
      Serial.println( "----- Setup done -----" );
    }

    void loop()
    {
     // Cycle printing each image
      Serial.println("Refreshing image...1");
      displayImage(SD, IMAGE_1, 800, 480);
      delay(5000);

      Serial.println("Refreshing image...2");
      displayImage(SD, IMAGE_2, 800, 480);
      delay(5000);

      Serial.println("Refreshing image...3");
      displayImage(SD, IMAGE_3, 800, 480);
      delay(5000);

      Serial.println("Refreshing image...4");
      displayImage(SD, IMAGE_4, 800, 480);
      delay(5000);

      // Serial.println("Refreshing image...5");
      // displayImage(SD, IMAGE_5, 800, 480);
      // delay(5000);
    }

    // SD card initialization
    int SD_init()
    {
      SPI.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS);

      SD_SPI.begin(SD_SCK, SD_MISO, SD_MOSI);
      if (!SD.begin(SD_CS, SD_SPI, 80000000))
      {
        Serial.println(F("ERROR: File system mount failed!"));
        SD_SPI.end();
        return 1;
      }
      else
      {
        Serial.println("Card Mount Successed");
        Serial.printf("SD Size: %lluMB \n", SD.cardSize() / (1024 * 1024));
        // hspi->end();
      }
      listDir(SD, "/", 2);
      Serial.println("**** TF Card init finished ****.");
      return 0;
    }

    /*
    Function: List files and subdirectories in the specified directory.
    Parameters:
      - fs: The file system object used to operate on the file system.
      - dirname: A pointer to the name of the directory whose contents are to be listed.
      - levels: Specifies the depth of recursive listing of subdirectories.
    */
    void listDir(fs::FS & fs, const char *dirname, uint8_t levels) {
      Serial.printf("Listing directory: %s\n", dirname); 
      File root = fs.open(dirname); // Open the specified directory.
      // If the directory cannot be opened.
      if (!root) { 
        Serial.println("Failed to open directory"); 
        return; 
      }
      // If the opened item is not a directory.
      if (!root.isDirectory()) { 
        Serial.println("Not a directory"); 
        return; 
      }
      File file = root.openNextFile(); // Open the next file in the directory.
      // While there are still files.
      while (file) { 
        // If the current file is a directory.
        if (file.isDirectory()) { 
          Serial.print("  DIR : "); 
          Serial.println(file.name()); // Print the directory name.
          // If there are still levels of depth for recursion.
          if (levels) { 
            listDir(fs, file.name(), levels - 1); // Recursively call the function to list the contents of the subdirectory, reducing the depth by 1.
          }
        } 
        // If the current file is not a directory, i.e., a regular file.
        else { 
          Serial.print("  FILE: "); 
          Serial.print(file.name()); // Print the file name.
          Serial.print("  SIZE: "); 
          Serial.println(file.size()); // Print the file size.
        }
        file = root.openNextFile(); // Continue to open the next file in the directory.
      }
    }

    /*
      Function:wrong position 7
        - Display image from file
      Parameters:
        - fs: The file system object
        - filename: The name of the BMP image file
        - x: The x - coordinate on the screen to start printing the image
        - y: The y - coordinate on the screen to start printing the image
      Returns:
        - 0 if the image is printed successfully, 0 if the file cannot be opened
    */
    int displayImage(fs::FS &fs, String filename, int x, int y)
    {
        File f = fs.open(filename, "r"); // Open the file for reading
        if (!f)
        {
            Serial.println("Failed to open file for reading");
            f.close();
            return 0; // File open failed, return 0
        }
        f.seek(54); // Skip the 54 - byte BMP file header
        int X = x; // representing the width of the image
        int Y = y; // representing the height of the image
        uint8_t RGB[3 * X]; // Storage space for RGB data of each row, 320 pixels, 3 bytes per pixel (RGB)

        for (int row = 0; row < Y; row++) // Iterate through each row of the image
        {
            f.seek(54 + 3 * X * row); // Jump to the position of the current row
            f.read(RGB, 3 * X); // Read the RGB data of the current row
            gfx.pushImage(0, row, X, 1, (lgfx::rgb888_t *)RGB); // Display the data of the current row
        }
        f.close(); // Close the file
        return 0; 
    }

LovyanGFX_Driver.h:

#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>
#include <driver/i2c.h>

class LGFX : public lgfx::LGFX_Device {
public:

  lgfx::Bus_RGB _bus_instance;
  lgfx::Panel_RGB _panel_instance;
//  lgfx::Light_PWM _light_instance;
  lgfx::Touch_GT911 _touch_instance;

  LGFX(void) {
    {
      auto cfg = _panel_instance.config();

      cfg.memory_width = 800;
      cfg.memory_height = 480;
      cfg.panel_width = 800;
      cfg.panel_height = 480;

      cfg.offset_x = 10;
      cfg.offset_y = 0;

      _panel_instance.config(cfg);
    }

    {Serial.println("Refreshing image...5");

      auto cfg = _panel_instance.config_detail();

      cfg.use_psram = 1;

      _panel_instance.config_detail(cfg);
    }

    {
      auto cfg = _bus_instance.config();
      cfg.panel = &_panel_instance;
      cfg.pin_d0 = GPIO_NUM_21;    // B0
      cfg.pin_d1 = GPIO_NUM_47;    // B1
      cfg.pin_d2 = GPIO_NUM_48;   // B2
      cfg.pin_d3 = GPIO_NUM_45;    // B3
      cfg.pin_d4 = GPIO_NUM_38;    // B4
      cfg.pin_d5 = GPIO_NUM_9;    // G0
      cfg.pin_d6 = GPIO_NUM_10;    // G1
      cfg.pin_d7 = GPIO_NUM_11;    // G2
      cfg.pin_d8 = GPIO_NUM_12;   // G3
      cfg.pin_d9 = GPIO_NUM_13;   // G4
      cfg.pin_d10 = GPIO_NUM_14;   // G5
      cfg.pin_d11 = GPIO_NUM_7;  // R0
      cfg.pin_d12 = GPIO_NUM_17;  // R1
      cfg.pin_d13 = GPIO_NUM_18;  // R2
      cfg.pin_d14 = GPIO_NUM_3;  // R3
      cfg.pin_d15 = GPIO_NUM_46;  // R4

      cfg.pin_henable = GPIO_NUM_42;
      cfg.pin_vsync = GPIO_NUM_41;
      cfg.pin_hsync = GPIO_NUM_40;
      cfg.pin_pclk = GPIO_NUM_39;
      cfg.freq_write = 14000000;

      cfg.hsync_polarity = 0;
      cfg.hsync_front_porch = 8;
      cfg.hsync_pulse_width = 4;
      cfg.hsync_back_porch = 8;
      cfg.vsync_polarity = 0;
      cfg.vsync_front_porch = 8;
      cfg.vsync_pulse_width = 4;
      cfg.vsync_back_porch = 8;
      cfg.pclk_idle_high = 1;

      _bus_instance.config(cfg);
    }
    _panel_instance.setBus(&_bus_instance);

//    {
//      auto cfg = _light_instance.config();
//      cfg.pin_bl = GPIO_NUM_2;
//      _light_instance.config(cfg);
//    }
//    _panel_instance.light(&_light_instance);

    {
      auto cfg = _touch_instance.config();
      cfg.x_min = 0;
      cfg.x_max = 800;
      cfg.y_min = 0;
      cfg.y_max = 480;
      cfg.pin_int = -1;
      cfg.bus_shared = false;
      cfg.offset_rotation = 0;
      // I2C接続
      cfg.i2c_port = I2C_NUM_0;
      cfg.pin_sda = GPIO_NUM_15;
      cfg.pin_scl = GPIO_NUM_16;
      cfg.pin_rst = -1;
      cfg.freq = 400000;
      cfg.i2c_addr = 0x5D;  // 0x5D , 0x14
      _touch_instance.config(cfg);
      _panel_instance.setTouch(&_touch_instance);
    }

    setPanel(&_panel_instance);
  }
};

Sry for missing <code> i cant add it, dont know how.


Sign In or Register to comment.