From 035ca511f6c6caed6590aff31935dc33f410ead4 Mon Sep 17 00:00:00 2001 From: hamza Date: Wed, 24 Jul 2024 21:00:27 +0300 Subject: [PATCH] V1.16 --- CHANGELOG.txt | 12 +++++- Core/Inc/can.h | 3 ++ Core/Src/can.c | 87 +++++++++++++++++++++++++-------------- Core/Src/main.c | 3 +- Core/Src/soc_estimation.c | 8 ++-- Core/Src/state_machine.c | 66 ++++++++++++++++++----------- Core/Src/status_LED.c | 2 +- 7 files changed, 118 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index c9c4405..46aff6d 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -98,4 +98,14 @@ V1.15 - 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 +- added different blink speeds for different states + +V1.16 +- TIME_BLINK_SLOW: 1000 -> 2000 +- moved can.c timers to can.h to detec +- added logging of cells on can ID 0x503 +- eeprom gets initialized in main +- startup delay is now 500ms +- removed a zero from ocv_soc_pairs +- changed precharge and discharge timers to 8000ms +- \ No newline at end of file diff --git a/Core/Inc/can.h b/Core/Inc/can.h index 6cb8369..e836515 100644 --- a/Core/Inc/can.h +++ b/Core/Inc/can.h @@ -13,9 +13,12 @@ #include "can-halal.h" #include "state_machine.h" +extern uint32_t can_status_timer, can_log_timer, can_timeout_timer; + void can_init(CAN_HandleTypeDef* hcan); void can_handle_send_status(); +void can_handle_send_log(); void can_handle_dump(); diff --git a/Core/Src/can.c b/Core/Src/can.c index 73e5e76..2084e94 100644 --- a/Core/Src/can.c +++ b/Core/Src/can.c @@ -8,25 +8,39 @@ #include "can.h" #include "AMS_HighLevel.h" #include "PWM_control.h" +#include "TMP1075.h" #include "can-halal.h" #include "eeprom.h" #include "soc_estimation.h" #include "state_machine.h" +#include "stm32f3xx_hal.h" #include "stm32f3xx_hal_def.h" #include -#define CAN_ID_IN 0x501 -#define CAN_ID_OUT 0x502 -#define CAN_STATUS_FREQ 1000 -#define CAN_DUMP_FREQ 10; +#define CAN_ID_IN 0x501 +#define CAN_ID_OUT 0x502 +#define CAN_ID_LOGGING 0x503 +// Every X ms, send message +#define CAN_STATUS_FREQ 1000 +#define CAN_LOGGING_FREQ 200 +#define CAN_DUMP_FREQ 10 + +// Max time to wait for CAN messages. If we reach it then we target state is set to STATE_ERROR. +#define CAN_TIMEOUT 5000 + +uint8_t id_to_log; uint8_t last_message[8]; -static uint32_t can_delay_manager = 0; + void can_init(CAN_HandleTypeDef* hcan) { ftcan_init(hcan); ftcan_add_filter(CAN_ID_IN, 0xFFF); last_message[0] = -1; last_message[1] = -1; + can_status_timer = HAL_GetTick() + CAN_STATUS_FREQ; + can_log_timer = HAL_GetTick() + CAN_LOGGING_FREQ; + can_timeout_timer = HAL_GetTick() + CAN_TIMEOUT; + id_to_log =0; } /* @@ -68,31 +82,44 @@ bit 52-63 (12b): empty */ void can_handle_send_status() { - if (can_delay_manager > HAL_GetTick()) + if (can_status_timer > HAL_GetTick()) return; - else - can_delay_manager = HAL_GetTick() + CAN_STATUS_FREQ; + else { + uint8_t data[8] = {}; + can_status_timer = HAL_GetTick() + CAN_STATUS_FREQ; - uint8_t data[8] = {}; - 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]; - //} + uint8_t id_highest_temp = 0; + uint16_t highest_temp = 0; + sm_check_battery_temperature(&id_highest_temp, &highest_temp); - 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[3] = ((int) current_soc); // 8 bit state of charge - 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)); - + 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[3] = ((int) current_soc); // 8 bit state of charge + 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)); + } +} + +void can_handle_send_log(){ + if (can_log_timer > HAL_GetTick()) + return; + else { + uint8_t data[8] = {}; + can_log_timer = HAL_GetTick() + CAN_LOGGING_FREQ; + data[0] = id_to_log; + data[1] = module.cellVoltages[id_to_log] >> 8; + data[2] = module.cellVoltages[id_to_log]; + data[3] = tmp1075_temps[id_to_log] >> 4; + ftcan_transmit(CAN_ID_LOGGING, data, 4); + id_to_log++; + if (id_to_log == 13) + id_to_log = 0; +} /* 021E 30 0232 50 @@ -144,10 +171,7 @@ void can_handle_dump() { uint8_t* data = {}; HAL_StatusTypeDef status = HAL_OK; while (status == HAL_OK){ - if (can_delay_manager > HAL_GetTick()) - continue; - else - can_delay_manager = HAL_GetTick() + CAN_DUMP_FREQ; + HAL_Delay(2); eeprom_read(data, 62); for (int i = 0; i < (EEPROM_MEMORY_SIZE-8)/8; i += 8) { ftcan_transmit(CAN_ID_OUT, &data[i], 8); @@ -170,6 +194,7 @@ void ftcan_msg_received_cb(uint16_t id, size_t datalen, const uint8_t *data){ } if (id == 0x501 && datalen == 2){ + can_timeout_timer = HAL_GetTick() + CAN_TIMEOUT; if (last_message[0] != data[0] || last_message[1] != data[1]){ last_message[0] = data[0]; last_message[1] = data[1]; diff --git a/Core/Src/main.c b/Core/Src/main.c index 7a4762c..77d6b7a 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -140,8 +140,9 @@ int main(void) soc_init(); status_led_init(&htim4, &htim4, &htim4); sm_program_powerground(); + eeprom_init(&hi2c2); AMS_Loop(); - uint32_t startup_timer = 1000 + HAL_GetTick(); + uint32_t startup_timer = 500 + HAL_GetTick(); while (startup_timer > HAL_GetTick()); /* USER CODE END 2 */ diff --git a/Core/Src/soc_estimation.c b/Core/Src/soc_estimation.c index 68d35f1..e364c26 100644 --- a/Core/Src/soc_estimation.c +++ b/Core/Src/soc_estimation.c @@ -11,10 +11,10 @@ // https://www.desmos.com/calculator/mm22vmxl2x ocv_soc_pair_t OCV_SOC_PAIRS[] = { - {30000, 0.00f}, {33500, 10.00f}, {34500, 20.00f}, - {35000, 30.00f}, {35300, 40.00f}, {35700, 50.00f}, - {36000, 60.00f}, {36300, 70.00f}, {37000, 80.00f}, - {38000, 90.00f}, {41300, 100.00f} + {3000, 0.00f}, {3350, 10.00f}, {3450, 20.00f}, + {3500, 30.00f}, {3530, 40.00f}, {3570, 50.00f}, + {3600, 60.00f}, {3630, 70.00f}, {3700, 80.00f}, + {3800, 90.00f}, {4130, 100.00f} }; float current_soc; diff --git a/Core/Src/state_machine.c b/Core/Src/state_machine.c index bf0379c..55d4e34 100644 --- a/Core/Src/state_machine.c +++ b/Core/Src/state_machine.c @@ -9,26 +9,37 @@ #include #include "AMS_HighLevel.h" #include "PWM_control.h" +#include "can.h" +#include "eeprom.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 -#define PRECHARGE_DURATION 5000 // ms +#define PRECHARGE_DURATION 8000 // ms // Time to wait for discharge -#define DISCHARGE_DURATION 5000 // ms -// Time to wait for charger voltage before going to TS_ERROR -#define MAX_CHARGING_CHECK_DURATION 2000 // ms +#define DISCHARGE_DURATION 8000 // ms // 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 5000 // waiting time between to eeprom writes #define EEPROM_WRITE_FREQ 1000 - +// how delay between steps of 5 -> 15ms * (100/5) = 300ms #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 +/* +10 +20 +30 +40 +50 +60 +70 +80 +90 +100 +*/ + bool programming_mode; bool debugging_mode; @@ -42,8 +53,7 @@ float base_offset = 0; uint32_t error_timer; uint32_t precharge_timer; uint32_t discharge_timer; -uint32_t CAN_timer; -uint32_t EEPROM_timer; +uint32_t eeprom_timer; uint32_t powerground_softstart_timer; uint32_t powerground_calibration_timer; @@ -58,15 +68,28 @@ void sm_init(){ state.current_state = STATE_INACTIVE; state.target_state = STATE_INACTIVE; state.error_source = 0; - precharge_timer = discharge_timer = powerground_calibration_timer = error_timer = 0; - CAN_timer = HAL_GetTick() + 5000; - + precharge_timer = discharge_timer = powerground_calibration_timer = error_timer = eeprom_timer = 0; programming_mode = 0; debugging_mode = 0; } -void sm_update(){ +void sm_update(){ + + 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.19; + RELAY_BAT_SIDE_VOLTAGE = module.auxVoltages[3] * 15.19; // the calculation says the factor is 11. 11.711 yields the better result + + if (can_timeout_timer < HAL_GetTick()) + state.current_state = state.target_state = STATE_ERROR; + /* + if (eeprom_timer < HAL_GetTick()){ + eeprom_write_status(); + eeprom_timer = HAL_GetTick() + EEPROM_WRITE_FREQ; + } + */ can_handle_send_status(); + can_handle_send_log(); sm_check_errors(); sm_precharge_discharge_manager(); //sm_calibrate_powerground(); @@ -74,14 +97,7 @@ void sm_update(){ tmp1075_measure(); status_led_update(); soc_update(); - - //if (CAN_timer < HAL_GetTick()) - // state.current_state = state.target_state = STATE_ERROR; - 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.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 @@ -116,7 +132,6 @@ void sm_update(){ void sm_handle_ams_in(const uint8_t *data){ if (programming_mode == 1 && (state.current_state == STATE_READY || state.current_state == STATE_ACTIVE)){ PWM_powerground_control(data[1]); } - CAN_timer = HAL_GetTick() + CAN_TIMEOUT; switch (data[0]) { case 0x00: if (state.current_state != STATE_INACTIVE){ @@ -145,8 +160,9 @@ void sm_handle_ams_in(const uint8_t *data){ } break; case 0xF1: // EEPROM + break; if (state.current_state == STATE_INACTIVE) - can_handle_dump(); + // can_handle_dump(); break; case 0xFF: // EMERGENCY SHUTDOWN state.current_state = STATE_DISCHARGE; @@ -243,9 +259,9 @@ void sm_program_powerground(){ } void sm_eeprom_write_status(){ - if (EEPROM_timer < HAL_GetTick()){ + if (eeprom_timer < HAL_GetTick()){ eeprom_write_status(); - EEPROM_timer = HAL_GetTick() + EEPROM_WRITE_FREQ; + eeprom_timer = HAL_GetTick() + EEPROM_WRITE_FREQ; } } diff --git a/Core/Src/status_LED.c b/Core/Src/status_LED.c index 0357339..9e0fe18 100644 --- a/Core/Src/status_LED.c +++ b/Core/Src/status_LED.c @@ -26,7 +26,7 @@ F_CLK = 16 MHz */ #define STATUS_LED_ARR 255 -#define TIME_BLINK_SLOW 1000 +#define TIME_BLINK_SLOW 2000 #define TIME_BLINK_FAST 500 TIM_HandleTypeDef* red;