Close
0%
0%

JBD BMS protocol

In this project, I tried to deal with the BMS communication protocol, which is compatible with the JBDTool program.

Public Chat
Similar projects worth following
In this project, I tried to deal with the BMS communication protocol, which is compatible with the JBDTool program.
A part of the protocol is available from the manufacturer.
But this part describes only a request for common data.
The process of configuring BMS and writing / reading logs in the documentation is missed.

Standard requests to BMS in the form of a request for basic data, secondary voltage and names in the ASCII line are parsed in the file (from the manufacturer).
I will not analyze them.

Further, the deals with undocumented features in the form of reading / writing EEPROM.

BMS class.zip

See https://hackaday.io/project/162806-jbd-bms-protocol/log/166769-code-for-working-with-bms

x-zip-compressed - 6.15 kB - 08/08/2019 at 06:18

Download

LH_SP10S006 20180612-1.hex

Firmware for BMS

hex - 62.11 kB - 06/04/2019 at 08:23

Download

x-zip-compressed - 2.17 MB - 12/14/2018 at 10:16

Download

Adobe Portable Document Format - 635.63 kB - 12/14/2018 at 09:43

Preview
Download

x-zip-compressed - 325.18 kB - 12/14/2018 at 09:43

Download

View all 6 files

  • Overcurrent protection

    rahmaevao10/07/2019 at 11:01 0 comments

    BMS have very interested overcurrent protection.

    BMS have three levels overcurrent protection:

    - slow protection;

    - fast protection;

    - short-circuit protection.

    For using this protections checkbox "Doubled Overcurrent and short-circuit value" mast be reset (see below).

    So how do you set up all three levels?

    1. Set correct "Current Res" value.

    At BMS installed shunts (see below).

    The program window JbdTools necessary to set the resistance of the current-measuring stage. But if you just calculate this resistance formula conductivities addition, it does not mean that you set the correct value of the shunt. In my BMS sets 1 mOhm, but only 0.5 mOhm current calculation is correct.

    So you need to:

    - set the calculated resistance;

    - load the battery for a specific load;

    - to adjust the value of the shunt in the program so that the current was determined correctly.

    2. Set DSGOC

    This value must correspond to the maximum current that flows for a long time (> 1 sec). In my case it is 30 A, 3 seconds.

    3. Set DSGOC2

    Current value  set in the field voltage.

    If I want a quick disconnect from the current of 50 A at 8 ms, then I install DSGOC2 I*R = 50 A * 0.0005 Ohm = 25 mV.

    3. Set SC Value

    It is short-circuit value (see paragraph 3).

    Set the time of the reset of this error (see below).

  • Wrote a library for Arduino

    rahmaevao09/05/2019 at 14:04 0 comments
  • Code for working with BMS

    rahmaevao08/08/2019 at 06:40 0 comments

    Introduction

    The files below I used in my project to communicate with BMS.
    My project uses two types of BMS: JBD or Lithuanian BMS.

    I am using STM32F303.

    My implementation is very sophisticated. Therefore, I did not post it for a long time. But the people are asking, so hold on.

    How i worked with this class?

    1. Attached the header file:

    #include "BMS.hpp"

    2. I did create global variables (in main.cpp):

    //For BMS
    HAL_StatusTypeDef bufferHalStatus = HAL_OK;
    uint8_t * requestMessage = new uint8_t[9];
    uint8_t lenRequestMessage = 7; ///< 7 For China BMS. Change if used Tiny BMS. 
    uint8_t * dmaBuffer;
    uint16_t lenDmaBuffer = 34; ///< length message from Tiny BMS
    BmsData batteryData;

     2. Enabled DMA Fill and Timer Interrupts.

    // For BMS
    	HAL_NVIC_DisableIRQ(DMA1_Channel6_IRQn);
    	HAL_NVIC_DisableIRQ(TIM6_DAC_IRQn);

     3. In the thread, the BMS has defined a message that will be sent after a response from the BMS.

    	requestMessage[0] = 0xDD;
    	requestMessage[1] = 0xA5;
    	requestMessage[2] = 0x03;
    	requestMessage[3] = 0x00;
    	requestMessage[4] = 0xFF;
    	requestMessage[5] = 0xFD;
    	requestMessage[6] = 0x77;

     4. Defined a dma buffer, created an instance of the BMS class. Launched the mode of automatic sending requests to BMS.

    dmaBuffer = new uint8_t[lenDmaBuffer];
    BMS bms;
    bms.autoSenderModeEnable();

    5. I read data with bms in a loop. In the case of a successful read (batteryData.halStatus == HAL_OK), you can work with data.

    for (;;) { batteryData = bms.readBmsData(); if (batteryData.halStatus == HAL_OK) { telemetryMessage.ADC_battery = batteryData.chargePercentage; /*.more.*/ } else { /* error */ }

    6. Below stm32f3xx_it.c file:

    /**
     * @brief Handler interrupt DMA1 channel6.
     * 
     * 1. Resets timer 6 for reset timeout event BMS UART BUS.
     * 2. Sends a new request to the BMS.
     */
    void DMA1_Channel6_IRQHandler(void) {
    
    	if (((DMA1->ISR) & DMA_ISR_TCIF6) != 0)
    	{
    		// 1. Resets timer 6 for reset timeout event BMS UART BUS.
    		bufferHalStatus = HAL_OK;
    		timeout500msAlreadyBeen = 0;
    		__HAL_TIM_SET_COUNTER(&htim6, 0);
    
    		// 2. Sends a new request to the BMS
    		bmsInterruptedCountRxDMA++;
    		//HAL_UART_Transmit(&huartBMS, requestMessage, lenRequestMessage, 100);
    	}
    	
    	HAL_DMA_IRQHandler(&hdma_usart2_rx);
    }
    /**
     * @brief Handler interrupt TIM6
     * 
     * Intended for set timeout event if blank UART more 1 sec.
     * After 0,5 с - send requset message.
     * Thereafter 0,5 sec set timeout.
     */
    void TIM6_DAC_IRQHandler(void) {
        HAL_TIM_IRQHandler(&htim6);
        
        if (timeout500msAlreadyBeen == 1) {
            bufferHalStatus = HAL_TIMEOUT;
        }
        
        bmsInterruptedCountTim6++;
    //    HAL_UART_Transmit(&huartBMS, requestMessage, lenRequestMessage, 100);
    //    HAL_UART_Receive_DMA(&huartBMS, dmaBuffer, lenDmaBuffer);
        timeout500msAlreadyBeen = 1;
    }
    
    

     If you have questions, then write in telegram.

  • BMS current consumption

    rahmaevao06/11/2019 at 11:52 0 comments

    I measured the currents of the consumption of the BMS itself.

    The results are below.

    ModeCurrent consumption
    The load is not connected, the LED on the board is not on.70 uA, and every five seconds 150..200 uA
    The load is not connected, the LED on the board is not on, BMS connected to PC through UART100 uA, and every five seconds 200 uA
    LED on the board is on18 mA

  • Change of firmware

    rahmaevao06/04/2019 at 08:25 0 comments

    The manufacturer shared the firmware for BMS from 12.06.2018. We really liked this firmware, as it works adequately with the button. The images below show how the firmware changes. Firmware In here.

View all 5 project logs

  • 1
    Process of reading configs (EEPROM)

    1. To switch to the EEPROM mode, you need to send the first packet to write to the zero register of the value: 0x56 0x78.

    In response, zeros arrive (see figure below).

    2. Then read (0xA5) registers from 0x10 to 0xA2 and 0xAA.

    In figure below shown meaning registers (but I'm not sure about the accuracy of everything).

    3. After reading, the write command to the register 0x01.

    Without the start packet and the final, an error (0x80) is returned when the configuration registers are requested or changed.

  • 2
    Error counter

    1 BMS stores in memory the fact of errors that can be configured in JBD Tools.
    It is useful to read them every time you start a device with BMS to analyze past events. After reading them, you need to pack them up so that next time you can only read actual events.


    Reading is possible only in EEPROM reading mode (see step 1).

    2 The command to read the register 0xDD 0xA5 0xAA 0x00 0xFF 0x56 0x77.
    Register that stores error counters 0xAA. The table below shows the meaning of each byte in sending a reply from BMS to the request 0xAA. High byte in front.

    Byte in the packageMeaning
    4-5SC count
    6-7CHGOC (Charge Over Current)
    8-9DSGOC (Discharge Over Current)
    10-11COVP (Cell Over Voltage Protection)
    12-13CUVP (Cell Under Voltage Protection)
    14-15CHGOT (Charge Over Temperature)
    16-17CHGUT (Charge Under Temperature)
    18-19DSGOT (Discharge Over Temperature)
    20-21DSGUT (Discharge Under Temperature)
    22-23POVP (Pack Over Voltage Protection)
    24-25PUVP (Pack Under Voltage Protection)

    3 Reset errors
    Error reset occurs by writing to configuration register 0x01.
    The package: 0xDD 0x5A, 0x01, 0x02, 0x28, 0x28, 0xFF, 0xAD, 0x77.

View all instructions

Enjoy this project?

Share

Discussions

Passerby77 wrote 11/02/2019 at 18:34 point

Hello Friend, pease i need help, i  need flash BMS JBD_SP15S020.hex my bms don't work, because I do update to my bms, But I made a flash of another bms LH_SP10S006 20180612-1.hex i find it here 

https://hackaday.io/project/162806-jbd-bms-protocol in this page in file

Naw my bms stop working, cannot read the cell voltages, i need flash This BMS, ( JBD-SP15S020 : 30A 48V ), Please Help.

  Are you sure? yes | no

rahmaevao wrote 12/08/2019 at 21:04 point

You must contact the seller. My firmware was provided by my seller.

  Are you sure? yes | no

Dennis wrote 07/18/2019 at 00:07 point

Hello there. This page has been very helpful, thank you! But I have one problem. I updated my bms firmware and now it cannot read the cell voltages. Any idea whats wrong?

  Are you sure? yes | no

rahmaevao wrote 08/07/2019 at 06:34 point

Hello, my friend.
Hmm. What is your BMS. What firmware file?

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates