MainCode/adalm1000_logger.py aktualisiert

Alle Spannungswerte korrekt gemessen werden

    Das Programm stabil bleibt, auch ohne angeschlossene Batterie

    Der Benutzer klare Rückmeldungen über den Systemzustand erhält

    Die Hardware in einem sicheren Zustand bleibt
(D)
This commit is contained in:
Jan 2025-07-14 13:16:44 +02:00
parent 725bc83ab6
commit 44baefa581

View File

@ -38,21 +38,39 @@ class MeasurementThread(QThread):
self.current_direction = 1 # 1 for source, -1 for sink
def run(self):
"""Continuous measurement loop"""
"""Continuous measurement with proper validation"""
self._running = True
consecutive_errors = 0
while self._running:
try:
samples = self.device.read(self.filter_window_size, 500, True)
# Check for device disconnection
if not samples:
raise DeviceDisconnectedError("No samples received")
consecutive_errors += 1
if consecutive_errors > 3:
raise DeviceDisconnectedError("Keine Messwerte empfangen")
time.sleep(0.1)
continue
consecutive_errors = 0 # Reset counter on successful read
current_time = time.time() - self.start_time
raw_voltage = np.mean([s[1][0] for s in samples]) # Channel B
# Get voltage from Channel B (HI_Z mode) and current from Channel A
raw_voltage = np.mean([s[1][0] for s in samples]) # Channel B voltage
raw_current = np.mean([s[0][1] for s in samples]) * self.current_direction # Channel A current with direction
# Strict voltage validation (0-5V range)
if raw_voltage < 0 or raw_voltage > 5.0:
raise ValueError(f"Ungültige Spannung: {raw_voltage}V (außerhalb 0-5V Bereich)")
# Update filter windows
# Current measurement with direction
raw_current = np.mean([s[0][1] for s in samples]) * self.current_direction
# Current validation (-200mA to +200mA)
if not (-0.25 <= raw_current <= 0.25):
raise ValueError(f"Ungültiger Strom: {raw_current}A (außerhalb ±200mA Bereich)")
# Apply filtering
self.voltage_window.append(raw_voltage)
self.current_window.append(raw_current)
@ -63,16 +81,10 @@ class MeasurementThread(QThread):
voltage = np.mean(self.voltage_window)
current = np.mean(self.current_window)
# Validate measurements
if not (0 <= voltage <= 5.0):
raise ValueError(f"Invalid voltage: {voltage}V")
if not (-0.25 <= current <= 0.25):
raise ValueError(f"Invalid current: {current}A")
# Emit update
# Emit measurements
self.update_signal.emit(voltage, current, current_time)
# Store measurement
# Store in queue
try:
self.measurement_queue.put_nowait((voltage, current))
except Full:
@ -80,10 +92,14 @@ class MeasurementThread(QThread):
time.sleep(max(0.05, self.interval))
except Exception as e:
self.error_signal.emit(f"Read error: {str(e)}")
except DeviceDisconnectedError as e:
self.error_signal.emit(f"Gerätefehler: {str(e)}")
time.sleep(1)
continue
except Exception as e:
self.error_signal.emit(f"Messfehler: {str(e)}")
time.sleep(0.5)
continue
def set_direction(self, direction):
"""Set current direction (1 for source, -1 for sink)"""
@ -892,9 +908,9 @@ class BatteryTester(QMainWindow):
self.main_layout.addWidget(self.canvas, 1)
def init_device(self):
"""Initialize the ADALM1000 device with continuous measurement"""
"""Initialize the ADALM1000 with proper connection checks"""
try:
# Clean up any existing session
# Cleanup previous session
if hasattr(self, 'session'):
try:
self.session.end()
@ -902,23 +918,45 @@ class BatteryTester(QMainWindow):
except:
pass
# Hardware reset delay
time.sleep(1)
try:
self.session = pysmu.Session(ignore_dataflow=True, queue_size=10000)
if not self.session.devices:
raise Exception("No ADALM1000 detected - check connections")
raise Exception("Kein ADALM1000 erkannt - Verbindung prüfen")
except Exception as e:
if "resource busy" in str(e).lower():
raise Exception("ADALM1000 wird bereits von einem anderen Programm verwendet")
raise
self.dev = self.session.devices[0]
# Set safe defaults
self.dev.channels['A'].mode = pysmu.Mode.HI_Z
self.dev.channels['B'].mode = pysmu.Mode.HI_Z
self.dev.channels['A'].constant(0)
self.dev.channels['B'].constant(0)
# Connection test with actual measurement
try:
samples = self.dev.read(5, 500, True) # 5 samples for stability
if not samples:
raise DeviceDisconnectedError("Keine Messwerte empfangen")
# Check if we're getting valid data (not just noise)
voltages = [s[1][0] for s in samples] # Channel B voltages
if all(abs(v) < 0.0001 for v in voltages): # 100µV threshold
self.status_bar.showMessage("Gerät verbunden, aber keine Batterie angeschlossen")
except Exception as e:
raise DeviceDisconnectedError(f"Verbindungstest fehlgeschlagen: {str(e)}")
self.session.start(0)
self.status_light.setStyleSheet(f"background-color: green; border-radius: 10px;")
self.connection_label.setText("Connected")
self.status_bar.showMessage("Device connected | Ready to measure")
# Update UI
self.status_light.setStyleSheet("background-color: green; border-radius: 10px;")
self.connection_label.setText("Verbunden")
self.status_bar.showMessage("Gerät bereit - Batterie anschließen um zu messen")
self.session_active = True
self.start_button.setEnabled(True)
@ -1852,33 +1890,39 @@ class BatteryTester(QMainWindow):
@pyqtSlot(str)
def handle_device_error(self, error):
"""Handle device connection errors"""
"""Handle errors with proper state management"""
error_msg = str(error)
print(f"Device error: {error_msg}")
print(f"Fehler: {error_msg}")
# Special cases
if "resource busy" in error_msg.lower():
error_msg = "ADALM1000 is already in use"
elif "no samples" in error_msg.lower():
error_msg = "No measurments - Check connection"
# Cleanup
if hasattr(self, 'session'):
try:
if self.session_active:
self.session.end()
del self.session
except Exception as e:
print(f"Error cleaning up session: {e}")
except:
pass
self.status_light.setStyleSheet(f"background-color: red; border-radius: 10px;")
# Update UI
self.status_light.setStyleSheet("background-color: red; border-radius: 10px;")
self.connection_label.setText("Disconnected")
self.status_bar.showMessage(f"Device error: {error_msg}")
self.status_bar.showMessage(f"Error: {error_msg}")
# Disable controls
self.session_active = False
self.test_running = False
self.continuous_mode = False
self.measuring = False
self.start_button.setEnabled(False)
self.stop_button.setEnabled(False)
self.time_data.clear()
self.voltage_data.clear()
self.current_data.clear()
# Attempt recovery for certain errors
if "no samples" in error_msg.lower() or "resource busy" in error_msg.lower():
QTimer.singleShot(3000, self.reconnect_device)
@pyqtSlot(str)
def update_test_phase(self, phase_text):