o-gs / dji-firmware-tools

Tools for handling firmwares of DJI products, with focus on quadcopters.
GNU General Public License v3.0
1.54k stars 418 forks source link

About Permanent Fault and low voltage batteries #226

Open maxdd opened 3 years ago

maxdd commented 3 years ago

Hi, recently i tried to charge 4 batteries of my mavic pro platinum and unfortunately i discovered they were not charging probably due to the too low voltage. I charged them slowly and now they are back to around 3.87V. (11.6V - 11.8V) Even by removing power supply to the chip it seems that the batteries are still not working. I've seen the possibility to reset the permanent fault error via i2c and i was wondering whether it is what i'm currently missing to make them work again.

Regards,

mefistotelis commented 3 years ago

Clearing PF is not fixing, it's letting the IC know that you physically serviced and fixed the cells.

https://www.youtube.com/watch?v=P5PNOO2GebY

Note description: Clearing error flags within the battery chip will not fix the cells inside your battery. The PF flags are usually set for a reason. If they need replacement, clearing error state is not enough to repair the battery. Though it may still be used to less demanding jobs, like power bank.

maxdd commented 3 years ago

I've seen the video and i've reached here. What does mean "will not fix the cells inside your battery"? Of course chemical aspects cannot be fixed with a register flip. What i don't understand is whether once i "restored" them (properly or improperly) the PF error clearing is sufficient to have "current/power" from/into the battery. In a situation like the one i described above can i achieve charging/discharging if i clear the PF?

mefistotelis commented 3 years ago

Of course chemical aspects cannot be fixed with a register flip.

Yes, that's what I meant.

What i don't understand is whether once i "restored" them (properly or improperly) the PF error clearing is sufficient to have "current/power" from/into the battery.

So your question is, are there another conditions, which could affect battery turning on, besides PF? The answer for that is: yes. For details, read datasheet of the BQ chip.

In a situation like the one i described above can i achieve charging/discharging if i clear the PF?

There is only one permanent failure mechanism within the BQ30z55.

maxdd commented 3 years ago

So it seems like that it could potentially restore the battery. Another question, the different models of DJI batteries have SDA and SCL on the external connector. In your video it is required to solder instead, have you tested already whether SDA and SCL are on the connector?

mefistotelis commented 3 years ago

Yes. Look at wiki of this project for details on each board.

maxdd commented 3 years ago

Mhmm according to this table

https://github.com/o-gs/dji-firmware-tools/wiki/WM220-Battery-Intelligent-Board#external-connector-of-the-battery

there is no i2c exposed to the outside? In the Mavic 1/2 mini i've seen SCL and SDA as first and last pin, can i assume the same? if so which of the pin is which?

mefistotelis commented 3 years ago

Go ahead, experiment. My hint would be to first assume it's UART, though.

maxdd commented 3 years ago

You mean to swap TX/RX? Also what frequency shall the i2c configured to? I'm using an odroid with debian which is quite similar to a raspberry pi but it defaults to 100Khz (can be configured to 300Khz)

with i2cdetect -y 1 i see no data with python3 ./comm_sbs_bqctrl.py -vvv --dev_address 0x0b read BatteryStatus i see

Opening i2c:1
Raw write: DATA=22 3e
Chip detection failded: BlockingIOError: [Errno 11] Resource temporarily unavailable
Auto-selected chip: SBS, Generic chip with SBS support
Warning: Could not open chip definition file 'comm_sbs_chips/SBS.py'
Reading simple command at addr=0xb, cmd=0x16, type=uint16, opts={'subcmd': None}
Error: BlockingIOError: [Errno 11] Resource temporarily unavailable
mefistotelis commented 3 years ago

You mean to swap TX/RX?

I mean to figure out the connection protocol.

maxdd commented 3 years ago

Isn't that i2c ? i thought the BQ30Z55 was also mounted on them. I do read a similar text on the chip I have added the GND (my bad)

the output now is


i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- 1c 1d 1e 1f
20: 20 21 -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- 47 48 49 4a 4b 4c 4d -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- 73 74 75 76 77

but the python script is not working

EDIT: I ended up buying a CP2112, lets see

maxdd commented 3 years ago

@mefistotelis

i was able to recover one of the 2 batteries i've opened up but not the second. The only different thing i did wrt to one that works was to connect it to the charger before putting it into the drone. Here's the output i'm receiving

pi@raspberrypi:~/dji-firmware-tools $ python3 ./comm_sbs_bqctrl.py -vvv --dev_address 0x0b --short monitor BQStatusBits
Opening i2c:1
Raw write: DATA=22 3e
Raw write: DATA=20 3e
Raw write: DATA=22 3e
Raw FirmwareVersion response: 0d 05 50 00 36 00 34 00 03 80 00 01 00 03 c5
Auto-selected chip: BQ30z55, Texas Instruments BQ30z55 chip
Importing comm_sbs_chips/BQ30z554.py
Reading simple command at addr=0xb, cmd=0x50, type=uint32_blk, opts={'subcmd': None}
Raw SafetyAlert response: 04 00 00 00 00 05
SafetyAlert:            0x00000000      bitfields       Safety Alert bits
[ ResU=0][ ResT=0][ ResS=0][ ResR=0][ ResQ=0][ ResP=0][ ResO=0][ CHGV=0]
[ CHGC=0][   OC=0][ CTOS=0][  CTO=0][ PTOS=0][  PTO=0][  HWD=0][  OTF=0]
[ ResF=0][ CUVC=0][  OTD=0][  OTC=0][ ResB=0][  SCD=0][ Res9=0][  SCC=0]
[ Res7=0][  OLD=0][ OCD2=0][ OCD1=0][ OCC2=0][ OCC1=0][  COV=0][  CUV=0]
Reading simple command at addr=0xb, cmd=0x51, type=uint32_blk, opts={'subcmd': None}
Raw SafetyStatus response: 04 00 00 00 00 da
SafetyStatus:           0x00000000      bitfields       Safety Status bits
[ ResU=0][ ResT=0][ ResS=0][ ResR=0][ ResQ=0][ ResP=0][ ResO=0][ CHGV=0]
[ CHGC=0][   OC=0][ ResK=0][  CTO=0][ ResI=0][  PTO=0][  HWD=0][  OTF=0]
[ ResF=0][ CUVC=0][  OTD=0][  OTC=0][ SCDL=0][  SCD=0][ SCCL=0][  SCC=0]
[ OLDL=0][  OLD=0][ OCD2=0][ OCD1=0][ OCC2=0][ OCC1=0][  COV=0][  CUV=0]
Reading simple command at addr=0xb, cmd=0x52, type=uint32_blk, opts={'subcmd': None}
Raw PFAlert response: 04 00 00 00 00 bc
PFAlert:                0x00000000      bitfields       Permanent Failure Alert bits
[ ResU=0][ ResT=0][ ResS=0][ ResR=0][ ResQ=0][ ResP=0][OCECO=0][ ResN=0]
[ ResM=0][ 2LVL=0][ AFEC=0][ AFER=0][ FUSE=0][THERM=0][ DFET=0][CFETF=0]
[ ResF=0][ ResE=0][ ResD=0][ VIMA=0][ VIMR=0][   CD=0][  IMP=0][   CB=0]
[  QIM=0][  OTF=0][ Res5=0][ OTCE=0][ Res3=0][CUDEP=0][  COV=0][  CUV=0]
Reading simple command at addr=0xb, cmd=0x53, type=uint32_blk, opts={'subcmd': None}
Raw PFStatus response: 04 00 00 00 00 63
PFStatus:               0x00000000      bitfields       Permanent Failure Status bits
[ ResU=0][ ResT=0][ ResS=0][ ResR=0][ ResQ=0][  DFW=0][OCECO=0][  IFC=0]
[  PTC=0][ 2LVL=0][ AFEC=0][ AFER=0][ FUSE=0][THERM=0][ DFET=0][CFETF=0]
[ ResF=0][ ResE=0][ ResD=0][ VIMA=0][ VIMR=0][   CD=0][  IMP=0][   CB=0]
[  QIM=0][  OTF=0][ Res5=0][ OTCE=0][ Res3=0][CUDEP=0][  COV=0][  CUV=0]
Reading simple command at addr=0xb, cmd=0x54, type=uint32_blk, opts={'subcmd': None}
Raw OperationStatus response: 04 00 62 10 00 34
OperationStatus:        0x00106200      bitfields       Operational Status bits
[ ResU=0][ ResT=0][ ResS=0][XLSBS=0][SLEPC=0][SLEPQM=0][SLCAL=0][ INIT=0]
[SLEPM=0][  SDV=0][ CALO=0][  FVS=1][  AWD=0][ AUTH=0][ SHPM=0][  SDM=0]
[SLEEP=0][ XCHG=1][ XDSG=1][   PF=0][   SS=0][  CAL=0][           SEC=2]
[  LED=0][   CB=0][ FUSE=0][ GPOD=0][ PCHG=0][  CHG=0][  DSG=0][ PRES=0]
Reading simple command at addr=0xb, cmd=0x55, type=uint24_blk, opts={'subcmd': None}
Raw ChargingStatus response: 03 08 02 00 20
ChargingStatus:         0x000208        bitfields       Charging Status bits
[ ResN=0][ ResM=0][ ResL=0][ ResK=0][ ResJ=0][ MCHG=0][ ResH=0][  VCT=0]
[  CCC=0][  CVR=0][  CCR=0][   SU=0][   IN=0][   HV=0][   MV=1][   LV=0]
[   PV=0][   OT=0][   HT=0][  STH=0][   RT=1][  STL=0][   LT=0][   UT=0]
Reading simple command at addr=0xb, cmd=0x56, type=uint16_blk, opts={'subcmd': None}
Raw GaugingStatus response: 02 1f 09 a1
GaugingStatus:          0x091f  bitfields       Gauging Status bits
[LPFRlx=0][  TCA=0][  TDA=0][OCVFR=0][ LDMD=1][   RX=0][ QMax=0][  VDQ=1]
[ NSFM=0][   FC=0][   FD=0][  QEN=1][  VOK=1][   RU=1][  DSG=1][RESTD0=1]
Reading simple command at addr=0xb, cmd=0x57, type=uint16_blk, opts={'subcmd': None}
Raw ManufacturingStatus response: 02 58 00 cc
ManufacturingStatus:    0x0058  bitfields       Manufacturing Status bits
[  CAL=0][ ResE=0][ ResD=0][ ResC=0][ ResB=0][ ResA=0][  LED=0][ FUSE=0]
[  BBR=0][   PF=1][   LF=0][  FET=1][GAUGE=1][  DSG=0][  CHG=0][ PCHG=0]

I see few registers which normally are not set to 1, do you have any idea if that could be the issue? The battery has the closest LED to the button turned on and the motors spin for like 100ms and they just stop.

mefistotelis commented 3 years ago

I'm pretty sure you do have to connect charger to let the battery figure out it's not at 0% anymore.

maxdd commented 3 years ago

I charged the battery a little bit more with my LiPo charger (up to not even 12V, cells are balanced). Now the 4 LEDs are not turning on anymore when i press the button but the BQ30Z55 is alive and i can launch the commands normally. Have you ever encountered this issue?

maxdd commented 3 years ago

@mefistotelis when you service the cells do you normally de-solder the red pole before charging them? Given the fact that opening the cover battery is really a pain in the ass i was wondering whether it is sufficient to drill some holes on the side to have access to the poles of the package

mefistotelis commented 3 years ago

When charging overdischarged cells without replacing, I did drilled one hole at front to charge it. The hole was for "PACK+", as "PACK-" is always on the connector.

maxdd commented 3 years ago

According to this https://github.com/o-gs/dji-firmware-tools/wiki/WM220-Battery-Intelligent-Board#external-connector-of-the-battery

PACK+ is on the connector, but are they all bridge together? Does this mean i shall drill on PACK- (black cable)?

mefistotelis commented 3 years ago

Ok yeah I used wrong names.. On the wiki, what I named "GND" is the "PACK-". And for "PACK+" - you should drill to "BAT+" instead. I drilled on the flat surface below the connector.

maxdd commented 3 years ago

What is PACK+ on the connector then? Do you also disconnect the 4-pin VSENSE connector while charging it?

usmanimtiaz63 commented 2 years ago

Hi, @mefistotelis , I have recovered one of my two laptop batteries using this tool. However the other one has SS=1 and I am unable to recover it. Is there a method to reset SS to 0?

mefistotelis commented 2 years ago

Not sure what exactly you mean. Seal State 0 usually means Unsealed, 1 Sealed. Though that may probably change between chips. Ways of Unsealing change as well - the script currently supports chips with two different unsealing methods: by integer password and by SHA password.

EDIT: Oh, on the chips for which we've published support scripts, SS is Safety Status. Anyway, read the "Technical Reference" of your chip for some details on it.

usmanimtiaz63 commented 2 years ago

Yes SS is safety status, My chip is bq30z55 in Toshiba Satellite laptop.

I tried to use trigger command by passing SafetyStatus (it was't available in trigger-list but added somewhere in code) to it like we pass PermanentFailureReset. However it ended up with python struct error that required argument is not integer at https://github.com/o-gs/dji-firmware-tools/blob/master/comm_sbs_bqctrl.py#L1420 so I replaced it with https://github.com/o-gs/dji-firmware-tools/blob/master/comm_sbs_bqctrl.py#L1424 then it returned with failure that "could not read error_code from battery" at function "i2c_rwdr" and no success.

However after connecting battery input directly to output for a while, its alive now.

cesaralcaide commented 8 months ago

EDIT: to usmanimtiaz63: "connecting battery input directly to output", can you explain detailed, please?

usmanimtiaz63 commented 8 months ago

can you explain detailed, please?

Its old story, If I remember correctly its connecting input and output of bq30z55 to same battery, as there was no hope. bq30z55 was visible alive after that however dead again and finally had to find a replacement.

cesaralcaide commented 8 months ago

can you explain detailed, please?

Its old story, If I remember correctly its connecting input and output of bq30z55 to same battery, as there was no hope. bq30z55 was visible alive after that however dead again and finally had to find a replacement.

Ok, thank you for the replay. It is very strange