Communication between BYD Battery and Kostal Plenticore Inverter

Having just had a bit of a holly sh** moment... puzzling about 3 byte floats...

I started programming on a Z80 (Sharp MZ80K)... I started in the twilight zone !!
 
Usually takes me longer than 3 bites to eat a float. I try to savoir the flavor, and not get an ice cream headache :p
 
@huntworker, what is the final goal of this project? You want to build some monitoring system or connect some other battery to your inverter using this protocol.
I am trying to use a battery from an EV, maybe BMW i3 or even the tesla battery. i3 would be nice since the voltage is in a good range. With a Tesla battery I would need to use the whole pack with 60 to 100 kWh to have a good voltage, which might be a bit oversized. :D
So am trying to simulate the BYD battery for the existing Kostal inverter.
I also thought about using another inverter. I like the Victron pars for its uninterruptible power supply and fast transfer switches. But they are using only single phase concepts. So I would need 3x the MultiPlus || and the SmartSolar RS to have a tree phase system which lead to additional cost for the inverter of around 7 k€. With this system I would have the UPS but thats not worth it.

I am working as electrical engineer for a german company which builds cell management controller, battery management controller and battery junction boxes for different OEMs so I know what I am doing. :)
Only unusual thing for me is to not having a description of the protocols and buses.
 
OK. I got it. So, we are running on the same track here :) That is pretty similar to what I've done with a Goodwe inverter in my project.
BTW, I'm curious what do you think about this brand of inverters? They are well priced, and for about 1700-1800 euro, you can get a 10kW 3 phase HV hybrid inverter with UPS functionality.
 
OK. I got it. So, we are running on the same track here :) That is pretty similar to what I've done with a Goodwe inverter in my project.
BTW, I'm curious what do you think about this brand of inverters? They are well priced, and for about 1700-1800 euro, you can get a 10kW 3 phase HV hybrid inverter with UPS functionality.
I didn't know Goodwe when I installed my setup.
In the meantime I got in touch with the 48V 3,6kW version GW 3648-EM which has quite interesting data. I like the home consumption measurement with its current transformers. In my case it was "more complicated" with the Kostal smart energy meter which does direct measurement, so all the current need to go though the device.
From technical data and for sure compared to the price, they are pretty good. I do not have any data for durability but expect them to be similar to others.

Your project is very similar to mine, respect for the work you did!
 
Silent lurker here. Having read the thread with great interest. Wondering if this has materialised into a custom sort of "BYD-BMS-emulator"? Would love to know how this developed!
 
I am trying to use a battery from an EV, maybe BMW i3 or even the tesla battery. i3 would be nice since the voltage is in a good range. With a Tesla battery I would need to use the whole pack with 60 to 100 kWh to have a good voltage, which might be a bit oversized. :D
So am trying to simulate the BYD battery for the existing Kostal inverter.
I also thought about using another inverter. I like the Victron pars for its uninterruptible power supply and fast transfer switches. But they are using only single phase concepts. So I would need 3x the MultiPlus || and the SmartSolar RS to have a tree phase system which lead to additional cost for the inverter of around 7 k€. With this system I would have the UPS but thats not worth it.

I am working as electrical engineer for a german company which builds cell management controller, battery management controller and battery junction boxes for different OEMs so I know what I am doing. :)
Only unusual thing for me is to not having a description of the protocols and buses.
It is exactly what i intend to install for our home location as well.
Multiple tesla modules are already here due to the fact, that we are reapiring hv-packs.
Before putting them again into real cars, my idea is to use them in our own pv-installation.
The boosttech BMS looks good from easy-installation perspective so i would like to bring these guys
into that thread to assist in that adoption into some piece of usable communication between the plenticores
and the battpack.
After that i would even consider to abandon our PowerWall2 from past referals.
@huntworker If you are located in germany maybe we can combine our efforts ... ;-)
 
Hi all,
my activities stopped during summer because I didn't find any time.
But during summer I got new ideas for the hardware and I will bring it to a PCB design and test it this winter. Plan is to have a running system for Christmas.
@Jagganaut yes, I am in Germany, currently in the south, but soon in the south-west. I am always interested in "damaged" battery modules.
 
Hi All,

this topic is very interesting for me. I have old Piko BA without battery und I just connect high voltage DC to battery connection only to make it still stanby on the night to keep the inverter measuring home use.

I did simple deviding your log to some 4 byte floating point and got this result:

Code:
Current: -1.775
SOC: 63.000%
SysTemp: 20.300
MaxCellVolt: 3.264
MinCellVolt: 3.260
MaxCellTemp: 19.600
MinCellTemp: 17.600
MaxVolPos: 3
MinVolPos: 4
MaxTempPos: 1
MinTempPos: 4

0A E2 FF 02 FF 29
CF 77 82 43 -> 0x438277cf = 260.936004639    Cur Voltage
01 0F 8D 43 -> 0x438d0f01 = 282.117218018    Max Allowed Voltage
66 66 A2 41 -> 0x41a26666 = 20.2999992371    SysTemp
66 66 E6 BF -> 0xbfe66666 = -1.79999995232    Current
46 E1 DA BF -> 0xbfdae146 = -1.70999979973    Current
01 03 48 42 -> 0x42480301 = 50.0029335022    Peak discharge current
01 03 C8 41 -> 0x41c80301 = 25.0014667511    Nominal discharge current
01 14 A0 41 -> 0x410a1401 = 8.62988376617
CD CC 9C 41 -> 0x419ccccd = 19.6000003815    MaxCellTemp
CD CC 8C 41 -> 0x418ccccd = 17.6000003815    MinCellTemp
FE D4 50 40 -> 0x4050d4fe = 3.26300001144    MaxCellVolt
75 93 50 40 -> 0x40509375 = 3.25900006294    MinCellVolt
FC        -> 0xFC = 252            Cycle count
02 01 02
3F         -> 0x3f = 63            SoC
01 01 02
B4        ->    checksum

It could be possible that last byte floating point is used to code other thing like max-min voltage position and temperature position.

If I looked your first log, the second byte from each frame have "E2" or "62", it remain me to webasto protocol that use 4bit for sender address and destination address.

@huntworker could you share your log on power on and power off?
 
Hi,
nice to see you interested in the topic. :)

It could be possible that last byte floating point is used to code other thing like max-min voltage position and temperature position.
You mean the last block, in this case 75 93 50 40? I am pretty sure that this is the voltage of the lowest cell since this matches well with the SOC.

If I looked your first log, the second byte from each frame have "E2" or "62", it remain me to webasto protocol that use 4bit for sender address and destination address.
If I have a closer look, the Header of the messages is always the same
E2 FF 02 FF 29 for messages from the battery to the inverter
62 FF 02 FF 29 for messages from the inverter to the battery
So the only change is in the first nibble. But with a even closer look you might see that it is even only changed in the first bit:
0x6 = 0b0110
0xE = 0b1110

@huntworker could you share your log on power on and power off?
Sure, please find the file attached.
Power off is quite easy, the communication just stops.


Edit: attachment was duplicated
 

Attachments

  • einschaltenBatt.txt
    14.3 KB · Views: 170
Last edited:
Hi All,

@huntworker thanks for the data

I tried to analyze the data and the information that could be shown in the inverter (since I just have the inverter but not the battery).
I think the inverter doesnt need info where max and in in the battery module and this information are not in the data frame.
So, on long frame, the data just look simple like my last post and the short frame could be some status info like:

Code:
09 62 FF 02 FF 29 4A 08 23 00 -> device check/starting
09 62 FF 02 FF 29 4A 04 27 00 -> device ok/run
06 E2 FF 02 FF 29 ...    -> some or one value could not be read like missing charging voltage from the inverter or measurement not avaliable yet

@huntworker You said for short frame the checksum just standart 8bit-checksum without first byte but on starting frame there is 07 frame that not matched

Code:
07 63FF02FF295E02 16    -> checksum8=14 ???
07 E3FF02FF29 F4    -> checksum8=F4
09 62FF02FF294A08 23    -> checksum8=23
08 E2FF02FF2906 EF     -> checksum8=EF

About checksum for long frame, I tought it was a special crc-8 but I tried all possibility that could be done with crc calculation with no result then I did 8-bit checksum and founded that it just sum of all bytes added with 0xC0 then inverted.

I am currious with short frame now.

@huntworker Could you share some logs with charging 99% to full and also 1% before DoD until DoD.
Since the inverter act as charger/decharger, I expected some data like "ready to charge", "full charged", "charger (inverter) (detected) error", "discharge ready"

Discarge cycle is also still a mystery, some logs along 255-257 and 511-513 could be also helpfull
 
Hi,

So, on long frame, the data just look simple like my last post and the short frame could be some status info like:
totally agree with you.

About checksum for long frame, I tought it was a special crc-8 but I tried all possibility that could be done with crc calculation with no result then I did 8-bit checksum and founded that it just sum of all bytes added with 0xC0 then inverted.
I don't have the adding of 0xC0 in mind, but yes, this is sum of all bytes inverted. But we already found that out.

I am currious with short frame now.
With checksum it is solved already. What the data in the short frame are standing for is still not known. But as you said, it needs to be some short status or request frames.

@huntworker Could you share some logs with charging 99% to full and also 1% before DoD until DoD.
Since the inverter act as charger/decharger, I expected some data like "ready to charge", "full charged", "charger (inverter) (detected) error", "discharge ready"
I already done this. SOC is byte 58.
Byte 57 is a status byte which is 0x00 when the battery is allowerd to charge and 0x40 whe it is fully charged. other values than that have not been seen yet.

Discarge cycle is also still a mystery, some logs along 255-257 and 511-513 could be also helpfull
This is byte 54 and 55. i did not reached 511 cycles, but I know that they are using zwo bytes because the already use the one bit for 256 to 350 (current cycle count).

If I have time for it I will build a long term logger and analyzer to attach it permanently to the bus and figure out what happens if the battery is fully dischaged. This is not that easy because min.SOC in the inverter is 5% so I need to wait for the self discharge of the battery but I do not want the battery in that low state of charge to not damage it.
 
With checksum it is solved already. What the data in the short frame are standing for is still not known. But as you said, it needs to be some short status or request frames.
There is 07 frame on start sequence that has not right checksum (07 63FF02FF295E02 16. It has 16 instead of 14)

I already done this. SOC is byte 58.
Byte 57 is a status byte which is 0x00 when the battery is allowerd to charge and 0x40 whe it is fully charged. other values than that have not been seen yet.
Yes it is, but I am interested with 3 short frame around it, near SoC 100% until stop charging and nead DoD until stop discharging. Maybe there are some status changing short frame.
This is byte 54 and 55. i did not reached 511 cycles, but I know that they are using zwo bytes because the already use the one bit for 256 to 350 (current cycle count).
I just have one long frame from your post that stating cycle 259:
0AE2FF02FF299EBF8343010F8D433333A7419A99D9BF9A99D9BF010348420103C8410103A041010FA041CDCC90419643534023DB514003010102500101021200
Before it reach 256 byte 55 was 02 then it became 01, there should be a way to read the right way.
Could you share some long and short frame logs around it?

I wrote a simple python script to pharse the long frame, just give long frame data included 00 ending as input. Reading cycle count is still not right. Is it not allowed to attach python file?


1635263069534.png
 
There is 07 frame on start sequence that has not right checksum (07 63FF02FF295E02 16. It has 16 instead of 14)
Do you need to do the checksum before doing the replacements of the 00 bytes?
Yes it is, but I am interested with 3 short frame around it, near SoC 100% until stop charging and nead DoD until stop discharging. Maybe there are some status changing short frame.
Hm, I will have a look for that. As I wrote, all the logs are done by hand.
I wrote a simple python script to pharse the long frame, just give long frame data included 00 ending as input. Reading cycle count is still not right. Is it not allowed to attach python file?
Thats on my todo list als well for a long time. :D
 
Do you need to do the checksum before doing the replacements of the 00 bytes?
00 byte is illegal data and use only to marking end of frame. Inside the frame 01 could be "00" or "01" so the receiver could not guess what it was but checksum must always be correct calculated, that's way checksum must always be calculated after replacing "00" to "01".

I see also curious byte just I wrote in my first post:
Code:
01 0F 8D 43 -> 0x438d(0f01) = 282   Max Allowed Voltage
01 03 48 42 -> 0x4248(0301) = 50    Peak discharge current
01 03 C8 41 -> 0x41c8(0301) = 25    Nominal discharge current
All above three value can we have from datasheet, so the 2 byte LSB should be always "00 00".
I saw on Max Allowed Voltage the LSB value from log can be: "0301", "0701" or "0F01"
0x03=0b0000 0011, 0x07=0b0000 0111, 0x0F=0b0000 1111
It looks like showing something

@huntworker could you provide some logs and its web value from battery

For cycle count I have idee in my mind how it could be but I need more logs during charging/discarging and full charged with cycle count: 254, 255, 256, 257, 258, 259, 511, 512, 513, 514 and 515. Do you have some of it?
 
For all the riddle players I did some new logs.
file "on_2021-11-15.txt" contains communication with switched off battery. At some point I switched it on.
file "on_off_2021-15.txt" is the same procedure but with switching it off afterwards.
You can now compare it to the old file and with each other.

I will do the same for sure. :)

EDIT: Please do not use the files, they are corrupt, use the file from the next post.
 

Attachments

  • on_off_2021-11-15.txt
    15 KB · Views: 95
  • on_2021-11-15.txt
    36.8 KB · Views: 81
Last edited:
I changed my toolchain from Linux to windows and logging in windows with puTTY "forgots" some chars. I wondered about the missing "headers" so I checked the HW Bus and they werer there.
So in short: please forget the files from today and use the new one here.

I hope you didn't start analyzing the corrupt files...

File starts now with battery switched off, then switched on and then switched off again. You can clearly see this in the data.

Best regards
 

Attachments

  • 2021-11-15_on_off.txt
    24.2 KB · Views: 124
I was so busy during year end.
I just continue for this interesting bit puzzeling.

I updated my inverter firmware to enable BYD support, then I got data out from my inverter with second byte 62 and 63. So It just like my guess that 62 and E2 is a addressing.
So, the inverter is a master and battery as slave, the second byte has function as follow:

x2 -> read data command
x3 -> set data command
6x -> data from inverter
Ex -> data response from battery

about Checksum, I was half wrong. The checksum is calculated (without first byte) before data '00' eliminating but the checksum calculation should be still valid by adding 0xC1 after '00' eliminating and this control by first byte.

for example:
Code:
Data-Send:  0A E2FF02FF292FCD804301078D4333338B410101010101010101010348420103C8410116A041CDCC8C41CDCC84413F354E40B6F34D40630101020E010102 5100
Data-Clean: -- e2ff02ff292fcd804300008d4333338b410000000000000000000048420000c8410000a041cdcc8c41cdcc84413f354e40b6f34d40630101000e000000    -> sum=0xAF -sum=0x51
Data-Dirty: -- E2FF02FF292FCD804301078D4333338B410101010101010101010348420103C8410116A041CDCC8C41CDCC84413F354E40B6F34D40630101020E010102+C1 -> sum=0xA5

First byte = 0xAF - 0xA5 = 0x0A

Now I am curious with charging and discharging situation, there should be also coded in the frame.
@huntworker could you make few log along charging and discharging
I also read on manual that the inverter could ask battery to do battery capacity calibration, it should send 63/E3 frame but to catch this you need to make longtherm logging with filtering only for that both second byte or force manually from battery website

from Manual:
1642531278826.png
 
Hello, New here, but not new to RE or engineering.

The most recent post on the SOC calibration, it works like this. The Battery reports in its status when polled by the inverter to flag a calibration cycle. This can happen by the battery if more than 6-8 weeks have passed or manual initiation from the BYD HTTP interface.

All the inverter does is stop any charging, nothing else. Once the SOC gets somewhere below 10% the battery will responding with the calibration flag set and the inverter then starts charging the battery depending on the inverters option ( charge from grid enabled or solar energy available ).
 
Last edited:
Back
Top