From 5bf6b286b6683603b62f6857f5bea85385cca7eb Mon Sep 17 00:00:00 2001 From: "Jasper v. Blanckenburg" Date: Sat, 28 Jan 2023 20:43:15 +0100 Subject: [PATCH] Read current & coulomb counter --- load_controller/bms.py | 44 +++++++++++++++++++++++++++++++-------- load_controller/gui.py | 2 ++ load_controller/logger.py | 2 ++ ui/main_window.qml | 40 +++++++++++++++++++++++++++-------- 4 files changed, 70 insertions(+), 18 deletions(-) diff --git a/load_controller/bms.py b/load_controller/bms.py index a5c5a60..b1a2bad 100644 --- a/load_controller/bms.py +++ b/load_controller/bms.py @@ -1,4 +1,6 @@ from abc import abstractmethod +import sys +import struct import time from dataclasses import dataclass from enum import Enum @@ -12,10 +14,12 @@ from pymodbus.client import ModbusSerialClient MODBUS_BAUDRATE = 115200 VOLTAGE_ADDRESS = 0x00 +CURRENT_ADDRESS = 2048 SLAVE_UNIT_ID = 0x02 NUM_CELLS = 3 VOLTAGE_QUANT = 1 / 10000.0 +CURRENT_QUANT = 1 / (500 * 72e-6) THRESH_UV = 2.5 THRESH_OV = 4.2 @@ -58,6 +62,8 @@ class BMSData: voltages: list[float] temperatures: list[float] error: BMSError + current: float + current_integrated: float class BMS(QObject): @@ -75,7 +81,13 @@ class BMS(QObject): self._load = load self._num_cells = num_cells self._num_sensors = num_sensors - self._data = BMSData([0.0] * num_cells, [0.0] * num_sensors, BMSError.NONE) + self._data = BMSData( + voltages=[0.0] * num_cells, + temperatures=[0.0] * num_sensors, + error=BMSError.NONE, + current=0, + current_integrated=0, + ) def _check_for_errors(self): error = BMSError.NONE @@ -126,19 +138,33 @@ class BMSEvalBoard(BMS): def do_work(self): while True: + self._check_for_errors() time.sleep(0.1) result = self._dev.read_holding_registers( VOLTAGE_ADDRESS, NUM_CELLS, SLAVE_UNIT_ID ) if result.isError(): - print(f"ERROR READING VOLTAGES: {result}") - else: - self._data.voltages = list( - map(lambda v: v * VOLTAGE_QUANT, result.registers) - ) - self._last_voltage_time = time.time() - self.dataUpdated.emit(self._data) - self._check_for_errors() + print(f"ERROR READING VOLTAGES: {result}", file=sys.stderr) + continue + self._data.voltages = list( + map(lambda v: v * VOLTAGE_QUANT, result.registers) + ) + self._last_voltage_time = time.time() + result = self._dev.read_holding_registers(CURRENT_ADDRESS, 6, SLAVE_UNIT_ID) + if result.isError(): + print(f"ERROR READING CURRENT: {result}", file=sys.stderr) + continue + assert len(result.registers) == 6 + self._data.current = ( + (result.registers[0] << 16) | result.registers[1] + ) * CURRENT_QUANT + self._data.current_integrated = ( + (result.registers[2] << 48) + | (result.registers[3] << 32) + | (result.registers[4] << 16) + | result.registers[5] + ) * CURRENT_QUANT + self.dataUpdated.emit(self._data) @Slot(list) def _updateTemperatures(self, temps: list[float]): diff --git a/load_controller/gui.py b/load_controller/gui.py index 7ef72e8..5537d73 100644 --- a/load_controller/gui.py +++ b/load_controller/gui.py @@ -89,3 +89,5 @@ class GUI(QObject): self._win.setProperty("temp_min", min(data.temperatures)) self._win.setProperty("temp_max", max(data.temperatures)) self._win.setProperty("bmsError", str(data.error)) + self._win.setProperty("currentActual", data.current) + self._win.setProperty("currentIntegrated", data.current_integrated) diff --git a/load_controller/logger.py b/load_controller/logger.py index 61a74c5..36c670f 100644 --- a/load_controller/logger.py +++ b/load_controller/logger.py @@ -51,6 +51,8 @@ class Logger(QObject): time.time() - self._start_time, self._data.error.value, self._current, + self._data.current, + self._data.current_integrated, *self._data.voltages, *self._data.temperatures, ] diff --git a/ui/main_window.qml b/ui/main_window.qml index 20c5ad3..ad68045 100644 --- a/ui/main_window.qml +++ b/ui/main_window.qml @@ -13,6 +13,8 @@ ApplicationWindow { property string profile: "None" property real profileTime: 0 property real current: 0 + property real currentActual: 0 + property real currentIntegrated: 0 property string time: "00:00 / 00:00" property real voltage_min: 0 property real voltage_max: 0 @@ -143,7 +145,7 @@ ApplicationWindow { } GridLayout { Text { - text: "Current [A]:" + text: "Current (target) [A]:" Layout.row: 0 Layout.column: 0 } @@ -153,38 +155,58 @@ ApplicationWindow { Layout.column: 1 } Text { - text: "Time [min]:" + text: "Current (actual) [A]:" Layout.row: 1 Layout.column: 0 } + Text { + text: currentActual.toFixed(1) + Layout.row: 1 + Layout.column: 1 + } + Text { + text: "Time [min]:" + Layout.row: 2 + Layout.column: 0 + } Text { text: time - Layout.row: 1 + Layout.row: 2 Layout.column: 1 } Text { text: "Voltage [V]:" - Layout.row: 2 + Layout.row: 3 Layout.column: 0 } Text { text: "[" + voltage_min.toFixed(2) + ", " + voltage_max.toFixed(2) + "]" - Layout.row: 2 + Layout.row: 3 Layout.column: 1 } Text { text: "Temperature [°C]:" - Layout.row: 3 + Layout.row: 4 Layout.column: 0 } Text { text: "[" + temp_min.toFixed(1) + ", " + temp_max.toFixed(1) + "]" - Layout.row: 3 + Layout.row: 4 + Layout.column: 1 + } + Text { + text: "Coulomb counter [Ah]:" + Layout.row: 5 + Layout.column: 0 + } + Text { + text: currentIntegrated.toFixed(1) + Layout.row: 5 Layout.column: 1 } Text { text: "BMS Error:" - Layout.row: 4 + Layout.row: 6 Layout.column: 0 visible: bmsErrorVisible color: "red" @@ -192,7 +214,7 @@ ApplicationWindow { } Text { text: bmsError - Layout.row: 4 + Layout.row: 6 Layout.column: 1 visible: bmsErrorVisible color: "red"