From 1020d8731e99aef07a3ed1ec7503381c62a1ab03 Mon Sep 17 00:00:00 2001 From: "Jasper v. Blanckenburg" Date: Mon, 16 Jan 2023 21:42:04 +0100 Subject: [PATCH] Talk to Nucleo running babystack-tempsensing --- load_controller/gui.py | 10 ++++++++-- load_controller/temperatures.py | 35 +++++++++++++++++++++++++++++++++ main.py | 13 +++++++++--- 3 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 load_controller/temperatures.py diff --git a/load_controller/gui.py b/load_controller/gui.py index 12443bf..965f7c5 100644 --- a/load_controller/gui.py +++ b/load_controller/gui.py @@ -1,7 +1,7 @@ import os.path import time -from PySide6.QtCore import QTimer, QObject +from PySide6.QtCore import QTimer, QObject, Signal from PySide6.QtWidgets import QFileDialog from PySide6.QtQml import QQmlApplicationEngine @@ -17,7 +17,7 @@ class GUI(QObject): _start_pause_btn: QObject _stop_btn: QObject - def __init__(self, profile_handler: ProfileHandler): + def __init__(self, profile_handler: ProfileHandler, temperaturesUpdated: Signal): super().__init__(None) self._engine = QQmlApplicationEngine() @@ -42,6 +42,8 @@ class GUI(QObject): self._update_timer.timeout.connect(self._update) self._update_timer.start(100) + temperaturesUpdated.connect(self._updateTemperatures) + def _choose_profile(self): dlg = QFileDialog() dlg.setFileMode(QFileDialog.FileMode.ExistingFile) @@ -79,3 +81,7 @@ class GUI(QObject): if self._profile_handler.state == ProfileState.RUNNING: dt = time.time() - self._profile_handler.profile_start self._win.setProperty("profileTime", dt) + + def _updateTemperatures(self, temperatures: list[int]): + self._win.setProperty("temp_min", min(temperatures)) + self._win.setProperty("temp_max", max(temperatures)) diff --git a/load_controller/temperatures.py b/load_controller/temperatures.py new file mode 100644 index 0000000..ac0a75b --- /dev/null +++ b/load_controller/temperatures.py @@ -0,0 +1,35 @@ +import sys +import serial +import struct + +from PySide6.QtCore import QObject, Signal + +START_OF_TEMPS = bytes((0xFF, 0xFF)) +N_SENSORS = 12 +TEMP_QUANT = 0.0625 # °C/quant + + +class Temperatures(QObject): + temperaturesUpdated = Signal(list) + + _temps: list[float] + + def __init__(self, uart_path: str): + super().__init__(parent=None) + self.dev = serial.Serial(uart_path, 115200) + self._temps = [0.0] * N_SENSORS + + def run(self): + while True: + self.dev.read_until(START_OF_TEMPS) + data = self.dev.read(N_SENSORS * 2) + temps = struct.unpack(f">{N_SENSORS}h", data) + for i, t in enumerate(temps): + if (t & 0x0F) != 0: + print( + f"WARN: temperature had a non-zero least-significant nibble: {t:04x}", + file=sys.stderr, + ) + else: + self._temps[i] = (t >> 4) * TEMP_QUANT + self.temperaturesUpdated.emit(self._temps) diff --git a/main.py b/main.py index a04faa0..d77da49 100755 --- a/main.py +++ b/main.py @@ -9,21 +9,28 @@ from PySide6.QtWidgets import QApplication from load_controller.gui import GUI from load_controller.load import Load from load_controller.profile_handler import ProfileHandler +from load_controller.temperatures import Temperatures def main(argv: list[str]) -> int: app = QApplication(sys.argv) profile_handler = ProfileHandler() - gui = GUI(profile_handler) load = Load(argv[1], profile_handler) + temps = Temperatures(argv[2]) + temp_thread = QThread() + temps.moveToThread(temp_thread) + temp_thread.started.connect(temps.run) + temp_thread.start() + + gui = GUI(profile_handler, temps.temperaturesUpdated) return app.exec() if __name__ == "__main__": - if len(sys.argv) != 3: - print(f"Usage: {sys.argv[0]} LOAD-PORT BMS-PORT", file=sys.stderr) + if len(sys.argv) != 4: + print(f"Usage: {sys.argv[0]} LOAD-PORT TEMP-PORT BMS-PORT", file=sys.stderr) sys.exit(os.EX_USAGE) sys.exit(main(sys.argv))