MainCode/adalm1000_logger.py aktualisiert

Entladephase analog zur Ladephase verstärken

    Doppelten msg_box Aufruf entfernen

   (D)
This commit is contained in:
Jan 2025-06-28 01:34:27 +02:00
parent f779d97397
commit bc77ae2f6b

View File

@ -596,68 +596,115 @@ class BatteryTester(QMainWindow):
def execute_charge_phase(self, current, target_voltage): def execute_charge_phase(self, current, target_voltage):
"""Führt die Ladephase durch""" """Führt die Ladephase durch"""
if not hasattr(self, 'dev') or not self.session_active:
self.error_signal.emit("Device not connected")
return
self.test_phase = "Laden" self.test_phase = "Laden"
self.phase_label.setText(self.test_phase) self.phase_label.setText(self.test_phase)
self.status_bar.setText(f"Laden auf {target_voltage}V @ {current:.3f}A") self.status_bar.setText(f"Laden auf {target_voltage}V @ {current:.3f}A")
self.measuring = True self.measuring = True
self.dev.channels['A'].mode = pysmu.Mode.SIMV try:
self.dev.channels['A'].constant(current) # Reset channel first
self.charge_capacity = 0.0 self.dev.channels['A'].mode = pysmu.Mode.HI_Z
self.charge_capacity_label.setText("0.000")
last_update = time.time()
while self.test_running and not self.request_stop:
if not self.voltage_data:
time.sleep(0.1)
continue
now = time.time()
delta_t = now - last_update
last_update = now
measured_current = abs(self.current_data[-1])
self.charge_capacity += measured_current * delta_t / 3600
self.charge_capacity_label.setText(f"{self.charge_capacity:.4f}")
current_voltage = self.voltage_data[-1]
if current_voltage >= target_voltage or self.request_stop:
break
time.sleep(0.1) time.sleep(0.1)
# Configure for current sourcing
self.dev.channels['A'].mode = pysmu.Mode.SIMV
time.sleep(0.05)
self.dev.channels['A'].constant(current)
time.sleep(0.1) # Allow settling time
actual_current = self.dev.channels['A'].current
if abs(actual_current - current) > 0.01: # 10mA tolerance
self.error_signal.emit(f"Current mismatch: {actual_current:.3f}A vs {current:.3f}A")
self.charge_capacity = 0.0
self.charge_capacity_label.setText("0.000")
last_update = time.time()
while self.test_running and not self.request_stop:
if not self.voltage_data:
time.sleep(0.1)
continue
now = time.time()
delta_t = now - last_update
last_update = now
measured_current = abs(self.current_data[-1])
self.charge_capacity += measured_current * delta_t / 3600
self.charge_capacity_label.setText(f"{self.charge_capacity:.4f}")
current_voltage = self.voltage_data[-1]
if current_voltage >= target_voltage or self.request_stop:
break
time.sleep(0.1)
except Exception as e:
self.error_signal.emit(f"Charge error: {str(e)}")
def execute_discharge_phase(self, current, target_voltage): def execute_discharge_phase(self, current, target_voltage):
"""Führt die Entladephase durch""" """Führt die Entladephase durch"""
if not hasattr(self, 'dev') or not self.session_active:
self.error_signal.emit("Device not connected")
return
self.test_phase = "Entladen" self.test_phase = "Entladen"
self.phase_label.setText(self.test_phase) self.phase_label.setText(self.test_phase)
self.status_bar.setText(f"Entladen auf {target_voltage}V @ {current:.3f}A") self.status_bar.setText(f"Entladen auf {target_voltage}V @ {current:.3f}A")
self.measuring = True self.measuring = True
self.dev.channels['A'].mode = pysmu.Mode.SIMV try:
self.dev.channels['A'].constant(-current) # Reset channel first
self.capacity_ah = 0.0 self.dev.channels['A'].mode = pysmu.Mode.HI_Z
self.capacity_label.setText("0.000")
last_update = time.time()
while self.test_running and not self.request_stop:
if not self.current_data:
time.sleep(0.1)
continue
now = time.time()
delta_t = now - last_update
last_update = now
measured_current = abs(self.current_data[-1])
self.capacity_ah += measured_current * delta_t / 3600
self.capacity_label.setText(f"{self.capacity_ah:.4f}")
current_voltage = self.voltage_data[-1]
if current_voltage <= target_voltage or self.request_stop:
break
time.sleep(0.1) time.sleep(0.1)
# Configure for current sinking
self.dev.channels['A'].mode = pysmu.Mode.SIMV
time.sleep(0.05)
self.dev.channels['A'].constant(-current)
time.sleep(0.1)
# Current verification
samples = self.dev.read(5)
measured_current = -np.mean([s[0][1] for s in samples])
if abs(measured_current - current) > 0.02:
self.error_signal.emit(f"Entladestrom Abweichung: {measured_current:.3f}A vs {current:.3f}A")
self.capacity_ah = 0.0
self.capacity_label.setText("0.000")
last_update = time.time()
while self.test_running and not self.request_stop:
if not self.current_data:
time.sleep(0.1)
continue
now = time.time()
delta_t = now - last_update
last_update = now
measured_current = abs(self.current_data[-1])
self.capacity_ah += measured_current * delta_t / 3600
self.capacity_label.setText(f"{self.capacity_ah:.4f}")
current_voltage = self.voltage_data[-1]
if current_voltage <= target_voltage or self.request_stop:
break
time.sleep(0.1)
except Exception as e:
self.error_signal.emit(f"Discharge error: {str(e)}")
finally:
# Sicherstellen, dass der Kanal zurückgesetzt wird
try:
self.dev.channels['A'].mode = pysmu.Mode.HI_Z
self.dev.channels['A'].constant(0)
except Exception as e:
print(f"Error resetting channel: {e}")
def execute_rest_phase(self, phase_name): def execute_rest_phase(self, phase_name):
"""Führt eine Ruhephase durch""" """Führt eine Ruhephase durch"""
self.test_phase = f"Ruhen ({phase_name})" self.test_phase = f"Ruhen ({phase_name})"
@ -742,10 +789,9 @@ class BatteryTester(QMainWindow):
self.stop_button.setEnabled(False) self.stop_button.setEnabled(False)
self.start_button.setEnabled(True) self.start_button.setEnabled(True)
# Testdaten finalisieren self.finalize_test(show_message=False)
QTimer.singleShot(100, self.finalize_test)
def finalize_test(self): def finalize_test(self, show_message=True):
"""Finale Bereinigung nach Testende mit verbessertem Fenster-Handling""" """Finale Bereinigung nach Testende mit verbessertem Fenster-Handling"""
try: try:
# 1. Protokolldaten schreiben (mit zusätzlichem Lock) # 1. Protokolldaten schreiben (mit zusätzlichem Lock)
@ -767,30 +813,14 @@ class BatteryTester(QMainWindow):
print(f"Fehler beim Schließen der Protokolldatei: {e}") print(f"Fehler beim Schließen der Protokolldatei: {e}")
# 3. Benachrichtigung anzeigen (mit Fokus-Sicherung) # 3. Benachrichtigung anzeigen (mit Fokus-Sicherung)
msg_box = QMessageBox(self) # Expliziter Parent if show_message: # Only show if explicitly requested
msg_box.setWindowFlags(msg_box.windowFlags() | msg_box = QMessageBox(self)
Qt.WindowStaysOnTopHint | # Immer im Vordergrund msg_box.setWindowFlags(msg_box.windowFlags() |
Qt.MSWindowsFixedSizeDialogHint) # Besseres Verhalten unter Windows Qt.WindowStaysOnTopHint)
msg_box.setIcon(QMessageBox.Information)
msg_box.setIcon(QMessageBox.Information) msg_box.setWindowTitle("Test abgeschlossen")
msg_box.setWindowTitle("Test abgeschlossen") msg_box.setText(f"Test beendet\nZyklen: {self.cycle_count}")
msg_box.setText( msg_box.exec_()
f"Test wurde sicher beendet.\n\n"
f"Entladekapazität: {self.capacity_ah:.3f}Ah\n"
f"Abgeschlossene Zyklen: {self.cycle_count}"
)
# Sicherstellen, dass das Fenster sichtbar wird
msg_box.raise_()
msg_box.activateWindow()
# Non-blocking anzeigen und Fokus erzwingen
QTimer.singleShot(100, lambda: (
msg_box.show(),
msg_box.raise_(),
msg_box.activateWindow()
))
msg_box.exec_()
except Exception as e: except Exception as e:
print(f"Kritischer Fehler in finalize_test: {e}") print(f"Kritischer Fehler in finalize_test: {e}")