Skip to main content
Associate III
December 13, 2023
Solved

BMS63EN Diagnostics - How to?

  • December 13, 2023
  • 3 replies
  • 9418 views

I had a fine working setup with BMS63 for some hours. 

Than cell 12 showed 0V and the fault light in the ISO SPI came up. 

A short measurement showed, the cell was indeed empty (I am testing with very old cells). 

After replacing the cell cell 12 still shows 0V, and the fault light is still on. 

If I measure with the testpins on the BMS63EN itself, I can see that there is a cell voltage. So something went wrong with the BMS63EN I think. 

 

Do I need to reset the error/fault? In the manual its stated that software diagnostics need to be run in such case. But..how? 

And shouldn´t that be all reset after a complete disconnect and new init? 

 

Best answer by ATROI

Hi Orbiter,

In order to print on Serial terminal diagnostic info please replace main_core0 function with:

void main_core0(void) {

  char message[15];

  AEK_POW_BMS63EN_module_t AEK_POW_BMS63EN_BatteryModule;

  uint8_t cell_idx = 0;

  /* Enable Interrupts */

  irqIsrEnable();

  sd_lld_start(&SD5,&serial_config_BMS_serial);

 

  /* Application main loop.*/

  for ( ; ; ) {

 

              if((osalThreadGetMilliseconds()%100)==0){

                            AEK_POW_BMS63EN_BatteryModule = AEK_POW_BMS63EN_GetModule(i_device_disp);

 

                                    //SOC Elaboration Done

                                    sprintf(message, "DEV:%d         \n", (int)(i_device_disp+1));

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    //Printing SOC

                                    for(cell_idx = AEK_POW_BMS63EN_CELL1; cell_idx <= AEK_POW_BMS63EN_CELL14; cell_idx ++){

                                                sprintf(message, "T%.2d:%.3f      ", cell_idx+1, AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Pack_CellTemperatureNTC[cell_idx]);

                                                            sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    }

                                    sprintf(message,"              \n");

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    //Printing Bal

                                    for(cell_idx = AEK_POW_BMS63EN_CELL1; cell_idx <= AEK_POW_BMS63EN_CELL14; cell_idx ++){

                                                            sprintf(message, "B%.2d:%.3d        ", cell_idx+1, AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Pack_Bal_cmd[cell_idx]);

                                                            sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    }

                                    sprintf(message,"              \n");

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    //Printing Voltage

                                    for(cell_idx = AEK_POW_BMS63EN_CELL1; cell_idx <= AEK_POW_BMS63EN_CELL14; cell_idx ++){

                                                            sprintf(message, "V%.2d:%.3f      ", cell_idx+1, AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Pack_CellVoltage[cell_idx]);

                                                            sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    }

                                    sprintf(message,"              \n");

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    //Printing Current

                                    sprintf(message, "C:%.4f        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Pack_Current);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    //Printing Current

                                    sprintf(message, "F1:%d        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Fault1_data);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    sprintf(message, "F2:%d        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Fault2_data);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    sprintf(message, "VOV:%d        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_VcellOV_Fault_data);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    sprintf(message, "VIUV:%d        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_VcellUV_Fault_data);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    sprintf(message, "OVL:%d        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_OverLatch);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    sprintf(message, "GPIOF:%d        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_GPIOOTUT_Fault_data);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                        }

  }

 

}

Moreover, please, make sure that cell 9 is connected to cell 12.

 

Best Regards,

AutoDevKit Team.

3 replies

OrbiterAuthor
Associate III
December 13, 2023

Follow up... how would one output any diagnostic error? 

I can´t get the RLA Serial example to output any meaningful text- so I am a bit puzzled on how to easily use the console as well. 

Is there a part II of the UM "getting started with BMS63EN"? There are so many things going on in the basic example.. The doxygen documents are not explaining, aren´t they? And the L9963E datasheet is on bit level. Maybe I look in the wrong places? 

Max VIZZINI
Technical Moderator
December 14, 2023

Hi Michael,

The debug is done with a console terminal (e.g. teraterm) on a PC connected via USB to the AEK-MCU-C4MLIT1.

After plugging the USB cable, you should see a COM port enabled in your PC drivers. If not, there could be some issues with your FTDI drivers in your PC. 

In the BMS example, the second core is devoted to send the signal to the terminal via the serial COM port. If you look at the code, there is the reading of the data and diagnostic errors (faults 1, faults 2, etc.) and "printing" on the serial port.

This will work only if the battery are properly connected otherwise the second core will see only empty values.

Therefore, the question becomes how did you connect the battery cells? Did you make sure that the first two and the last two are connected as indicated in the user manual?

Please be reminded that L9963E is supplied from the same batteries, therefore if the connection is not correct the ISOSPI communication will not work.

I am not sure what you mean with "old cells"... I hope they are not out from the accepted values.

Best Regards,

AutoDevKit Team

OrbiterAuthor
Associate III
December 14, 2023

Hi Max!

Terminal? Is this the same as the use of the serial terminal in Autodevkit? COM Port and 115200? That is what I used so far. I just checked with Putty, I get the same output there. Picture attached. 

I looked for the diagnostic reading in the code, but I could not find it... I just found that the main() calls AEK_POW_BMS63EN_Start_Mgn_exec(); which also runs  if(AEK_COM_ISOSPI_GetFault(ISOSPI_DEV0)){
AEK_POW_BMS63EN_DIAG_Measurement();. 

But that function just writes the fault data into AEK_POW_BMS63EN_BatteryModules[AEK_POW_BMS63EN_DEVICE(dev)].AEK_POW_BMS63EN_Fault1_data
}

But in the main on core 0 this data is never outputed:

  if((osalThreadGetMilliseconds()%100)==0){
    AEK_POW_BMS63EN_BatteryModule = AEK_POW_BMS63EN_GetModule(i_device_disp);
 
//SOC Elaboration Done
sprintf(message, "DEV:%d     \n", (int)(i_device_disp+1));
sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));
//Printing SOC
for(cell_idx = AEK_POW_BMS63EN_CELL1; cell_idx <= AEK_POW_BMS63EN_CELL14; cell_idx ++){
sprintf(message, "S%.2d:%.3d    ", cell_idx+1, (int)((AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Pack_SOC[cell_idx]) * 100));
sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));
}
sprintf(message,"          \n");
sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));
//Printing Bal
for(cell_idx = AEK_POW_BMS63EN_CELL1; cell_idx <= AEK_POW_BMS63EN_CELL14; cell_idx ++){
sprintf(message, "B%.2d:%.3d    ", cell_idx+1, AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Pack_Bal_cmd[cell_idx]);
sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));
}
sprintf(message,"          \n");
sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));
//Printing Voltage
for(cell_idx = AEK_POW_BMS63EN_CELL1; cell_idx <= AEK_POW_BMS63EN_CELL14; cell_idx ++){
sprintf(message, "V%.2d:%.3f  ", cell_idx+1, AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Pack_CellVoltage[cell_idx]);
sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));
}
sprintf(message,"          \n");
sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));
//Printing Current
sprintf(message, "C:%.4f    \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Pack_Current);
sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

 

Or- did I miss something? (probably)

Cell connection: 

I have 12 LiFePo4 Cells, series connected. 

I left Cell 10 and Cell11 out on the BMS63EN, so 1-9 and 12-14 are connected to the 12 cells on my test system. 

Old cells...means old cells, they are all charged up but quite used and some have quite a low capacity left - which is what makes charging and draining a bit faster. But yes-they all are between 2.9 and 3.1V charged right now 

LED:

I have the green LED on the BMS on

Green, Blue, Yellow and Red on ISO SPI

Green blinking on the outmost right LED (LED2) on MCLIT4

ATROI
ATROIBest answer
ST Employee
December 15, 2023

Hi Orbiter,

In order to print on Serial terminal diagnostic info please replace main_core0 function with:

void main_core0(void) {

  char message[15];

  AEK_POW_BMS63EN_module_t AEK_POW_BMS63EN_BatteryModule;

  uint8_t cell_idx = 0;

  /* Enable Interrupts */

  irqIsrEnable();

  sd_lld_start(&SD5,&serial_config_BMS_serial);

 

  /* Application main loop.*/

  for ( ; ; ) {

 

              if((osalThreadGetMilliseconds()%100)==0){

                            AEK_POW_BMS63EN_BatteryModule = AEK_POW_BMS63EN_GetModule(i_device_disp);

 

                                    //SOC Elaboration Done

                                    sprintf(message, "DEV:%d         \n", (int)(i_device_disp+1));

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    //Printing SOC

                                    for(cell_idx = AEK_POW_BMS63EN_CELL1; cell_idx <= AEK_POW_BMS63EN_CELL14; cell_idx ++){

                                                sprintf(message, "T%.2d:%.3f      ", cell_idx+1, AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Pack_CellTemperatureNTC[cell_idx]);

                                                            sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    }

                                    sprintf(message,"              \n");

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    //Printing Bal

                                    for(cell_idx = AEK_POW_BMS63EN_CELL1; cell_idx <= AEK_POW_BMS63EN_CELL14; cell_idx ++){

                                                            sprintf(message, "B%.2d:%.3d        ", cell_idx+1, AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Pack_Bal_cmd[cell_idx]);

                                                            sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    }

                                    sprintf(message,"              \n");

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    //Printing Voltage

                                    for(cell_idx = AEK_POW_BMS63EN_CELL1; cell_idx <= AEK_POW_BMS63EN_CELL14; cell_idx ++){

                                                            sprintf(message, "V%.2d:%.3f      ", cell_idx+1, AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Pack_CellVoltage[cell_idx]);

                                                            sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    }

                                    sprintf(message,"              \n");

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    //Printing Current

                                    sprintf(message, "C:%.4f        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Pack_Current);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    //Printing Current

                                    sprintf(message, "F1:%d        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Fault1_data);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    sprintf(message, "F2:%d        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_Fault2_data);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    sprintf(message, "VOV:%d        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_VcellOV_Fault_data);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    sprintf(message, "VIUV:%d        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_VcellUV_Fault_data);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    sprintf(message, "OVL:%d        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_OverLatch);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                                    sprintf(message, "GPIOF:%d        \n", AEK_POW_BMS63EN_BatteryModule.AEK_POW_BMS63EN_GPIOOTUT_Fault_data);

                                    sd_lld_write(&SD5, (uint8_t *)message, (uint16_t)(sizeof(message)/sizeof(message[0])));

                        }

  }

 

}

Moreover, please, make sure that cell 9 is connected to cell 12.

 

Best Regards,

AutoDevKit Team.

Max VIZZINI
Technical Moderator
December 16, 2023

Hi Michael,

There is a full help file for each component with all available functions.

It would make no sense to build a driver and to force the driver user to go change single registers.

right-click on the component, AEK-POW-BMS63EN --> documents --> .chm file (see attached pictures).

In addition, there is UM3185

 https://www.st.com/resource/en/user_manual/um3185-getting-started-with-the-aekpowbms63en-battery-management-system-bms-evaluation-board-based-on-the-l9963e-stmicroelectronics.pdf

At page 40 / paragraph 10 you also have the list of main APIs.

I understand that it is easier to ask than read a manual but it in this way it becomes more a co-development than a support...

Thanks.

AutoDevKit Teams

OrbiterAuthor
Associate III
December 17, 2023

Hi Max,

it´s not that I am not trying, I really don´t get behind it. 

My BMS is in latched state and has a lit up fault LED and can´t read voltages from cell 12. At least it reads 0V where it should read a voltage inside the defined range. 

So I hope thats because its latched. 

No matter how often I read, I can´t find the API to reset the latch. 

Or does your bms example do all of this by default and the error persist and I need to look somewhere else? 

 

OrbiterAuthor
Associate III
December 17, 2023

I just rebuild the hardware of my test-BMS to narrow it down. 

I removed another two cells and connected the remaining cells sense wires together as described in the Datasheet. 

According to the cfg.c the changes are correct:

/* List of the L9963 Driver cell status structures. */
static AEK_POW_BMS63EN_cell_stack_state_t AEK_POW_BMS63EN_cell_stack_state_dev1 = {
    { AEK_POW_BMS63EN_CELL1, AEK_POW_BMS63EN_CELL_CONNECTED, AEK_POW_BMS63EN_CELL_ENABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN },
    { AEK_POW_BMS63EN_CELL2, AEK_POW_BMS63EN_CELL_CONNECTED, AEK_POW_BMS63EN_CELL_ENABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN },
    { AEK_POW_BMS63EN_CELL3, AEK_POW_BMS63EN_CELL_CONNECTED, AEK_POW_BMS63EN_CELL_ENABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN },
    { AEK_POW_BMS63EN_CELL4, AEK_POW_BMS63EN_CELL_CONNECTED, AEK_POW_BMS63EN_CELL_ENABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN },
    { AEK_POW_BMS63EN_CELL5, AEK_POW_BMS63EN_CELL_CONNECTED, AEK_POW_BMS63EN_CELL_ENABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN },
    { AEK_POW_BMS63EN_CELL6, AEK_POW_BMS63EN_CELL_CONNECTED, AEK_POW_BMS63EN_CELL_ENABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN },
    { AEK_POW_BMS63EN_CELL7, AEK_POW_BMS63EN_CELL_CONNECTED, AEK_POW_BMS63EN_CELL_ENABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN },
    { AEK_POW_BMS63EN_CELL8, AEK_POW_BMS63EN_CELL_CONNECTED, AEK_POW_BMS63EN_CELL_ENABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN },
    { AEK_POW_BMS63EN_CELL9, AEK_POW_BMS63EN_CELL_UNCONNECTED, AEK_POW_BMS63EN_CELL_DISABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN },
    { AEK_POW_BMS63EN_CELL10, AEK_POW_BMS63EN_CELL_UNCONNECTED, AEK_POW_BMS63EN_CELL_DISABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN },
    { AEK_POW_BMS63EN_CELL11, AEK_POW_BMS63EN_CELL_UNCONNECTED, AEK_POW_BMS63EN_CELL_DISABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN },
    { AEK_POW_BMS63EN_CELL12, AEK_POW_BMS63EN_CELL_UNCONNECTED, AEK_POW_BMS63EN_CELL_DISABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN },
    { AEK_POW_BMS63EN_CELL13, AEK_POW_BMS63EN_CELL_CONNECTED, AEK_POW_BMS63EN_CELL_ENABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN },
    { AEK_POW_BMS63EN_CELL14, AEK_POW_BMS63EN_CELL_CONNECTED, AEK_POW_BMS63EN_CELL_ENABLED, AEK_POW_BMS63EN_CELL_PCB_UNKNOWN }
};
 
But over serial I get:
DEV:1
V01:2.909 V02:3.118 V03:3.088 V04:3.096 V05:3.093 V06:3.133 V07:2.996 V08:3.106 V09:0.000 V10:0.000 V11:0.000 V12:0.000 V13:3.010 V14:3.013
C:0.0003
Fault 1:8 Fault 2:0 VCell 0V:0 VCell UV:2304 Overlatch:1 GPIO Faults:0
Error detected: Device State: 7
 
->4 cells are inactive (odd and even)
->All cells are between 0.5 and 5V
->Fault1 8 shows an error on the lowest device
-> VcellUV 2304 shows undervoltage on cell  9 and 12 
Both, 9 and 12 are inactive, but they still raise overlatch and fault line- Are you sure this is not a bug?