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
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.