diff --git a/src/rom/app.py b/src/rom/app.py index 5b5892f..32245f4 100644 --- a/src/rom/app.py +++ b/src/rom/app.py @@ -9,6 +9,7 @@ import time import machine import uasyncio from config import config +from display import display # 导入液晶屏管理模块 from wifi_manager import wifi_manager # 全局变量存储最新的天气数据 @@ -107,6 +108,7 @@ async def weather_update_task(): interval_ms = interval_minutes * 60 * 1000 # 转换为毫秒 print(f"开始定时更新天气数据,间隔{interval_minutes}分钟") + await uasyncio.sleep_ms(1 * 1000) while True: try: @@ -127,31 +129,17 @@ async def weather_update_task(): # 精简的动画显示任务 async def animation_task(): """显示JPG动画的后台任务""" + # 检查液晶屏是否已初始化 + if not display.is_ready(): + print("液晶屏未初始化,跳过动画任务") + return + try: - import st7789 - from machine import SPI, Pin - - # 初始化显示屏 - tft = st7789.ST7789( - SPI(1, 40_000_000, polarity=1), - 240, - 240, - dc=Pin(0, Pin.OUT), - reset=Pin(2, Pin.OUT), - backlight=Pin(5, Pin.OUT), - buffer_size=0, - ) - - # 初始化并清屏 - tft.init() - gc.collect() - tft.fill(st7789.BLACK) - tft.off() - # 动画参数 frame_count = 20 frame_delay = 10 # 帧延迟(毫秒) + await uasyncio.sleep_ms(2 * 1000) print(f"开始JPG动画,帧延迟: {frame_delay}ms") frame = 0 @@ -161,8 +149,8 @@ async def animation_task(): current_frame = (frame % frame_count) + 1 filename = f"/rom/www/images/T{current_frame}.jpg" - # 显示当前帧 - tft.jpg(filename, 160, 160, st7789.FAST) + # 显示当前帧,右下角 + display.show_jpg(filename, 160, 160) # 控制帧率 await uasyncio.sleep_ms(frame_delay) @@ -185,13 +173,18 @@ async def animation_task(): def start(): - # init lcd screen + # 初始化液晶屏 + display.init_display() + display.show_jpg("/rom/www/images/T1.jpg", 80, 80) + gc.collect() + if not wifi_manager.connect(): print("Failed to connect to WiFi, starting CaptivePortal for configuration") from captive_portal import CaptivePortal portal = CaptivePortal() return portal.start() + gc.collect() # init web server from rom.nanoweb import Nanoweb diff --git a/src/rom/display.py b/src/rom/display.py new file mode 100644 index 0000000..97322ee --- /dev/null +++ b/src/rom/display.py @@ -0,0 +1,92 @@ +""" +液晶屏管理模块 - 单例模式实现 + +提供液晶屏的统一初始化和管理接口,确保整个系统中只有一个液晶屏实例。 +适用于ESP8266等内存有限的平台。 +""" + +import gc + +import st7789 + + +class Display: + """液晶屏管理类 - 单例模式""" + + _instance = None + _initialized = False + + def __new__(cls): + """单例模式实现""" + if cls._instance is None: + cls._instance = super(Display, cls).__new__(cls) + return cls._instance + + def __init__(self): + """初始化液晶屏,只在第一次调用时执行""" + if not self._initialized: + self.tft = None + self._backlight = None + self._brightness = 50 # 默认亮度50% + self._initialized = True + + def init_display(self): + """初始化液晶屏""" + try: + from machine import PWM, SPI, Pin + + # 初始化显示屏 + self.tft = st7789.ST7789( + SPI(1, 40_000_000, polarity=1), + 240, + 240, + dc=Pin(0, Pin.OUT), + reset=Pin(2, Pin.OUT), + buffer_size=0, + ) + + # 初始化PWM背光控制 + self._backlight = PWM(Pin(5), freq=1000) + self.brightness(self._brightness) + + # 初始化并清屏 + self.tft.init() + gc.collect() + self.tft.fill(st7789.BLACK) + print("液晶屏初始化成功") + return True + + except Exception as e: + print(f"液晶屏初始化失败: {e}") + self.tft = None + self._backlight = None + return False + + def is_ready(self): + """检查液晶屏是否已初始化""" + return self.tft is not None + + def driver(self): + """获取液晶屏对象""" + return self.tft + + def clear(self, color=st7789.BLACK): + """清屏""" + self.tft.fill(color) + + def show_jpg(self, filename, x=0, y=0, mode=st7789.FAST): + """显示JPG图片""" + self.tft.jpg(filename, x, y, mode) + + def brightness(self, _brightness=-1): + """设置背光亮度 (0-100)""" + if _brightness >= 0 and _brightness <= 100: + # 将0-100范围映射到0-1023 (PWM占空比) + duty = int(1023 * _brightness / 100) + self._backlight.duty(duty) + self._brightness = _brightness + return self._brightness + + +# 全局液晶屏实例 +display = Display()