Close

Code for working with BMS

A project log for JBD BMS protocol

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

rahmaevaorahmaevao 08/08/2019 at 06:400 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.

Discussions