Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32_2432S028R display tearing, landscape/portrait incorrect, vertical direction flipped #35

Closed
truppelito opened this issue Oct 21, 2023 · 7 comments

Comments

@truppelito
Copy link

truppelito commented Oct 21, 2023

I bought two displays recently and just found your wonderful library. I've successfully identified my displays as being of the ESP32_2432S028R type and I've been trying to get them to work correctly.

I'm using the following demo code:

#include <Arduino.h>
#include <ArduinoOTA.h>

#include "esp32_smartdisplay.h"

// LVGL Objects
static lv_obj_t *label_cds;
static lv_obj_t *label_date;
static lv_obj_t *label_ipaddress;

void display_update() {
    char buffer[32];
    itoa(millis(), buffer, 10);
    lv_label_set_text(label_date, buffer);
    lv_label_set_text(label_ipaddress, WiFi.localIP().toString().c_str());
    lv_label_set_text(label_cds, String(smartdisplay_get_light_intensity()).c_str());
}

void btn_event_cb(lv_event_t *e) {
    const std::lock_guard<std::recursive_mutex> lock(lvgl_mutex);

    auto code = lv_event_get_code(e);
    auto btn = lv_event_get_target(e);
    if (code == LV_EVENT_CLICKED) {
        static uint8_t cnt = 0;
        cnt++;

        smartdisplay_beep(1000, 50);

        auto label = lv_obj_get_child(btn, 0);
        lv_label_set_text_fmt(label, "Button: %d", cnt);
    }
}

void mainscreen() {
    const std::lock_guard<std::recursive_mutex> lock(lvgl_mutex);

    // Clear screen
    lv_obj_clean(lv_scr_act());

    // Create a buttom
    auto btn = lv_btn_create(lv_scr_act());
    lv_obj_set_pos(btn, 10, 10);
    lv_obj_set_size(btn, 120, 50);
    lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_ALL, NULL);
    // Set label to Button
    auto label = lv_label_create(btn);
    lv_label_set_text(label, "Button");
    lv_obj_center(label);

    // Create a label for the date
    label_date = lv_label_create(lv_scr_act());
    lv_obj_set_style_text_font(label_date, &lv_font_montserrat_22, LV_STATE_DEFAULT);
    lv_obj_align(label_date, LV_ALIGN_BOTTOM_MID, 0, -50);

    // Create a label for the IP Address
    label_ipaddress = lv_label_create(lv_scr_act());
    lv_obj_set_style_text_font(label_ipaddress, &lv_font_montserrat_22, LV_STATE_DEFAULT);
    lv_obj_align(label_ipaddress, LV_ALIGN_BOTTOM_MID, 0, -80);

    // Create a label for the CDS Sensor
    label_cds = lv_label_create(lv_scr_act());
    lv_obj_set_style_text_font(label_cds, &lv_font_montserrat_22, LV_STATE_DEFAULT);
    lv_obj_align(label_cds, LV_ALIGN_TOP_RIGHT, 0, 0);
}

void setup() {
    // put your setup code here, to run once:
    Serial.begin(115200);

    smartdisplay_init();

    WiFi.begin();

    // Set the time servers
    configTime(0, 0, "pool.ntp.org");

    mainscreen();
}

void loop() {
    // put your main code here, to run repeatedly:

    // Red if no wifi, otherwise green
    bool connected = WiFi.isConnected();
    smartdisplay_set_led_color(connected ? lv_color32_t({.ch = {.green = 0xFF}}) : lv_color32_t({.ch = {.red = 0xFF}}));

    ArduinoOTA.handle();

    display_update();
    lv_timer_handler();
}

First, I just set the following compiler flags as per the instructions:
-D ESP32_2432S028R -D TFT_PANEL_ORDER_BGR -D TFT_ORIENTATION_LANDSCAPE -D LV_CONF_PATH=...lv_conf.h
and I got this result:
IMG_7880

Having worked with displays before, this seemed to me like the width/height pixel sizes were wrong, so I switched them in esp32_smartdisplay.h:

#ifdef ESP32_2432S028R
#define TFT_WIDTH 320 // Switched
#define TFT_HEIGHT 240 // Switched
#define ILI9431
#define ILI9431_SPI_SCLK 14

That gave me this result:
IMG_7881

There's two things wrong with this:

  1. I selected the landscape orientation, but it's showing in portrait (that's maybe understandeable given that I manually switched width/height above)
  2. The vertical dimension is flipped. As a proof, if I flip the photo I took, it's correct:
    IMG_7881

Any idea what could be causing this, and what I can do to solve it? Maybe there's some #define I can change? I looked through lv_conf.h and esp32_smartdisplay.h and didn't find anything that seemed useful.

Thank you!

@Curtiss02
Copy link

Hey, I have the same board type and managed to figure out a solution based on lcdwiki/LCDWIKI_kbv#3
I made the same changes to esp32_smartdisplay.h as you mentioned, but in addition, I updated tft_ilI9341.cpp with the following changes:
Change the declaration for uint8_t madctl[] (lines 113-123) to the following

#ifdef TFT_ORIENTATION_PORTRAIT
  static const uint8_t madctl[] = {MADCTL_ML | MADCTL_PANEL_ORDER}; // Portrait 0 Degrees
#else
#ifdef TFT_ORIENTATION_LANDSCAPE
  static const uint8_t madctl[] = {MADCTL_MY | MADCTL_MV | MADCTL_PANEL_ORDER}; // Landscape 90 Degrees
#else
#ifdef TFT_ORIENTATION_PORTRAIT_INV
  static const uint8_t madctl[] = {MADCTL_MY | MADCTL_MX | MADCTL_MH | MADCTL_PANEL_ORDER}; // Portrait inverted 180 Degrees
#else
#ifdef TFT_ORIENTATION_LANDSCAPE_INV
  static const uint8_t madctl[] = {MADCTL_MX | MADCTL_MV | MADCTL_PANEL_ORDER}; // Landscape inverted 270 Degrees

After updating this declaration, I was able to run the demo project successfully with the screen outputting a correctly displayed image.
395442998_2389375077935799_7843498353588191286_n

I am unsure exactly what this change does (perhaps the creator of this repository may have a more clear idea of the impact of these definitions) but it seems to work. I haven't tested the touch screen calibration, but tapping the button in the center of the screen worked for me, not sure if the touch calibration will need to be reoriented too.

Hope this helps!

@truppelito
Copy link
Author

Amazing, thank you very much. I'll try it out as soon as I can! Did you test for all 4 orientations (TFT_ORIENTATION_PORTRAIT, LANDSCAPE, etc)? If not, I'll test it myself.

@rzeldent
Copy link
Owner

Strange,

Just compiled and retested the library and it is all working normally, nothing switched. However, as Curtis02 mentioned, some of the displays are mirrored? Maybe they're mounted the wrong way up or something?
I tried the fix above but, together with flipping the width/height it is mirrored and only half the screen / out of bounds.
If the touch is working and the fix above works for you I can introduce a new variable to switch the screen....

@truppelito
Copy link
Author

truppelito commented Oct 24, 2023

@rzeldent Clearly our hardware has to be different than yours in some way. But I don't think this can be explained by just mounting the display the wrong way up because that would only affect the orientation/"flippedness" of the image, I think, not the fact that in our case (at least my case) the library code is drawing out of bounds...

This could perhaps be explained with the draw order being different, like for example the library assumes the pixels are sent to the display row by row, and for whatever reason our hardware instead expects column by column...? That's what I suppose the uint8_t madctl[] code is defining, but I haven't yet had the chance to dig deeper.

@Curtiss02
Copy link

Update

I have done some further tinkering and testing. The previous changes were somewhat correct, however the touch coordinates were now completely out of wack. After some further testing, I realised that the Landscape / Portrait definitions for madctl[] needed to be switched. I have updated them to the following

#ifdef TFT_ORIENTATION_PORTRAIT
  static const uint8_t madctl[] = {MADCTL_MY | MADCTL_MV | MADCTL_PANEL_ORDER}; // Portrait 0 Degrees
#else
#ifdef TFT_ORIENTATION_LANDSCAPE
  static const uint8_t madctl[] = {MADCTL_ML | MADCTL_PANEL_ORDER}; // Landscape 90 Degrees
#else
#ifdef TFT_ORIENTATION_PORTRAIT_INV
  static const uint8_t madctl[] = {MADCTL_MX | MADCTL_MV | MADCTL_PANEL_ORDER}; // Portrait inverted 180 Degrees
#else
#ifdef TFT_ORIENTATION_LANDSCAPE_INV
  static const uint8_t madctl[] = {MADCTL_MY | MADCTL_MX | MADCTL_MH | MADCTL_PANEL_ORDER}; // Landscape inverted 270 Degrees
#else

After doing this, I reverted all changes I made to esp32_smartdisplay.h previously (Switched the height and width back to the default values), and the screen now both displays correctly in each define orientation, as well as reports the correct touch coordinates. I briefly verified this by re-enabling some of the logging in the tft_ili9341.cpp file.

It would be great if @truppelito is able to verify is this is also working for them, and then possibly add a variable to switch as suggested by @rzeldent.

@truppelito
Copy link
Author

@Curtiss02 That's exactly right, I reached the same conclusion yesterday, but only tested the TFT_ORIENTATION_LANDSCAPE_INV. Now I tested the other cases and I can confirm the images are displayed correctly in all of them. Touch also seems to be working correctly. In conclusion, the only changes needed for a fix are indeed the four madctl cases.

@rzeldent
Copy link
Owner

Just made a new branch. Can you verify this works for you?

feature/flipped_display

This has a new option TFT_FLIPPEDMIRRORED

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants