My laptop's battery is misbehaving. Its refusing to charge (says "waiting to charge"), reporting 11.7V as its 100% SoC (its a 3S2P battery, 12.3V is 100%)
This wouldn't have been a deal breaker by itself but for whatever reason, 11.6V is considered 0% SoC.
I can get maybe 20 minutes of use out of my laptop, until the it drop from 100% to 0% (actually only drops from 11.7V to 11.6V)
Files
linux.sr
Data captured when I logged into my Linux Mint installation. May contain useful data?
I opened my battery today, and looks like it an actual genuine Lenovo ThinkPad battery. I suspected it was a knock-off but that's not the case. The main IC is a 51F51 BMS IC. I couldn't find any information about it so I decided to read up more on the workings of these battery packs.
Apparently these batteries use SMBus for communication and the communication protocol is given in the Smart Battery Data Specification 1.1, which I found here after searching a bit on the internet.
I also searched the pinout of the battery and can confirm, its the following
I then soldered a wires on the battery SDA and SCL lines and connected the battery to my cheap logic analyser which was connected to my desktop. Of course, the laptop is unpowered, and the adaptor is not connected either.
I then started pulseview and started recording 1G samples at 8MHz, and proceed to plug in the battery connector to the laptop. I managed to get quite great readings on the first try. I set correct labels to the logic channels and set the I2C decoder lose (there doesn't seem to be SMBus decoder present, I2C should work well enough)
I then took a better look at the data being sent and received. It looked like the device's address was 0x0B, which was being sent with a write bit set. The byte proceeding that is the command. After this there is a repeated start condition, with now the read bit set along with the BMS address. The BMS responds with the command response.
Below is the second transaction happening in the sequence after being plugged in (I omitted the first one because I couldn't make much sense out of it honestly)
IMPORTANT: The data format is LSB first. The data in the above image is 0x300C, not 0x0C30
Now I tried to make sense out of this by trying to cross reference the commands from the PDF to SBS1.1 standard to actually what's happening. If you'll see, the command here is 0x15, which is the below command in the document.
So 0x15 is the battery pack charging voltage in mV. It has to be between 12.0V to 12.6V, depending on if the charging is supposed to stop at 4V/cell or 4.2V/cell.
So then I decode the data, just as a sanity check.
Yes that looks right! Now lets move on to the next transaction. Same process again.
Command is 0x18, which is the pack capacity
The capacity mode bit was supposed to be in the response of the first transaction but I was unable to map it to the command, so I decided to have a look to what format looks right. It was CAPACITY_MODE=1, the data was in units of 10mWh. My battery pack marked as 48Whr so this looks very close.
My end goal is to program an MCU to handle the communication between the battery pack and laptop so that I can make some whacky custom battery packs for laptops. I'm interested in making a 4S LiFePO4 76Whr pack.
This is the end of the log. I wrote it down because I could not find comprehensive information about this stuff anywhere. I am attaching my pulseview recordings, if anyone wants them