V1.15
This commit is contained in:
parent
7dd742af22
commit
3edafc58cc
@ -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
|
@ -8,8 +8,6 @@
|
||||
#ifndef INC_STATE_MACHINE_H
|
||||
#define INC_STATE_MACHINE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "ADBMS_LL_Driver.h"
|
||||
#include <AMS_HighLevel.h>
|
||||
#include <can.h>
|
||||
@ -19,6 +17,10 @@
|
||||
#include <status_LED.h>
|
||||
#include <TMP1075.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
|
||||
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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,19 +38,36 @@ 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) {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nfailed_temp_sensors > MAX_FAILED_TEMP) {
|
||||
|
@ -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[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));
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "soc_estimation.h"
|
||||
#include "state_machine.h"
|
||||
#include <status_LED.h>
|
||||
#include <stdint.h>
|
||||
#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 */
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "soc_estimation.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#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
|
||||
|
@ -6,8 +6,10 @@
|
||||
*/
|
||||
|
||||
#include <state_machine.h>
|
||||
#include <stdint.h>
|
||||
#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,12 +77,10 @@ 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:
|
||||
@ -186,11 +191,11 @@ void sm_powerground_manager(){
|
||||
|
||||
if (powerground_softstart_timer < HAL_GetTick()){
|
||||
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;
|
||||
} 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;
|
||||
@ -258,12 +263,14 @@ void sm_check_errors(){
|
||||
|
||||
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){
|
||||
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){
|
||||
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();
|
||||
|
@ -26,8 +26,8 @@ F_CLK = 16 MHz
|
||||
*/
|
||||
|
||||
#define STATUS_LED_ARR 255
|
||||
#define TIME_BLINK_OFF 100
|
||||
#define TIME_BLINK_ON 1000
|
||||
#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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user