OK, I’ve made some progress, I no longer get the memory allocation error.
The micropython with Lvgl support is working OK, but despite several days of work I’m unable to get anything to display on the Touch-LCD-1.46 device.
By searching online for code and using an AI coding tool I have at last got some code to run without errors. However nothing appears on the display.
Can you please check my code below and tell me where I’m going wrong.
Thanks
from micropython import const
import machine
import lcd_bus
import spd2010
import lvgl as lv
import task_handler
import time
# — Dimensions —
_WIDTH = const(412)
_HEIGHT = const(412)
# — Hardware Constants —
_LCD_BL = const(5) # Backlight Pin (GPIO5)
_SCL = const(10) # Shared I2C Clock
_SDA = const(11) # Shared I2C Data
_LCD_CS = const(21) # Display Chip Select
_LCD_SCK = const(40) # SPI Clock Line
_LCD_SDA3 = const(41) # QSPI Data 3
_LCD_SDA2 = const(42) # QSPI Data 2
_LCD_SDA1 = const(45) # QSPI Data 1
_LCD_SDA0 = const(46) # QSPI Data 0
TCA9554_ADDR = const(0x20)
# 1. Hard-Reset the Display Panel via Standard Native machine.I2C
i2c = machine.I2C(0, sda=machine.Pin(_SDA), scl=machine.Pin(_SCL), freq=400000)
try:
i2c.writeto_mem(TCA9554_ADDR, 0x03, b'\\x00') # Configure expander pins as Outputs
time.sleep_ms(10)
\# Assert Hard Reset: Pull Pin 2 Low (Bit 2 = 0 -> 0xFB)
i2c.writeto_mem(TCA9554_ADDR, 0x01, b'\\xFB')
time.sleep_ms(100)
\# Release Reset: Drive pins High (0xFF) to take screen out of standby sleep
i2c.writeto_mem(TCA9554_ADDR, 0x01, b'\\xFF')
print("Display Hardware Reset successfully achieved via native I2C!")
except Exception as e:
print("Native expander wake configuration notice:", e)
time.sleep_ms(150) # Let the hardware circuits stabilize
# 2. Create Hardware Host SPI bus
display_spi = machine.SPI.Bus(
host=2,
sck=\_LCD_SCK,
quad_pins=(\_LCD_SDA0, \_LCD_SDA1, \_LCD_SDA2, \_LCD_SDA3)
)
# 3. Attach display bus passing native parameters
display_bus = lcd_bus.SPIBus(
spi_bus=display_spi,
dc=-1,
cs=\_LCD_CS,
freq=40000000,
quad=True
)
print(“QSPI Hardware Display Bus bound!”)
# 4. Initialize LVGL Engine
lv.init()
# 5. Create the display instance using EXPLICIT KEYWORDS ONLY
# This forces the Python interpreter to map the correct objects to variables,
# completely bypassing any positional layout assumptions in the driver.
display = spd2010.SPD2010(
data_bus=display_bus,
display_width=\_WIDTH,
display_height=\_HEIGHT,
reset_pin=None,
backlight_pin=\_LCD_BL
)
# 6. Unfold Power and Flash Screen Control Registers
if hasattr(display, ‘set_power’):
display.set_power(True)
display.init()
# 7. Build a Simple Layout View to verify pixels (LVGL Slider)
scrn = lv.screen_active()
slider = lv.slider(scrn)
slider.center()
# Flush the frame and start the background ticker service
lv.refr_now(scrn.get_display())
th = task_handler.TaskHandler()
print(“System Active! Ramping backlight scale…”)
# Safe direct integer duty fallback block if set_backlight requires it
if hasattr(display, ‘set_backlight’):
for i in range(1, 101, 1):
try:
display.set_backlight(float(i))
except:
display.set_backlight(i)
time.sleep_ms(10)
else:
\# Manual hardware PWM control fallback to guarantee initialization brightness
bl_pwm = machine.PWM(machine.Pin(\_LCD_BL))
bl_pwm.freq(2000)
bl_pwm.duty_u16(58000)