syssi / esphome-jbd-bms

ESPHome component to monitor and control a Xiaoxiang Battery Management System (JBD-BMS) via UART-TTL or BLE
Apache License 2.0
100 stars 28 forks source link

Force SoC reset #63

Open taHC81 opened 10 months ago

taHC81 commented 10 months ago

Hello Syssi, any chance to add button/switch to reset SoC on demand? BMS is slowly drifting and there's no other way to calibrate SoC than full charge. I'd like to have an opportunity to request "reset SoC" based on voltage, while my inverter is in bypass mode and battery voltage is stable. I can attach logic analyzer and try to find what is requested, but not sure whether you had to chance to check it sooner :) thanks

taHC81 commented 10 months ago

I see reference to "Set remaining capacity" but it's not used in any GUI element. https://github.com/syssi/esphome-jbd-bms/blob/c628c833fdf25176fbdda105fed1dc5827c1ad67/components/jbd_bms/jbd_bms.cpp#L23C1-L23C73

syssi commented 10 months ago

A traffic capture would reduce the risk to pass critical payload to the BMS accidentally. Are you able to capture some traffic (UART or BLE)? A capture using a logic analyzer is also fine.

If I add the feature without samples there is the risk to brick your BMS.

taHC81 commented 10 months ago

Will give a try, but currently I've got just an UART connection to the ESP8266. From what I read, it should be possible to operate UART and BT module simultaneously, right? If so, I can use the ESPhome UART debug, or use the logic analyzer.

syssi commented 10 months ago

Yes. You can use the BLE module and just add the RX and GND pin of the ESP to the serial lines to dump some traffic. Please don't try to use both clients simultaneously (RX+TX) because this isn't supported in general.

This snipped can be used to dump serial traffic to the log:

uart:
  - id: uart_0
    baud_rate: 9600
    tx_pin: ${tx_pin}
    rx_pin: ${rx_pin}
    debug:
      direction: BOTH

Please don't load the jbd_bms component.

taHC81 commented 10 months ago

Okay, but how we get the message sent to reset the capacity (SoC)? With the RX only, I could catch only the reply from BMS.

syssi commented 10 months ago

You can load multiple uart and use multiple GPIOs so sniff the traffic on different lines:

uart:
  - id: uart_0
    baud_rate: 9600
    tx_pin: ${tx_pin}
    rx_pin: ${rx_pin}
    debug:
      direction: BOTH
  - id: uart_1
    baud_rate: 9600
    tx_pin: ${tx_pin2}
    rx_pin: ${rx_pin2}
    debug:
      direction: BOTH

If you aren't lucky the ESP will pull-up/down some of the lines and disturbs the communication. In this case a logic analyzer would be the better choice.

taHC81 commented 10 months ago

Anything :) Will test and let you know. Today BMS reported 45% SoC and after Capacity reset it went down to 21%...

leodesigner commented 10 months ago

Hey, Thanks for the excellent project !

Same issues with SOC here. Even implemented an external counter for battery capacity by integrating current over the time. The results I've got are the same as an internal BMS capacity counter. But it would be much better to have an accurate SOC from BMS.

Do you have any other ideas for accurate SOC estimation especially when battery is not fully charged/discharged ? Researching papers at the moment, seems SOC estimation for LFP is not so easy at all.

taHC81 commented 9 months ago

Still waiting for some really dark day with no solar gains to sniff the Capacity reset.

leodesigner: you can't estimate SoC while battery is in a charging or discharging state, only when it's disconnected and resting few hours - that's why I'd like to have a chance to reset SoC when inverter is in a bypass. BMS will calculate it according to the data in a config. Here's a table with SoC-voltage pairs. LFP-voltage-chart

leodesigner commented 9 months ago

Yeah, SOC estimation is not trivial. Even trained small ML model to estimate SOC, got some early results. It looks like ML model can correct SOC from BMS when it's getting non accurate.

taHC81 commented 9 months ago

So here we are! Saleae Logic did the trick, here's the dump.

TX: 0xDD, 0x5A, 0x0A, 0x02, 0x01, 0x00, 0xFF, 0xF3, 0x77 RX: 0xDD, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x77 JBD-cap-reset

Could you please let me know how to implement it, or make a fork with this functionality, I'll test. Thanks a lot!

taHC81 commented 9 months ago

Just checked it with an additional button within the ESP and it's working perfectly!

button:
  - platform: template
    name: "Reset Capacity/SoC"
    on_press:
      - uart.write: [0xDD, 0x5A, 0x0A, 0x02, 0x01, 0x00, 0xFF, 0xF3, 0x77]
syssi commented 9 months ago
0xDD, 0x5A, 0x0A, 0x02, 0x01, 0x00, 0xFF, 0xF3, 0x77
  |     |     |     |     |     |     |     |     |
  |     |     |     |     |     |     |     |     JBD_PKT_END
  |     |     |     |     |     |     |     CRC
  |     |     |     |     |     |     CRC
  |     |     |     |     |     data1
  |     |     |     |     data0
  |     |     |     data_len
  |     |     address
  |     JBD_CMD_READ
  JBD_PKT_START
syssi commented 9 months ago

Could you tell me the capacity of your battery pack?

I see reference to "Set remaining capacity" but it's not used in any GUI element. https://github.com/syssi/esphome-jbd-bms/blob/c628c833fdf25176fbdda105fed1dc5827c1ad67/components/jbd_bms/jbd_bms.cpp#L23C1-L23C73

FYI: This command uses address 0x0e + a battery capacity value. We are talking about 0x0a now.

taHC81 commented 9 months ago

I've got 280 Ah, and it's also set within the BMS app.

taHC81 commented 9 months ago

In fact, there are 2 messages sent and 2 received, with a 0.1 sec gap. Second message and reply below:

TX: 0xDD, 0x5A, 0x01, 0x02, 0x00, 0x00, 0xFF, 0xFD, 0x77 RX: 0xDD, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77 Capture