--[[ @module tsb_wavein_page @summary 波形输入页面 @version 1.0 @date 2026.03.18 @author 李一玮 @usage 本文件是波形输入页面,展示波形数据和控制功能。 ]] local tsb_wavein_page = {} -- 页面UI元素 local main_container = nil local scroll_container = nil local chart_timer = nil -- 数据推送定时器ID local page_active = false -- 页面是否活跃,用于定时器安全 local common_ui = require("tsb_common_page") local chart = nil -- 图表对象 local freq_label = nil -- 频率显示标签 local vmax_label = nil -- 电压最大值标签 local vmin_label = nil -- 电压最小值标签 local trigger_threshold_input = nil -- 触发阈值输入框 local trigger_type_btn = nil -- 触发类型按钮 local trigger_mode_btn = nil -- 触发方式按钮 -- 控制参数 local time_scale = "100ms" -- 时间档位 local vertical_scale = "1V" -- 垂直档位 local trigger_threshold = "0" -- 触发阈值 local trigger_type = "上升沿" -- 触发类型:上升沿、下降沿、双边沿 local trigger_mode = "自动" -- 触发方式:自动、普通、单次 -- 创建数字键盘 local function create_numeric_keyboard() return airui.keyboard({ x = 0, y = 0, w = 480, h = 220, mode = "numeric", auto_hide = true, bg_color = 0xf1f1f1, on_commit = function() log.info("keyboard", "commit") end }) end -- 创建UI function tsb_wavein_page.create_ui() main_container = airui.container({ x = 0, y = 0, w = 480, h = 320, color = 0xF5F5F5, }) --------------------- 标题栏 ------------------------ local title_bar = airui.container({ parent = main_container, x = 0, y = 0, w = 480, h = 30, color = 0xFFD93D, }) airui.label({ parent = title_bar, text = "波形输入", x = 200, y = 8, w = 80, h = 20, font_size = 16, color = 0xFFFFFF, }) -- 标题栏公共信息展示 common_ui.add_battery_display(title_bar) common_ui.create_back_button(title_bar, tsb_wavein_page.cleanup) --------------------------------------------------- -- 主容器 scroll_container = airui.container({ parent = main_container, x = 0, y = 30, w = 480, h = 270, color = 0xFFFFFF, }) -- 图表区域(左上方) local chart_container = airui.container({ parent = scroll_container, x = 10, y = 10, w = 320, h = 200, color = 0xFFFFFF, radius = 8, border_width = 1, border_color = 0xDDDDDD, }) chart = airui.chart({ parent = chart_container, x = 10, y = 10, w = 300, h = 180, y_min = 0, y_max = 100, point_count = 100, -- 增加点数以适应宽屏 update_mode = "shift", -- 滚动模式 line_color = 0x00b4ff, line_width = 2, hdiv = 5, vdiv = 4, }) -- 预置一组初始值(平滑过渡) chart:set_values(1, {50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 68, 66, 64, 62, 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50}) -- 控制区域(右侧) local control_container = airui.container({ parent = scroll_container, x = 340, y = 10, w = 130, h = 155, color = 0xFFFFFF, radius = 8, border_width = 1, border_color = 0xDDDDDD, }) local control_y = 10 -- 时间档位 airui.label({ parent = control_container, text = "时间档位", x = 10, y = control_y, w = 110, h = 20, font_size = 12, color = 0x333333, }) airui.dropdown({ parent = control_container, x = 10, y = control_y + 20, w = 100, h = 25, options = {"1s", "500ms", "200ms", "100ms", "50ms", "20ms", "10ms", "5ms", "2ms", "1ms", "500us"}, default_index = 3, -- 默认100ms on_change = function(self, idx) local options = {"1s", "500ms", "200ms", "100ms", "50ms", "20ms", "10ms", "5ms", "2ms", "1ms", "500us"} time_scale = options[idx + 1] log.info("chart", "时间档位: " .. time_scale) end }) control_y = control_y + 50 -- 垂直档位 airui.label({ parent = control_container, text = "垂直档位", x = 10, y = control_y, w = 110, h = 20, font_size = 12, color = 0x333333, }) airui.dropdown({ parent = control_container, x = 10, y = control_y + 20, w = 100, h = 25, options = {"10V", "5V", "2V", "1V", "500mv", "200mv"}, default_index = 3, -- 默认1V on_change = function(self, idx) local options = {"10V", "5V", "2V", "1V", "500mv", "200mv"} vertical_scale = options[idx + 1] log.info("chart", "垂直档位: " .. vertical_scale) end }) control_y = control_y + 50 -- 水平偏移 airui.label({ parent = control_container, text = "水平偏移", x = 10, y = control_y, w = 110, h = 20, font_size = 12, color = 0x333333, }) local h_offset_container = airui.container({ parent = control_container, x = 10, y = control_y + 20, w = 110, h = 25, color = 0xFFFFFF, radius = 4, }) airui.button({ parent = h_offset_container, text = "←", x = 5, y = 2, w = 40, h = 20, on_click = function() log.info("chart", "水平偏移左") end }) airui.button({ parent = h_offset_container, text = "→", x = 60, y = 2, w = 40, h = 20, on_click = function() log.info("chart", "水平偏移右") end }) control_y = control_y + 50 -- 垂直偏移 airui.label({ parent = control_container, text = "垂直偏移", x = 10, y = control_y, w = 110, h = 20, font_size = 12, color = 0x333333, }) local v_offset_container = airui.container({ parent = control_container, x = 10, y = control_y + 20, w = 110, h = 25, color = 0xFFFFFF, radius = 4, }) airui.button({ parent = v_offset_container, text = "↑", x = 5, y = 2, w = 40, h = 20, on_click = function() log.info("chart", "垂直偏移上") end }) control_y = control_y + 35 airui.button({ parent = v_offset_container, text = "↓", x = 60, y = 2, w = 40, h = 20, on_click = function() log.info("chart", "垂直偏移下") end }) -- 触发控制区域 local trigger_container = airui.container({ parent = scroll_container, x = 340, y = 170, w = 130, h = 90, color = 0xFFFFFF, radius = 8, border_width = 1, border_color = 0xDDDDDD, }) -- 触发阈值 airui.label({ parent = trigger_container, text = "触发阈值", x = 10, y = 5, w = 60, h = 20, font_size = 12, color = 0x333333, }) trigger_threshold_input = airui.textarea({ parent = trigger_container, x = 10, y = 25, w = 70, h = 25, text = "500", max_len = 5, keyboard = create_numeric_keyboard() }) airui.label({ parent = trigger_container, text = "mv", x = 90, y = 30, w = 30, h = 20, font_size = 12, color = 0x333333, }) -- 触发类型 trigger_type_btn = airui.button({ parent = trigger_container, text = "上升沿", x = 10, y = 55, w = 55, h = 25, font_size = 10, on_click = function(self) if trigger_type == "上升沿" then trigger_type = "下降沿" elseif trigger_type == "下降沿" then trigger_type = "双边沿" else trigger_type = "上升沿" end self:set_text(trigger_type) log.info("chart", "触发类型: " .. trigger_type) end }) -- 触发方式 trigger_mode_btn = airui.button({ parent = trigger_container, text = "自动", x = 70, y = 55, w = 50, h = 25, font_size = 10, on_click = function(self) if trigger_mode == "自动" then trigger_mode = "普通" elseif trigger_mode == "普通" then trigger_mode = "单次" else trigger_mode = "自动" end self:set_text(trigger_mode) log.info("chart", "触发方式: " .. trigger_mode) end }) -- 信息显示区域(图表下方) local info_container = airui.container({ parent = scroll_container, x = 10, y = 220, w = 320, h = 40, color = 0xFFFFFF, radius = 8, border_width = 1, border_color = 0xDDDDDD, }) airui.label({ parent = info_container, text = "频率:", x = 5, y = 10, w = 40, h = 20, font_size = 13, color = 0x333333, }) freq_label = airui.label({ parent = info_container, text = "10.0 Hz", x = 40, y = 10, w = 60, h = 20, font_size = 13, color = 0x333333, }) airui.label({ parent = info_container, text = "V大:", x = 110, y = 10, w = 60, h = 20, font_size = 13, color = 0x333333, }) vmax_label = airui.label({ parent = info_container, text = "80.0 mV", x = 140, y = 10, w = 65, h = 20, font_size = 13, color = 0x333333, }) airui.label({ parent = info_container, text = "V小:", x = 220, y = 10, w = 80, h = 20, font_size = 13, color = 0x333333, }) vmin_label = airui.label({ parent = info_container, text = "20.0 mV", x = 250, y = 10, w = 65, h = 20, font_size = 13, color = 0x333333, }) -- 底部信息 common_ui.create_status_bar(main_container) end -- 定时器回调:模拟10Hz数据推送 local function chart_timer_cb() if not page_active then return -- 页面已销毁,不再更新 end -- 简单的正弦波模拟 local tick = _G.__chart_tick or 0 tick = tick + 1 _G.__chart_tick = tick local base = 50 + 30 * math.sin(tick * 0.1) local noise = math.random(-3, 3) local value = math.floor(base + noise + 0.5) -- 限制范围 if value < 0 then value = 0 end if value > 100 then value = 100 end if chart then chart:push(1, value) end -- 每50个周期更新一次信息显示 if tick % 50 == 0 then if freq_label then freq_label:set_text("10.0 Hz") end if vmax_label then vmax_label:set_text("80.0 mV") end if vmin_label then vmin_label:set_text("20.0 mV") end log.info("chart", "running 10Hz, sample=", value) end end -- 初始化页面 function tsb_wavein_page.init(params) tsb_wavein_page.create_ui() page_active = true -- 启动定时器(100ms = 10Hz) if chart_timer then sys.timerStop(chart_timer) end chart_timer = sys.timerLoopStart(chart_timer_cb, 100) end -- 清理页面 function tsb_wavein_page.cleanup() page_active = false if chart_timer then sys.timerStop(chart_timer) chart_timer = nil end if main_container then main_container:destroy() main_container = nil scroll_container = nil chart = nil freq_label = nil vmax_label = nil vmin_label = nil trigger_threshold_input = nil trigger_type_btn = nil trigger_mode_btn = nil end end return tsb_wavein_page