Read current & coulomb counter

This commit is contained in:
Jasper Blanckenburg 2023-01-28 20:43:15 +01:00
parent 23f96c214b
commit 5bf6b286b6
4 changed files with 70 additions and 18 deletions

View File

@ -1,4 +1,6 @@
from abc import abstractmethod from abc import abstractmethod
import sys
import struct
import time import time
from dataclasses import dataclass from dataclasses import dataclass
from enum import Enum from enum import Enum
@ -12,10 +14,12 @@ from pymodbus.client import ModbusSerialClient
MODBUS_BAUDRATE = 115200 MODBUS_BAUDRATE = 115200
VOLTAGE_ADDRESS = 0x00 VOLTAGE_ADDRESS = 0x00
CURRENT_ADDRESS = 2048
SLAVE_UNIT_ID = 0x02 SLAVE_UNIT_ID = 0x02
NUM_CELLS = 3 NUM_CELLS = 3
VOLTAGE_QUANT = 1 / 10000.0 VOLTAGE_QUANT = 1 / 10000.0
CURRENT_QUANT = 1 / (500 * 72e-6)
THRESH_UV = 2.5 THRESH_UV = 2.5
THRESH_OV = 4.2 THRESH_OV = 4.2
@ -58,6 +62,8 @@ class BMSData:
voltages: list[float] voltages: list[float]
temperatures: list[float] temperatures: list[float]
error: BMSError error: BMSError
current: float
current_integrated: float
class BMS(QObject): class BMS(QObject):
@ -75,7 +81,13 @@ class BMS(QObject):
self._load = load self._load = load
self._num_cells = num_cells self._num_cells = num_cells
self._num_sensors = num_sensors 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): def _check_for_errors(self):
error = BMSError.NONE error = BMSError.NONE
@ -126,19 +138,33 @@ class BMSEvalBoard(BMS):
def do_work(self): def do_work(self):
while True: while True:
self._check_for_errors()
time.sleep(0.1) time.sleep(0.1)
result = self._dev.read_holding_registers( result = self._dev.read_holding_registers(
VOLTAGE_ADDRESS, NUM_CELLS, SLAVE_UNIT_ID VOLTAGE_ADDRESS, NUM_CELLS, SLAVE_UNIT_ID
) )
if result.isError(): if result.isError():
print(f"ERROR READING VOLTAGES: {result}") print(f"ERROR READING VOLTAGES: {result}", file=sys.stderr)
else: continue
self._data.voltages = list( self._data.voltages = list(
map(lambda v: v * VOLTAGE_QUANT, result.registers) map(lambda v: v * VOLTAGE_QUANT, result.registers)
) )
self._last_voltage_time = time.time() self._last_voltage_time = time.time()
self.dataUpdated.emit(self._data) result = self._dev.read_holding_registers(CURRENT_ADDRESS, 6, SLAVE_UNIT_ID)
self._check_for_errors() 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) @Slot(list)
def _updateTemperatures(self, temps: list[float]): def _updateTemperatures(self, temps: list[float]):

View File

@ -89,3 +89,5 @@ class GUI(QObject):
self._win.setProperty("temp_min", min(data.temperatures)) self._win.setProperty("temp_min", min(data.temperatures))
self._win.setProperty("temp_max", max(data.temperatures)) self._win.setProperty("temp_max", max(data.temperatures))
self._win.setProperty("bmsError", str(data.error)) self._win.setProperty("bmsError", str(data.error))
self._win.setProperty("currentActual", data.current)
self._win.setProperty("currentIntegrated", data.current_integrated)

View File

@ -51,6 +51,8 @@ class Logger(QObject):
time.time() - self._start_time, time.time() - self._start_time,
self._data.error.value, self._data.error.value,
self._current, self._current,
self._data.current,
self._data.current_integrated,
*self._data.voltages, *self._data.voltages,
*self._data.temperatures, *self._data.temperatures,
] ]

View File

@ -13,6 +13,8 @@ ApplicationWindow {
property string profile: "None" property string profile: "None"
property real profileTime: 0 property real profileTime: 0
property real current: 0 property real current: 0
property real currentActual: 0
property real currentIntegrated: 0
property string time: "00:00 / 00:00" property string time: "00:00 / 00:00"
property real voltage_min: 0 property real voltage_min: 0
property real voltage_max: 0 property real voltage_max: 0
@ -143,7 +145,7 @@ ApplicationWindow {
} }
GridLayout { GridLayout {
Text { Text {
text: "Current [A]:" text: "Current (target) [A]:"
Layout.row: 0 Layout.row: 0
Layout.column: 0 Layout.column: 0
} }
@ -153,38 +155,58 @@ ApplicationWindow {
Layout.column: 1 Layout.column: 1
} }
Text { Text {
text: "Time [min]:" text: "Current (actual) [A]:"
Layout.row: 1 Layout.row: 1
Layout.column: 0 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 {
text: time text: time
Layout.row: 1 Layout.row: 2
Layout.column: 1 Layout.column: 1
} }
Text { Text {
text: "Voltage [V]:" text: "Voltage [V]:"
Layout.row: 2 Layout.row: 3
Layout.column: 0 Layout.column: 0
} }
Text { Text {
text: "[" + voltage_min.toFixed(2) + ", " + voltage_max.toFixed(2) + "]" text: "[" + voltage_min.toFixed(2) + ", " + voltage_max.toFixed(2) + "]"
Layout.row: 2 Layout.row: 3
Layout.column: 1 Layout.column: 1
} }
Text { Text {
text: "Temperature [°C]:" text: "Temperature [°C]:"
Layout.row: 3 Layout.row: 4
Layout.column: 0 Layout.column: 0
} }
Text { Text {
text: "[" + temp_min.toFixed(1) + ", " + temp_max.toFixed(1) + "]" 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 Layout.column: 1
} }
Text { Text {
text: "BMS Error:" text: "BMS Error:"
Layout.row: 4 Layout.row: 6
Layout.column: 0 Layout.column: 0
visible: bmsErrorVisible visible: bmsErrorVisible
color: "red" color: "red"
@ -192,7 +214,7 @@ ApplicationWindow {
} }
Text { Text {
text: bmsError text: bmsError
Layout.row: 4 Layout.row: 6
Layout.column: 1 Layout.column: 1
visible: bmsErrorVisible visible: bmsErrorVisible
color: "red" color: "red"