Edit spm6103_viewer.py

This commit is contained in:
Christoffer Martinsson 2025-04-13 18:06:19 +02:00
parent 7422a3b4c3
commit 1bc6db3f37

View File

@ -3,7 +3,52 @@ from tkinter.font import Font
import serial
import os
import json
import threading
import time
class SerialManager:
def __init__(self, port_name="/dev/ttyUSB0", baud_rate=115200, reconnect_interval=2):
self.port_name = port_name
self.baud_rate = baud_rate
self.reconnect_interval = reconnect_interval
self.ser = None
self.lock = threading.Lock()
self.running = True
self.thread = threading.Thread(target=self._monitor_serial)
self.thread.daemon = True
self.thread.start()
def _monitor_serial(self):
while self.running:
with self.lock:
if self.ser is None or not self.ser.is_open:
try:
self.ser = serial.Serial(self.port_name, self.baud_rate, timeout=1)
print(f"[INFO] Connected to {self.port_name}")
except serial.SerialException as e:
print(f"[WARN] Serial port error: {e}")
self.ser = None
time.sleep(self.reconnect_interval)
def send_command(self, command):
with self.lock:
if self.ser and self.ser.is_open:
try:
self.ser.write((command + '\n').encode('utf-8'))
response = self.ser.readline().decode('utf-8').strip()
return response
except Exception as e:
print(f"[ERROR] Failed to send/receive: {e}")
self.ser = None
return "Serial not connected"
def stop(self):
self.running = False
self.thread.join()
if self.ser and self.ser.is_open:
self.ser.close()
# Set DPI scale for Wayland
os.environ['GDK_SCALE'] = '2'
# Load saved window geometry if exists
@ -23,21 +68,10 @@ def save_window_geometry():
json.dump(settings, f)
# Serial configuration
port = '/dev/ttyUSB0' # Adjust to your specific port
baud_rate = 115200 # Adjust to your device's baud rate
ser = SerialManager(port='/dev/ttyUSB0')
try:
ser = serial.Serial(port, baud_rate, timeout=1)
except serial.SerialException as e:
ser = None
print(f"Serial port error: {e}")
def send_command(command):
if not ser:
return "Serial port not available"
ser.write((command + '\n').encode('utf-8'))
response = ser.readline().decode('utf-8').strip()
return response
def send_command(cmd):
return ser.send_command(cmd)
def get_id():
if not ser:
@ -121,8 +155,8 @@ app.title("OWON SPM6103")
app.geometry(load_window_geometry())
app.configure(bg="black")
# Add a window close event to save the geometry
app.protocol("WM_DELETE_WINDOW", lambda: [save_window_geometry(), app.quit()])
# For cleanup on exit
app.protocol("WM_DELETE_WINDOW", lambda: [save_window_geometry(), serial_manager.stop(), app.quit()])
multimeter_type_var = tk.StringVar()
multimeter_data_var = tk.StringVar()
@ -135,7 +169,6 @@ fontBig = Font(size=24)
resize_after_id = None
def apply_font_resize():
width = app.winfo_width()
@ -157,8 +190,6 @@ app.columnconfigure(0, weight=1, uniform="equal", minsize=100)
for i in range(7):
app.columnconfigure(i+1, weight=1, uniform="equal")
button_fg = "#444444"
# Labels
# Type and Range
tk.Label(app, textvariable=multimeter_type_var, font=fontMedium, bg="black", fg="lightgrey") \
@ -172,26 +203,21 @@ tk.Label(app, textvariable=multimeter_data_var, font=fontBig, bg="black", fg="li
.grid(column=1, columnspan=6, row=0, rowspan=1, sticky="nsew", padx=0, pady=10)
# Buttons
tk.Button(app, text="RES", command=set_res_mode, font=fontSmall, bg="black", fg=button_fg, highlightbackground="black", borderwidth=0) \
.grid(column=1, row=1, sticky="nsew", padx=0, pady=0)
buttons = [
("RES", set_res_mode),
("RES200", set_res200_mode),
("CONT", set_cont_mode),
("VOLT:DC", set_voltdc_mode),
("VOLT:AC", set_voltac_mode),
("DIOD", set_diod_mode),
("CAP", set_cap_mode),
]
tk.Button(app, text="RES200", command=set_res200_mode, font=fontSmall, bg="black", fg=button_fg, highlightbackground="black", borderwidth=0) \
.grid(column=2, row=1, sticky="nsew", padx=0, pady=0)
for i, (label, cmd) in enumerate(buttons, start=1):
tk.Button(app, text=label, command=cmd, font=fontSmall,
bg="black", fg=#444444, highlightbackground="black", borderwidth=0) \
.grid(column=i, row=1, sticky="nsew", padx=0, pady=0)
tk.Button(app, text="CONT", command=set_cont_mode, font=fontSmall, bg="black", fg=button_fg, highlightbackground="black", borderwidth=0) \
.grid(column=3, row=1, sticky="nsew", padx=0, pady=0)
tk.Button(app, text="VOLT:DC", command=set_voltdc_mode, font=fontSmall, bg="black", fg=button_fg, highlightbackground="black", borderwidth=0) \
.grid(column=4, row=1, sticky="nsew", padx=0, pady=0)
tk.Button(app, text="VOLT:AC", command=set_voltac_mode, font=fontSmall, bg="black", fg=button_fg, highlightbackground="black", borderwidth=0) \
.grid(column=5, row=1, sticky="nsew", padx=0, pady=0)
tk.Button(app, text="DIOD", command=set_diod_mode, font=fontSmall, bg="black", fg=button_fg, highlightbackground="black", borderwidth=0) \
.grid(column=6, row=1, sticky="nsew", padx=0, pady=0)
tk.Button(app, text="CAP", command=set_cap_mode, font=fontSmall, bg="black", fg=button_fg, highlightbackground="black", borderwidth=0) \
.grid(column=7, row=1, sticky="nsew", padx=0, pady=0)
# Initial fetch to start the auto-update process
fetch_device_info()