diff --git a/MainCode/adalm1000_logger.py b/MainCode/adalm1000_logger.py index da2aab1..dc9a031 100644 --- a/MainCode/adalm1000_logger.py +++ b/MainCode/adalm1000_logger.py @@ -95,49 +95,6 @@ class MeasurementThread(QThread): self._running = False self.wait(500) - -class TestSequenceWorker(QObject): - # ... keep all existing methods except the run() method ... - - def run(self): - """Main test sequence loop""" - try: - while self._running and (self.continuous_mode or self.parent.cycle_count == 0): - # Reset stop request at start of each cycle - self.parent.request_stop = False - self.parent.cycle_count += 1 - - # 1. Charge phase (constant current) - self.charge_phase() - if not self._running or self.parent.request_stop: - break - - # 2. Rest period after charge - self.rest_phase("Post-Charge") - if not self._running or self.parent.request_stop: - break - - # 3. Discharge phase (capacity measurement) - self.discharge_phase() - if not self._running or self.parent.request_stop: - break - - # 4. Rest period after discharge (only if not stopping) - if self._running and not self.parent.request_stop: - self.rest_phase("Post-Discharge") - - # Calculate Coulomb efficiency if not stopping - if not self.parent.request_stop and self.parent.charge_capacity > 0: - self.parent.coulomb_efficiency = (self.parent.capacity_ah / self.parent.charge_capacity) * 100 - - # Test completed - self.test_completed.emit() - - except Exception as e: - self.error_occurred.emit(f"Test sequence error: {str(e)}") - finally: - self.finished.emit() - class TestSequenceWorker(QObject): finished = pyqtSignal() update_phase = pyqtSignal(str) @@ -672,24 +629,28 @@ class BatteryTester(QMainWindow): @pyqtSlot(float, float, float) def update_measurements(self, voltage, current, current_time): - """Update measurements from the measurement thread""" - self.time_data.append(current_time) - self.voltage_data.append(voltage) - self.current_data.append(current) - - # Update display - self.voltage_label.setText(f"{voltage:.4f}") - self.current_label.setText(f"{current:.4f}") - self.time_label.setText(self.format_time(current_time)) - - # Throttle plot updates to avoid recursive repaint - now = time.time() - if not hasattr(self, '_last_plot_update'): - self._last_plot_update = 0 - - if now - self._last_plot_update > 0.1: # Update plot max 10 times per second - self._last_plot_update = now - QTimer.singleShot(0, self.update_plot) + try: + with self.plot_mutex: + self.time_data.append(current_time) + self.voltage_data.append(voltage) + self.current_data.append(current) + + # Update display labels (always) + self.voltage_label.setText(f"{voltage:.4f}") + self.current_label.setText(f"{current:.4f}") + self.time_label.setText(self.format_time(current_time)) + + # Throttle plot updates to 10Hz max + now = time.time() + if not hasattr(self, '_last_plot_update'): + self._last_plot_update = 0 + + if now - self._last_plot_update >= 0.1: # 100ms minimum between updates + self._last_plot_update = now + QTimer.singleShot(0, self.update_plot) + + except Exception as e: + print(f"Error in update_measurements: {e}") def update_status(self): """Update status information periodically""" @@ -743,11 +704,13 @@ class BatteryTester(QMainWindow): if test_current > 0.2: raise ValueError("Current must be ≤200mA (0.2A) for ADALM1000") - # Clear previous data + # Clear ALL previous data completely self.time_data.clear() self.voltage_data.clear() self.current_data.clear() self.phase_data.clear() + + # Reset capacities and timing self.start_time = time.time() self.last_update_time = self.start_time self.capacity_ah = 0.0 @@ -755,17 +718,22 @@ class BatteryTester(QMainWindow): self.coulomb_efficiency = 0.0 self.cycle_count = 0 + # Reset measurement thread's timer and queues if hasattr(self, 'measurement_thread'): self.measurement_thread.start_time = time.time() + self.measurement_thread.voltage_window.clear() + self.measurement_thread.current_window.clear() + with self.measurement_thread.measurement_queue.mutex: + self.measurement_thread.measurement_queue.queue.clear() - # Reset plot with proper ranges - self.reset_plot() - # Generate filename and create log file timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") self.base_filename = os.path.join(self.log_dir, f"battery_test_{timestamp}") self.create_cycle_log_file() + # Reset plot completely + self.reset_plot() + # Start test self.test_running = True self.start_time = time.time() @@ -914,12 +882,12 @@ class BatteryTester(QMainWindow): self.charge_capacity = 0.0 self.coulomb_efficiency = 0.0 + QApplication.processEvents() + time.sleep(0.1) + # Reset plot self.reset_plot() - # Reset elapsed time label - self.time_label.setText("00:00:00") - # Update UI self.status_bar.showMessage("Test stopped - Ready for new test") self.stop_button.setEnabled(False) @@ -1052,28 +1020,37 @@ class BatteryTester(QMainWindow): self.status_bar.showMessage("Error during test finalization") def reset_plot(self): - """Reset the plot completely for a new test""" + """Completely reset the plot - clears all data and visuals""" + # 1. Clear line data self.line_voltage.set_data([], []) self.line_current.set_data([], []) + # 2. Clear data buffers self.time_data.clear() self.voltage_data.clear() self.current_data.clear() + self.phase_data.clear() + # 3. Reset axes with appropriate ranges voltage_padding = 0.2 min_voltage = max(0, self.discharge_cutoff - voltage_padding) max_voltage = self.charge_cutoff + voltage_padding - # Reset X and Y axes - self.ax.set_xlim(0, 10) # Start at 0 with 10s initial window + self.ax.set_xlim(0, 10) # Reset X axis self.ax.set_ylim(min_voltage, max_voltage) - self.ax2.set_xlim(0, 10) # Sync twin axis + # Reset twin axis (current) current_padding = 0.05 test_current = self.c_rate * self.capacity max_current = test_current * 1.5 + self.ax2.set_xlim(0, 10) self.ax2.set_ylim(-max_current - current_padding, max_current + current_padding) + # 4. Clear any matplotlib internal caches + self.fig.canvas.draw_idle() + self.fig.canvas.flush_events() + + # 5. Force immediate redraw self.canvas.draw() def write_cycle_summary(self): @@ -1128,10 +1105,13 @@ class BatteryTester(QMainWindow): self.canvas.draw_idle() except Exception as e: - print(f"Plot error: {e}") + print(f"Plot update error: {e}") + import traceback + traceback.print_exc() # Reset plot on error - self.line_voltage.set_data([], []) - self.line_current.set_data([], []) + with self.plot_mutex: + self.line_voltage.set_data([], []) + self.line_current.set_data([], []) self.canvas.draw_idle() def auto_scale_axes(self):