Touchscreen on CrowPanel 7inch v3.0 not working

13»

Comments

  • hi any solution guys same issue here

    include <PCA9557.h>

    include <lvgl.h>

    include <Crowbits_DHT20.h>

    include <Preferences.h>

    define LGFX_USE_V1

    include <LovyanGFX.hpp>

    include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>

    include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>

    // ============= ANGLE LIMITS - EDIT THESE VALUES =============

    define PAN_MIN_ANGLE 0 // Minimum pan angle

    define PAN_MAX_ANGLE 360 // Maximum pan angle

    define TILT_MIN_ANGLE 0 // Minimum tilt angle

    define TILT_MAX_ANGLE 180 // Maximum tilt angle

    define SERIAL_BAUD 9600 // Serial baud rate

    define SPLASH_DURATION 3000 // Splash screen duration in milliseconds

    // ============================================================

    define TFT_BL 2

    // Global variables for angles
    int panAngle = 0;
    int tiltAngle = 0;

    // Preferences object for saving angles
    Preferences preferences;

    // LGFX Display Class
    class LGFX : public lgfx::LGFX_Device
    {
    public:
    lgfx::Bus_RGB _bus_instance;
    lgfx::Panel_RGB _panel_instance;

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

      cfg.pin_d0  = GPIO_NUM_15; // B0
      cfg.pin_d1  = GPIO_NUM_7;  // B1
      cfg.pin_d2  = GPIO_NUM_6;  // B2
      cfg.pin_d3  = GPIO_NUM_5;  // B3
      cfg.pin_d4  = GPIO_NUM_4;  // B4
    
      cfg.pin_d5  = GPIO_NUM_9;  // G0
      cfg.pin_d6  = GPIO_NUM_46; // G1
      cfg.pin_d7  = GPIO_NUM_3;  // G2
      cfg.pin_d8  = GPIO_NUM_8;  // G3
      cfg.pin_d9  = GPIO_NUM_16; // G4
      cfg.pin_d10 = GPIO_NUM_1;  // G5
    
      cfg.pin_d11 = GPIO_NUM_14; // R0
      cfg.pin_d12 = GPIO_NUM_21; // R1
      cfg.pin_d13 = GPIO_NUM_47; // R2
      cfg.pin_d14 = GPIO_NUM_48; // R3
      cfg.pin_d15 = GPIO_NUM_45; // R4
    
      cfg.pin_henable = GPIO_NUM_41;
      cfg.pin_vsync   = GPIO_NUM_40;
      cfg.pin_hsync   = GPIO_NUM_39;
      cfg.pin_pclk    = GPIO_NUM_0;
      cfg.freq_write  = 15000000;
    
      cfg.hsync_polarity    = 0;
      cfg.hsync_front_porch = 40;
      cfg.hsync_pulse_width = 48;
      cfg.hsync_back_porch  = 40;
    
      cfg.vsync_polarity    = 0;
      cfg.vsync_front_porch = 1;
      cfg.vsync_pulse_width = 31;
      cfg.vsync_back_porch  = 13;
    
      cfg.pclk_active_neg   = 1;
      cfg.de_idle_high      = 0;
      cfg.pclk_idle_high    = 0;
    
      _bus_instance.config(cfg);
    }
    {
      auto cfg = _panel_instance.config();
      cfg.memory_width  = 800;
      cfg.memory_height = 480;
      cfg.panel_width  = 800;
      cfg.panel_height = 480;
      cfg.offset_x = 0;
      cfg.offset_y = 0;
      _panel_instance.config(cfg);
    }
    _panel_instance.setBus(&_bus_instance);
    setPanel(&_panel_instance);
    

    }
    };

    LGFX lcd;

    // UI

    include "ui.h"

    Crowbits_DHT20 dht20;

    // Touch

    include "touch.h"

    // Display buffers
    static uint32_t screenWidth;
    static uint32_t screenHeight;
    static lv_disp_draw_buf_t draw_buf;
    static lv_color_t disp_draw_buf[800 * 480 / 15];
    static lv_disp_drv_t disp_drv;

    // ============= HELPER FUNCTIONS =============

    // Constrain angle within limits
    int constrainAngle(int angle, int minVal, int maxVal) {
    if (angle < minVal) return minVal;
    if (angle > maxVal) return maxVal;
    return angle;
    }

    // Update text area with angle value
    void updateAngleDisplay(lv_obj_t* textarea, int angle) {
    char buf[16];
    snprintf(buf, sizeof(buf), "%d", angle);
    lv_textarea_set_text(textarea, buf);
    }

    // Send serial command
    void sendSerial(const char* command) {
    Serial.println(command);
    }

    // Save angles to preferences
    void saveAngles() {
    preferences.begin("motor", false);
    preferences.putInt("panAngle", panAngle);
    preferences.putInt("tiltAngle", tiltAngle);
    preferences.end();
    }

    // Load angles from preferences
    void loadAngles() {
    preferences.begin("motor", true);
    panAngle = preferences.getInt("panAngle", 0);
    tiltAngle = preferences.getInt("tiltAngle", 0);
    preferences.end();

    // Constrain loaded values
    panAngle = constrainAngle(panAngle, PAN_MIN_ANGLE, PAN_MAX_ANGLE);
    tiltAngle = constrainAngle(tiltAngle, TILT_MIN_ANGLE, TILT_MAX_ANGLE);

    Serial.print("Loaded Pan: ");
    Serial.print(panAngle);
    Serial.print(" Tilt: ");
    Serial.println(tiltAngle);
    }

    // ============= EVENT HANDLERS =============

    // Pan Plus Button
    void panPlusClicked(lv_event_t * e) {
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_CLICKED) {
    panAngle++;
    panAngle = constrainAngle(panAngle, PAN_MIN_ANGLE, PAN_MAX_ANGLE);
    updateAngleDisplay(ui_PANANGLE, panAngle);
    sendSerial("PAN_PLUS");
    char buf[32];
    snprintf(buf, sizeof(buf), "PAN_ANGLE:%d", panAngle);
    sendSerial(buf);
    saveAngles();
    }
    }

    // Pan Minus Button
    void panMinusClicked(lv_event_t * e) {
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_CLICKED) {
    panAngle--;
    panAngle = constrainAngle(panAngle, PAN_MIN_ANGLE, PAN_MAX_ANGLE);
    updateAngleDisplay(ui_PANANGLE, panAngle);
    sendSerial("PAN_MINUS");
    char buf[32];
    snprintf(buf, sizeof(buf), "PAN_ANGLE:%d", panAngle);
    sendSerial(buf);
    saveAngles();
    }
    }

    // Tilt Plus Button
    void tiltPlusClicked(lv_event_t * e) {
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_CLICKED) {
    tiltAngle++;
    tiltAngle = constrainAngle(tiltAngle, TILT_MIN_ANGLE, TILT_MAX_ANGLE);
    updateAngleDisplay(ui_PANANGLE1, tiltAngle);
    sendSerial("TILT_PLUS");
    char buf[32];
    snprintf(buf, sizeof(buf), "TILT_ANGLE:%d", tiltAngle);
    sendSerial(buf);
    saveAngles();
    }
    }

    // Tilt Minus Button
    void tiltMinusClicked(lv_event_t * e) {
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_CLICKED) {
    tiltAngle--;
    tiltAngle = constrainAngle(tiltAngle, TILT_MIN_ANGLE, TILT_MAX_ANGLE);
    updateAngleDisplay(ui_PANANGLE1, tiltAngle);
    sendSerial("TILT_MINUS");
    char buf[32];
    snprintf(buf, sizeof(buf), "TILT_ANGLE:%d", tiltAngle);
    sendSerial(buf);
    saveAngles();
    }
    }

    // Pan Angle keyboard READY event (when user presses Enter/OK)
    void panAngleReady(lv_event_t * e) {
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_READY) {
    const char* txt = lv_textarea_get_text(ui_PANANGLE);
    int newAngle = atoi(txt);
    panAngle = constrainAngle(newAngle, PAN_MIN_ANGLE, PAN_MAX_ANGLE);
    updateAngleDisplay(ui_PANANGLE, panAngle);
    char buf[32];
    snprintf(buf, sizeof(buf), "PAN_ANGLE:%d", panAngle);
    sendSerial(buf);
    saveAngles();
    }
    }

    // Tilt Angle keyboard READY event (when user presses Enter/OK)
    void tiltAngleReady(lv_event_t * e) {
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_READY) {
    const char* txt = lv_textarea_get_text(ui_PANANGLE1);
    int newAngle = atoi(txt);
    tiltAngle = constrainAngle(newAngle, TILT_MIN_ANGLE, TILT_MAX_ANGLE);
    updateAngleDisplay(ui_PANANGLE1, tiltAngle);
    char buf[32];
    snprintf(buf, sizeof(buf), "TILT_ANGLE:%d", tiltAngle);
    sendSerial(buf);
    saveAngles();
    }
    }

    // Extend Button
    void extendClicked(lv_event_t * e) {
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_CLICKED) {
    sendSerial("EXTEND");
    }
    }

    // Retract Button
    void retractClicked(lv_event_t * e) {
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_CLICKED) {
    sendSerial("RETRACT");
    }
    }

    // ============= DISPLAY FUNCTIONS =============

    void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
    {
    uint32_t w = (area->x2 - area->x1 + 1);
    uint32_t h = (area->y2 - area->y1 + 1);

    if (LV_COLOR_16_SWAP != 0)

    lcd.pushImageDMA(area->x1, area->y1, w, h,(lgfx::rgb565_t*)&color_p->full);

    else

    lcd.pushImageDMA(area->x1, area->y1, w, h,(lgfx::rgb565_t*)&color_p->full);

    endif

    lv_disp_flush_ready(disp);
    }

    void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
    {
    if (touch_has_signal())
    {
    if (touch_touched())
    {
    data->state = LV_INDEV_STATE_PR;
    data->point.x = touch_last_x;
    data->point.y = touch_last_y;

      // Debug touch coordinates
      Serial.print("Touch X: ");
      Serial.print(touch_last_x);
      Serial.print(" Y: ");
      Serial.println(touch_last_y);
    }
    else if (touch_released())
    {
      data->state = LV_INDEV_STATE_REL;
    }
    

    }
    else
    {
    data->state = LV_INDEV_STATE_REL;
    }
    delay(15);
    }

    // Timer callback to switch from splash to main screen
    void splashTimerCallback(lv_timer_t * timer) {
    lv_scr_load_anim(ui_MainScreen, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, false);
    lv_timer_del(timer);

    // Add event callbacks AFTER main screen is loaded
    Serial.println("Main screen loaded, registering button events...");

    lv_obj_add_event_cb(ui_PLUSPAN, panPlusClicked, LV_EVENT_ALL, NULL);
    lv_obj_add_event_cb(ui_MINUSPAN, panMinusClicked, LV_EVENT_ALL, NULL);
    lv_obj_add_event_cb(ui_tilt_plus, tiltPlusClicked, LV_EVENT_ALL, NULL);
    lv_obj_add_event_cb(ui_MINUSTILT, tiltMinusClicked, LV_EVENT_ALL, NULL);
    lv_obj_add_event_cb(ui_OPEN_STAND, extendClicked, LV_EVENT_ALL, NULL);
    lv_obj_add_event_cb(ui_OPEN_STAND1, retractClicked, LV_EVENT_ALL, NULL);

    lv_obj_add_event_cb(ui_PANANGLE, panAngleReady, LV_EVENT_READY, NULL);
    lv_obj_add_event_cb(ui_PANANGLE1, tiltAngleReady, LV_EVENT_READY, NULL);

    // Set initial angle display values
    updateAngleDisplay(ui_PANANGLE, panAngle);
    updateAngleDisplay(ui_PANANGLE1, tiltAngle);

    Serial.println("All event handlers registered!");
    }

    // ============= SETUP =============

    PCA9557 Out;

    void setup()
    {
    Serial.begin(SERIAL_BAUD);
    Serial.println("Motor Control System Starting...");

    // IO pin setup
    pinMode(38, OUTPUT);
    digitalWrite(38, LOW);
    pinMode(17, OUTPUT);
    digitalWrite(17, LOW);
    pinMode(18, OUTPUT);
    digitalWrite(18, LOW);
    pinMode(42, OUTPUT);
    digitalWrite(42, LOW);

    delay(200);

    // CRITICAL: Touch screen power sequence via PCA9557 for V3.0
    Wire.begin(19, 20);
    delay(50);

    dht20.begin();

    // Initialize PCA9557 IO expander
    Out.reset();
    Out.setMode(IO_OUTPUT);

    // GT911 Touch Reset Sequence (CRITICAL for V3.0)
    Out.setState(IO0, IO_LOW); // Touch power low
    Out.setState(IO1, IO_LOW); // Touch reset low
    delay(20);
    Out.setState(IO0, IO_HIGH); // Touch power high
    delay(100);

    Out.setMode(IO1, IO_INPUT); // Release reset
    delay(50);

    Serial.println("Touch controller reset complete");

    // Init Display
    lcd.begin();
    lcd.fillScreen(TFT_BLACK);
    lcd.setTextSize(2);
    delay(200);

    // Init LVGL
    lv_init();

    // Init touch device AFTER PCA9557 initialization
    touch_init();
    Serial.println("Touch initialized");

    screenWidth = lcd.width();
    screenHeight = lcd.height();

    lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, screenWidth * screenHeight / 15);

    // Initialize the display
    lv_disp_drv_init(&disp_drv);
    disp_drv.hor_res = screenWidth;
    disp_drv.ver_res = screenHeight;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.draw_buf = &draw_buf;
    lv_disp_drv_register(&disp_drv);

    // Initialize the input device driver
    static lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = my_touchpad_read;
    lv_indev_drv_register(&indev_drv);

    ifdef TFT_BL

    ledcSetup(1, 300, 8);
    ledcAttachPin(TFT_BL, 1);
    ledcWrite(1, 255);

    endif

    // Initialize UI (shows splash screen by default)
    ui_init();

    // Start fade-in animation on splash screen logo
    fadein_Animation(ui_LOGO, 0);

    // Load saved angles from memory
    loadAngles();

    // Create timer to switch to main screen after splash duration
    lv_timer_create(splashTimerCallback, SPLASH_DURATION, NULL);

    Serial.println("System Ready! Touch should work now.");
    Serial.print("Pan Limits: ");
    Serial.print(PAN_MIN_ANGLE);
    Serial.print(" to ");
    Serial.println(PAN_MAX_ANGLE);
    Serial.print("Tilt Limits: ");
    Serial.print(TILT_MIN_ANGLE);
    Serial.print(" to ");
    Serial.println(TILT_MAX_ANGLE);

    Serial.println("Touch the screen to test...");
    }

    // ============= MAIN LOOP =============

    void loop()
    {
    lv_timer_handler();
    delay(5);
    }
    my code

Sign In or Register to comment.