Talk to EET BMS eval board

This commit is contained in:
Jasper Blanckenburg 2023-01-24 21:49:21 +01:00
parent 1020d8731e
commit 7bcafa2c4d
4 changed files with 79 additions and 6 deletions

62
load_controller/bms.py Normal file

@ -0,0 +1,62 @@
from abc import abstractmethod
import time
from dataclasses import dataclass
from .temperatures import N_SENSORS
from PySide6.QtCore import QObject, Signal, Slot, Qt
from pymodbus.client import ModbusSerialClient
MODBUS_BAUDRATE = 115200
VOLTAGE_ADDRESS = 0x00
SLAVE_UNIT_ID = 0x02
NUM_CELLS = 3
VOLTAGE_QUANT = 1 / 10000.0
@dataclass
class BMSData:
voltages: list[float]
temperatures: list[float]
class BMS(QObject):
dataUpdated = Signal(BMSData)
@abstractmethod
def do_work(self):
pass
class BMSEvalBoard(BMS):
_dev: ModbusSerialClient
_data: BMSData
def __init__(self, uart_path: str, temperaturesUpdated: Signal):
super().__init__(None)
self._dev = ModbusSerialClient(
method="rtu", port=uart_path, baudrate=MODBUS_BAUDRATE
)
self._data = BMSData([0.0] * NUM_CELLS, [0.0] * N_SENSORS)
temperaturesUpdated.connect(
self._updateTemperatures, Qt.ConnectionType.DirectConnection
)
def do_work(self):
while True:
time.sleep(0.1)
result = self._dev.read_holding_registers(
VOLTAGE_ADDRESS, NUM_CELLS, SLAVE_UNIT_ID
)
self._data.voltages = list(
map(lambda v: v * VOLTAGE_QUANT, result.registers)
)
self.dataUpdated.emit(self._data)
@Slot(list)
def _updateTemperatures(self, temps: list[float]):
assert len(temps) == N_SENSORS
self._data.temperatures = temps
self.dataUpdated.emit(self._data)

@ -5,6 +5,7 @@ from PySide6.QtCore import QTimer, QObject, Signal
from PySide6.QtWidgets import QFileDialog
from PySide6.QtQml import QQmlApplicationEngine
from .bms import BMSData
from .profile_handler import ProfileHandler, ProfileState
@ -17,7 +18,7 @@ class GUI(QObject):
_start_pause_btn: QObject
_stop_btn: QObject
def __init__(self, profile_handler: ProfileHandler, temperaturesUpdated: Signal):
def __init__(self, profile_handler: ProfileHandler, bmsUpdated: Signal):
super().__init__(None)
self._engine = QQmlApplicationEngine()
@ -42,7 +43,7 @@ class GUI(QObject):
self._update_timer.timeout.connect(self._update)
self._update_timer.start(100)
temperaturesUpdated.connect(self._updateTemperatures)
bmsUpdated.connect(self._updateBMS)
def _choose_profile(self):
dlg = QFileDialog()
@ -82,6 +83,8 @@ class GUI(QObject):
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))
def _updateBMS(self, data: BMSData):
self._win.setProperty("voltage_min", min(data.voltages))
self._win.setProperty("voltage_max", max(data.voltages))
self._win.setProperty("temp_min", min(data.temperatures))
self._win.setProperty("temp_max", max(data.temperatures))

@ -1,6 +1,7 @@
import sys
import serial
import struct
import time
from PySide6.QtCore import QObject, Signal
@ -21,6 +22,7 @@ class Temperatures(QObject):
def run(self):
while True:
time.sleep(0.1)
self.dev.read_until(START_OF_TEMPS)
data = self.dev.read(N_SENSORS * 2)
temps = struct.unpack(f">{N_SENSORS}h", data)

@ -10,6 +10,7 @@ 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
from load_controller.bms import BMSEvalBoard
def main(argv: list[str]) -> int:
@ -22,8 +23,13 @@ def main(argv: list[str]) -> int:
temps.moveToThread(temp_thread)
temp_thread.started.connect(temps.run)
temp_thread.start()
bms = BMSEvalBoard(argv[3], temps.temperaturesUpdated)
bms_thread = QThread()
bms.moveToThread(bms_thread)
bms_thread.started.connect(bms.do_work)
bms_thread.start()
gui = GUI(profile_handler, temps.temperaturesUpdated)
gui = GUI(profile_handler, bms.dataUpdated)
return app.exec()