Added temperature hysteresis for charge and discharge. Added separate command for fault state

This commit is contained in:
Yury Shuvakin
2023-03-26 23:44:40 +03:00
parent f24e206582
commit 714bf3ae8c
5 changed files with 107 additions and 27 deletions

View File

@@ -601,6 +601,7 @@ typedef enum {
COMM_GET_GSM_DATA, COMM_GET_GSM_DATA,
COMM_GET_GSM_DEFAULT_DATA, COMM_GET_GSM_DEFAULT_DATA,
COMM_SET_GSM_DATA, COMM_SET_GSM_DATA,
COMM_GET_FAULT_STATE,
} COMM_PACKET_ID; } COMM_PACKET_ID;
typedef enum { typedef enum {

View File

@@ -110,9 +110,13 @@ typedef struct {
uint8_t preChargeDesired; uint8_t preChargeDesired;
uint8_t disChargeDesired; uint8_t disChargeDesired;
uint8_t disChargeLCAllowed; uint8_t disChargeLCAllowed;
bool disChargeOverMaxTemperature;
bool disChargeOverMinTemperature;
uint8_t chargeDesired; uint8_t chargeDesired;
uint8_t chargePFETDesired; uint8_t chargePFETDesired;
uint8_t chargeAllowed; uint8_t chargeAllowed;
bool chargeOverMaxTemperature;
bool chargeOverMinTemperature;
uint8_t coolingDesired; uint8_t coolingDesired;
uint8_t coolingAllowed; uint8_t coolingAllowed;
uint8_t safetyOverCANHCSafeNSafe; uint8_t safetyOverCANHCSafeNSafe;

View File

@@ -1096,6 +1096,7 @@ void transmitCan1Packet()
uint8_t data1[8] = {0x45}; uint8_t data1[8] = {0x45};
CAN_Transmit(300, data1, 8, &hcan1); CAN_Transmit(300, data1, 8, &hcan1);
can1_transmit_clock = TIM_Clock;
return; return;
CAN_TxHeaderTypeDef header; CAN_TxHeaderTypeDef header;
@@ -2044,7 +2045,7 @@ int main(void)
//MX_CAN1_Init(); //MX_CAN1_Init();
//MX_CAN2_Init(); //MX_CAN2_Init();
// CAN_SetSpeed(CAN_SPD_100, &hcan1); CAN_SetSpeed(CAN_SPD_100, &hcan1);
//HAL_GPIO_WritePin(HL4_GPIO_Port, HL4_Pin, 1); //HAL_GPIO_WritePin(HL4_GPIO_Port, HL4_Pin, 1);
@@ -2290,7 +2291,7 @@ int main(void)
// If there is new data handle SoC estimation // If there is new data handle SoC estimation
// mainWatchDogReset(); // mainWatchDogReset();
// transmitCan1Packet(); transmitCan1Packet();
//transmitCan2Packet(); //transmitCan2Packet();
outputControl(); outputControl();

View File

@@ -528,6 +528,11 @@ void modCommandsProcessPacket(unsigned char *data, unsigned int len) {
modCommandsSendBuffer[ind++] = packet_id; modCommandsSendBuffer[ind++] = packet_id;
modCommandsSendPacket(modCommandsSendBuffer, ind); modCommandsSendPacket(modCommandsSendBuffer, ind);
break; break;
case COMM_GET_FAULT_STATE:
ind = 0;
modCommandsSendBuffer[ind++] = COMM_GET_FAULT_STATE;
libBufferAppend_uint16(modCommandsSendBuffer, (uint16_t)modCommandsGeneralState->faultState, &ind);
modCommandsSendPacket(modCommandsSendBuffer, ind);
default: default:
break; break;
} }

View File

@@ -123,6 +123,11 @@ void modPowerElectronicsInit(modPowerElectronicsPackStateTypedef *packState, mod
modPowerElectronicsPackStateHandle->powerDownDesired = false; modPowerElectronicsPackStateHandle->powerDownDesired = false;
modPowerElectronicsPackStateHandle->powerOnLongButtonPress = false; modPowerElectronicsPackStateHandle->powerOnLongButtonPress = false;
modPowerElectronicsPackStateHandle->disChargeOverMaxTemperature = false;
modPowerElectronicsPackStateHandle->disChargeOverMinTemperature = false;
modPowerElectronicsPackStateHandle->chargeOverMaxTemperature = false;
modPowerElectronicsPackStateHandle->chargeOverMinTemperature = false;
for (uint8_t tempPointer = 0; tempPointer < NoOfTempSensors; ++tempPointer) for (uint8_t tempPointer = 0; tempPointer < NoOfTempSensors; ++tempPointer)
{ {
modPowerElectronicsPackStateHandle->temperatures[tempPointer] = 0; modPowerElectronicsPackStateHandle->temperatures[tempPointer] = 0;
@@ -399,101 +404,165 @@ void modPowerElectronicsCallMonitorsCalcBalanceResistorArray(void) {
} }
} }
void modPowerElectronicsSubTaskVoltageWatch(void) { void modPowerElectronicsSubTaskVoltageWatch(void)
{
static bool lastdisChargeLCAllowed = false; static bool lastdisChargeLCAllowed = false;
static bool lastChargeAllowed = false; static bool lastChargeAllowed = false;
//modPowerElectronicsCellMonitorsReadVoltageFlags(&hardUnderVoltageFlags,&hardOverVoltageFlags); //modPowerElectronicsCellMonitorsReadVoltageFlags(&hardUnderVoltageFlags,&hardOverVoltageFlags);
modPowerElectronicsCalculateCellStats(); modPowerElectronicsCalculateCellStats();
if(modPowerElectronicsPackStateHandle->packOperationalCellState != PACK_STATE_ERROR_HARD_CELLVOLTAGE && modPowerElectronicsPackStateHandle->packOperationalCellState != PACK_STATE_ERROR_TEMPERATURE) { if (modPowerElectronicsPackStateHandle->packOperationalCellState != PACK_STATE_ERROR_HARD_CELLVOLTAGE && modPowerElectronicsPackStateHandle->packOperationalCellState != PACK_STATE_ERROR_TEMPERATURE)
{
// Handle soft cell voltage limits & temperatures // Handle soft cell voltage limits & temperatures
//Discharge disable //Discharge disable
if(modPowerElectronicsPackStateHandle->cellVoltageLow <= modPowerElectronicsGeneralConfigHandle->cellLCSoftUnderVoltage) { if (modPowerElectronicsPackStateHandle->cellVoltageLow <= modPowerElectronicsGeneralConfigHandle->cellLCSoftUnderVoltage)
{
modPowerElectronicsPackStateHandle->disChargeLCAllowed = false; modPowerElectronicsPackStateHandle->disChargeLCAllowed = false;
modPowerElectronicsDisChargeLCRetryLastTick = HAL_GetTick(); modPowerElectronicsDisChargeLCRetryLastTick = HAL_GetTick();
modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_CELL_SOFT_UNDER_VOLTAGE; modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_CELL_SOFT_UNDER_VOLTAGE;
} }
if(modPowerElectronicsPackStateHandle->tempBatteryHigh >= modPowerElectronicsGeneralConfigHandle->allowedTempBattDischargingMax){ const float minTempDisChargeThreshold = modPowerElectronicsPackStateHandle->disChargeOverMinTemperature ?
modPowerElectronicsGeneralConfigHandle->allowedTempBattDischargingMin + 10 :
modPowerElectronicsGeneralConfigHandle->allowedTempBattDischargingMin;
const float maxTempDisChargeThreshold = modPowerElectronicsPackStateHandle->disChargeOverMaxTemperature ?
modPowerElectronicsGeneralConfigHandle->allowedTempBattDischargingMax - 10 :
modPowerElectronicsGeneralConfigHandle->allowedTempBattDischargingMax;
if (modPowerElectronicsPackStateHandle->tempBatteryHigh >= maxTempDisChargeThreshold)
{
modPowerElectronicsPackStateHandle->disChargeLCAllowed = false; modPowerElectronicsPackStateHandle->disChargeLCAllowed = false;
modPowerElectronicsPackStateHandle->disChargeOverMinTemperature = false;
modPowerElectronicsPackStateHandle->disChargeOverMaxTemperature = true;
modPowerElectronicsDisChargeLCRetryLastTick = HAL_GetTick(); modPowerElectronicsDisChargeLCRetryLastTick = HAL_GetTick();
modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_DISCHARGE_OVER_TEMP_CELLS; modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_DISCHARGE_OVER_TEMP_CELLS;
} }
if(modPowerElectronicsPackStateHandle->tempBatteryLow <= modPowerElectronicsGeneralConfigHandle->allowedTempBattDischargingMin){ if (modPowerElectronicsPackStateHandle->tempBatteryLow <= minTempDisChargeThreshold)
{
modPowerElectronicsPackStateHandle->disChargeLCAllowed = false; modPowerElectronicsPackStateHandle->disChargeLCAllowed = false;
modPowerElectronicsPackStateHandle->disChargeOverMinTemperature = true;
modPowerElectronicsPackStateHandle->disChargeOverMaxTemperature = false;
modPowerElectronicsDisChargeLCRetryLastTick = HAL_GetTick(); modPowerElectronicsDisChargeLCRetryLastTick = HAL_GetTick();
modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_DISCHARGE_UNDER_TEMP_CELLS; modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_DISCHARGE_UNDER_TEMP_CELLS;
} }
//Charge disable //Charge disable
if(modPowerElectronicsPackStateHandle->cellVoltageHigh >= modPowerElectronicsGeneralConfigHandle->cellSoftOverVoltage) { if (modPowerElectronicsPackStateHandle->cellVoltageHigh >= modPowerElectronicsGeneralConfigHandle->cellSoftOverVoltage)
{
modPowerElectronicsPackStateHandle->chargeAllowed = false; modPowerElectronicsPackStateHandle->chargeAllowed = false;
modPowerElectronicsChargeRetryLastTick = HAL_GetTick(); modPowerElectronicsChargeRetryLastTick = HAL_GetTick();
modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_CELL_SOFT_OVER_VOLTAGE; modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_CELL_SOFT_OVER_VOLTAGE;
} }
const float minTempChargeThreshold = modPowerElectronicsPackStateHandle->chargeOverMinTemperature ?
modPowerElectronicsGeneralConfigHandle->allowedTempBattChargingMin + 10 :
modPowerElectronicsGeneralConfigHandle->allowedTempBattChargingMin;
const float maxTempChargeThreshold = modPowerElectronicsPackStateHandle->chargeOverMaxTemperature ?
modPowerElectronicsGeneralConfigHandle->allowedTempBattChargingMax - 10 :
modPowerElectronicsGeneralConfigHandle->allowedTempBattChargingMax;
if( modPowerElectronicsPackStateHandle->tempBatteryHigh >= modPowerElectronicsGeneralConfigHandle->allowedTempBattChargingMax) { if (modPowerElectronicsPackStateHandle->tempBatteryHigh >= maxTempChargeThreshold)
{
modPowerElectronicsPackStateHandle->chargeAllowed = false; modPowerElectronicsPackStateHandle->chargeAllowed = false;
modPowerElectronicsPackStateHandle->chargeOverMinTemperature = false;
modPowerElectronicsPackStateHandle->chargeOverMaxTemperature = true;
modPowerElectronicsChargeRetryLastTick = HAL_GetTick(); modPowerElectronicsChargeRetryLastTick = HAL_GetTick();
modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_CHARGE_OVER_TEMP_CELLS; modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_CHARGE_OVER_TEMP_CELLS;
} }
if(modPowerElectronicsPackStateHandle->tempBatteryLow <= modPowerElectronicsGeneralConfigHandle->allowedTempBattChargingMin) { if (modPowerElectronicsPackStateHandle->tempBatteryLow <= minTempChargeThreshold)
{
modPowerElectronicsPackStateHandle->chargeAllowed = false; modPowerElectronicsPackStateHandle->chargeAllowed = false;
modPowerElectronicsPackStateHandle->chargeOverMinTemperature = true;
modPowerElectronicsPackStateHandle->chargeOverMaxTemperature = false;
modPowerElectronicsChargeRetryLastTick = HAL_GetTick(); modPowerElectronicsChargeRetryLastTick = HAL_GetTick();
modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_CHARGE_UNDER_TEMP_CELLS; modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_CHARGE_UNDER_TEMP_CELLS;
} }
//Enable discharge //Enable discharge
if(modPowerElectronicsPackStateHandle->cellVoltageLow >= (modPowerElectronicsGeneralConfigHandle->cellLCSoftUnderVoltage + modPowerElectronicsGeneralConfigHandle->hysteresisDischarge) && modPowerElectronicsPackStateHandle->tempBatteryHigh <= modPowerElectronicsGeneralConfigHandle->allowedTempBattDischargingMax && modPowerElectronicsPackStateHandle->tempBatteryLow >= modPowerElectronicsGeneralConfigHandle->allowedTempBattDischargingMin) { if (modPowerElectronicsPackStateHandle->cellVoltageLow >= (modPowerElectronicsGeneralConfigHandle->cellLCSoftUnderVoltage + modPowerElectronicsGeneralConfigHandle->hysteresisDischarge) &&
if(modDelayTick1ms(&modPowerElectronicsDisChargeLCRetryLastTick,modPowerElectronicsGeneralConfigHandle->timeoutDischargeRetry)){ modPowerElectronicsPackStateHandle->tempBatteryHigh <= maxTempDisChargeThreshold &&
modPowerElectronicsPackStateHandle->tempBatteryLow >= minTempDisChargeThreshold)
{
if (modDelayTick1ms(&modPowerElectronicsDisChargeLCRetryLastTick, modPowerElectronicsGeneralConfigHandle->timeoutDischargeRetry))
{
modPowerElectronicsPackStateHandle->disChargeLCAllowed = true; modPowerElectronicsPackStateHandle->disChargeLCAllowed = true;
modPowerElectronicsPackStateHandle->disChargeOverMinTemperature = false;
modPowerElectronicsPackStateHandle->disChargeOverMaxTemperature = false;
modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_NONE; modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_NONE;
} }
} }
//Enable charge //Enable charge
if(modPowerElectronicsPackStateHandle->cellVoltageHigh <= (modPowerElectronicsGeneralConfigHandle->cellSoftOverVoltage - modPowerElectronicsGeneralConfigHandle->hysteresisCharge) && modPowerElectronicsPackStateHandle->tempBatteryHigh <= modPowerElectronicsGeneralConfigHandle->allowedTempBattChargingMax && modPowerElectronicsPackStateHandle->tempBatteryLow >= modPowerElectronicsGeneralConfigHandle->allowedTempBattChargingMin) { if (modPowerElectronicsPackStateHandle->cellVoltageHigh <= (modPowerElectronicsGeneralConfigHandle->cellSoftOverVoltage - modPowerElectronicsGeneralConfigHandle->hysteresisCharge) &&
if(modDelayTick1ms(&modPowerElectronicsChargeRetryLastTick,modPowerElectronicsGeneralConfigHandle->timeoutChargeRetry)){ modPowerElectronicsPackStateHandle->tempBatteryHigh <= maxTempChargeThreshold &&
modPowerElectronicsPackStateHandle->tempBatteryLow >= minTempChargeThreshold)
{
if (modDelayTick1ms(&modPowerElectronicsChargeRetryLastTick, modPowerElectronicsGeneralConfigHandle->timeoutChargeRetry))
{
modPowerElectronicsPackStateHandle->chargeAllowed = true; modPowerElectronicsPackStateHandle->chargeAllowed = true;
modPowerElectronicsPackStateHandle->chargeOverMinTemperature = false;
modPowerElectronicsPackStateHandle->chargeOverMaxTemperature = false;
modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_NONE; modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_NONE;
} }
} }
//Handle cooling //Handle cooling
if(modPowerElectronicsPackStateHandle->tempBatteryHigh <= modPowerElectronicsGeneralConfigHandle->allowedTempBattCoolingMax && modPowerElectronicsPackStateHandle->tempBatteryLow >= modPowerElectronicsGeneralConfigHandle->allowedTempBattCoolingMin){ if (modPowerElectronicsPackStateHandle->tempBatteryHigh <= modPowerElectronicsGeneralConfigHandle->allowedTempBattCoolingMax &&
modPowerElectronicsPackStateHandle->tempBatteryLow >= modPowerElectronicsGeneralConfigHandle->allowedTempBattCoolingMin)
{
modPowerElectronicsPackStateHandle->coolingAllowed = false; modPowerElectronicsPackStateHandle->coolingAllowed = false;
}else{ }
else
{
modPowerElectronicsPackStateHandle->coolingAllowed = true; modPowerElectronicsPackStateHandle->coolingAllowed = true;
}; };
} }
// Handle hard cell voltage limits // Handle hard cell voltage limits
if(modPowerElectronicsVoltageSenseError || modPowerElectronicsPackStateHandle->cellVoltageHigh > modPowerElectronicsGeneralConfigHandle-> cellHardOverVoltage || modPowerElectronicsPackStateHandle->cellVoltageLow < modPowerElectronicsGeneralConfigHandle-> cellHardUnderVoltage || (modPowerElectronicsPackStateHandle->packVoltage > modPowerElectronicsGeneralConfigHandle->noOfCellsSeries*modPowerElectronicsGeneralConfigHandle->cellHardOverVoltage)) { if (modPowerElectronicsVoltageSenseError ||
if(modPowerElectronicsUnderAndOverVoltageErrorCount++ > modPowerElectronicsGeneralConfigHandle->maxUnderAndOverVoltageErrorCount){ modPowerElectronicsPackStateHandle->cellVoltageHigh > modPowerElectronicsGeneralConfigHandle-> cellHardOverVoltage ||
modPowerElectronicsPackStateHandle->cellVoltageLow < modPowerElectronicsGeneralConfigHandle-> cellHardUnderVoltage ||
modPowerElectronicsPackStateHandle->packVoltage > modPowerElectronicsGeneralConfigHandle->noOfCellsSeries * modPowerElectronicsGeneralConfigHandle->cellHardOverVoltage)
{
if (modPowerElectronicsUnderAndOverVoltageErrorCount++ > modPowerElectronicsGeneralConfigHandle->maxUnderAndOverVoltageErrorCount)
{
modPowerElectronicsPackStateHandle->packOperationalCellState = PACK_STATE_ERROR_HARD_CELLVOLTAGE; modPowerElectronicsPackStateHandle->packOperationalCellState = PACK_STATE_ERROR_HARD_CELLVOLTAGE;
modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_MAX_UVP_OVP_ERRORS; modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_MAX_UVP_OVP_ERRORS;
} }
modPowerElectronicsPackStateHandle->disChargeLCAllowed = false; modPowerElectronicsPackStateHandle->disChargeLCAllowed = false;
modPowerElectronicsPackStateHandle->chargeAllowed = false; modPowerElectronicsPackStateHandle->chargeAllowed = false;
}else }
else
{
modPowerElectronicsUnderAndOverVoltageErrorCount = 0; modPowerElectronicsUnderAndOverVoltageErrorCount = 0;
}
// Handle temperature limits // Handle temperature limits
if(modPowerElectronicsPackStateHandle->tempBatteryHigh > (modPowerElectronicsGeneralConfigHandle->allowedTempBattDischargingMax + 10.0f) || modPowerElectronicsPackStateHandle->tempBatteryLow < (modPowerElectronicsGeneralConfigHandle->allowedTempBattDischargingMin - 10.0f)) { if (modPowerElectronicsPackStateHandle->tempBatteryHigh > (modPowerElectronicsGeneralConfigHandle->allowedTempBattDischargingMax + 10.0f) ||
if(modPowerElectronicsUnderAndOverTemperatureErrorCount++ > modPowerElectronicsGeneralConfigHandle->maxUnderAndOverTemperatureErrorCount){ modPowerElectronicsPackStateHandle->tempBatteryLow < (modPowerElectronicsGeneralConfigHandle->allowedTempBattDischargingMin - 10.0f))
{
if(modPowerElectronicsUnderAndOverTemperatureErrorCount++ > modPowerElectronicsGeneralConfigHandle->maxUnderAndOverTemperatureErrorCount)
{
modPowerElectronicsPackStateHandle->packOperationalCellState = PACK_STATE_ERROR_TEMPERATURE; modPowerElectronicsPackStateHandle->packOperationalCellState = PACK_STATE_ERROR_TEMPERATURE;
modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_MAX_UVT_OVT_ERRORS; modPowerElectronicsPackStateHandle->faultState = FAULT_CODE_MAX_UVT_OVT_ERRORS;
} }
modPowerElectronicsPackStateHandle->disChargeLCAllowed = false; modPowerElectronicsPackStateHandle->disChargeLCAllowed = false;
modPowerElectronicsPackStateHandle->chargeAllowed = false; modPowerElectronicsPackStateHandle->chargeAllowed = false;
}else }
else
{
modPowerElectronicsUnderAndOverTemperatureErrorCount = 0; modPowerElectronicsUnderAndOverTemperatureErrorCount = 0;
}
// update outputs directly if needed // update outputs directly if needed
if((lastChargeAllowed != modPowerElectronicsPackStateHandle->chargeAllowed) || (lastdisChargeLCAllowed != modPowerElectronicsPackStateHandle->disChargeLCAllowed)) { if (lastChargeAllowed != modPowerElectronicsPackStateHandle->chargeAllowed ||
lastdisChargeLCAllowed != modPowerElectronicsPackStateHandle->disChargeLCAllowed)
{
lastChargeAllowed = modPowerElectronicsPackStateHandle->chargeAllowed; lastChargeAllowed = modPowerElectronicsPackStateHandle->chargeAllowed;
lastdisChargeLCAllowed = modPowerElectronicsPackStateHandle->disChargeLCAllowed; lastdisChargeLCAllowed = modPowerElectronicsPackStateHandle->disChargeLCAllowed;
modPowerElectronicsUpdateSwitches(); modPowerElectronicsUpdateSwitches();