Karlsolar (en)

Summary

Originally planned in mid-2022 as a DIY open source BMS for small PV stand-alone systems in rental apartments based on a 48V platform.
The hardware has been put into operation, minor errors have been eliminated (and the data uploaded here has been corrected) and very basic EMC has been checked (using household means) .
Karlsolar consists of several individual projects:

License

CERN-OHL-S 2.0

Overview

The following diagram shows the overall structure as it was/is planned for Karlsolar:

Software

There is currently no software available for the BMM that offers functions beyond hardware testing. However, the BMM can already control all parts of the BMFE, read all data and check it for validity using Micropython. What is missing here is a better architecture, speed optimisations, charge status estimation and logging.

Battery module front-end (BMFE)

Electronics for acquiring all data from a 16-cell LiFePO4 battery module (<60V). For the first attempt, a continuous discharge current of 50A (75Apk/10s within 60s) and a continuous charge current of 25A (40Apk/10s within 60s) were assumed for 16x EVE LF105. This turned out to be very conservative – reducing the shunt resistance and assembling all MOSFETs will easily enable higher performance. Cooling (passive heat sink or active cooling) should again allow for a significant increase in performance.

  • The BMFE is designed in such a way that no software runs on the battery module. This prevents security-related errors from sneaking into multiple points in the software development process.
  • Hardware diagnostics are available for important circuit components (partly in discrete hardware, partly contained in the analogue front end (AFE, ADBMS1818ASWZ)).
  • Communication is via isoSPI at 1MBaud or, for tunneled I2C communication, 800kBaud.
  • Two measuring ranges, each with 16 bits, are available for current measurement (via TSC214 and TSZ124IYPT). With the currently planned shunt (300µΩ), the scaling corresponds to -100..+66.7A (IHigh) and -10..+6.67A (ILow). Negative values are intended as discharging, positive values as charging, so that a simple sum over time would (theoretically) result in the SOC.
  • External short circuits (min. 200nH, max. 5kA) are interrupted without software intervention by using an analogue comparator (NCV2252SQ2T2G). Its triggering is stored in a flip-flop (made of 74AHC00PW). The MOSFETs (8-12x IPT012N08N5) are avalanche-rated, so no additional free-wheeling diodes are required for switch-off.
  • The gate driver (UCC5304DWV) is supplied with 10V via a fly-buck (MAX17552AUB) and is also controlled. This prevents forced charging of the battery module by significantly higher external voltage. An isolated power-good signal is also available (TLV431AQFTA via ACPL-217-56CE).
    For the AFE, 5V VReg is generated by means of a linear regulator (TPS7A2450DBVR).
  • Each cell has its own temperature sensor (connected via the CVTT-M4 board). Furthermore, the shunt and all screw terminals (PCB-5, M5) feature temperature measurements (to monitor for deteriorating connections).
  • The balancing current is approx. 200mA/3.6V.
  • The external DC link is pre-charged via a switched constant current source (>350mA, short-circuit proof), which is able to pre-charge DC links up to several millifarads quickly and without any problems (<900mV difference).
  • Any cooling that may be necessary can be provided galvanically isolated over the entire surface via the underside of the single-sided PCB. If active cooling is necessary, a fan output is available for this purpose (12V, 400mA, LM5169).
  • To increase the number of GPIOs of the AFE to the required number, an I2C IO-expander (TCA9539PWR) and four 8-to-1 analog muxes (SN74LV4051APWR) are used.
  • An I2C EEPROM (M24C08-DRDW) is provided to store, for example, the model, serial number (in a lockable memory page) and calibration data, as well as energy consumption over the lifetime, short-circuit shutdowns in the past and similar information.
  • A switched auxiliary output for external access to the battery voltage, bypassing the main MOSFETs, is available (max. 420mA). This could be used, for example, to supply the BMM in the case of non-conductive MOSFETs. This output can be activated manually once in hardware and then self-latch via a GPIO.

Pictures

TODO: Pictures on heatsink

Downloads

Version: 0.1.2 (2025-07-24)
Schematic
Simulations (LTSpice, Python)
Initial operation documentation (0.1.0)
KiCad project
Production data

Cell voltage/temperature tap (CVTT-M4)

This aluminium PCB is meant to be mounted between the screw and the busbar to allow both voltage tapping and temperature measurement for each cell. It’s possible to replace R1 with, for example, 1Ω to enable a simple fuse function – however, this resistor is already included on the BMFE. It’s used there to enable diagnosis of the balancing current.

Pictures

Downloads

Version: 0.1.2 (2025-07-29)
Schematic
KiCad project
Production data

Battery module manager (BMM)

In order to require only a single piece of software in a system (consisting of several battery modules), the BMM implements both the ‘master’ and ‘slave’ logic. Two isoSPI transceivers (LTC6820IMS; forward/reverse) are available for communication with the AFEs on the BMFEs. Additional communication interfaces include the Bluetooth and WiFi of a Raspberry Pi Pico 2 W, a galvanically isolated RS-485 interface (ISOW1412BDFMR), 4x galvanically isolated UARTs (ISO6721QDWVRQ1; must be generated via PIO) and 4x optically isolated digital inputs and outputs each (ACPL-217-56CE). The UARTs are intended to communicate with ve.direct devices such as a PV charge controller or inverters.
There are two EEPROMs on the board: 8kbit as configuration memory (M24C08-DRDW), 1Mbit as data memory (CAV24M01YE-GT3). The configuration can only be changed if the write control signal is set to ‘low’ using a small slide switch. If the software is created in such a way that a configuration can only be loaded if it is read from the EEPROM (or consists of default values), this protects against unauthorised remote changes, acting as a kind of hardware authentication.
A button allows the application software, if available, to switch the device on or off, as well as to acknowledge an error. This should always be possible without an app. Furthermore, a piezo buzzer (PKLCS1212E20A0-R1) is located on the board to alert the user.

Software

The software for the initial operation is written in Micropython, using asyncio. The latter is particularly helpful for tidying up communication with I2C components, tunnelled through the isoSPI protocol. In short: The BMM sends a BMM request to the instantiated battery modules (e.g. init). The battery modules generate internal isoSPI transactions from this, which cannot be interrupted by other participants and are executed by the isoSPI controller. This architecture ensures that different battery modules, which do not (need to) know anything about each other, can operate as independently as possible. Of course, it is helpful if the modules are identical. In this way, the modules that do not ‘lead’ the current isoSPI transaction, but merely follow it and provide data for the read/write operations, can also make equally good use of the bus time. If the battery module leading an isoSPI transaction wants to end it and another module wants to extend it, for example I2C bus interactions, the latter takes over the lead until the end of the isoSPI transaction. If there are several simultaneous requests for isoSPI transactions to the isoSPI bus controller, the next leading module is selected using a round-robin procedure.
While all BMFE hardware can be addressed, all data can be measured and compared for meaningfulness, all discrete diagnostics work, and the DC link pre-charging and switching of the main MOSFETs works… there is currently no actual application firmware. It should at least be able to output data externally, e.g. via MQTT, collect energy consumption data and write log data.
The overhead generated by the flexibility of isoSPI transactions (many context switches) is not insignificant and, in the current Micropython implementation, considerably impairs performance. A Raspberry Pi Pico 2 is already well utilised with a single battery module, although not overloaded. It would therefore be worth considering porting the process to C with a correspondingly lighter RTOS.

Pictures

Downloads

Version: 0.1.1 (2025-07-31)
Schematic
Initial operation documentation (0.1.0)
KiCad project
Production data
Software (Micropython, 2025-07-23)
isoSPI flow of communication (2024-07-24)

Power supply 48/5V 3A galv. isol. (PS-48-i5/3)

A compact, galvanically isolated flyback converter for 30..60V input to 5V/3A output built around the LT8304 and a 6:1 Würth transformer (750315125). The controller regulates the output voltage on the primary side by measuring the reflected voltage. For this reason, a minimum load is required, which is ensured by default via the power LED.

The intention is to be able to supply the BMM from a battery module auxiliary output with good efficiency, i.e. without going through the mains. In addition, this power supply can be used as a universal 15W USB charger for low voltage (or 10W/2A at 20V input voltage).

  • The measured output voltage is in the range of 5.22V (100mA) down to 4.93V (3A) at 30V input voltage. At higher voltages, the output regulation tends to be better. Efficiency data can be found in the initial operation documentation.
  • Outputs: Terminal, USB-A (up to 2A; USB Dedicated Charging Port (DCP) controller: TPS2514DBVR) and USB-C (RP: 10kΩ for up to 3A).
  • The no-load current consumption is around 2.7mA at 48V (130mW). This includes the output-side power LED, which, with its 15mA, also serves as the base load (80 mW/5.2 V). If jumper JP2 is disconnected, efficiency can be significantly improved at light loads – provided that a connected load on the output ensures the base load. (Caution: if this load is missing, the output voltage will rise until the output electrolytic capacitors fail).

Pictures

Downloads

Version: 0.1.1 (2025-07-29)
Schematic
Simulations (LTSpice)
Initial operation documentation (0.1.0)
KiCad project
Production data

Capacitor bank 25x18mm, 60V (CPBNK-25×18-60)

Radial electrolytic capacitors with a diameter of up to 18mm can be quickly assembled into a capacitor bank without much tinkering. Examples include 25x Chemi-Con EKY-B630ELL102ML25S for 25mF or 25x Nichicon UPW1J222MHD for 55mF.
The capacitor bank is continuously discharged via a 15mA constant current source with LED. Starting at 60V, this takes 2:50 (25mF) to 6:15 (55mF). Below the forward voltage of the LED, the last energy is converted into heat via resistors.

Pictures

Downloads

Version: 0.1.1 (2025-07-29)
Schematic
Simulations (LTSpice)
KiCad project
Production data

Cell voltage temperature current simulator
(CVTCS-C und CVTCS-P)

Consisting of two projects: the control unit (CVTCS-C) and the power unit (CVTCS-P). In combination, all necessary voltages, e.g. current and temperature measurements represented by voltages, can be generated to put the BMFE and BMM into operation. While cell voltages and temperatures are tapped directly from the power section using a plug, connecting the control section to the BMFE is somewhat more complex: for example, there is – of course – no connector for the voltage drop across the shunt resistor (for the current measurement), so the measurement taps on a BMFE would have to be interrupted here.

The control section controls (using Raspberry Pi Pico) the desired values (voltage, current and temperature) via 16-bit DACs (DAC60508MRTE) and evaluates measured values from the power section (current, voltage, temperature) via an external ADC with internal reference (ADS1118IRUG) and 4x SPDT-MUX (TMUX1574PWR). The controlling part is completely galvanically isolated from the power part via a flyback converter (LT8403) and digital isolators (ISO6761DWR, ISO6731FDWR), but it is supplied from the power part. An EEPROM (M24C08-DRDW) is available to store configuration data. Two optically isolated inputs and outputs are available as expansion options for digital signals. To better dissipate the waste heat generated, a fan can be controlled in two speeds via a step-down converter (LM5169PDDAR).

The power section (CVTCS-P) is mounted on a heat sink (125379 from Wakefield-Vette, shortened to 200mm) and supports the control section. It contains the shunt regulators (NCV333AS with Darlington transistor output) for the stacked cell voltages and the temperature outputs (NCV333AS with compensation). The cell voltages (1.8..4.6V) are controlled at their respective potentials by means of current sinks, originating from the Bat–potential.
Important: The power section must always be supplied by a current-limited power supply <1A/<80V. If, for example, you want to balance the cells with a maximum of 200mA, 300mA would be a suitable cross-current. Over-temperature protection can be implemented in the software on the control section – three temperature sensors are available. Without the ability to control the actual power supply unit, the safest option would be to reduce the cell voltage to the absolute minimum.

Software

The software for the control section consists of a set of Micropython classes that are capable of controlling all existing components correctly (to my knowledge) and comprehensively.
Unfortunately, there is currently no real API or interactive mode for adjusting settings at runtime. Many things could be achieved relatively easily using asyncio (e.g. background temperature monitoring, fan control, etc.).

Pictures

The significant differences between the rendering and photos of the control unit are due to the fact that version 0.2.x has been (…had to be) significantly modified.

Downloads (control unit)

Version: 0.2.1 (2025-07-30)
Schematic
Simulations (LTSpice, Python; incl. power unit)
Initial operation documentation (0.1.1; incl. power unit)
KiCad project
Production data
Software (Micropython, 2025-01-18)

Downloads (power unit)

Version: 0.2.1 (2025-07-29)
Schematic
KiCad project
Production data