feat(HDMI-Tool): 光机串口参数可选(默认8-N-1) + TEC 控制与温度读取

This commit is contained in:
2026-09-12 02:07:26 +08:00
parent 96df14caea
commit e131646156
7 changed files with 136 additions and 43 deletions
+79 -18
View File
@@ -289,8 +289,18 @@ class App(ctk.CTk):
values=('115200', '57600', '38400', '9600'))
self.cbo_baud.set(str(config.SERIAL_CFG['baud']))
self.cbo_baud.pack(side='left', padx=6)
ctk.CTkLabel(row2, text='数据位 8 · 校验 N · 停止位 1(板卡固件固定)',
text_color='gray50').pack(side='left', padx=(0, 6))
ctk.CTkLabel(row2, text='数据位:').pack(side='left')
self.cbo_databits = ctk.CTkComboBox(row2, width=62, values=('8', '7', '6', '5'))
self.cbo_databits.set(str(config.SERIAL_CFG['bytesize']))
self.cbo_databits.pack(side='left', padx=(6, 0))
ctk.CTkLabel(row2, text='校验:').pack(side='left', padx=(10, 0))
self.cbo_parity = ctk.CTkComboBox(row2, width=54, values=('N', 'E', 'O'))
self.cbo_parity.set(str(config.SERIAL_CFG['parity']))
self.cbo_parity.pack(side='left', padx=(6, 0))
ctk.CTkLabel(row2, text='停止位:').pack(side='left', padx=(10, 0))
self.cbo_stopbits = ctk.CTkComboBox(row2, width=54, values=('1', '2'))
self.cbo_stopbits.set(str(config.SERIAL_CFG['stopbits']))
self.cbo_stopbits.pack(side='left', padx=(6, 0))
self.lbl_dlpc_st = ctk.CTkLabel(row2, text='未连接', text_color='gray60')
self.lbl_dlpc_st.pack(side='left', padx=6)
@@ -305,39 +315,48 @@ class App(ctk.CTk):
'累加和校验; 全部命令见 README"光机控制"')
# -- 光机命令 --
card, c = self._card(col,'光机命令 — 预设与自定义')
card, c = self._card(col,'光机命令 — 预设 / 自定义 / TEC')
card.grid(row=2, column=0, sticky='ew', pady=(10, 0))
row1 = ctk.CTkFrame(c, fg_color='transparent')
row1.pack(fill='x')
for name, cmd in (('开光机', 'M730S0'), ('关光机', 'M730S1'),
('查电流', 'M732'), ('查版本', 'M999'), ('软件重启', 'M888')):
ctk.CTkButton(row1, text=name, width=88,
('查电流', 'M732'), ('查版本', 'M999'), ('软件重启', 'M888'),
('开TEC', 'M7S0'), ('关TEC', 'M7S1'), ('TEC33.0°C', 'M8S330')):
ctk.CTkButton(row1, text=name, width=68,
command=lambda cc=cmd: self._dlpc_send(cc)
).pack(side='left', padx=(0, 6))
).pack(side='left', padx=(0, 4))
row2 = ctk.CTkFrame(c, fg_color='transparent')
row2.pack(fill='x', pady=(6, 0))
ctk.CTkLabel(row2, text='预设:').pack(side='left')
lf2 = ctk.CTkFrame(row2, fg_color='transparent')
lf2.pack(side='left', fill='x', expand=True)
ctk.CTkLabel(lf2, text='预设:', width=52, anchor='w').pack(side='left')
self._dlpc_presets = [(n, cmd) for n, cmd, _ in dlpc_rs485.PRESETS]
self.cbo_dlpc_cmd = ctk.CTkComboBox(
row2, width=240, state='readonly',
lf2, state='readonly',
values=[f'{n} {cmd}' for n, cmd in self._dlpc_presets])
self.cbo_dlpc_cmd.set(self._dlpc_presets[0][0] + ' ' + self._dlpc_presets[0][1])
self.cbo_dlpc_cmd.pack(side='left', padx=6)
ctk.CTkButton(row2, text='发送', width=64,
self.cbo_dlpc_cmd.pack(side='left', fill='x', expand=True, padx=6)
ctk.CTkButton(lf2, text='发送', width=64,
command=self._dlpc_send_preset).pack(side='left')
ctk.CTkButton(row2, text='查DMD温度', width=96,
command=lambda: self._dlpc_send('M201')).pack(side='right')
row3 = ctk.CTkFrame(c, fg_color='transparent')
row3.pack(fill='x', pady=(6, 0))
ctk.CTkLabel(row3, text='自定义:').pack(side='left')
lf3 = ctk.CTkFrame(row3, fg_color='transparent')
lf3.pack(side='left', fill='x', expand=True)
ctk.CTkLabel(lf3, text='自定义:', width=52, anchor='w').pack(side='left')
self.var_custom_cmd = tk.StringVar()
ent = ctk.CTkEntry(row3, width=180, textvariable=self.var_custom_cmd,
ent = ctk.CTkEntry(lf3, textvariable=self.var_custom_cmd,
placeholder_text='如 M730S0T2000')
ent.pack(side='left', padx=6)
ent.pack(side='left', fill='x', expand=True, padx=6)
ent.bind('<Return>', lambda _e: self._dlpc_send_custom())
ctk.CTkButton(row3, text='发送', width=64,
ctk.CTkButton(lf3, text='发送', width=64,
command=self._dlpc_send_custom).pack(side='left')
ctk.CTkButton(row3, text='查LAMP温度', width=96,
command=lambda: self._dlpc_send('M202')).pack(side='right')
# -- 快捷滑条 --
card, c = self._card(col,'快捷滑条 — 光强 / 定时投光')
card, c = self._card(col,'快捷滑条 — 光强 / 定时投光 / TEC 温度')
card.grid(row=3, column=0, sticky='ew', pady=(10, 0))
rowa = ctk.CTkFrame(c, fg_color='transparent')
rowa.pack(fill='x')
@@ -369,6 +388,21 @@ class App(ctk.CTk):
self.ent_timer.bind('<Return>', self._timer_entry_apply)
ctk.CTkButton(rowb, text='开光机(定时)', width=110,
command=self._dlpc_send_timer).pack(side='left', padx=(6, 0))
rowc = ctk.CTkFrame(c, fg_color='transparent')
rowc.pack(fill='x', pady=(8, 0))
ctk.CTkLabel(rowc, text='TEC凝露点(0.1°C):').pack(side='left')
self.var_tec = tk.StringVar(value='330')
sld_c = ctk.CTkSlider(rowc, from_=200, to=350, number_of_steps=150,
command=lambda v: self.var_tec.set(str(int(round(float(v))))))
sld_c.set(330)
sld_c.pack(side='left', fill='x', expand=True, padx=8)
self.sld_tec = sld_c
self.ent_tec = ctk.CTkEntry(rowc, width=56, justify='center',
textvariable=self.var_tec)
self.ent_tec.pack(side='left')
self.ent_tec.bind('<Return>', self._tec_entry_apply)
ctk.CTkButton(rowc, text='下发 M8S', width=110,
command=self._dlpc_send_tec).pack(side='left', padx=(6, 0))
# ============================================================
# 显示器 / 分辨率 / EDID
@@ -658,12 +692,16 @@ class App(ctk.CTk):
return
try:
baud = int(self.cbo_baud.get())
bytesize = int(self.cbo_databits.get())
stopbits = int(self.cbo_stopbits.get())
except ValueError:
self.lbl_dlpc_st.configure(text='波特率非法', text_color='#E07A3F')
self.lbl_dlpc_st.configure(text='串口参数非法', text_color='#E07A3F')
return
config.SERIAL_CFG['port'], config.SERIAL_CFG['baud'] = port, baud
parity = self.cbo_parity.get().strip().upper()[:1] or 'N'
config.SERIAL_CFG.update(port=port, baud=baud, bytesize=bytesize,
parity=parity, stopbits=stopbits)
config.save_slots(self.slots, self.area_var.get()) # 记住本次串口
self.dlpc.open(port, baud)
self.dlpc.open(port, baud, bytesize=bytesize, parity=parity, stopbits=stopbits)
def _dlpc_send(self, cmd):
if not self.dlpc.is_connected():
@@ -724,6 +762,29 @@ class App(ctk.CTk):
return
self._dlpc_send('M730S0' if v <= 0 else f'M730S0T{v * 1000}')
def _tec_entry_apply(self, _evt=None):
"""TEC 温度输入框回车: 校验并限幅 200-350(0.1°C), 同步回滑条"""
try:
v = int(self.var_tec.get())
except ValueError:
self.var_tec.set(str(int(float(self.sld_tec.get()))))
return
v = max(200, min(350, v))
self.sld_tec.set(v)
self.var_tec.set(str(v))
def _dlpc_send_tec(self):
try:
v = int(self.var_tec.get())
except ValueError:
messagebox.showinfo('TEC 温度非法', 'TEC 凝露点需为 200-350 的整数(0.1°C)')
return
if not 200 <= v <= 350:
messagebox.showinfo('TEC 温度越界',
'TEC 凝露点范围 200-350(0.1°C), 越界固件会回 err:OL')
return
self._dlpc_send(f'M8S{v}')
def destroy(self):
try: # 取消待触发的轮询回调, 避免销毁后 Tcl 报错
if self._poll_job: