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

Support for ESP32-S3-Box v3 #569

Open
patfelst opened this issue May 31, 2024 · 35 comments
Open

Support for ESP32-S3-Box v3 #569

patfelst opened this issue May 31, 2024 · 35 comments
Assignees
Labels
device support request Add new device driver pinned exempt from stale bot

Comments

@patfelst
Copy link

Hi there,

I see the library has support for ESP32-S3-BOX, however this is no longer in production and has been superseded by the ESP32-BOX-S3-3 (an overly long model number, note the "-3" suffix).

Please see here https://github.com/espressif/esp-box/tree/master
image

The device currently supported by your library has, I think, the same SPI pinout, but LCD backlight is on GPIO47 vs GPIO45 for the S3-BOX, hence selecting AUTODETECT or specifying

#define LGFX_ESP32_S3_BOX                  // Espressif ESP32-S3-BOX

Compiles ok, but nothing is displayed on the LCD.
image

The pinout is on the schematic here https://github.com/espressif/esp-box/blob/master/hardware/SCH_ESP32-S3-BOX-3_V1.0/SCH_ESP32-S3-BOX-3-MB_V1.1_20230808.pdf

The LCD backlight control is on GPIO47.
image
image

Thanks for your assistance.

@patfelst patfelst added the device support request Add new device driver label May 31, 2024
@tobozo
Copy link
Collaborator

tobozo commented May 31, 2024

hi,

thanks for your feedback 👍

indeed the autodetect sequence will need a new entry, but first let's validate the display and touch configuration

does it work if you edit manually the struct detector to set the correct pin number for the backlight and change MISO value to (gpio_num_t)-1 ?

@patfelst
Copy link
Author

thankyou - unfortunately after I manually edit the detector and recompile, the display is still black. I've never used ESP32-S3-BOX-3 before, so I'm not sure if there's some other initialisation that needs to be done, for example some kind of power supply enable or similar.

I turned on verbose logging and saw:

Reconnecting to /dev/cu.usbmodem2101 .   Connected!
[  5118][I][LGFX_AutoDetect_ESP32_all.hpp:991] init_impl(): [LovyanGFX] [Autodetect] load from NVS : board:0
[  5141][V][LGFX_AutoDetect_ESP32_all.hpp:696] _read_panel_id(): [LovyanGFX] [Autodetect] read cmd:04 = 00000000
[  5164][V][LGFX_AutoDetect_ESP32_all.hpp:696] _read_panel_id(): [LovyanGFX] [Autodetect] read cmd:04 = 00000000
[  5187][V][LGFX_AutoDetect_ESP32_all.hpp:696] _read_panel_id(): [LovyanGFX] [Autodetect] read cmd:04 = 00000000
[  5210][V][LGFX_AutoDetect_ESP32_all.hpp:696] _read_panel_id(): [LovyanGFX] [Autodetect] read cmd:04 = 00000000
[  5233][V][LGFX_AutoDetect_ESP32_all.hpp:696] _read_panel_id(): [LovyanGFX] [Autodetect] read cmd:04 = 00000000
[  5256][V][LGFX_AutoDetect_ESP32_all.hpp:696] _read_panel_id(): [LovyanGFX] [Autodetect] read cmd:04 = 00000000
[  5279][V][LGFX_AutoDetect_ESP32_all.hpp:696] _read_panel_id(): [LovyanGFX] [Autodetect] read cmd:04 = 00000000
[  5302][V][LGFX_AutoDetect_ESP32_all.hpp:696] _read_panel_id(): [LovyanGFX] [Autodetect] read cmd:04 = 00000000
[  5325][V][LGFX_AutoDetect_ESP32_all.hpp:696] _read_panel_id(): [LovyanGFX] [Autodetect] read cmd:04 = 00000000
[  5335][I][LGFX_AutoDetect_ESP32_all.hpp:1016] init_impl(): [LovyanGFX] [Autodetect] save to NVS : board:0

Here is the code I used
image

#include <Arduino.h>

#define LGFX_ESP32_S3_BOX  // Espressif ESP32-S3-BOX
// #define LGFX_AUTODETECT

#include <LGFX_AUTODETECT.hpp>
#include <LovyanGFX.hpp>
static LGFX lcd;

#include "FastLED.h"
#include "TickTwo.h"
// lots of variable declarations and #define constants
void setup(void) {
  Serial.begin(115200);
  delay(5000);  // Wait for serial port to begin

  lcd.init();
  lcd.setBrightness(255);

  lcd.clear(TFT_GREEN);
  delay(1000);
  lcd.clear();

  lcd.setFont(&fonts::FreeSans12pt7b);
  lcd.setTextColor(TFT_GREEN, TFT_BLACK);
  lcd.setTextDatum(top_center);
  int x = lcd.width() / 2;
  int y = lcd.height() / 2;
  lcd.drawString("Hello World", x, y);
  while (true);
}

PlatformIO.ini

[env:S3-Box-AD8318]
platform = espressif32
board = esp32s3box
framework = arduino
monitor_speed = 115200

build_flags = 
  ; -DCORE_DEBUG_LEVEL=0 ; None
  ; -DCORE_DEBUG_LEVEL=1 ; Error *
  ; -DCORE_DEBUG_LEVEL=2 ; Warn
  ; -DCORE_DEBUG_LEVEL=3 ; Info
  ; -DCORE_DEBUG_LEVEL=4 ; Debug *
  -DCORE_DEBUG_LEVEL=5 ; Verbose

lib_deps = 
  lovyan03/LovyanGFX
  fastled/FastLED
  sstaub/TickTwo

@tobozo
Copy link
Collaborator

tobozo commented May 31, 2024

can't find much difference either

maybe disable the id checker since miso is disabled, e.g. replace 0x04, 0xff, 0xE3 by 0,0,0

@patfelst
Copy link
Author

I don't know what those numbers do, but there is progress. The backlight is now on, and the screen is white. But the brightness level is changing, i.e. if I set brightness to 50%, it is definitely not as bright. But still no graphics displayed, now just a white screen. Log output slightly different:

Reconnecting to /dev/cu.usbmodem101      Connected!
[  5118][I][LGFX_AutoDetect_ESP32_all.hpp:991] init_impl(): [LovyanGFX] [Autodetect] load from NVS : board:0
[  5140][I][LGFX_AutoDetect_ESP32_all.hpp:1173] setup(): [LovyanGFX] [Autodetect] ESP32_S3_BOX
[  5301][I][esp32-hal-i2c.c:75] i2cInit(): Initialising I2C Master: sda=8 scl=18 freq=100000

@tobozo
Copy link
Collaborator

tobozo commented May 31, 2024

last thing to try: manually set the reset pin as input_pullup pinMode(GPIO_NUM_48, INPUT_PULLUP) and set the RST pin to (gpio_num_t)-1 in the autodetect config block

after this I can't think of anything else without ordering a unit and start poking around, but this will take weeks before it gets delivered

@patfelst
Copy link
Author

patfelst commented Jun 1, 2024

success! It was the reset pin that fixed it. Now for the touchscreen? Thanks for your help.

By the way, on this ESP32-S3 chip, I have to press the reset button to run code after an upload, it doesn't auto run for some reason.

@tobozo
Copy link
Collaborator

tobozo commented Jun 1, 2024

🥳

Now for the touchscreen?

remove the while(1) from you setup and use this loop() test function:

void loop() {
  std::int32_t x, y, number = 0;
  while (display.getTouch(&x, &y, number))
  {
    display.fillCircle(x, y, 5, (std::uint32_t)(number * 0x333333u));
    ++number;
  }
}

I have to press the reset button to run code after an upload

I have this too when I select OTG as USB mode (board_build.usb_mode=0), maybe this can be controlled from the platformio.ini

@patfelst
Copy link
Author

patfelst commented Jun 1, 2024

here we go again, no circles displayed on the screen. Any suggestions what to try this time? As far as I can tell, the touchscreen is the same as the previous ESP32-BOX, i.e. I2C lines SDA=GPIO8, SCL=GPIO18 and interrupt CTP_INT=GPIO3

@tobozo
Copy link
Collaborator

tobozo commented Jun 1, 2024

Touch_TT21xxx class doesn't seem to make much of cfg.pin_int so unless you want to read the touch data from an ISR it's safe to disable it

you can first try to set this: cfg.i2c_port = I2C_NUM_0

eventually perform an I2C scan to see if I2C0 is shared with other I2C devices, if so you can also try to set this: cfg.bus_shared = true

@patfelst
Copy link
Author

patfelst commented Jun 1, 2024

OK I've set cfg.pin_int to -1. And then have tried various combinations of I2C port 0 and 1, and shared true / false. I tried an I2C scanner, not sure if I set it up correct, in setup() I had to put Wire1.begin(8, 18);. I saw the following:

            I2C device found at address 0x18
            I2C device found at address 0x40
            I2C device found at address 0x5D
            I2C device found at address 0x68

I've substituted each of those addresses in cfg.i2c_addr = 0x24; but it still doesn't seem to work.

@tobozo
Copy link
Collaborator

tobozo commented Jun 1, 2024

Wire1.begin << something wrong with Wire.begin ? looks like you're scanning I2C1 instead of I2C0

@patfelst
Copy link
Author

patfelst commented Jun 1, 2024

Yes because when I scan I2C0 I get

[  2345][W][Wire.cpp:301] begin(): Bus already started in Master Mode.
Scanning...
No I2C devices found

@tobozo
Copy link
Collaborator

tobozo commented Jun 1, 2024

whoops I2C device found at address 0x5D actually smells like GT911 instead of TT21100

maybe update cfg.i2c_addr = 0x5D and change this: auto t = new lgfx::Touch_TT21xxx() into this auto t = new lgfx::Touch_GT911()

@patfelst
Copy link
Author

patfelst commented Jun 1, 2024

no good unfortunately, this is what I have

      struct _detector_ESP32_S3_BOX_t : public _detector_spi_t
      {
        constexpr _detector_ESP32_S3_BOX_t(void) :
        _detector_spi_t
        { board_t::board_ESP32_S3_BOX
        , 0, 0, 0 // ILI9342C
        , 40000000, 16000000
        , GPIO_NUM_6      // MOSI
        , (gpio_num_t)-1      // MISO
        , GPIO_NUM_7      // SCLK
        , GPIO_NUM_4      // DC
        , GPIO_NUM_5      // CS
        , (gpio_num_t)-1     // RST
        , (gpio_num_t)-1  // TF CARD CS
        , 0               // SPI MODE
        , true            // SPI 3wire
        , SPI2_HOST       // SPI HOST
        } {}

        void setup(_detector_result_t* result) const override
        {
          ESP_LOGI(LIBRARY_NAME, "[Autodetect] ESP32_S3_BOX");
          auto p = new Panel_ILI9342();
          result->panel = p;
          {
            auto cfg = p->config();
            // cfg.pin_cs  = GPIO_NUM_5;
            // cfg.pin_rst = GPIO_NUM_48;
            cfg.offset_rotation = 1;
            p->config(cfg);    // config設定;
            p->setRotation(1); // config設定後に向きを設定;
            p->light(_create_pwm_backlight(GPIO_NUM_47, 0, 12000));
          }

          {
            auto t = new lgfx::Touch_GT911();
            auto cfg = t->config();
            // cfg.pin_int  = GPIO_NUM_3;
            cfg.pin_int  = -1;
            cfg.pin_sda  = GPIO_NUM_8;
            cfg.pin_scl  = GPIO_NUM_18;
            // cfg.i2c_addr = 0x24;
            cfg.i2c_addr = 0x5D;
            // I2C device found at address 0x18
            // I2C device found at address 0x40
            // I2C device found at address 0x5D
            // I2C device found at address 0x68
            cfg.i2c_port = I2C_NUM_0;
            cfg.freq = 400000;
            cfg.x_min = 0;
            cfg.x_max = 319;
            cfg.y_min = 0;
            cfg.y_max = 239;
            cfg.bus_shared = true;
            t->config(cfg);
            p->touch(t);
            float affine[6] = { 1, 0, 0, 0, -1, 240 };
            p->setCalibrateAffine(affine);
          }
        }
      };

@tobozo
Copy link
Collaborator

tobozo commented Jun 1, 2024

cfg.i2c_port may need to be set to I2C_NUM_1 since that's where the touch interface responded to the scan

moreover, the only device using GT911 in the autodetect (M5Paper) seems to try a secondary I2C address between
t->config(cfg) and p->touch(t), so you might as well copy that code block too:

            cfg.i2c_addr = 0x14;
            // (...)
            t->config(cfg);
            if (!t->init())
            {
              cfg.i2c_addr = 0x5D; // addr change (0x14 or 0x5D)
              t->config(cfg);
            }
            p->touch(t);

@patfelst
Copy link
Author

patfelst commented Jun 1, 2024

still no good. I tried I2C freq of 10000 too, and various combinations of I2C0 and I2C1.

When I get time later today, I'll dig into Espressif's hardware docs and driver code and see if I can work out exactly which touch chip they're using. From a quick look, they don't reveal this on schematic or the hardware overview etc.

@patfelst
Copy link
Author

patfelst commented Jun 1, 2024

@tobozo there is some discussion on the touch driver here, I've not had time to read it all
espressif/esp-box#120

@tobozo
Copy link
Collaborator

tobozo commented Jun 1, 2024

yup the rust project is where I found the idea for the input pullup on the panel RST pin

GT911 does support interrupts (LGFX uses it for touch wakeup) and cfg.pin_int = GPIO_NUM_3 could probably be restored, or given the same treatment as the panel RST pin (input pullup from setup and set to -1 in config)

more insight on the dual i2c_address: https://github.com/espressif/esp-bsp/blob/master/components/lcd_touch/esp_lcd_touch_gt911/include/esp_lcd_touch_gt911.h#L35

  When power-on detects low level of the interrupt gpio, address is 0x5D. 
  Interrupt gpio is high level, address is 0x14.

@patfelst
Copy link
Author

patfelst commented Jun 2, 2024

success!!! The problem was the colour of the circles drawn on touch points. With one finger, it must be black. If I use two fingers, then very dark grey dots show up. If I use three fingers (difficult on small display), the colour is light grey.

I realised I can drag my finger and it draws a dotted line.

For now instead of lcd.fillCircle(x, y, 5, (std::uint32_t)(number * 0x333333u)); I will use a solid color like TFT_GREEN.

I changed a few other auto detect settings too, so I'll wind those back and see what really made it work. I will report back soon.

@patfelst
Copy link
Author

patfelst commented Jun 2, 2024

Here is the latest autodetect code. The last 2 lines in the touch config for calibration need to be commented out. Although it still needs calibration because the max-y I'm seeting is about 200. I haven't looked into user calibration yet, just happy its working!
I also tried increasing max-y to 280 so that the red touch button can be used, but that doesn't seem to work.

      struct _detector_ESP32_S3_BOX_t : public _detector_spi_t
      {
        constexpr _detector_ESP32_S3_BOX_t(void) :
        _detector_spi_t
        { board_t::board_ESP32_S3_BOX
        , 0, 0, 0 // ILI9342C
        , 40000000, 16000000
        , GPIO_NUM_6      // MOSI
        , (gpio_num_t)-1      // MISO
        , GPIO_NUM_7      // SCLK
        , GPIO_NUM_4      // DC
        , GPIO_NUM_5      // CS
        , (gpio_num_t)-1     // RST
        , (gpio_num_t)-1  // TF CARD CS
        , 0               // SPI MODE
        , true            // SPI 3wire
        , SPI2_HOST       // SPI HOST
        } {}

        void setup(_detector_result_t* result) const override
        {
          ESP_LOGI(LIBRARY_NAME, "[Autodetect] ESP32_S3_BOX");
          auto p = new Panel_ILI9342();
          result->panel = p;
          {
            auto cfg = p->config();
            // cfg.pin_cs  = GPIO_NUM_5;
            // cfg.pin_rst = GPIO_NUM_48;
            cfg.offset_rotation = 1;
            p->config(cfg);    // config設定;
            p->setRotation(1); // config設定後に向きを設定;
            p->light(_create_pwm_backlight(GPIO_NUM_47, 0, 12000));
          }

          {
            auto t = new lgfx::Touch_GT911();
            auto cfg = t->config();
            cfg.pin_int  = -1;
            cfg.pin_sda  = GPIO_NUM_8;
            cfg.pin_scl  = GPIO_NUM_18;
            cfg.i2c_addr = 0x14;
            cfg.i2c_port = I2C_NUM_0;
            // cfg.freq = 400000;
            cfg.x_min = 0;
            cfg.x_max = 319;
            cfg.y_min = 0;
            // cfg.y_max = 239;
            // Max-y = 239 + 40 pixels for "red" touch point below LCD active area
            cfg.y_max = 279;
            cfg.offset_rotation = 2;
            cfg.bus_shared = false;
            t->config(cfg);
            if (!t->init())
            {
              cfg.i2c_addr = 0x5D; // addr change (0x14 or 0x5D)
              t->config(cfg);
            }
            p->touch(t);
            // float affine[6] = { 1, 0, 0, 0, -1, 240 };
            // p->setCalibrateAffine(affine);
          }
        }
      };

setup() is

  pinMode(GPIO_NUM_48, INPUT_PULLUP);  // LCD Reset pin
  lcd.init();

using this loop code

void loop(void) {
  static bool touched = false;
  std::int32_t x, y, number = 0;
  while (lcd.getTouch(&x, &y)) {
    touched = true;
    // lcd.fillCircle(x, y, 5, (std::uint32_t)(number * 0x333333u));
    lcd.fillCircle(x, y, 5, TFT_GREEN);
  }

  if (touched) {
    touched = false;
    lcd.setTextColor(TFT_CYAN, TFT_BACKGND);
    sprintf(txt, "(%d, %d)", x, y);
    lcd.drawString(txt, x + 5, y);

    lcd.getTouchRaw(&x, &y);
    Serial.printf("Touch raw x=%d, y=%d\n", x, y);
    if (y > 200)
      lcd.clear();
  }

  lcd.setTextColor(TFT_ORANGE, TFT_BACKGND);
  lcd.drawNumber(num++, 10, 10);
}

IMG_9801

@tobozo
Copy link
Collaborator

tobozo commented Jun 2, 2024

thanks for testing this 👍

I've added your changes to a new block in the autodetect sequence (see struct _detector_ESP32_S3_BOX_V3_t), which is now the default s3box board.

you can test it by checking out the develop branch of this repository.

the _detector_ESP32_S3_BOX_V3_t now takes care of pulling up that RST pin so you can remove the extra pinMode from your setup.

the touch interrupt pin was added back to the touch config as some wake/sleep scenarios may need it, please confirm it didn't break anything :-)

now there's still room for improvement but it can be kept as a tech debt; so you can eventually ignore what follows:

according to the ilitek documentation the display is readable, and _detector_ESP32_S3_BOX_V3_t should be able to query the lcd to confirm it's an ili9342c (this was disabled when 0x04, 0xff, 0xE3 was replaced by 0,0,0):

image

if you feel like playing with that part, you can re-enable the 0x04, 0xff, 0xE3 data block, and try to tweak the read frequency (default 16000000) -> try 15000000, and/or poke with the DC pinmode (it is used to toggle read/write mode).

what the 0x04, 0xff, 0xE3 sequence does is that it sends the 0x04 command to the display and reads the response, expecting 0xE3 as the display identifier; enabling verbose mode will print that uint24t response as an uint32t to the serial console during init, if the response is different from 00000000 then it means success, and the lower byte value can then be used in the ID data block e.g. if the reponse is 00FFFFAA then the data block should be 0x04, 0xff, 0xAA.

[  5325][V][LGFX_AutoDetect_ESP32_all.hpp:696] _read_panel_id(): [LovyanGFX] [Autodetect] read cmd:04 = 00000000

image

thanks again for testing all this 👍

@patfelst
Copy link
Author

patfelst commented Jun 2, 2024

ok that's working perfectly with the develop branch. Regarding autodetect, with

#define LGFX_ESP32_S3_BOX_V3  // Espressif ESP32-S3-BOX-V3
// #define LGFX_AUTODETECT

I'm seeing:

Reconnecting to /dev/cu.usbmodem101 .    Connected!
[  2121][I][LGFX_AutoDetect_ESP32_all.hpp:1028] init_impl(): [LovyanGFX] [Autodetect] load from NVS : board:0
[  2132][V][LGFX_AutoDetect_ESP32_all.hpp:733] _read_panel_id(): [LovyanGFX] [Autodetect] read cmd:04 = 000000e3
[  2142][I][LGFX_AutoDetect_ESP32_all.hpp:1301] setup(): [LovyanGFX] [Autodetect] ESP32_S3_BOX_V3
[  2151][I][esp32-hal-i2c.c:75] i2cInit(): Initialising I2C Master: sda=8 scl=18 freq=100000
[  2160][V][common.cpp:1333] writeBytes(): [LGFX] i2c write error : ack wait
[  2168][I][esp32-hal-i2c.c:75] i2cInit(): Initialising I2C Master: sda=8 scl=18 freq=100000

So does that response of 000000e3 mean it's working? BTW I see no difference between freq of 16000000 or 15000000. I would need more ideas how to play with the DC signal, would that be in the autodetect code, and what would I set it to?

Then I went ahead with:

// #define LGFX_ESP32_S3_BOX_V3  // Espressif ESP32-S3-BOX
#define LGFX_AUTODETECT

and its still working ok, I saw a couple of extra lines in the logs, not sure why it tries to initialise I2C with SDA=12, SCL=11.

Reconnecting to /dev/cu.usbmodem101 .    Connected!
[  2124][I][LGFX_AutoDetect_ESP32_all.hpp:1028] init_impl(): [LovyanGFX] [Autodetect] load from NVS : board:0
[  2134][I][esp32-hal-i2c.c:75] i2cInit(): Initialising I2C Master: sda=12 scl=11 freq=100000
[  2143][V][common.cpp:1333] writeBytes(): [LGFX] i2c write error : ack wait
[  2151][V][LGFX_AutoDetect_ESP32_all.hpp:733] _read_panel_id(): [LovyanGFX] [Autodetect] read cmd:04 = 000000e3
[  2161][I][LGFX_AutoDetect_ESP32_all.hpp:1301] setup(): [LovyanGFX] [Autodetect] ESP32_S3_BOX_V3
[  2170][I][esp32-hal-i2c.c:75] i2cInit(): Initialising I2C Master: sda=8 scl=18 freq=100000
[  2179][V][common.cpp:1333] writeBytes(): [LGFX] i2c write error : ack wait
[  2187][I][esp32-hal-i2c.c:75] i2cInit(): Initialising I2C Master: sda=8 scl=18 freq=100000

A couple of comments:
You may not be finished, but the new #define LGFX_ESP32_S3_BOX_V3 should be added to the how_to_use example

I hear you about technical debt, but what about the red touch button below the screen? It would be similar to the M5Unified Core2 three red buttons below the display area. I haven't had a chance to calibrate the screen, so I can't confirm if this number actually works. Might be best to revert that y_max=239.

@tobozo
Copy link
Collaborator

tobozo commented Jun 2, 2024

So does that response of 000000e3 mean it's working?

yes ^^ I'll update the develop branch with the original 0x04, 0xff, 0xE3 sequence

BTW I see no difference between freq of 16000000 or 15000000

switching from 16MHz to 15MHz made a difference on M5StickCPlus, the M5StickC even needs to go down to 14MHz, but since it works with the S3box at 16MHz there's no need to change that

not sure why it tries to initialise I2C with SDA=12, SCL=11.

since the LGFX_ESP32_S3_BOX_V3 board hint isn't provided, autodetect is probing for other esp32-s3 boards, starting with M5Stack boards using their default I2C pinout, also the binary you compiled is compatible with all the probed boards and may be slightly bigger

image

cfg.y_max = 279;

that's 7/6th of the panel height, if you believe it should be more you can still set a higher value, but the finger/panel proportion is valid with the M5Core2 and the panel size seems to match the s3box

wether it should be enabled or not has been subject to many discussions (e.g. lvgl wants absolute data but users may want to implement 3 buttons instead of 1), and the conclusion is that it doesn't hurt to enable it since there's still access to the raw data and the calibration can be changed after init

thanks for your suggestions 👍

@patfelst
Copy link
Author

patfelst commented Jun 2, 2024

Thanks for all your help here @tobozo. Do you need anything more from me? I'll probably investigate getting the red touch button to work this week, but I guess you can do a PR before that.

@tobozo
Copy link
Collaborator

tobozo commented Jun 2, 2024

I'm not sure when the next release will be published, some other unrelated tasks may need to be achieved before the develop branch is merged with the master

but I've ordered a esp32-s3box-3b so hopefully in a few weeks I'll be able to investigate that red button too 🤞

@patfelst
Copy link
Author

patfelst commented Jun 3, 2024

Hi again, I ran the user calibration routine I found in the example HowToUse/2_user_setting/2_user_setting.ino (plus the method to print the result I found in another issue),

  lcd.init();

  // タッチが使用可能な場合のキャリブレーションを行います。(省略可)
  if (lcd.touch()) {
    if (lcd.width() < lcd.height()) lcd.setRotation(lcd.getRotation() ^ 1);

    // 画面に案内文章を描画します。
    lcd.setTextDatum(textdatum_t::middle_center);
    lcd.drawString("touch the arrow marker.", lcd.width() >> 1, lcd.height() >> 1);
    lcd.setTextDatum(textdatum_t::top_left);

    // タッチを使用する場合、キャリブレーションを行います。画面の四隅に表示される矢印の先端を順にタッチしてください。
    std::uint16_t fg = TFT_WHITE;
    std::uint16_t bg = TFT_BLACK;
    if (lcd.isEPD()) std::swap(fg, bg);
    uint16_t calibrationData[8];
    lcd.calibrateTouch(calibrationData, fg, bg, std::max(lcd.width(), lcd.height()) >> 3);
    for (int i = 0; i < 8; i++) {
      Serial.print(calibrationData[i]);
      Serial.print(", ");
    }
  }

This code returns these numbers:

23, 13, 24, 229, 301, 13, 311, 234, 

I'm not quite sure what's happening under the hood with calibration. Is it run once, and these numbers get saved to EEPROM and read back at startup? Or am I expecting too much, and I should write them to EEPROM and then read them back at startup and somehow set the calibration?

In any case, now when I tap the very top edge of the LCD I see y=-9, and the very bottom of the LCD (not as low down as red button) I see 240. I get no response when I tap the red button. Left and right seem a bit out too, left=-20, right=326. There is no difference between .getTouchRaw and .getTouch in my logs.

I know this is probably beyond the scope of this issue, so maybe we leave it here, and you can look into it when your unit arrives.

@tobozo
Copy link
Collaborator

tobozo commented Jun 3, 2024

those numbers look normal, the values offsets are caused by the finger not touching the exact corner maybe?

23, 13, 24, 229, 301, 13, 311, 234,

if I round up the values to the closest corner, the calibration data is: 0, 0, 0, 240, 320, 0, 320, 240

red circle

the gt911 will pretend multitouch is happening whenever one of the (up to) 4 buttons outside the panel area is touched

void loop() 
{
  std::int32_t x, y, number = 0;
  while (display.getTouch(&x, &y, number))
  {
    Serial.printf("index=%d, x=%d, y=%d", number, x, y); Serial.println();
    ++number;
  }
}

according to the esphome gt911 documentation (which is a different driver) the index value for the red button should be 0

you can confirm the behaviour of LGFX's gt911 driver is the same by comparing the index when you touch the middle of the screen, and the index when you touch the red button

[edit]

Touch_GT911 has an extra method, could you try this in the autodetect block, before p->touch(t):

            t->setTouchNums(2); 

the argument value can be 1, 2, 3, 4 or 5, my guess is it's defaulting to 1

@patfelst
Copy link
Author

patfelst commented Jun 3, 2024

ok I tried the above, index is only > 0 on multi-touch, e.g. two fingers and index == 1. Pressing the red button still results in nothing unfortunately.

@tobozo
Copy link
Collaborator

tobozo commented Jun 4, 2024

I've been searching through espressif labyrinthic codebase and got lost 🤣

the GT911 supports custom configs, so that's probably the angle to consider when comparing with working examples

I'm out of ideas so I'll wait for my s3box unit to be delivered before investigating further

btw the develop branch has been merged with the master branch, incoming new release :-)

@patfelst
Copy link
Author

patfelst commented Jun 4, 2024

thanks for trying. I tried that too, labyrinthic is the word.

Shall we close this issue now? I can keep an eye on the release notes to see if you ever solve the red button!

@tobozo
Copy link
Collaborator

tobozo commented Jun 4, 2024

if it works with M5Core2, it's legitimate to expect support for S3Box; let's keep the issue open until this red button mystery is solved

@tobozo
Copy link
Collaborator

tobozo commented Jun 11, 2024

hi,

I received the S3Box v3 and already found a few design defects, it seems that espressif was well inspired to acquire M5Stack as they have a lot to learn from them :-)

  • S3Box is unflashable when docked to the sensors
  • RST/Boot/Mute push buttons have weak tactile feedback
  • USB-C Cable is too short to be practical
  • Plastic from the docking units is unsmoothed and has cutting edges

a more in-depth analysis of Touch_GT911 driver exposed the lack of touch button support (0x8093 reg key) so I'll investigate this

@tobozo
Copy link
Collaborator

tobozo commented Jun 11, 2024

progress: managed to get 0x8093 reg data to be processed when available but I broke multitouch support

I created a dedicated branch and pushed the changes.

Whenever the red button is pushed, the y coordinates will be outside the touch window (i.e. x<0 || x>240).

using getTouchRaw():

    lgfx::touch_point_t tp;
    auto tpPtr = &tp;
    auto number = lcd.getTouchRaw(tpPtr, 5);
    if (number > 0) 
    {
      for( int i=0;i<number;i++) 
      {
        Serial.printf("[%d] x=%d, y=%d\n", i, tpPtr[i].x, tpPtr[i].y);
        if( tpPtr[i].y<0 || tpPtr[i].y>lcd.height() ) 
          lcd.clear();
        else
          lcd.fillCircle(tpPtr[i].x, tpPtr[i].y, 5, TFT_RED );
      }
    }

using getTouch()

    std::int32_t x, y, number = 0;
    while (lcd.getTouch(&x, &y, number))
    {
      Serial.printf("index=%d, x=%d, y=%d\n", number, x, y);
      if( y<0 || y>lcd.height() ) 
        lcd.clear();
      else
        lcd.fillCircle(x, y, 5, TFT_RED );
      ++number;
    }

@patfelst
Copy link
Author

  • S3Box is unflashable when docked to the sensors

I have not tried this, but is disappointing

  • RST/Boot/Mute push buttons have weak tactile feedback

Agree, I should have mentioned this, I thought the buttons were broken when I first pressed them

  • USB-C Cable is too short to be practical

I used my own for this reason

  • Plastic from the docking units is unsmoothed and has cutting edges

Agree again, M5 Stack do design better.

@patfelst
Copy link
Author

I have moved on and decided to use a different ESP32-S3 for my current project (Xiao, no LCD 😲), and am in the thick of coding for it, but when I get a chance, I will try your branch re red button touch - thanks

@tobozo tobozo self-assigned this Jun 12, 2024
@github-actions github-actions bot added the stale Inactive issues label Jul 12, 2024
@tobozo tobozo added pinned exempt from stale bot and removed stale Inactive issues labels Jul 12, 2024
Repository owner deleted a comment from github-actions bot Jul 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
device support request Add new device driver pinned exempt from stale bot
Projects
None yet
Development

No branches or pull requests

2 participants