• Have you tried out dark mode?! Scroll to the bottom of any page to find a sun or moon icon to turn dark mode on or off!

diy solar

diy solar

YamBMS JK-BMS-CAN with new Cut-Off Charging Logic (open-source)

Anyone have any thoughts on why yambms might suddenly report an extremely low voltage when my inverter switches from grid to battery? It doesn't happen every time, but I just lost grid power and it happened this time and I've seen it happen a couple of times before. In HA it reported a single instance of 12.79V when the grid input was lost and then 4s later back to 53.06V. Of course when it reports 12.79V my inverter shuts down, but then comes back on a few moments later. Yambms is still reporting an uptime of 19d, so I don't think it's restarting.

I checked the JBD BMS with the Overkill Solar app and it doesn't report any undervoltage issues. I also checked the Victron Smartshunt I'm using and it stores the lowest voltage as 47.45V which is expected. The only thing I can think of is if some noise on the RS485 lines to the BMS or Smartshunt causes yambms to read the wrong value?

I don't know if it might have something to do with the lack of galvanic isolation on the LilyGo T-CAN485, but I have a T-Connect on the way that will solve that problem. Here's my diagram

EDIT: Dug through the data more and the BMS was reporting normally and it was the SmartShunt that HA recorded as having the low voltage. The inverter didn't seem to see the voltage drop either (it has a separate sensor that tracks its own voltage but only in 20s intervals), so I'm going to assume it was a communications issue.
 
Last edited:
Hi. Can`t get it to work. JK-b2a8s20p. No data from UART port (at the same time, the esphome-jk-bms@syssi project works fine). Maybe I missed something in the config?
Code:
# Updated : 2025.04.01
# Version : 1.5.5
# GitHub  : https://github.com/Sleeper85/esphome-yambms

# YamBMS ( Yet another multi-BMS Merging Solution )

# This YAML is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.

######################## YamBMS Remote Packages Version ########################

# You can compile this YAML directly without the `packages` folder.
# The packages will be automatically downloaded from GitHub.
# Don't forget to configure your WiFi credentials in the secrets.yaml

################################################################################

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

logger:
  level: DEBUG # VERBOSE / DEBUG / INFO / WARN

ota:
  platform: esphome
 
# Please use the native `api` component instead of the `mqtt` section.
# If you use Home Assistant, the native API is more lightweight.
# If there is no HA server connected to this API, the ESP32 reboots every 15 minutes to try to resolve the problem.
# The "reboot_timeout: 0s" option will keep your ESP32 up and running even if you lose connection to your HA server.
api:
  reboot_timeout: 0s

# If you don't want to use ESPHome's native API you can use MQTT instead.
# In this case don't forget to remove the 'api:' section.
# mqtt:
#   broker: !secret mqtt_host
#   username: !secret mqtt_username
#   password: !secret mqtt_password
#   id: mqtt_client

# Please note that enabling this component will take up a lot of memory and may decrease
# stability and be the cause of reboot depending on the capabilities of the board used.
# web_server:
#   port: 80
#   log: false
#   ota: false

# +--------------------------------------+
# | Global Settings                      |
# +--------------------------------------+
substitutions:
  # ESP32 name / hostname
  name: yambms
  # +--------------------------------------+
  # | YamBMS Settings                      |
  # +--------------------------------------+
  # Please read the cut-off charging logic README to understand how the YamBMS works
  yambms_id: 'Dacha'
  yambms_name: 'YamBMS'
  yambms_update_interval: '1s'
  # Input numbers can be displayed as a slider or an input box, options are 'slider' or 'box'.
  yambms_input_number_mode: 'box'
  # Please check and fill in the options below correctly according to your battery chemistry and number of cells in series.
  # These parameters are important and used for charging logic.
  # Battery Chemistry
  yambms_battery_chemistry: '1' # 1-LFP | 2-Li-ion | 3-LTO
  # Number of cells in series
  yambms_cell_count: '8'
  # Bulk / Absorption Voltage : corresponds to the Bulk voltage that will be used to charge the battery. (LFP : 27.6V = 3.45V/Cell for 8S battery)
  yambms_bulk_v: '27.6'
  # Float Voltage : corresponds to the voltage at which the battery would be maintained at the end of charge. (LFP : 26.8V = 3.35V/Cell for 8S battery)
  yambms_float_v: '26.8'
  # Rebulk voltage, voltage from which a new Bulk charge can start. (LFP : 26.4V = 3.3V/Cell for 8S battery)
  yambms_rebulk_v: '26.4'
  # Maximum time in minutes that the cut-off step can last before charging is complete
  # If your cells are properly balanced this step ends at the fastest after the `cut-off timer`
  # This timer can be deactivated with a switch
  yambms_eoc_timer: '30'
  # Time in seconds during which the end of charge conditions must be respected (cut-off + cells not equalizing)
  yambms_cutoff_timer: '60'
  # +--------------------------------------+
  # | Shunt Settings                      |
  # +--------------------------------------+
  shunt_update_interval: '3s'  # frequency at which Shunt data is refreshed
  shunt_combine_interval: '1s' # frequency at which Shunt data is combined in YamBMS
  # +--------------------------------------+
  # | BMS Settings                         |
  # +--------------------------------------+
  bms_update_interval: '3s'    # frequency at which BMS data is refreshed, going below '3s' can cause problems
  bms_combine_interval: '1s'   # frequency at which BMS data is combined in YamBMS
  bms_cutoff_timer: '50s'      # time during which the end of charge conditions must be respected (cut-off + cells not equalizing)

# +--------------------------------------+
# | Packages                             |
# +--------------------------------------+
packages:

  ############### >>> UNCOMMENT YOUR BOARD <<< ###############
  ############### >>>   ONLY ONE BOARD !   <<< ###############

  board:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      - path: 'packages/board/board_ESP32_DevKit-V1.yaml'

  ########### >>> UNCOMMENT YOUR BOARD OPTIONS <<< ###########

  board_options:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      # UART
      - path: 'packages/board/board_options_itf_uart_esp_1.yaml'
      # ESP32_CAN (SN65HVD230 unit)
      - path: 'packages/board/board_options_itf_canbus_esp32_can.yaml'
        vars:
          canbus_node_id: 'canbus_inverter_1'

  ############################################################

  # shunt:
  #   url: https://github.com/Sleeper85/esphome-yambms
  #   ref: main
  #   refresh: 0s
  #   files:
  #     # Shunt 1
  #     - path: 'packages/shunt/shunt_combine_Victron_SmartShunt_UART.yaml' # shunt_combine_Junctek_KHF_UART.yaml
  #       vars:
  #         shunt_id: '1' # must be a number
  #         shunt_name: 'Shunt 1'
  #         shunt_uart_id: 'uart_esp_3'

  bms:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      # BMS 1
      - path: 'packages/bms/bms_combine_JK_UART_4G-GPS_full.yaml'
        vars:
          bms_id: '1' # must be a number
          bms_name: 'JK-b2a8s20p'
          bms_uart_id: 'uart_esp_1'
          bms_address: '0x01'
          # Maximum cell charging cycles is used to calculate the battey SoH.
          # MB31=8000.0, LF280K v3=8000.0, LF280K v2=6000.0, LF280=3000.0 (decimal is required)
          bms_cell_max_cycles: '6000.0'

  # auto charge off triggers for individual BMS
  bms_options:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      # BMS 1
      - path: 'packages/bms/bms_options_charging_logic.yaml'
        vars:
          bms_id: '1' # must be a number

  yambms:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      - path: 'packages/yambms/yambms.yaml'

  canbus:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      - path: 'packages/yambms/yambms_canbus.yaml'
        vars:
          canbus_id: 'canbus1'
          canbus_name: 'CANBUS'
          canbus_node_id: 'canbus_inverter_1'
          canbus_light_id: 'esp_light'
          # The CANBUS link will be considered down if no response from the inverter (0x305 frame) for 5s
          # The Deye inverter sends the ACK 0x305 only when it receives the 0x356 frame.
          canbus_link_timer: '5s'

# +--------------------------------------+
# | DEBUG ( logger level must be DEBUG ) |
# +--------------------------------------+

  debug:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      - path: packages/base/device_debug_ESP32.yaml
        vars:
          debug_name: 'Debug'
          debug_update_interval: '5s'

# +--------------------------------------+
# | Custom config                        |
# +--------------------------------------+

switch:
  - platform: template
    name: "${name} ${yambms_name} Force Float"
    id: ${yambms_id}_switch_force_float
    restore_mode: RESTORE_DEFAULT_OFF
    optimistic: true
    entity_category: config

interval:
  # Force Float
  - interval: ${yambms_update_interval}
    then:
      - lambda: |-
          // Force Float => Float
          if (id(${yambms_id}_switch_force_float).state) id(${yambms_id}_charge_status) = "Float";

  # Setup min/max value
  - interval: 24h # 60s
    then:
      - lambda: |-
          // Float V.
          id(${yambms_id}_float_voltage).traits.set_min_value(${yambms_cell_count} * 3.125);
          id(${yambms_id}_float_voltage).traits.set_max_value(${yambms_cell_count} * 3.375);
- Thx in advance
 
Hi. Can`t get it to work. JK-b2a8s20p. No data from UART port (at the same time, the esphome-jk-bms@syssi project works fine). Maybe I missed something in the config?
Code:
# Updated : 2025.04.01
# Version : 1.5.5
# GitHub  : https://github.com/Sleeper85/esphome-yambms

# YamBMS ( Yet another multi-BMS Merging Solution )

# This YAML is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.

######################## YamBMS Remote Packages Version ########################

# You can compile this YAML directly without the `packages` folder.
# The packages will be automatically downloaded from GitHub.
# Don't forget to configure your WiFi credentials in the secrets.yaml

################################################################################

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

logger:
  level: DEBUG # VERBOSE / DEBUG / INFO / WARN

ota:
  platform: esphome
 
# Please use the native `api` component instead of the `mqtt` section.
# If you use Home Assistant, the native API is more lightweight.
# If there is no HA server connected to this API, the ESP32 reboots every 15 minutes to try to resolve the problem.
# The "reboot_timeout: 0s" option will keep your ESP32 up and running even if you lose connection to your HA server.
api:
  reboot_timeout: 0s

# If you don't want to use ESPHome's native API you can use MQTT instead.
# In this case don't forget to remove the 'api:' section.
# mqtt:
#   broker: !secret mqtt_host
#   username: !secret mqtt_username
#   password: !secret mqtt_password
#   id: mqtt_client

# Please note that enabling this component will take up a lot of memory and may decrease
# stability and be the cause of reboot depending on the capabilities of the board used.
# web_server:
#   port: 80
#   log: false
#   ota: false

# +--------------------------------------+
# | Global Settings                      |
# +--------------------------------------+
substitutions:
  # ESP32 name / hostname
  name: yambms
  # +--------------------------------------+
  # | YamBMS Settings                      |
  # +--------------------------------------+
  # Please read the cut-off charging logic README to understand how the YamBMS works
  yambms_id: 'Dacha'
  yambms_name: 'YamBMS'
  yambms_update_interval: '1s'
  # Input numbers can be displayed as a slider or an input box, options are 'slider' or 'box'.
  yambms_input_number_mode: 'box'
  # Please check and fill in the options below correctly according to your battery chemistry and number of cells in series.
  # These parameters are important and used for charging logic.
  # Battery Chemistry
  yambms_battery_chemistry: '1' # 1-LFP | 2-Li-ion | 3-LTO
  # Number of cells in series
  yambms_cell_count: '8'
  # Bulk / Absorption Voltage : corresponds to the Bulk voltage that will be used to charge the battery. (LFP : 27.6V = 3.45V/Cell for 8S battery)
  yambms_bulk_v: '27.6'
  # Float Voltage : corresponds to the voltage at which the battery would be maintained at the end of charge. (LFP : 26.8V = 3.35V/Cell for 8S battery)
  yambms_float_v: '26.8'
  # Rebulk voltage, voltage from which a new Bulk charge can start. (LFP : 26.4V = 3.3V/Cell for 8S battery)
  yambms_rebulk_v: '26.4'
  # Maximum time in minutes that the cut-off step can last before charging is complete
  # If your cells are properly balanced this step ends at the fastest after the `cut-off timer`
  # This timer can be deactivated with a switch
  yambms_eoc_timer: '30'
  # Time in seconds during which the end of charge conditions must be respected (cut-off + cells not equalizing)
  yambms_cutoff_timer: '60'
  # +--------------------------------------+
  # | Shunt Settings                      |
  # +--------------------------------------+
  shunt_update_interval: '3s'  # frequency at which Shunt data is refreshed
  shunt_combine_interval: '1s' # frequency at which Shunt data is combined in YamBMS
  # +--------------------------------------+
  # | BMS Settings                         |
  # +--------------------------------------+
  bms_update_interval: '3s'    # frequency at which BMS data is refreshed, going below '3s' can cause problems
  bms_combine_interval: '1s'   # frequency at which BMS data is combined in YamBMS
  bms_cutoff_timer: '50s'      # time during which the end of charge conditions must be respected (cut-off + cells not equalizing)

# +--------------------------------------+
# | Packages                             |
# +--------------------------------------+
packages:

  ############### >>> UNCOMMENT YOUR BOARD <<< ###############
  ############### >>>   ONLY ONE BOARD !   <<< ###############

  board:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      - path: 'packages/board/board_ESP32_DevKit-V1.yaml'

  ########### >>> UNCOMMENT YOUR BOARD OPTIONS <<< ###########

  board_options:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      # UART
      - path: 'packages/board/board_options_itf_uart_esp_1.yaml'
      # ESP32_CAN (SN65HVD230 unit)
      - path: 'packages/board/board_options_itf_canbus_esp32_can.yaml'
        vars:
          canbus_node_id: 'canbus_inverter_1'

  ############################################################

  # shunt:
  #   url: https://github.com/Sleeper85/esphome-yambms
  #   ref: main
  #   refresh: 0s
  #   files:
  #     # Shunt 1
  #     - path: 'packages/shunt/shunt_combine_Victron_SmartShunt_UART.yaml' # shunt_combine_Junctek_KHF_UART.yaml
  #       vars:
  #         shunt_id: '1' # must be a number
  #         shunt_name: 'Shunt 1'
  #         shunt_uart_id: 'uart_esp_3'

  bms:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      # BMS 1
      - path: 'packages/bms/bms_combine_JK_UART_4G-GPS_full.yaml'
        vars:
          bms_id: '1' # must be a number
          bms_name: 'JK-b2a8s20p'
          bms_uart_id: 'uart_esp_1'
          bms_address: '0x01'
          # Maximum cell charging cycles is used to calculate the battey SoH.
          # MB31=8000.0, LF280K v3=8000.0, LF280K v2=6000.0, LF280=3000.0 (decimal is required)
          bms_cell_max_cycles: '6000.0'

  # auto charge off triggers for individual BMS
  bms_options:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      # BMS 1
      - path: 'packages/bms/bms_options_charging_logic.yaml'
        vars:
          bms_id: '1' # must be a number

  yambms:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      - path: 'packages/yambms/yambms.yaml'

  canbus:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      - path: 'packages/yambms/yambms_canbus.yaml'
        vars:
          canbus_id: 'canbus1'
          canbus_name: 'CANBUS'
          canbus_node_id: 'canbus_inverter_1'
          canbus_light_id: 'esp_light'
          # The CANBUS link will be considered down if no response from the inverter (0x305 frame) for 5s
          # The Deye inverter sends the ACK 0x305 only when it receives the 0x356 frame.
          canbus_link_timer: '5s'

# +--------------------------------------+
# | DEBUG ( logger level must be DEBUG ) |
# +--------------------------------------+

  debug:
    url: https://github.com/Sleeper85/esphome-yambms
    ref: main
    refresh: 0s
    files:
      - path: packages/base/device_debug_ESP32.yaml
        vars:
          debug_name: 'Debug'
          debug_update_interval: '5s'

# +--------------------------------------+
# | Custom config                        |
# +--------------------------------------+

switch:
  - platform: template
    name: "${name} ${yambms_name} Force Float"
    id: ${yambms_id}_switch_force_float
    restore_mode: RESTORE_DEFAULT_OFF
    optimistic: true
    entity_category: config

interval:
  # Force Float
  - interval: ${yambms_update_interval}
    then:
      - lambda: |-
          // Force Float => Float
          if (id(${yambms_id}_switch_force_float).state) id(${yambms_id}_charge_status) = "Float";

  # Setup min/max value
  - interval: 24h # 60s
    then:
      - lambda: |-
          // Float V.
          id(${yambms_id}_float_voltage).traits.set_min_value(${yambms_cell_count} * 3.125);
          id(${yambms_id}_float_voltage).traits.set_max_value(${yambms_cell_count} * 3.375);
- Thx in advance

Hi,

It looks like you copied @Dmode YAML.

Do you need this additional custom code?

This YAML connects a JK-B BMS to the uart_esp_1 port (TX 17 and RX 16) to JK GPS port.

The component used is that of @syssi

YAML:
  bms1: !include
    file: packages/bms/bms_combine_JK_UART_4G-GPS_full.yaml
    vars:
      bms_id: '1' # must be a number
      bms_name: 'JK-BMS 1'
      bms_uart_id: 'uart_esp_1'
      # Maximum cell charging cycles is used to calculate the battey SoH.
      # MB31=8000.0, LF280K v3=8000.0, LF280K v2=6000.0, LF280=3000.0 (decimal is required)
      bms_cell_max_cycles: '6000.0'

YAML:
substitutions:
  board_chip: "ESP32"
  board_name: "DevKit V1"
  # Interfaces GPIOs
  # uart_esp_1
  tx_pin_1: '17'
  rx_pin_1: '16'
  # uart_esp_2
  tx_pin_2: '19'
  rx_pin_2: '18'
  # uart_esp_3
  tx_pin_3: '26'
  rx_pin_3: '25'
  # canbus_esp32_can
  tx_pin_4: '23'
  rx_pin_4: '22'
  # canbus_mcp2515
  spi_mosi_pin: '13'
  spi_miso_pin: '12'
  spi_clk_pin: '14'
  mcp2515_cs_pin: '15'
 
It looks like you copied @Dmode YAML.
Yes, that's right.
This YAML connects a JK-B BMS to the uart_esp_1 port (TX 17 and RX 16) to JK GPS port.
Yes, TX 17 and RX 16 (including swapping). No data.

Do you need this additional custom code?
I don't know yet ))

Small part of log:
Code:
[09:50:20][C][uart.idf:159]: UART Bus 0:
[09:50:20][C][uart.idf:160]:   TX Pin: GPIO17
[09:50:20][C][uart.idf:161]:   RX Pin: GPIO16
[09:50:20][C][uart.idf:163]:   RX Buffer Size: 512
[09:50:20][C][uart.idf:165]:   Baud Rate: 115200 baud
[09:50:20][C][uart.idf:166]:   Data Bits: 8
[09:50:20][C][uart.idf:167]:   Parity: NONE
[09:50:20][C][uart.idf:168]:   Stop bits: 1

This is a part of esphome-jk-bms@syssi config file:
Code:
substitutions:
  name: jk-b2a8s20p
  device_description: "Monitor a JK-BMS using the GPS port (UART-TTL)"
  external_components_source: github://syssi/esphome-jk-bms@main
  tx_pin: GPIO17
  rx_pin: GPIO16

uart:
  - id: uart_0
    baud_rate: 115200
    rx_buffer_size: 384
    tx_pin: ${tx_pin}
    rx_pin: ${rx_pin}

jk_modbus:
  - id: modbus0
    uart_id: uart_0
    rx_timeout: 50ms

jk_bms:
  - id: bms0
    jk_modbus_id: modbus0
    update_interval: 5s
 
Last edited:
Yes, that's right.

Yes, TX 17 and RX 16 (including swapping). No data.


I don't know yet ))

Small part of log:
Code:
[09:50:20][C][uart.idf:159]: UART Bus 0:
[09:50:20][C][uart.idf:160]:   TX Pin: GPIO17
[09:50:20][C][uart.idf:161]:   RX Pin: GPIO16
[09:50:20][C][uart.idf:163]:   RX Buffer Size: 512
[09:50:20][C][uart.idf:165]:   Baud Rate: 115200 baud
[09:50:20][C][uart.idf:166]:   Data Bits: 8
[09:50:20][C][uart.idf:167]:   Parity: NONE
[09:50:20][C][uart.idf:168]:   Stop bits: 1

This is a part of esphome-jk-bms@syssi config file:
Code:
substitutions:
  name: jk-b2a8s20p
  device_description: "Monitor a JK-BMS using the GPS port (UART-TTL)"
  external_components_source: github://syssi/esphome-jk-bms@main
  tx_pin: GPIO17
  rx_pin: GPIO16

uart:
  - id: uart_0
    baud_rate: 115200
    rx_buffer_size: 384
    tx_pin: ${tx_pin}
    rx_pin: ${rx_pin}

jk_modbus:
  - id: modbus0
    uart_id: uart_0
    rx_timeout: 50ms

jk_bms:
  - id: bms0
    jk_modbus_id: modbus0
    update_interval: 5s

What BMS firmware and hardware version ?

Does @syssi code work on the same board with the same GPIOs ?

This works for me with the same board as you and a JK-B2A20S20P.
 
What BMS firmware and hardware version ?
JK-B2A8S20P, hw 11.XA, sw 11.48, using UART-TTL (reported by @BytEvil) (from syssi github page)
@syssi code work on the same board with the same GPIOs ?
Yes, I flashed it for testing and then want to use permanently.

This works for me with the same board as you and a JK-B2A20S20P.
This is great, but it doesn't work for me yet, but I would like it to ;)
 
JK-B2A8S20P, hw 11.XA, sw 11.48, using UART-TTL (reported by @BytEvil) (from syssi github page)

Yes, I flashed it for testing and then want to use permanently.


This is great, but it doesn't work for me yet, but I would like it to ;)

With your BMS, do you have the choice of protocol used with the UART1 port?

JK-B doc

1745399046655.png
 
Is it possible to connect 2 x JK-PB-RS485 + Shunt BLE to one ESP32_LilyGo-T-CAN485. Or do I have to split it into 2 x ESP32
 
Is it possible to connect 2 x JK-PB-RS485 + Shunt BLE to one ESP32_LilyGo-T-CAN485. Or do I have to split it into 2 x ESP32

You just need to keep in mind that the T-CAN485 is an ESP32 (not ESP32-S3) and that using Bluetooth consumes a lot of memory, which can lead to crashes.

The T-CAN485 has GPIOs available that you can use to connect your shunt using a galvanic isolation board (the best solution in my opinion).
YAML:
substitutions:
  board_chip: "ESP32"
  board_name: "LilyGo T-CAN485"
  # Interfaces GPIOs
  # uart_esp_1 (RS485 port)
  tx_pin_1: '22'
  rx_pin_1: '21'
  # uart_esp_2
  tx_pin_2: '33'
  rx_pin_2: '32'
  # uart_esp_3
  tx_pin_3: '35'
  rx_pin_3: '34'
  # canbus_esp32_can (CAN port)
  tx_pin_4: '27'
  rx_pin_4: '26'
  # canbus_mcp2515
  spi_mosi_pin: '12'
  spi_miso_pin: '5'
  spi_clk_pin: '18'
  mcp2515_cs_pin: '25'
 
I understand that communication between the BMU and your two battery packs takes place over an RS485 bus with an unknown BYD protocol.

We could remove the BMU and connect everything to YamBMS (if the BYD RS485 protocol document is easily found).
YamBMS is, in a way, a BMU.

Keep the BMU and connect it to YamBMS via a CAN bus input.
In this case, I assume you have a choice of CAN protocol for the BMU output ?

In both cases, this requires custom development.
Hi @Sleeper85, sorry for taking some time to reply on this, I recently became father and the little one decided to come a bit early..

To answer your question, yes the BMU sends it's data over CAN to the Cerbo GX.. So what would the procedure be to grab this data on YAMBMS and also the data for 2x JK-B BMS (through bluetooth will be fine) and then send this through CAN output with Victron protocol?

Do you maybe have a diagram how I would need to connect the CAN input from the BYD bank (presume it's BYD protocol and I see you already included this in YAMBMS) and what would the pins be that I need to use on the ESP32 (would it need to be S3 version?) board and what changes / setup would I need to do with the software side?

I would greatly appreciate this if I can get this working and also learn a lot!!

Thanks for all the tremendous work on this!!
 
yes the BMU sends it's data over CAN to the Cerbo GX.. So what would the procedure be to grab this data on YAMBMS and also the data for 2x JK-B BMS (through bluetooth will be fine) and then send this through CAN output with Victron protocol?
What is the protocol configured in your Cerbo GX settings ?
Can you post relevant screenshots?

Also, Can you Flash the canrxall config from https://github.com/shvmm/esphome_can_expt
Then you can connect the ESP32+CAN transceiver directly to the BMU and sniff the incoming frames.

Send the sniffed CAN frames to us.
Also include the readings of battery parameters if from app/console.
 
Just integrated my T-Connect S3 board into my Sunsynk's for the first time, so still getting used to it. But I'm finding that with Auto CCL/DCL switched on the battery doesn't discharge. When I turn OFF Auto CCL/DCL it works ok as expected. In the previous version of @Sleeper85 code pre-YAM (JK Bms - CAN) I found the CCL/DCL worked fine and I never had to change anything. This is a more complex system, but am I missing a setting or something?
 
Just integrated my T-Connect S3 board into my Sunsynk's for the first time, so still getting used to it. But I'm finding that with Auto CCL/DCL switched on the battery doesn't discharge. When I turn OFF Auto CCL/DCL it works ok as expected. In the previous version of @Sleeper85 code pre-YAM (JK Bms - CAN) I found the CCL/DCL worked fine and I never had to change anything. This is a more complex system, but am I missing a setting or something?

@MrPablo ?
 
Interesting, if discharge isn't happening then that sounds like autoDCL isn't working for you.
Can you enable both, then send details of your min and max cell voltages, plus the requested charge and discharge current?

After that, do you continue to see the issue when only autoDCL is disabled?
I'd be quite surprised if autoCCL is causing the issue, but we shall see!
 
Interesting, if discharge isn't happening then that sounds like autoDCL isn't working for you.
Can you enable both, then send details of your min and max cell voltages, plus the requested charge and discharge current?

After that, do you continue to see the issue when only autoDCL is disabled?
I'd be quite surprised if autoCCL is causing the issue, but we shall see!
Slight update: I'm referring to the main dashboard on the control tab. if I turn off the main on/off for auto, but on the two sub buttons, keeping auto charge current on, but turning off auto discharge current works ok.

Requested charge = 40A, requested discharge = 66A. But I've got these values by moving the '% slider' to 25% for charge and 39% for discharge.
The picture might be getting muddied as I've got a Goodwe 48V PV charger going direct to the batteries that Yam doesn't know about. This is set to 58V and 35A charge, which is another reason I keep the Yam charge current a bit low to take account of the extra 35A coming from the Goodwe. I can see that when at the full 58V it'll have 4.14v per cell (14s NCM), and I'm guessing that push it over what it sees as the max voltage, but that's set to 58v in Yam too.
Right now the average cell voltage is 3.8V and discharging ok (no alarms), I'll switch DCL back on and see what happens... Yeah it still virtually shuts down and I start pulling about 400W from the grid. Switch DCL off = discharging normally again.

One possible problem is that I don't think I integrated the Bluetooth bms correctly, I didn't realise I was meant to make an include file in the main Yambms.yaml, instead I've added the bluetooth function directly into Yambms.yaml as BMS3. (consequently I'm also not getting cell voltages or resistances, just the main currents and power).
 
When autoDCL is enabled, is the requested discharge current zero?
The logic for autoDCL uses three inputs:
  • Max discharge current
  • Current minimum cell voltage
  • Under voltage cell protection value + 0.2V
If either of the latter two are unusual values then you can get unexpected values for requested discharge current.
 
When autoDCL is enabled, is the requested discharge current zero?
The logic for autoDCL uses three inputs:
  • Max discharge current
  • Current minimum cell voltage
  • Under voltage cell protection value + 0.2V
If either of the latter two are unusual values then you can get unexpected values for requested discharge current.
When I switch DCL back on, yes I get zero requested discharge current... But I have an idea now - the ONLY ble I can get to work is JK minimal, all the others crash the T-connect board after around 60s (I tried turning off the web server, but it made no difference). Here's the thing - the minimal ble doesn't report any cell voltages in the BMS section, so I reckon there's a fair chance that the auto DCL see's this as an error and shuts down discharge, according to your logic above, even though there's no problem with any cells.
 
I have a question for you @Sleeper85 I see you have a DEYE, what protocol can you use for your DEYE and your batteries?
 

Attachments

  • Zrzut ekranu 2025-04-28 212338.png
    Zrzut ekranu 2025-04-28 212338.png
    41.1 KB · Views: 6

diy solar

diy solar
Back
Top