add 2 graphs if data is available

update calculations and values
update diameter from float (mm) to int (um)
This commit is contained in:
Jonathan Roth 2025-04-27 10:50:07 +02:00
parent 625ea6c511
commit 226f4469f8
2 changed files with 117 additions and 54 deletions

View File

@ -155,21 +155,6 @@ class BlockStackApp(QWidget):
if confirmation == QMessageBox.Yes: if confirmation == QMessageBox.Yes:
self.close() self.close()
def change_button_color(self, block_id, button_name, color): def change_button_color(self, block_id, button_name, color):
block = self.blocks.get(block_id) block = self.blocks.get(block_id)
if block: if block:
@ -200,17 +185,17 @@ class BlockStackApp(QWidget):
# Handle the data received from the serial port # Handle the data received from the serial port
print(f"Data received: {data}") print(f"Data received: {data}")
def update_block(self, is_running, diameter_value, position_value): def update_block(self, is_running, dial_number, diameter_value, position_value):
ts = round(time.time() * 1000) ts = round(time.time() * 1000)
# Update the block with diameter_value and position_value # Update the block with diameter_value and position_value
worker = self.sender() worker = self.sender()
diameter_avg = 0.0000 diameter_avg = 0.0000
est_wgh = 0 est_wgh = 0
worker.block.dia_label.setText(f"{diameter_value:.3f} ") if dial_number == 0:
worker.block.len_label.setText(f"{position_value/1000:.3f}") worker.block.len_label.setText(f"{position_value/1000:.3f}")
if is_running: if True:
if worker.reset_data: if worker.reset_data:
worker.diameter_total = diameter_value worker.diameter_total = diameter_value
worker.diameter_count = 1 worker.diameter_count = 1
@ -220,26 +205,22 @@ class BlockStackApp(QWidget):
worker.data_list.clear() worker.data_list.clear()
worker.reset_data = False worker.reset_data = False
else: else:
worker.diameter_total += diameter_value # to calc average diameter if is_running:
worker.diameter_count += 1 worker.diameter_total += diameter_value # to calc average diameter
worker.diameter_count += 1
if diameter_value < worker.diameter_min: # process min/max worker.block.min_label.setText(f"{worker.diameter_min:.3f} ")
worker.diameter_min = diameter_value worker.block.max_label.setText(f"{worker.diameter_max:.3f} ")
if diameter_value > worker.diameter_max:
worker.diameter_max = diameter_value
worker.block.min_label.setText(f"{worker.diameter_min:.3f} ")
worker.block.max_label.setText(f"{worker.diameter_max:.3f} ")
# push data to memory for report # push data to memory for report
worker.data_list.append((ts, position_value, diameter_value)) worker.data_list.append((ts, dial_number, position_value, diameter_value))
# push data to graph and update it # push data to graph and update it
self.update_graph(worker, diameter_value) self.update_graph(worker, dial_number, diameter_value)
# calculate and display average diameter # calculate and display average diameter
diameter_avg = worker.diameter_total / worker.diameter_count if worker.diameter_count > 0 else 0.0 if is_running:
worker.block.avg_label.setText(f"{diameter_avg:.4f}") diameter_avg = worker.diameter_total / worker.diameter_count if worker.diameter_count > 0 else 0.0
worker.block.avg_label.setText(f"{diameter_avg:.4f}")
# calculate and display estimated weight # calculate and display estimated weight
vol = math.pi * (diameter_avg / 2) ** 2 * position_value # all in mm → mm³ vol = math.pi * (diameter_avg / 2) ** 2 * position_value # all in mm → mm³
@ -247,23 +228,87 @@ class BlockStackApp(QWidget):
worker.block.wht_label.setText(f"{est_wgh/1000:.3f} ") worker.block.wht_label.setText(f"{est_wgh/1000:.3f} ")
def update_graph(self, worker, diameter_value): def update_graph(self, worker, dial_number,diameter_value):
# Update the graph with the new diameter value # def update_graph(self, worker, dial_number, diameter_value, diameter_value2, diameter_value3):
x_data = worker.line.get_xdata()
y_data = worker.line.get_ydata()
x_data = list(x_data)
y_data = list(y_data)
# Append new data point # diameter_value2 = diameter_value + random.randrange(-300, 300, 10)/1000
x_data.append(len(x_data)) # diameter_value3 = diameter_value + random.randrange(-300, 300, 10)/1000
y_data.append(diameter_value)
# Update the graph with the new diameter values
x_data1 = worker.line1.get_xdata()
y_data1 = worker.line1.get_ydata()
x_data2 = worker.line2.get_xdata()
y_data2 = worker.line2.get_ydata()
x_data3 = worker.line3.get_xdata()
y_data3 = worker.line3.get_ydata()
# Update the line with the new data x_data1 = list(x_data1)
worker.line.set_data(x_data, y_data) y_data1 = list(y_data1)
x_data2 = list(x_data2)
y_data2 = list(y_data2)
x_data3 = list(x_data3)
y_data3 = list(y_data3)
# Append new data points
match dial_number:
case 0:
x_data1.append(len(x_data1))
y_data1.append(diameter_value)
worker.diameter_value1 = diameter_value
case 1:
x_data2.append(len(x_data2))
y_data2.append(diameter_value)
worker.diameter_value2 = diameter_value
case 2:
x_data3.append(len(x_data3))
y_data3.append(diameter_value)
worker.diameter_value3 = diameter_value
# Keep only the last 100 values
if not worker.is_running:
# Keep only the last 100 values
if len(y_data1) > 100:
y_data1 = y_data1[-100:]
y_data2 = y_data2[-100:]
y_data3 = y_data3[-100:]
# Update x-axis values to reflect the rolling window
x_data1 = list(range(len(y_data1)))
x_data2 = list(range(len(y_data2)))
x_data3 = list(range(len(y_data3)))
all_y_data = y_data1 + y_data2 + y_data3
worker.diameter_min = min(all_y_data)
worker.diameter_max = max(all_y_data)
worker.block.min_label.setText(f"{worker.diameter_min:.3f} ")
worker.block.max_label.setText(f"{worker.diameter_max:.3f} ")
diameter_avg = sum(all_y_data) / len(all_y_data) if all_y_data else 0
worker.block.avg_label.setText(f"{diameter_avg:.4f}")
diameter_calc = worker.diameter_value1
diameter_n = 1
# Update the lines with the new data
worker.line1.set_data(x_data1, y_data1)
if len(y_data2) > 0:
worker.line2.set_data(x_data2, y_data2)
diameter_calc += worker.diameter_value2
diameter_n += 1
if len(y_data3) > 0:
worker.line3.set_data(x_data3, y_data3)
diameter_calc += worker.diameter_value3
diameter_n += 1
worker.diameter_value = diameter_calc / diameter_n
worker.block.dia_label.setText(f"{worker.diameter_value:.3f} ")
# Rescale the graph # Rescale the graph
worker.line.axes.relim() worker.line1.axes.relim()
worker.line.axes.autoscale_view() worker.line1.axes.autoscale_view()
# Redraw the canvas # Redraw the canvas
worker.canvas.draw() worker.canvas.draw()

View File

@ -16,7 +16,7 @@ from datetime import datetime
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
class UpdateWorker(QThread): class UpdateWorker(QThread):
update_signal = pyqtSignal(bool, float, float, float, float) update_signal = pyqtSignal(bool, int, float, float)
data_received = pyqtSignal(str) data_received = pyqtSignal(str)
stop_signal = pyqtSignal() stop_signal = pyqtSignal()
mode_signal = pyqtSignal(int) mode_signal = pyqtSignal(int)
@ -39,6 +39,9 @@ class UpdateWorker(QThread):
self.diameter_total = 0.0 # for average calculation self.diameter_total = 0.0 # for average calculation
self.diameter_count = 0 self.diameter_count = 0
self.diameter_value = 0.0 self.diameter_value = 0.0
self.diameter_value1 = 0.0
self.diameter_value2 = 0.0
self.diameter_value3 = 0.0
self.diameter_min = 0.0 self.diameter_min = 0.0
self.diameter_max = 0.0 self.diameter_max = 0.0
self.density = 1.0 self.density = 1.0
@ -161,12 +164,21 @@ class UpdateWorker(QThread):
def parse_data(self, data): def parse_data(self, data):
match = re.match(r"^[#d]:(-?[\d\.]+),p:(-?[\d\.]+)$", data) match = re.match(r"^[#d](\d):(-?[\d]+),p:(-?[\d\.]+)$", data)
if match: if match:
self.diameter_value = float(match.group(1)) diameter_int = int(match.group(2))
self.position_value = float(match.group(2)) if diameter_int<65000:
self.update_signal.emit(self.is_running, self.diameter_value, self.position_value, self.diameter_min, self.diameter_max) dial_number = int(match.group(1))
self.reset_flag = True position_value = float(match.group(3))
diameter_value = float(diameter_int)/1000
if diameter_value < self.diameter_min: # process min/max
self.diameter_min = diameter_value
if diameter_value > self.diameter_max:
self.diameter_max = diameter_value
self.update_signal.emit(self.is_running, dial_number, diameter_value, position_value)
self.reset_flag = True
offset_match = re.match(r"^#h:(\d+)", data) offset_match = re.match(r"^#h:(\d+)", data)
if offset_match: if offset_match:
@ -272,7 +284,9 @@ class UpdateWorker(QThread):
def clear_graph(self): def clear_graph(self):
self.line.set_data([], []) self.line1.set_data([], [])
self.line2.set_data([], [])
self.line3.set_data([], [])
self.canvas.draw() self.canvas.draw()
def add_block(self, serial_number, bench_id, port, block_id, main_app): def add_block(self, serial_number, bench_id, port, block_id, main_app):
@ -505,7 +519,11 @@ class UpdateWorker(QThread):
ax.set_xticks([]) # Hide x-axis values ax.set_xticks([]) # Hide x-axis values
ax.set_frame_on(True) ax.set_frame_on(True)
# ax.set_ylabel('Diameter (mm)') # Show y-axis label # ax.set_ylabel('Diameter (mm)') # Show y-axis label
self.line, = ax.plot([], [], '#ff5000', linewidth=0.5)
self.line2, = ax.plot([], [], '#00ff50', linewidth=0.5)
self.line3, = ax.plot([], [], '#fffb00', linewidth=0.5)
self.line1, = ax.plot([], [], '#ff5000', linewidth=1.5)
self.canvas = FigureCanvas(fig) self.canvas = FigureCanvas(fig)
self.canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored) self.canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored)
center_layout.addWidget(self.canvas) center_layout.addWidget(self.canvas)