both backends works. But data from tty device read rather slow. So USB stack on stm32 is freezing

This commit is contained in:
2025-12-19 20:08:46 +03:00
parent 4959cb6347
commit 718bff0c4b

View File

@ -4,7 +4,7 @@
Формат строк: Формат строк:
- "Sweep_start" — начало нового свипа (предыдущий считается завершённым) - "Sweep_start" — начало нового свипа (предыдущий считается завершённым)
- "curr_step X Y" — точка (индекс X, значение Y), все целые со знаком - "stp X Y" — точка (индекс X, значение Y), все целые со знаком
Отрисовываются два графика: Отрисовываются два графика:
- Левый: последний полученный свип (Y vs X) - Левый: последний полученный свип (Y vs X)
@ -30,6 +30,8 @@ from typing import Optional, Tuple
import numpy as np import numpy as np
WF_WIDTH = 1000 # максимальное число точек в ряду водопада
def try_open_pyserial(path: str, baud: int, timeout: float): def try_open_pyserial(path: str, baud: int, timeout: float):
try: try:
@ -221,10 +223,10 @@ class SweepReader(threading.Thread):
ys.clear() ys.clear()
continue continue
# curr_step X Y # stp X Y
# Разрешим как с пробелами, так и табами # Разрешим как с пробелами, так и табами
parts = line.split() parts = line.split()
if len(parts) >= 3 and parts[0].lower() == "curr_step": if len(parts) >= 3 and parts[0].lower() == "stp":
try: try:
x = int(parts[1], 10) x = int(parts[1], 10)
y = int(parts[2], 10) y = int(parts[2], 10)
@ -343,25 +345,25 @@ def main():
interval_ms = int(1000.0 / max_fps) interval_ms = int(1000.0 / max_fps)
frames_since_ylim_update = 0 frames_since_ylim_update = 0
def ensure_buffer(w: int): def ensure_buffer(_w: int):
nonlocal ring, width, head, x_shared nonlocal ring, width, head, x_shared
if ring is not None and width == w: if ring is not None:
return return
width = w width = WF_WIDTH
x_shared = np.arange(w, dtype=np.int32) x_shared = np.arange(width, dtype=np.int32)
ring = np.full((max_sweeps, w), np.nan, dtype=np.float32) ring = np.full((max_sweeps, width), np.nan, dtype=np.float32)
head = 0 head = 0
# Обновляем изображение под новые размеры # Обновляем изображение под новые размеры
img_obj.set_data(ring) img_obj.set_data(ring)
img_obj.set_extent((0, w - 1 if w > 0 else 1, 0, max_sweeps - 1)) img_obj.set_extent((0, width - 1 if width > 0 else 1, 0, max_sweeps - 1))
ax_img.set_xlim(0, max(1, w - 1)) ax_img.set_xlim(0, max(1, width - 1))
ax_img.set_ylim(max_sweeps - 1, 0) ax_img.set_ylim(max_sweeps - 1, 0)
def push_sweep(s: np.ndarray): def push_sweep(s: np.ndarray):
nonlocal ring, head, y_min, y_max nonlocal ring, head, y_min, y_max
if s is None or s.size == 0 or ring is None: if s is None or s.size == 0 or ring is None:
return return
# Нормализуем длину # Нормализуем длину до фиксированной ширины
w = ring.shape[1] w = ring.shape[1]
row = np.full((w,), np.nan, dtype=np.float32) row = np.full((w,), np.nan, dtype=np.float32)
take = min(w, s.size) take = min(w, s.size)
@ -404,7 +406,10 @@ def main():
# Обновление линии последнего свипа # Обновление линии последнего свипа
if current_sweep is not None: if current_sweep is not None:
xs = x_shared if x_shared is not None and x_shared.size == current_sweep.size else np.arange(current_sweep.size, dtype=np.int32) if x_shared is not None and current_sweep.size <= x_shared.size:
xs = x_shared[: current_sweep.size]
else:
xs = np.arange(current_sweep.size, dtype=np.int32)
line_obj.set_data(xs, current_sweep) line_obj.set_data(xs, current_sweep)
# Лимиты по X постоянные под текущую ширину # Лимиты по X постоянные под текущую ширину
ax_line.set_xlim(0, max(1, current_sweep.size - 1)) ax_line.set_xlim(0, max(1, current_sweep.size - 1))
@ -503,17 +508,17 @@ def run_pyqtgraph(args):
except Exception: except Exception:
pass pass
def ensure_buffer(w: int): def ensure_buffer(_w: int):
nonlocal ring, head, width, x_shared nonlocal ring, head, width, x_shared
if ring is not None and width == w: if ring is not None:
return return
width = w width = WF_WIDTH
x_shared = np.arange(w, dtype=np.int32) x_shared = np.arange(width, dtype=np.int32)
ring = np.full((max_sweeps, w), np.nan, dtype=np.float32) ring = np.full((max_sweeps, width), np.nan, dtype=np.float32)
head = 0 head = 0
img.setImage(ring, autoLevels=False) img.setImage(ring, autoLevels=False)
p_img.setRange(xRange=(0, max(1, w - 1)), yRange=(0, max_sweeps - 1), padding=0) p_img.setRange(xRange=(0, max(1, width - 1)), yRange=(0, max_sweeps - 1), padding=0)
p_line.setXRange(0, max(1, w - 1), padding=0) p_line.setXRange(0, max(1, width - 1), padding=0)
def push_sweep(s: np.ndarray): def push_sweep(s: np.ndarray):
nonlocal ring, head, y_min, y_max nonlocal ring, head, y_min, y_max
@ -559,7 +564,11 @@ def run_pyqtgraph(args):
def update(): def update():
changed = drain_queue() > 0 changed = drain_queue() > 0
if current_sweep is not None and x_shared is not None: if current_sweep is not None and x_shared is not None:
curve.setData(x_shared[: current_sweep.size], current_sweep, autoDownsample=True) if current_sweep.size <= x_shared.size:
xs = x_shared[: current_sweep.size]
else:
xs = np.arange(current_sweep.size)
curve.setData(xs, current_sweep, autoDownsample=True)
if fixed_ylim is None: if fixed_ylim is None:
y0 = float(np.nanmin(current_sweep)) y0 = float(np.nanmin(current_sweep))
y1 = float(np.nanmax(current_sweep)) y1 = float(np.nanmax(current_sweep))