Skip to content

ESP32-S3-LCD-1.47 Horizontal #387

@dcmcshan

Description

@dcmcshan

I have a ESP32-S3-LCD-1.47 working, but I would like to use it horizontally. Is there a rotation parameter I can give init?

"""
ESP32-S3 Waveshare Display Module (No Hardware Reset)
Handles display initialization without disconnecting USB
"""

import lvgl as lv
import lcd_bus
import st7789
import machine
import time

# Display configuration - try Arduino's original PORTRAIT mode
WIDTH = 172   # Arduino's original width
HEIGHT = 320  # Arduino's original height
OFFSET_X = 34  # Arduino's original X offset
OFFSET_Y = 0   # Arduino's original Y offset

# SPI Pin Configuration (matching Arduino demo)
SPI_MOSI = 45
SPI_SCK = 40
SPI_MISO = 13  # Not used for display but needed for SPI bus

# Display Pin Configuration (matching Arduino demo)
PIN_DC = 41
PIN_CS = 42
PIN_RESET = 39
PIN_BACKLIGHT = 48

def init_display():
    # Initialize LVGL first (like MCT)
    lv.init()
    
    # Initialize SPI bus using parameters with reset fallback
    try:
        spi_bus = machine.SPI.Bus(
            host=1,
            mosi=SPI_MOSI,
            miso=SPI_MISO,
            sck=SPI_SCK
        )
    except Exception as e:
        print(f"SPI Bus initialization failed: {e}")
        print("Resetting machine...")
        machine.reset()
    
    # Initialize LCD bus using the SPI bus
    display_bus = lcd_bus.SPIBus(
        spi_bus=spi_bus,
        dc=PIN_DC,
        cs=PIN_CS,
        freq=80_000_000  # 80MHz like Arduino
    )
    
    # Allocate framebuffers
    buf_size = WIDTH * HEIGHT * 2 // 10  # Arduino formula: /20 but we use /10 for stability
    fb1 = display_bus.allocate_framebuffer(buf_size, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_DMA)
    fb2 = display_bus.allocate_framebuffer(buf_size, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_DMA)
    
    # Initialize ST7789 display with Arduino-compatible settings
    display = st7789.ST7789(
        data_bus=display_bus,
        display_width=WIDTH,
        display_height=HEIGHT,
        frame_buffer1=fb1,
        frame_buffer2=fb2,
        reset_pin=PIN_RESET,
        reset_state=st7789.STATE_LOW,
        power_on_state=st7789.STATE_HIGH,
        backlight_pin=PIN_BACKLIGHT,
        backlight_on_state=st7789.STATE_HIGH,
        offset_x=OFFSET_X,  # Critical 34-pixel offset from Arduino demo
        offset_y=OFFSET_Y,
        color_space=lv.COLOR_FORMAT.RGB565,
        color_byte_order=st7789.BYTE_ORDER_BGR,  # Keep BGR as it was working
        rgb565_byte_swap=True
    )
    
    # Initialize display (like MCT) - let the driver handle initialization
    display.init()
    display.set_power(True)
    
    # Set up PWM backlight (matching Arduino: 1000Hz)
    backlight_pwm = machine.PWM(machine.Pin(PIN_BACKLIGHT), freq=1000)
    backlight_pwm.duty_u16(int(65535 * 0.9))  # 90% brightness like Arduino
    
    return display

def test_display():
    """Test the display with a simple red screen to fix colors first"""
    print("Initializing display with Arduino-compatible settings...")
    display = init_display()
    
    # Get active screen (like MCT)
    screen = lv.screen_active()
    
    # Make the entire screen PURPLE
    screen.set_style_bg_color(lv.color_make(255, 0, 255), 0)  # Purple (Red + Blue)
    screen.set_style_bg_opa(lv.OPA.COVER, 0)
    
    # Add marker at (0,0) - top-left corner
    marker_0_0 = lv.obj(screen)
    marker_0_0.set_size(20, 20)  # 20x20 pixel marker (bigger)
    marker_0_0.set_pos(0, 0)
    marker_0_0.set_style_bg_color(lv.color_make(255, 255, 0), 0)  # Yellow
    marker_0_0.set_style_bg_opa(lv.OPA.COVER, 0)
    marker_0_0.set_style_border_width(0, 0)
    marker_0_0.set_style_radius(0, 0)
    
    # Add marker at (172-20, 320-20) - bottom-right corner (adjusted for marker size)
    marker_max = lv.obj(screen)
    marker_max.set_size(20, 20)  # 20x20 pixel marker (bigger)
    marker_max.set_pos(WIDTH - 20, HEIGHT - 20)  # Bottom-right corner
    marker_max.set_style_bg_color(lv.color_make(0, 255, 255), 0)  # Cyan
    marker_max.set_style_bg_opa(lv.OPA.COVER, 0)
    marker_max.set_style_border_width(0, 0)
    marker_max.set_style_radius(0, 0)
    
    # Force refresh (like MCT)
    screen.invalidate()
    lv.refr_now(None)
    
    print("Display test loaded - purple screen with corner markers (portrait 172x320)")
    print("Entire screen should be PURPLE with:")
    print("- YELLOW marker (20x20) at (0,0) - top-left corner")
    print("- CYAN marker (20x20) at (152,300) - bottom-right corner")
    print("Settings applied:")
    print("- 80MHz SPI frequency")
    print("- BGR color order with byte swap")
    print("- 1000Hz PWM backlight")
    print(f"- Offset X={OFFSET_X}, Y={OFFSET_Y}")
    print("Press Ctrl+C to exit")
    
    # Keep the display running with LVGL updates
    try:
        while True:
            lv.tick_inc(50)  # 50ms tick increment
            lv.task_handler()  # Process LVGL tasks
            time.sleep_ms(50)
    except KeyboardInterrupt:
        print("\nExiting...")

if __name__ == "__main__":
    test_display() ```

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions