From 3edafc58cc6da3b1e87bc5fd8d3e97356326fde1 Mon Sep 17 00:00:00 2001 From: hamza Date: Sun, 21 Jul 2024 23:53:48 +0300 Subject: [PATCH] V1.15 --- CHANGELOG.txt | 7 ++++++ Core/Inc/state_machine.h | 6 ++++-- Core/Src/AMS_HighLevel.c | 7 ++++-- Core/Src/TMP1075.c | 36 +++++++++++++++++++++++++------ Core/Src/can.c | 16 ++++++++------ Core/Src/main.c | 7 +++--- Core/Src/soc_estimation.c | 5 +++-- Core/Src/state_machine.c | 45 ++++++++++++++++++++++----------------- Core/Src/status_LED.c | 16 +++++++++----- 9 files changed, 99 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index a8f6f90..c9c4405 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -92,3 +92,10 @@ V1.14 V1.15 - changed max temperature to 55 from 60 according to the data sheet of the cell - changed ocv_soc_pairs to something close to the curve of other swaytronics batteries +- the can messages uses roundf to round the values +- made the pwm spool up in 300ms +- increased MIN_CELL_VOLTAGE +- the STM32 wait 1s for the BMS to finish its measurements +- added debugging mode (turns off error checking) +- added and ERROR_LATCH_TIME +- added different blink speeds for different states \ No newline at end of file diff --git a/Core/Inc/state_machine.h b/Core/Inc/state_machine.h index bf8d7e1..53baafe 100644 --- a/Core/Inc/state_machine.h +++ b/Core/Inc/state_machine.h @@ -8,8 +8,6 @@ #ifndef INC_STATE_MACHINE_H #define INC_STATE_MACHINE_H -#include -#include #include "ADBMS_LL_Driver.h" #include #include @@ -19,6 +17,10 @@ #include #include +#include +#include +#include + typedef enum { // states -> 3 bit. valid transitions: (all could transition to error) STATE_INACTIVE, // INACTIVE -> PRECHARGE, CHARGING, ERROR STATE_PRECHARGE, // PRECHARGE -> INACTIVE, READY, DISCHARGE, ERROR diff --git a/Core/Src/AMS_HighLevel.c b/Core/Src/AMS_HighLevel.c index 56fd2bc..ce6ea28 100755 --- a/Core/Src/AMS_HighLevel.c +++ b/Core/Src/AMS_HighLevel.c @@ -25,7 +25,7 @@ uint8_t packetChecksumFails = 0; uint8_t deviceSleeps = 0; #define MAX_DEVICE_SLEEP 3 //TODO: change to correct value #define MAX_CELL_VOLTAGE 4200 //change to 4200 -#define MIN_CELL_VOLTAGE 3000 //change to 3000 +#define MIN_CELL_VOLTAGE 3200 //change to 3000 #define CELL_VOLTAGE_DIFF_BALANCING 20 //max difference between lowest cell and any other cell amsState currentAMSState = AMSDEACTIVE; @@ -201,9 +201,12 @@ uint8_t AMS_Balancing_Loop() { amsConfigBalancing((1 << i), 0x0); } } - if (num_of_cells_to_balance == 0) + if (num_of_cells_to_balance == 0){ + balancingActive = 0; return 0; + } + balancingActive = 1; amsStartBalancing(0); return 0; } diff --git a/Core/Src/TMP1075.c b/Core/Src/TMP1075.c index 6dc54d6..0709cfa 100644 --- a/Core/Src/TMP1075.c +++ b/Core/Src/TMP1075.c @@ -1,6 +1,11 @@ #include "TMP1075.h" +#include "state_machine.h" + +#define MAX_TEMP_DISCHARGING ((int16_t)(59 / 0.0625f)) +#define MIN_TEMP_DISCHARGING ((int16_t)(-20 / 0.0625f)) +#define MAX_TEMP_CHARGING ((int16_t)(45 / 0.0625f)) +#define MIN_TEMP_CHARGING ((int16_t)(0 / 0.0625f)) -#define MAX_TEMP ((int16_t)(55 / 0.0625f)) #define MAX_FAILED_TEMP 2 //TODO: change value for compliance with the actual number of sensors // TODO: "change value for compliance with the actual number of sensors", change temps to float @@ -33,18 +38,35 @@ HAL_StatusTypeDef tmp1075_measure() { int err = 0; int temp_error = 0; for (int i = 0; i < N_TEMP_SENSORS; i++) { - if (tmp1075_sensor_read(i, &tmp1075_temps[i]) != HAL_OK || - (tmp1075_temps[i] & 0x000F) != 0) { + if (tmp1075_sensor_read(i, &tmp1075_temps[i]) != HAL_OK || (tmp1075_temps[i] & 0x000F) != 0) { tmp1075_failed_sensors |= 1 << i; nfailed_temp_sensors++; err = 1; } else { tmp1075_temps[i] >>= 4; - //tmp1075_temps[i] = tmp1075_temps[i] * 100/1600; tmp1075_failed_sensors &= ~(1 << i); - if (tmp1075_temps[i] >= MAX_TEMP) { - temp_error = 1; - handle_over_maxtemp(i, tmp1075_temps[i]); + if (state.current_state == STATE_CHARGING || state.current_state == STATE_CHARGING_PRECHARGE){ + if (tmp1075_temps[i] >= MAX_TEMP_CHARGING) { + temp_error = 1; + handle_over_maxtemp(i, tmp1075_temps[i]); + } + } else { + if (tmp1075_temps[i] >= MAX_TEMP_DISCHARGING) { + temp_error = 1; + handle_over_maxtemp(i, tmp1075_temps[i]); + } + } + + if (state.current_state == STATE_CHARGING || state.current_state == STATE_CHARGING_PRECHARGE){ + if (tmp1075_temps[i] <= MIN_TEMP_CHARGING) { + temp_error = 1; + handle_over_maxtemp(i, tmp1075_temps[i]); + } + } else { + if (tmp1075_temps[i] <= MIN_TEMP_DISCHARGING) { + temp_error = 1; + handle_over_maxtemp(i, tmp1075_temps[i]); + } } } } diff --git a/Core/Src/can.c b/Core/Src/can.c index af3d11e..73e5e76 100644 --- a/Core/Src/can.c +++ b/Core/Src/can.c @@ -6,6 +6,7 @@ */ #include "can.h" +#include "AMS_HighLevel.h" #include "PWM_control.h" #include "can-halal.h" #include "eeprom.h" @@ -76,15 +77,18 @@ void can_handle_send_status() { uint8_t id_highest_temp = 0; uint16_t highest_temp = 0; sm_check_battery_temperature(&id_highest_temp, &highest_temp); - + //uint32_t packvoltage = 0; + //for (int i = 0; i < numberofCells; i++) { + // packvoltage += module.cellVoltages[i]; + //} data[0] = ((state.current_state << 4) | (current_powerground_status >> 4)); // 1 bit emptyy | 3 bit state | 4 bit powerground data[1] = ((current_powerground_status << 4) | (state.error_source >> 4)); // 4 bit powerground | 4 bit error - data[2] = ((state.error_source << 4)); // 4 bit error | 4 bit state of charge + data[2] = ((state.error_source << 4)); // 4 bit error | 4 bit state of charge data[3] = ((int) current_soc); // 8 bit state of charge - data[4] = ((RELAY_BAT_SIDE_VOLTAGE / 1000)); // 8 bit battery voltage - data[5] = ((RELAY_ESC_SIDE_VOLTAGE / 1000)); // 8 bit Inverter voltage - data[6] = ((CURRENT_MEASUREMENT / 1000)); // 8 bit Current + data[4] = (roundf(RELAY_BAT_SIDE_VOLTAGE / 1000.0)); // 8 bit battery voltage + data[5] = (roundf(RELAY_ESC_SIDE_VOLTAGE / 1000.0)); // 8 bit Inverter voltage + data[6] = (roundf(CURRENT_MEASUREMENT / 1000.0)); // 8 bit Current data[7] = ((highest_temp) >> 4); // 8 bit highest cell temperature //data[7] = state.error_source; ftcan_transmit(CAN_ID_OUT, data, sizeof(data)); @@ -164,7 +168,7 @@ void ftcan_msg_received_cb(uint16_t id, size_t datalen, const uint8_t *data){ can_handle_recieve_command(data); return; } - + if (id == 0x501 && datalen == 2){ if (last_message[0] != data[0] || last_message[1] != data[1]){ last_message[0] = data[0]; diff --git a/Core/Src/main.c b/Core/Src/main.c index 41626cc..7a4762c 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -29,6 +29,7 @@ #include "soc_estimation.h" #include "state_machine.h" #include +#include #include "TMP1075.h" #include "errors.h" #include "stm32f302xc.h" @@ -139,9 +140,9 @@ int main(void) soc_init(); status_led_init(&htim4, &htim4, &htim4); sm_program_powerground(); - //AMS_Loop(); - //int ttrgrtd = 2000 + HAL_GetTick(); - //while (ttrgrtd > HAL_GetTick()); + AMS_Loop(); + uint32_t startup_timer = 1000 + HAL_GetTick(); + while (startup_timer > HAL_GetTick()); /* USER CODE END 2 */ /* Infinite loop */ diff --git a/Core/Src/soc_estimation.c b/Core/Src/soc_estimation.c index ca26474..68d35f1 100644 --- a/Core/Src/soc_estimation.c +++ b/Core/Src/soc_estimation.c @@ -1,4 +1,5 @@ #include "soc_estimation.h" +#include #define SOC_ESTIMATION_NO_CURRENT_THRESH 1000 // mA #define SOC_ESTIMATION_NO_CURRENT_TIME 100000 // ms @@ -8,7 +9,6 @@ #define MAX_CELL_VOLTAGE 4130 -#warning TODO // https://www.desmos.com/calculator/mm22vmxl2x ocv_soc_pair_t OCV_SOC_PAIRS[] = { {30000, 0.00f}, {33500, 10.00f}, {34500, 20.00f}, @@ -47,8 +47,9 @@ void soc_update() { last_current_time == 0) { // Assume we're measuring OCV if there's been no current for a while (or // we've just turned on the battery). + uint8_t id = 0; uint16_t min_voltage = 0; - sm_check_battery_temperature(0, &min_voltage); + sm_check_battery_temperature(&id, &min_voltage); current_soc = soc_for_ocv(min_voltage); } else { // Otherwise, use the current counter to update SoC diff --git a/Core/Src/state_machine.c b/Core/Src/state_machine.c index 555c10f..bf0379c 100644 --- a/Core/Src/state_machine.c +++ b/Core/Src/state_machine.c @@ -6,8 +6,10 @@ */ #include +#include #include "AMS_HighLevel.h" #include "PWM_control.h" +#include "stm32f3xx_hal.h" // Time to wait after reaching 95% of battery voltage before exiting precharge // Set this to 1000 in scruti to demonstrate the voltage on the multimeter @@ -19,13 +21,16 @@ // Time to wait between closing relays #define RELAY_CLOSE_WAIT 10 // ms // Max time to wait for CAN messages. If we reach it then we emergency shutdown. -#define CAN_TIMEOUT 1000 +#define CAN_TIMEOUT 5000 // waiting time between to eeprom writes #define EEPROM_WRITE_FREQ 1000 -#define POWERGROUND_SOFTSTART_INCREMENT_DELAY 3 +#define POWERGROUND_SOFTSTART_INCREMENT_DELAY 15 +// after errors are cleared wait for ERROR_LATCH_TIME ms before returning to inactive mode +#define ERROR_LATCH_TIME 10000 //ms bool programming_mode; +bool debugging_mode; StateHandle state; int32_t RELAY_BAT_SIDE_VOLTAGE; @@ -34,6 +39,7 @@ int32_t CURRENT_MEASUREMENT; bool CURRENT_MEASUREMENT_ON; float base_offset = 0; +uint32_t error_timer; uint32_t precharge_timer; uint32_t discharge_timer; uint32_t CAN_timer; @@ -52,17 +58,18 @@ void sm_init(){ state.current_state = STATE_INACTIVE; state.target_state = STATE_INACTIVE; state.error_source = 0; - precharge_timer = discharge_timer = powerground_calibration_timer; + precharge_timer = discharge_timer = powerground_calibration_timer = error_timer = 0; CAN_timer = HAL_GetTick() + 5000; + programming_mode = 0; + debugging_mode = 0; } -#warning change amsState here void sm_update(){ can_handle_send_status(); sm_check_errors(); sm_precharge_discharge_manager(); - sm_calibrate_powerground(); + //sm_calibrate_powerground(); sm_powerground_manager(); tmp1075_measure(); status_led_update(); @@ -70,13 +77,11 @@ void sm_update(){ //if (CAN_timer < HAL_GetTick()) // state.current_state = state.target_state = STATE_ERROR; - CURRENT_MEASUREMENT = (module.auxVoltages[0] > 2494) ? (module.auxVoltages[0] - (2494.0)) * (300.0) : 0; - + CURRENT_MEASUREMENT = (module.auxVoltages[0] > 2495) ? (module.auxVoltages[0] - (2495.0)) * (300.0) : 0; CURRENT_MEASUREMENT_ON = (module.auxVoltages[1] > 2400); - RELAY_ESC_SIDE_VOLTAGE = module.auxVoltages[2] * 15.25; - RELAY_BAT_SIDE_VOLTAGE = module.auxVoltages[3] * 15.25; // the calculation says the factor is 11. 11.711 yields the better result + RELAY_ESC_SIDE_VOLTAGE = module.auxVoltages[2] * 15.19; + RELAY_BAT_SIDE_VOLTAGE = module.auxVoltages[3] * 15.19; // the calculation says the factor is 11. 11.711 yields the better result - switch (state.current_state) { case STATE_INACTIVE: state.current_state = sm_update_inactive(); // monitor only @@ -185,12 +190,12 @@ void sm_powerground_manager(){ } if (powerground_softstart_timer < HAL_GetTick()){ - if (current_powerground_status < target_powerground_status ){ - current_powerground_status++; + if (current_powerground_status < target_powerground_status){ + current_powerground_status += 5; PWM_powerground_softcontrol(); powerground_softstart_timer = HAL_GetTick() + POWERGROUND_SOFTSTART_INCREMENT_DELAY; } else if (current_powerground_status > target_powerground_status) { - current_powerground_status--; + current_powerground_status -= 5; PWM_powerground_softcontrol(); powerground_softstart_timer = HAL_GetTick() + POWERGROUND_SOFTSTART_INCREMENT_DELAY; } @@ -245,7 +250,7 @@ void sm_eeprom_write_status(){ } void sm_check_errors(){ - if (programming_mode == 1) {return;} // to disable error checking + if (programming_mode == 1 || debugging_mode == 1) {return;} // to disable error checking state.error_type.temperature_error = (error_data.error_sources & (1 << 0) || error_data.error_sources & (1 << 1) || error_data.error_sources & (1 << 4)) ? 1 : 0; state.error_type.voltage_error = (error_data.error_sources & (1 << 2)|| error_data.error_sources & (1 << 3)|| error_data.error_sources & (1 << 5) || RELAY_BAT_SIDE_VOLTAGE < 30000) ? 1 : 0; state.error_type.bms_timeout = (error_data.error_sources & (1 << 7)) ? 1 : 0; @@ -256,15 +261,17 @@ void sm_check_errors(){ state.error_type.voltage_missing = (RELAY_BAT_SIDE_VOLTAGE < 1000) ? 1 : 0; - if ( state.error_type.current_error == 1 || state.error_type.current_sensor_missing == 1 || //state.error_type.eeprom_error == 1 || - state.error_type.state_transition_fail == 1 || state.error_type.temperature_error == 1 || state.error_type.voltage_error == 1 || - state.error_type.voltage_missing == 1 || state.error_type.bms_fault == 1 || state.error_type.bms_timeout == 1){ + if (state.error_type.current_error == 1 || state.error_type.current_sensor_missing == 1 || //state.error_type.eeprom_error == 1 || + state.error_type.state_transition_fail == 1 || state.error_type.temperature_error == 1 || state.error_type.voltage_error == 1 || + state.error_type.voltage_missing == 1 || state.error_type.bms_fault == 1 || state.error_type.bms_timeout == 1) + { if (state.current_state != STATE_INACTIVE && state.current_state != STATE_ERROR) state.current_state = STATE_DISCHARGE; state.target_state = STATE_ERROR; PWM_powerground_control(255); - } else if (state.current_state == STATE_ERROR){ - state.target_state = STATE_INACTIVE; + error_timer = HAL_GetTick() + ERROR_LATCH_TIME; + } else if (state.current_state == STATE_ERROR && error_timer < HAL_GetTick()){ + state.target_state = STATE_INACTIVE; } sm_set_error_source(); } diff --git a/Core/Src/status_LED.c b/Core/Src/status_LED.c index b75685a..0357339 100644 --- a/Core/Src/status_LED.c +++ b/Core/Src/status_LED.c @@ -25,9 +25,9 @@ Prescaler: F_CLK = 16 MHz */ -#define STATUS_LED_ARR 255 -#define TIME_BLINK_OFF 100 -#define TIME_BLINK_ON 1000 +#define STATUS_LED_ARR 255 +#define TIME_BLINK_SLOW 1000 +#define TIME_BLINK_FAST 500 TIM_HandleTypeDef* red; TIM_HandleTypeDef* green; @@ -61,12 +61,18 @@ void status_led_update(){ } if (blink_state == 1){ - blink_timer = HAL_GetTick() + TIME_BLINK_OFF; + if (state.current_state == STATE_INACTIVE) + blink_timer = HAL_GetTick() + TIME_BLINK_SLOW/10; + else + blink_timer = HAL_GetTick() + TIME_BLINK_FAST/10; blink_state = 0; status_led_set_color(OFF); return; } else { - blink_timer = HAL_GetTick() + TIME_BLINK_ON; + if (state.current_state == STATE_INACTIVE) + blink_timer = HAL_GetTick() + TIME_BLINK_SLOW; + else + blink_timer = HAL_GetTick() + TIME_BLINK_FAST; blink_state = 1; }