fix
This commit is contained in:
parent
5eb500644c
commit
559f512bee
@ -1,5 +1,5 @@
|
|||||||
# device_controller.py
|
# device_controller.py
|
||||||
import threading, queue, time, math, os, csv
|
import threading, queue, time, math, os, csv, statistics
|
||||||
|
|
||||||
RAW_SAMPLE_RATE = 100_000.0 # M1K nominal
|
RAW_SAMPLE_RATE = 100_000.0 # M1K nominal
|
||||||
CHUNK_RAW = 2000 # ~20 ms pro Chunk pro Gerät
|
CHUNK_RAW = 2000 # ~20 ms pro Chunk pro Gerät
|
||||||
@ -40,92 +40,66 @@ class DeviceController:
|
|||||||
|
|
||||||
# -------- Reader: liest roh und decimiert --------
|
# -------- Reader: liest roh und decimiert --------
|
||||||
def reader_loop(self):
|
def reader_loop(self):
|
||||||
print(f"[{self.serial}] Reader start (decim={self.decim}, eff_rate={self.eff_rate:.0f} S/s)")
|
filter_window_size = 10 # wie in deinem Logger
|
||||||
|
interval = 0.1 # 10 Hz Mess-Update
|
||||||
|
last_log_time = 0
|
||||||
|
|
||||||
while not self.stop_evt.is_set():
|
while not self.stop_evt.is_set():
|
||||||
# Kommandos
|
# Start/Stop Kommandos
|
||||||
try:
|
try:
|
||||||
cmd, _ = self.cmdq.get_nowait()
|
cmd, _ = self.cmdq.get_nowait()
|
||||||
if cmd == "start" and not self.running:
|
if cmd == "start" and not self.running:
|
||||||
self.sm.start() # Session ggf. starten
|
self.sm.start()
|
||||||
self.running = True
|
self.running = True
|
||||||
elif cmd == "stop" and self.running:
|
elif cmd == "stop" and self.running:
|
||||||
|
self.sm.stop()
|
||||||
self.running = False
|
self.running = False
|
||||||
self.sm.stop() # Session ggf. stoppen
|
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if not self.running:
|
if not self.running:
|
||||||
time.sleep(0.02)
|
time.sleep(0.05)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# pysmu: Liste von [VA, IA, VB, IB]
|
# Rohdaten holen (filter_window_size Samples)
|
||||||
samples = self.dev.read(CHUNK_RAW, -1) # je nach Version evtl. .read(CHUNK_RAW)
|
samples = self.dev.read(filter_window_size, -1)
|
||||||
if not samples:
|
if not samples:
|
||||||
time.sleep(0.001)
|
time.sleep(interval)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Kanäle extrahieren
|
# Kanäle extrahieren & mitteln
|
||||||
va_raw = [row[0] for row in samples]
|
va = statistics.mean(row[0] for row in samples)
|
||||||
vb_raw = [row[2] for row in samples]
|
vb = statistics.mean(row[2] for row in samples)
|
||||||
|
|
||||||
# -------- Decimation: jedes N-te Sample --------
|
now = time.time()
|
||||||
if self.decim > 1:
|
if now - last_log_time >= 1.0: # nur jede Sekunde loggen
|
||||||
va = va_raw[::self.decim]
|
self.writer_q.put((now, va, vb))
|
||||||
vb = vb_raw[::self.decim]
|
last_log_time = now
|
||||||
else:
|
|
||||||
va, vb = va_raw, vb_raw
|
|
||||||
|
|
||||||
# In Writer-Queue; bei voller Queue ältestes verwerfen (Ringpuffer)
|
|
||||||
try:
|
|
||||||
self.writer_q.put_nowait((va, vb))
|
|
||||||
except queue.Full:
|
|
||||||
try:
|
|
||||||
_ = self.writer_q.get_nowait() # drop oldest
|
|
||||||
except queue.Empty:
|
|
||||||
pass
|
|
||||||
finally:
|
|
||||||
# (erneut versuchen, blockiert jetzt nicht)
|
|
||||||
try:
|
|
||||||
self.writer_q.put_nowait((va, vb))
|
|
||||||
except queue.Full:
|
|
||||||
# wenn immer noch voll, dann überspringen wir diesen Chunk
|
|
||||||
pass
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[{self.serial}] Read-Fehler: {e}")
|
print(f"[{self.serial}] Read-Fehler: {e}")
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|
||||||
print(f"[{self.serial}] Reader stop")
|
# Loop-Rate steuern
|
||||||
|
time.sleep(max(0.05, interval))
|
||||||
|
|
||||||
# -------- Writer: Wide-Format, effektive Zeitachse --------
|
# -------- Writer: Wide-Format, effektive Zeitachse --------
|
||||||
def writer_loop(self):
|
def writer_loop(self):
|
||||||
os.makedirs(OUTDIR, exist_ok=True)
|
os.makedirs(OUTDIR, exist_ok=True)
|
||||||
fn = os.path.join(OUTDIR, f"{time.strftime('%Y%m%d_%H%M%S')}_{self.serial}.csv")
|
fn = os.path.join(OUTDIR, f"{time.strftime('%Y%m%d_%H%M%S')}_{self.serial}.csv")
|
||||||
sample_idx = 0
|
print(f"[{self.serial}] Writer -> {fn}")
|
||||||
rows_since_flush = 0
|
|
||||||
print(f"[{self.serial}] Writer -> {fn} (dt={self.dt:.6e}s)")
|
|
||||||
try:
|
try:
|
||||||
with open(fn, "w", newline="") as f:
|
with open(fn, "w", newline="") as f:
|
||||||
w = csv.writer(f)
|
w = csv.writer(f)
|
||||||
w.writerow(["t_rel_s", "A", "B"])
|
w.writerow(["timestamp", "A", "B"])
|
||||||
while not (self.stop_evt.is_set() and self.writer_q.empty()):
|
while not (self.stop_evt.is_set() and self.writer_q.empty()):
|
||||||
try:
|
try:
|
||||||
va, vb = self.writer_q.get(timeout=0.5)
|
ts, va, vb = self.writer_q.get(timeout=0.5)
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
continue
|
continue
|
||||||
|
w.writerow([ts, va, vb])
|
||||||
n = min(len(va), len(vb))
|
f.flush()
|
||||||
# Zeitachse mit effektiver Rate
|
|
||||||
for i in range(n):
|
|
||||||
t_rel = (sample_idx + i) * self.dt
|
|
||||||
w.writerow([t_rel, va[i], vb[i]])
|
|
||||||
sample_idx += n
|
|
||||||
rows_since_flush += n
|
|
||||||
|
|
||||||
if rows_since_flush >= 10_000: # alle ~10k Samples flushen
|
|
||||||
f.flush()
|
|
||||||
rows_since_flush = 0
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[{self.serial}] Writer-Fehler: {e}")
|
print(f"[{self.serial}] Writer-Fehler: {e}")
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user