This commit is contained in:
hamza 2024-07-24 21:00:27 +03:00
parent 3edafc58cc
commit 035ca511f6
7 changed files with 118 additions and 63 deletions

View File

@ -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
- 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
-

View File

@ -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();

View File

@ -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 <stdint.h>
#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];

View File

@ -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 */

View File

@ -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;

View File

@ -9,26 +9,37 @@
#include <stdint.h>
#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;
}
}

View File

@ -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;