81 lines
3.2 KiB
Python
81 lines
3.2 KiB
Python
import threading, queue, time, csv, os
|
|
|
|
CHUNK = 2000
|
|
OUTDIR = "logs"
|
|
os.makedirs(OUTDIR, exist_ok=True)
|
|
|
|
class DeviceController:
|
|
def __init__(self, sess, dev):
|
|
self.sess = sess # <— Session referenzieren
|
|
self.dev = dev
|
|
self.cmdq = queue.Queue()
|
|
self.stop_evt = threading.Event()
|
|
self.running = False
|
|
self.writer_q = queue.Queue(maxsize=50)
|
|
self.reader_t = threading.Thread(target=self.reader_loop, daemon=True)
|
|
self.writer_t = threading.Thread(target=self.writer_loop, daemon=True)
|
|
|
|
def start(self):
|
|
if not self.reader_t.is_alive(): self.reader_t.start()
|
|
if not self.writer_t.is_alive(): self.writer_t.start()
|
|
self.cmdq.put(("start", None))
|
|
|
|
def stop(self):
|
|
self.cmdq.put(("stop", None))
|
|
|
|
def set_mode(self, ch, mode):
|
|
# BUGFIX: nicht rekursiv sich selbst aufrufen!
|
|
self.dev.channels[ch].mode = mode
|
|
|
|
def reader_loop(self):
|
|
while not self.stop_evt.is_set():
|
|
try:
|
|
cmd, arg = self.cmdq.get_nowait()
|
|
if cmd == "start" and not self.running:
|
|
# Continuous Session-Stream starten (für alle Devices)
|
|
self.sess.start(0) # <— statt dev.run(0)
|
|
self.running = True
|
|
elif cmd == "stop" and self.running:
|
|
self.sess.end() # <— Session sauber beenden
|
|
# optional: Puffer leeren
|
|
# self.sess.flush(-1, True) # falls verfügbar in deiner Version
|
|
self.running = False
|
|
elif cmd == "mode":
|
|
ch, mode = arg
|
|
self.dev.channels[ch].mode = mode
|
|
except queue.Empty:
|
|
pass
|
|
|
|
if self.running:
|
|
try:
|
|
# Lies jeweils CHUNK Samples (blockierend bis voll)
|
|
data = self.dev.read(CHUNK, -1) # -> [[VA, IA, VB, IB], ...]
|
|
vsA = [row[0] for row in data]
|
|
vsB = [row[2] for row in data]
|
|
self.writer_q.put((time.time(), vsA, vsB))
|
|
except Exception:
|
|
time.sleep(0.001)
|
|
else:
|
|
time.sleep(0.01)
|
|
|
|
def writer_loop(self):
|
|
ts0 = None
|
|
fn = os.path.join(OUTDIR, f"{time.strftime('%Y%m%d_%H%M%S')}_{self.dev.serial}.csv")
|
|
with open(fn, "w", newline="") as f:
|
|
w = csv.writer(f)
|
|
w.writerow(["t_rel_s", "ch", "value"])
|
|
sample_idx = 0
|
|
while not (self.stop_evt.is_set() and self.writer_q.empty()):
|
|
try:
|
|
ts, va, vb = self.writer_q.get(timeout=0.2)
|
|
except Exception:
|
|
continue
|
|
if ts0 is None: ts0 = ts
|
|
for i, v in enumerate(va):
|
|
t_rel = (sample_idx + i) * 1e-5 # 100 kS/s → 10 µs
|
|
w.writerow([t_rel, "A", v])
|
|
for i, v in enumerate(vb):
|
|
t_rel = (sample_idx + i) * 1e-5
|
|
w.writerow([t_rel, "B", v])
|
|
sample_idx += len(va)
|
|
print(f"[{self.dev.serial}] Datei geschlossen.") |