From 9e523ccfbee848bb0dbbce945aebdf51969bc120 Mon Sep 17 00:00:00 2001 From: dyldonahue <98500199+dyldonahue@users.noreply.github.com> Date: Wed, 29 Nov 2023 21:24:55 -0500 Subject: [PATCH] sht30 & internal cell comm fault (#62) * ported internal cell comm fault * ported sht30 --------- Co-authored-by: Dylan Donahue --- Core/Inc/analyzer.h | 20 +++++++++++++------- Core/Inc/bmsConfig.h | 5 +++++ Core/Inc/datastructs.h | 3 +++ Core/Inc/segment.h | 3 +++ Core/Inc/stateMachine.h | 2 +- Core/Src/analyzer.c | 15 ++++++++++++--- Core/Src/main.c | 4 ++++ Core/Src/segment.c | 14 ++++++++++---- Core/Src/stateMachine.c | 18 +++++++++++------- 9 files changed, 62 insertions(+), 22 deletions(-) diff --git a/Core/Inc/analyzer.h b/Core/Inc/analyzer.h index 702f040..c83c24b 100644 --- a/Core/Inc/analyzer.h +++ b/Core/Inc/analyzer.h @@ -4,6 +4,7 @@ //#include Replace #include "datastructs.h" #include "segment.h" +#include "sht30.h" /* We want to make sure we aren't doing useless analysis on the same set of data since we are * backfilling segment data */ @@ -11,23 +12,28 @@ //#define MAX_SIZE_OF_HIST_QUEUE 300000U //bytes +/** + * @brief Calculates the PWM required to drive the fans at the current moment in time + * + * @param bmsdata + * @return uint8_t + */ +uint8_t analyzer_calc_fan_pwm(); + /** * @brief Pushes in a new data point if we have waited long enough * * @param data */ -void analyzer_push(acc_data_t* data); +void analyzer_push(acc_data_t* accdata); /** - * @brief Calculates the PWM required to drive the fans at the current moment in time - * - * @param bmsdata - * @return uint8_t + * @brief Create a new object to store the most recent data point for the temp sensor */ -uint8_t analyzer_calc_fan_pwm(); +void analyzer_sht30_init(); /** - * @brief Pointer to the address of the most recent data point + * @brief Pointer to the address of the most recent data point */ extern acc_data_t* bmsdata; diff --git a/Core/Inc/bmsConfig.h b/Core/Inc/bmsConfig.h index 5cf69df..71071cf 100644 --- a/Core/Inc/bmsConfig.h +++ b/Core/Inc/bmsConfig.h @@ -48,10 +48,15 @@ #define OVER_VOLT_TIME 15000 #define LOW_CELL_TIME 15000 #define HIGH_TEMP_TIME 60000 +#define INT_CELL_COMM_TIME 1000 +#define HIGH_INT_TEMP_TIME 0 // TODO SET THIS #define CURR_ERR_MARG 50 // in A * 10 #define DCDC_CURRENT_DRAW 2 // in A, this is generous +//Compute limits +#define MAX_INTERNAL_TEMP 0 // TODO SET THIS + #define CAN_MESSAGE_WAIT 10 #endif \ No newline at end of file diff --git a/Core/Inc/datastructs.h b/Core/Inc/datastructs.h index 5fb35d3..db39a4c 100644 --- a/Core/Inc/datastructs.h +++ b/Core/Inc/datastructs.h @@ -5,6 +5,7 @@ #include #include "bmsConfig.h" #include "timer.h" +#include "sht30.h" /** * @brief Individual chip data @@ -121,6 +122,8 @@ typedef struct { uint16_t boost_setting; bool is_charger_connected; + + sht30_t* sht30_data; } acc_data_t; /** diff --git a/Core/Inc/segment.h b/Core/Inc/segment.h index b16a269..fa843bb 100644 --- a/Core/Inc/segment.h +++ b/Core/Inc/segment.h @@ -5,6 +5,9 @@ #include "bmsConfig.h" #include "datastructs.h" +// global that passes cell comm faults upstream to sm +extern bool cell_comm_fault_status; + /** * @brief Initializes the segments */ diff --git a/Core/Inc/stateMachine.h b/Core/Inc/stateMachine.h index f007520..c9f40fe 100644 --- a/Core/Inc/stateMachine.h +++ b/Core/Inc/stateMachine.h @@ -7,7 +7,7 @@ #include "analyzer.h" #include "timer.h" -#define NUM_FAULTS 8 +#define NUM_FAULTS 9 /** * @brief Returns if we want to balance cells during a particular frame diff --git a/Core/Src/analyzer.c b/Core/Src/analyzer.c index 21049ef..d52bac4 100644 --- a/Core/Src/analyzer.c +++ b/Core/Src/analyzer.c @@ -1,10 +1,13 @@ #include "analyzer.h" #include +#include "stm32f4xx_hal.h" acc_data_t* bmsdata; - acc_data_t* prevbmsdata; +extern I2C_HandleTypeDef hi2c1; + + // clang-format off /** * @brief Mapping Cell temperature to the cell resistance based on the @@ -452,13 +455,13 @@ uint8_t analyzer_calc_fan_pwm() / (2 * 5); } -void analyzer_push(acc_data_t* data) +void analyzer_push(acc_data_t* accdata) { if (prevbmsdata != NULL) free(bmsdata); prevbmsdata = bmsdata; - bmsdata = data; + bmsdata = accdata; disable_therms(); @@ -477,10 +480,16 @@ void analyzer_push(acc_data_t* data) calc_cont_dcl(); calc_cont_ccl(); calc_state_of_charge(); + sht30_get_temp_humid(accdata->sht30_data); is_first_reading_ = false; } +void analyzer_sht30_init(acc_data_t* accdata) +{ + accdata->sht30_data->i2c_handle = &hi2c1; +} + void disable_therms() { int8_t temp_rep_1 = 25; /* Iniitalize to room temp (necessary to stabilize when the BMS first diff --git a/Core/Src/main.c b/Core/Src/main.c index 457e71f..2329d7f 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -198,7 +198,9 @@ int main(void) /* USER CODE BEGIN Init */ compute_set_fault(0); segment_init(); + analyzer_sht30_init(); watchdog_init(); + /* USER CODE END Init */ /* Configure the system clock */ @@ -218,6 +220,7 @@ int main(void) MX_UART4_Init(); MX_USB_OTG_FS_PCD_Init(); MX_I2C1_Init(); + /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ @@ -227,6 +230,7 @@ int main(void) for(;;) { /* Create a dynamically allocated structure */ acc_data_t *acc_data = malloc(sizeof(acc_data_t)); + acc_data->sht30_data = malloc(sizeof(sht30_t)); //acc_data->faultCode = FAULTS_CLEAR; diff --git a/Core/Src/segment.c b/Core/Src/segment.c index 6fe8cd6..6caa8d2 100644 --- a/Core/Src/segment.c +++ b/Core/Src/segment.c @@ -25,8 +25,10 @@ nertimer_t therm_timer; nertimer_t voltage_reading_timer; nertimer_t variance_timer; -int voltage_error = 0; //not faulted -int therm_error = 0; //not faulted +int voltage_error = FAULTS_CLEAR; +int therm_error = FAULTS_CLEAR; + +bool cell_comm_fault_status = false; uint16_t therm_settle_time_ = 0; @@ -69,6 +71,8 @@ void segment_init() local_config[c][5] = 0x00; } push_chip_configuration(); + + cell_comm_fault_status = false; } void select_therm(uint8_t therm) @@ -199,7 +203,7 @@ int pull_voltages() memcpy(segment_data[i].voltage_reading, previous_data[i].voltage_reading, sizeof(segment_data[i].voltage_reading)); } - return 1; + return 1; //error } /* If the read was successful, copy the voltage data */ @@ -223,7 +227,7 @@ int pull_voltages() /* Start the timer between readings if successful */ start_timer(&voltage_reading_timer, VOLTAGE_WAIT_TIME); - return 0; + return 0; /* Read Succesfully */ } int pull_thermistors() @@ -301,6 +305,8 @@ void segment_retrieve_data(chipdata_t databuf[NUM_CHIPS]) * data */ memcpy(previous_data, segment_data, sizeof(chipdata_t) * NUM_CHIPS); + cell_comm_fault_status = (voltage_error || therm_error); + segment_data = NULL; } diff --git a/Core/Src/stateMachine.c b/Core/Src/stateMachine.c index d116cd7..519fb33 100644 --- a/Core/Src/stateMachine.c +++ b/Core/Src/stateMachine.c @@ -206,6 +206,8 @@ uint32_t sm_fault_return(acc_data_t* accData) static nertimer_t ovr_volt_timer = {0}; static nertimer_t low_cell_timer = {0}; static nertimer_t high_temp_timer = {0}; + static nertimer_t int_cell_comm_tmr = {0}; + static nertimer_t int_temp_tmr = {0}; static fault_eval_t* fault_table = NULL; static acc_data_t* fault_data = NULL; @@ -218,13 +220,15 @@ uint32_t sm_fault_return(acc_data_t* accData) // clang-format off // ___________FAULT ID____________ __________TIMER___________ _____________DATA________________ __OPERATOR__ __________________________THRESHOLD____________________________ _______TIMER LENGTH_________ _____________FAULT CODE_________________ ___OPERATOR 2__ _______________DATA 2______________ __THRESHOLD 2__ fault_table[0] = (fault_eval_t) {.id = "Discharge Current Limit", .timer = ovr_curr_timer, .data_1 = fault_data->pack_current, .optype_1 = GT, .lim_1 = (fault_data->discharge_limit + DCDC_CURRENT_DRAW)*10*1.04, .timeout = OVER_CURR_TIME, .code = DISCHARGE_LIMIT_ENFORCEMENT_FAULT, .optype_2 = NOP/* ---------------------------UNUSED------------------- */ }; - fault_table[1] = (fault_eval_t) {.id = "Charge Current Limit", .timer = ovr_chgcurr_timer, .data_1 = fault_data->pack_current, .optype_1 = GT, .lim_1 = (fault_data->charge_limit)*10, .timeout = OVER_CHG_CURR_TIME, .code = CHARGE_LIMIT_ENFORCEMENT_FAULT, .optype_2 = LT, .data_2 = fault_data->pack_current, .lim_2 = 0 }; - fault_table[2] = (fault_eval_t) {.id = "Low Cell Voltage", .timer = undr_volt_timer, .data_1 = fault_data->min_voltage.val, .optype_1 = LT, .lim_1 = MIN_VOLT * 10000, .timeout = UNDER_VOLT_TIME, .code = CELL_VOLTAGE_TOO_LOW, .optype_2 = NOP/* ---------------------------UNUSED-------------------*/ }; - fault_table[3] = (fault_eval_t) {.id = "High Cell Voltage", .timer = ovr_chgvolt_timer, .data_1 = fault_data->max_voltage.val, .optype_1 = GT, .lim_1 = MAX_CHARGE_VOLT * 10000, .timeout = OVER_VOLT_TIME, .code = CELL_VOLTAGE_TOO_HIGH, .optype_2 = NOP/* ---------------------------UNUSED-------------------*/ }; - fault_table[4] = (fault_eval_t) {.id = "High Cell Voltage", .timer = ovr_volt_timer, .data_1 = fault_data->max_voltage.val, .optype_1 = GT, .lim_1 = MAX_VOLT * 10000, .timeout = OVER_VOLT_TIME, .code = CELL_VOLTAGE_TOO_HIGH, .optype_2 = EQ, .data_2 = fault_data->is_charger_connected, .lim_2 = false }; - fault_table[5] = (fault_eval_t) {.id = "High Temp", .timer = high_temp_timer, .data_1 = fault_data->max_temp.val, .optype_1 = GT, .lim_1 = MAX_CELL_TEMP, .timeout = LOW_CELL_TIME, .code = PACK_TOO_HOT, .optype_2 = NOP/* ----------------------------------------------------*/ }; - fault_table[6] = (fault_eval_t) {.id = "Extremely Low Voltage", .timer = low_cell_timer, .data_1 = fault_data->min_voltage.val, .optype_1 = LT, .lim_1 = 900, .timeout = HIGH_TEMP_TIME, .code = LOW_CELL_VOLTAGE, .optype_2 = NOP/* --------------------------UNUSED--------------------*/ }; - fault_table[7] = (fault_eval_t) {.id = NULL}; + fault_table[1] = (fault_eval_t) {.id = "Charge Current Limit", .timer = ovr_chgcurr_timer, .data_1 = fault_data->pack_current, .optype_1 = GT, .lim_1 = (fault_data->charge_limit)*10, .timeout = OVER_CHG_CURR_TIME, .code = CHARGE_LIMIT_ENFORCEMENT_FAULT, .optype_2 = LT, .data_2 = fault_data->pack_current, .lim_2 = 0 }; + fault_table[2] = (fault_eval_t) {.id = "Low Cell Voltage", .timer = undr_volt_timer, .data_1 = fault_data->min_voltage.val, .optype_1 = LT, .lim_1 = MIN_VOLT * 10000, .timeout = UNDER_VOLT_TIME, .code = CELL_VOLTAGE_TOO_LOW, .optype_2 = NOP/* ---------------------------UNUSED-------------------*/ }; + fault_table[3] = (fault_eval_t) {.id = "High Cell Voltage", .timer = ovr_chgvolt_timer, .data_1 = fault_data->max_voltage.val, .optype_1 = GT, .lim_1 = MAX_CHARGE_VOLT * 10000, .timeout = OVER_VOLT_TIME, .code = CELL_VOLTAGE_TOO_HIGH, .optype_2 = NOP/* ---------------------------UNUSED-------------------*/ }; + fault_table[4] = (fault_eval_t) {.id = "High Cell Voltage", .timer = ovr_volt_timer, .data_1 = fault_data->max_voltage.val, .optype_1 = GT, .lim_1 = MAX_VOLT * 10000, .timeout = OVER_VOLT_TIME, .code = CELL_VOLTAGE_TOO_HIGH, .optype_2 = EQ, .data_2 = fault_data->is_charger_connected,.lim_2 = false }; + fault_table[5] = (fault_eval_t) {.id = "High Temp", .timer = high_temp_timer, .data_1 = fault_data->max_temp.val, .optype_1 = GT, .lim_1 = MAX_CELL_TEMP, .timeout = LOW_CELL_TIME, .code = PACK_TOO_HOT, .optype_2 = NOP/* ----------------------------------------------------*/ }; + fault_table[6] = (fault_eval_t) {.id = "Internal Cell Comm Fault",.timer = int_cell_comm_tmr, .data_1 = cell_comm_fault_status, .optype_1 = NEQ,.lim_1 = FAULTS_CLEAR, .timeout = INT_CELL_COMM_TIME, .code = INTERNAL_CELL_COMM_FAULT, .optype_2 = NOP/* --------------------------UNUSED--------------------*/ }; + fault_table[7] = (fault_eval_t) {.id = "Extremely Low Voltage", .timer = low_cell_timer, .data_1 = fault_data->min_voltage.val, .optype_1 = LT, .lim_1 = 900, .timeout = HIGH_TEMP_TIME, .code = LOW_CELL_VOLTAGE, .optype_2 = NOP/* --------------------------UNUSED--------------------*/ }; + fault_table[8] = (fault_eval_t) {.id = "High Internal Temp", .timer = int_temp_tmr, .data_1 =fault_data->sht30_data->temp, .optype_1 = GT, .lim_1 = MAX_INTERNAL_TEMP, .timeout = HIGH_INT_TEMP_TIME, .code = INTERNAL_THERMAL_ERROR, .optype_2 = NOP /* -----------------------------------UNUSED-----------*/ }; + fault_table[8] = (fault_eval_t) {.id = NULL}; // clang-format on } uint32_t fault_status = 0;