Compare commits

...

2 Commits

Author SHA1 Message Date
0f3f70c991 Properly parse current 2023-02-01 21:55:24 +01:00
5bf6b286b6 Read current & coulomb counter 2023-01-28 20:44:30 +01:00
4 changed files with 67 additions and 18 deletions

View File

@ -1,4 +1,6 @@
from abc import abstractmethod
import sys
import struct
import time
from dataclasses import dataclass
from enum import Enum
@ -9,13 +11,16 @@ from .temperatures import N_SENSORS
from PySide6.QtCore import QObject, Signal, Slot, Qt
from pymodbus.client import ModbusSerialClient
from pymodbus.payload import BinaryPayloadDecoder, Endian
MODBUS_BAUDRATE = 115200
VOLTAGE_ADDRESS = 0x00
CURRENT_ADDRESS = 2048
SLAVE_UNIT_ID = 0x02
NUM_CELLS = 3
VOLTAGE_QUANT = 1 / 10000.0
CURRENT_QUANT = 1 / (10000 * 500 * 72e-6)
THRESH_UV = 2.5
THRESH_OV = 4.2
@ -58,6 +63,8 @@ class BMSData:
voltages: list[float]
temperatures: list[float]
error: BMSError
current: float
current_integrated: float
class BMS(QObject):
@ -75,7 +82,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 +139,29 @@ 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
dec = BinaryPayloadDecoder.fromRegisters(result.registers, Endian.Big)
self._data.current = dec.decode_32bit_int() * CURRENT_QUANT
self._data.current_integrated = (
dec.decode_64bit_int() * CURRENT_QUANT * 0.05 / 3600
)
self.dataUpdated.emit(self._data)
@Slot(list)
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_max", max(data.temperatures))
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,
self._data.error.value,
self._current,
self._data.current,
self._data.current_integrated,
*self._data.voltages,
*self._data.temperatures,
]

View File

@ -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"