From 49fc785aaef383498681b404b8a1d12af8ef2de0 Mon Sep 17 00:00:00 2001 From: emmebrusa Date: Fri, 16 Aug 2024 18:01:08 +0200 Subject: [PATCH] fixed power limit issue --- src/ebike_app.c | 96 +++++++++++++++++-------------------------------- src/main.h | 9 ++--- src/motor.c | 6 ++-- 3 files changed, 39 insertions(+), 72 deletions(-) diff --git a/src/ebike_app.c b/src/ebike_app.c index 92b42205..2419aa6b 100644 --- a/src/ebike_app.c +++ b/src/ebike_app.c @@ -107,9 +107,9 @@ static uint16_t ui16_duty_cycle_percent = 0; volatile uint8_t ui8_adc_motor_phase_current_max = ADC_10_BIT_MOTOR_PHASE_CURRENT_MAX; static uint8_t ui8_error_battery_overcurrent = 0; static uint8_t ui8_adc_battery_overcurrent = (uint8_t)(ADC_10_BIT_BATTERY_CURRENT_MAX + ADC_10_BIT_BATTERY_EXTRACURRENT); -static uint8_t ui8_adc_battery_current_max_array[2]; -static uint8_t ui8_adc_motor_phase_current_max_array[2]; -static uint8_t ui8_adc_battery_overcurrent_array[2]; +static uint8_t ui8_adc_battery_current_max_temp_1 = 0; +static uint8_t ui8_adc_battery_current_max_temp_2 = 0; +static uint32_t ui32_adc_battery_power_max_x1000_array[2]; // Motor ERPS static uint16_t ui16_motor_speed_erps = 0; @@ -303,13 +303,12 @@ void ebike_app_init(void) (uint8_t) SMOOTH_START_RAMP_MIN); // set pedal torque per 10_bit DC_step x100 advanced (calibrated) or default(not calibrated) + ui8_pedal_torque_per_10_bit_ADC_step_x100_array[TORQUE_STEP_DEFAULT] = PEDAL_TORQUE_PER_10_BIT_ADC_STEP_X100; if (ui8_torque_sensor_calibrated) { - ui8_pedal_torque_per_10_bit_ADC_step_x100_array[TORQUE_STEP_DEFAULT] = PEDAL_TORQUE_PER_10_BIT_ADC_STEP_X100; ui8_pedal_torque_per_10_bit_ADC_step_x100_array[TORQUE_STEP_ADVANCED] = PEDAL_TORQUE_PER_10_BIT_ADC_STEP_ADV_X100; } else { - ui8_pedal_torque_per_10_bit_ADC_step_x100_array[TORQUE_STEP_DEFAULT] = PEDAL_TORQUE_PER_10_BIT_ADC_STEP_X100; - ui8_pedal_torque_per_10_bit_ADC_step_x100_array[TORQUE_STEP_DEFAULT] = PEDAL_TORQUE_PER_10_BIT_ADC_STEP_X100; + ui8_pedal_torque_per_10_bit_ADC_step_x100_array[TORQUE_STEP_ADVANCED] = PEDAL_TORQUE_PER_10_BIT_ADC_STEP_X100; } // parameters status on startup @@ -357,54 +356,26 @@ void ebike_app_init(void) #if DATA_DISPLAY_ON_STARTUP ui8_display_data_enabled = 1; #endif - - // calculate current limit in offroad and street mode - uint8_t ui8_adc_battery_current_max_temp_1; - uint8_t ui8_adc_battery_current_max_temp_2; - uint32_t ui32_battery_current_max_x100; - uint16_t ui16_temp; - - // calculate max battery current in ADC steps from the received battery current limit - ui8_adc_battery_current_max_temp_1 = (uint16_t)(m_configuration_variables.ui8_battery_current_max * (uint8_t)100) - / (uint16_t)BATTERY_CURRENT_PER_10_BIT_ADC_STEP_X100; - - // calculate max adc battery current from the received power limit in offroad mode - ui32_battery_current_max_x100 = (TARGET_MAX_BATTERY_POWER_DIV25 * 2500000) - / ui16_battery_voltage_filtered_x1000; - ui8_adc_battery_current_max_temp_2 = ui32_battery_current_max_x100 / BATTERY_CURRENT_PER_10_BIT_ADC_STEP_X100; - - // set max battery current in offroad mode - ui8_adc_battery_current_max_array[OFFROAD_MODE] = ui8_min(ui8_adc_battery_current_max_temp_1, ui8_adc_battery_current_max_temp_2); - - // calculate max adc battery current from the received power limit in street mode - ui32_battery_current_max_x100 = (STREET_MODE_POWER_LIMIT_DIV25 * 2500000) - / ui16_battery_voltage_filtered_x1000; - ui8_adc_battery_current_max_temp_2 = ui32_battery_current_max_x100 / BATTERY_CURRENT_PER_10_BIT_ADC_STEP_X100; - // set max battery current in street mode - ui8_adc_battery_current_max_array[STREET_MODE] = ui8_min(ui8_adc_battery_current_max_temp_1, ui8_adc_battery_current_max_temp_2); + // calculate max adc battery current from the received battery current limit + ui8_adc_battery_current_max_temp_1 = (uint8_t)((uint16_t)(m_configuration_variables.ui8_battery_current_max * 100U) + / BATTERY_CURRENT_PER_10_BIT_ADC_STEP_X100); - // set max motor phase current in offroad mode - ui16_temp = ui8_adc_battery_current_max_array[OFFROAD_MODE] * ADC_10_BIT_MOTOR_PHASE_CURRENT_MAX; - ui8_adc_motor_phase_current_max_array[OFFROAD_MODE] = (uint8_t)(ui16_temp / ADC_10_BIT_BATTERY_CURRENT_MAX); - // limit max motor phase current if higher than configured hardware limit (safety) - if (ui8_adc_motor_phase_current_max_array[OFFROAD_MODE] > ADC_10_BIT_MOTOR_PHASE_CURRENT_MAX) { - ui8_adc_motor_phase_current_max_array[OFFROAD_MODE] = ADC_10_BIT_MOTOR_PHASE_CURRENT_MAX; - } - - // set max motor phase current in street mode - ui16_temp = ui8_adc_battery_current_max_array[STREET_MODE] * ADC_10_BIT_MOTOR_PHASE_CURRENT_MAX; - ui8_adc_motor_phase_current_max_array[STREET_MODE] = (uint8_t)(ui16_temp / ADC_10_BIT_BATTERY_CURRENT_MAX); + // calculate the max adc battery power from the power limit received in offroad mode + ui32_adc_battery_power_max_x1000_array[OFFROAD_MODE] = (uint32_t)((uint32_t)TARGET_MAX_BATTERY_POWER * 100U * 1000U) + / BATTERY_CURRENT_PER_10_BIT_ADC_STEP_X100; + + // calculate the max adc battery power from the received power limit in street mode + ui32_adc_battery_power_max_x1000_array[STREET_MODE] = (uint32_t)((uint32_t)STREET_MODE_POWER_LIMIT * 100U * 1000U) + / BATTERY_CURRENT_PER_10_BIT_ADC_STEP_X100; + + // set max motor phase current + uint16_t ui16_temp = ui8_adc_battery_current_max_temp_1 * ADC_10_BIT_MOTOR_PHASE_CURRENT_MAX; + ui8_adc_motor_phase_current_max = (uint8_t)(ui16_temp / ADC_10_BIT_BATTERY_CURRENT_MAX); // limit max motor phase current if higher than configured hardware limit (safety) - if (ui8_adc_motor_phase_current_max_array[STREET_MODE] > ADC_10_BIT_MOTOR_PHASE_CURRENT_MAX) { - ui8_adc_motor_phase_current_max_array[STREET_MODE] = ADC_10_BIT_MOTOR_PHASE_CURRENT_MAX; + if (ui8_adc_motor_phase_current_max > ADC_10_BIT_MOTOR_PHASE_CURRENT_MAX) { + ui8_adc_motor_phase_current_max = ADC_10_BIT_MOTOR_PHASE_CURRENT_MAX; } - - // set battery overcurrent limit in offroad mode - ui8_adc_battery_overcurrent_array[OFFROAD_MODE] = ui8_adc_battery_current_max_array[OFFROAD_MODE] + ADC_10_BIT_BATTERY_EXTRACURRENT; - - // set battery overcurrent limit in street mode - ui8_adc_battery_overcurrent_array[STREET_MODE] = ui8_adc_battery_current_max_array[STREET_MODE] + ADC_10_BIT_BATTERY_EXTRACURRENT; } @@ -554,17 +525,15 @@ static void ebike_control_motor(void) if (ui8_adc_battery_current_max > ADC_10_BIT_BATTERY_CURRENT_MAX) { ui8_adc_battery_current_max = ADC_10_BIT_BATTERY_CURRENT_MAX; } - + + // set limit battery overcurrent + ui8_adc_battery_overcurrent = ui8_adc_battery_current_max + ADC_10_BIT_BATTERY_EXTRACURRENT; + // limit target current if higher than max value (safety) if (ui8_adc_battery_current_target > ui8_adc_battery_current_max) { ui8_adc_battery_current_target = ui8_adc_battery_current_max; } - // limit target duty cycle if higher than max value - if (ui8_duty_cycle_target > PWM_DUTY_CYCLE_MAX) { - ui8_duty_cycle_target = PWM_DUTY_CYCLE_MAX; - } - // limit target duty cycle ramp up inverse step if lower than min value (safety) if (ui8_duty_cycle_ramp_up_inverse_step < PWM_DUTY_CYCLE_RAMP_UP_INVERSE_STEP_MIN) { ui8_duty_cycle_ramp_up_inverse_step = PWM_DUTY_CYCLE_RAMP_UP_INVERSE_STEP_MIN; @@ -1444,8 +1413,9 @@ static void apply_temperature_limiting(void) } -static void apply_speed_limit(void) { - if (m_configuration_variables.ui8_wheel_speed_max > 0U) { +static void apply_speed_limit(void) +{ + if (m_configuration_variables.ui8_wheel_speed_max > 0U) { uint16_t speed_limit_low = (uint16_t)((uint8_t)(m_configuration_variables.ui8_wheel_speed_max - 2U) * (uint8_t)10U); // casting literal to uint8_t ensures usage of MUL X,A uint16_t speed_limit_high = (uint16_t)((uint8_t)(m_configuration_variables.ui8_wheel_speed_max + 2U) * (uint8_t)10U); @@ -2818,12 +2788,12 @@ static void uart_receive_package(void) m_configuration_variables.ui8_wheel_speed_max = ui8_wheel_speed_max_array[m_configuration_variables.ui8_street_mode_enabled]; } + // current limit with power limit + ui8_adc_battery_current_max_temp_2 = (uint8_t)((uint32_t)(ui32_adc_battery_power_max_x1000_array[m_configuration_variables.ui8_street_mode_enabled] + / ui16_battery_voltage_filtered_x1000)); + // set max battery current - ui8_adc_battery_current_max = ui8_adc_battery_current_max_array[m_configuration_variables.ui8_street_mode_enabled]; - // set max motor phase current - ui8_adc_motor_phase_current_max = ui8_adc_motor_phase_current_max_array[m_configuration_variables.ui8_street_mode_enabled]; - // set limit battery overcurrent - ui8_adc_battery_overcurrent = ui8_adc_battery_overcurrent_array[m_configuration_variables.ui8_street_mode_enabled]; + ui8_adc_battery_current_max = ui8_min(ui8_adc_battery_current_max_temp_1, ui8_adc_battery_current_max_temp_2); // set pedal torque per 10_bit DC_step x100 advanced ui8_pedal_torque_per_10_bit_ADC_step_x100 = ui8_pedal_torque_per_10_bit_ADC_step_x100_array[m_configuration_variables.ui8_torque_sensor_adv_enabled]; diff --git a/src/main.h b/src/main.h index 03584520..f4701fed 100644 --- a/src/main.h +++ b/src/main.h @@ -101,7 +101,8 @@ #define WHEEL_SPEED_SENSOR_TICKS_COUNTER_MAX (uint16_t)((uint32_t)PWM_CYCLES_SECOND*10U/1157U) // (135 at 15,625KHz) something like 200 m/h with a 6'' wheel #define WHEEL_SPEED_SENSOR_TICKS_COUNTER_MIN (uint16_t)((uint32_t)PWM_CYCLES_SECOND*1000U/477U) // 32767@15625KHz could be a bigger number but will make for a slow detection of stopped wheel speed -#define PWM_DUTY_CYCLE_MAX 254 +// duty cycle +#define PWM_DUTY_CYCLE_MAX 255 #define PWM_DUTY_CYCLE_STARTUP 30 // Initial PWM Duty Cycle at motor startup // ---------------------------------------------------------------------------------------------------------------- @@ -373,11 +374,7 @@ HALL_COUNTER_OFFSET_UP: 29 -> 44 #define DIFFERENCE_CUT_OFF_SHUTDOWN_8_BIT 26 // battery voltage for saving battery capacity at shutdown #define BATTERY_VOLTAGE_SHUTDOWN_8_BIT (uint8_t) ((uint16_t)(BATTERY_LOW_VOLTAGE_CUT_OFF * 250 / BATTERY_VOLTAGE_PER_10_BIT_ADC_STEP_X1000)) - ((uint16_t) DIFFERENCE_CUT_OFF_SHUTDOWN_8_BIT) -#define BATTERY_VOLTAGE_SHUTDOWN_10_BIT (uint16_t) (BATTERY_VOLTAGE_SHUTDOWN_8_BIT << 2) -// max battery power div25 -#define TARGET_MAX_BATTERY_POWER_DIV25 (uint8_t)(TARGET_MAX_BATTERY_POWER / 25) -// power street limit value div25 -#define STREET_MODE_POWER_LIMIT_DIV25 (uint8_t)(STREET_MODE_POWER_LIMIT / 25) +#define BATTERY_VOLTAGE_SHUTDOWN_10_BIT (uint16_t) (BATTERY_VOLTAGE_SHUTDOWN_8_BIT << 2) // battery voltage reset SOC percentage #define BATTERY_VOLTAGE_RESET_SOC_PERCENT_X10 (uint16_t)((float)LI_ION_CELL_RESET_SOC_PERCENT * (float)(BATTERY_CELLS_NUMBER * 10)) // battery SOC eeprom value saved (8 bit) diff --git a/src/motor.c b/src/motor.c index c1a8025f..b315161b 100644 --- a/src/motor.c +++ b/src/motor.c @@ -795,9 +795,9 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) // - ramp up/down PWM duty_cycle and/or field weakening angle value // check if to decrease, increase or maintain duty cycle - if ( (ui8_controller_duty_cycle_target < ui8_g_duty_cycle) + if ((ui8_controller_duty_cycle_target < ui8_g_duty_cycle) || (ui8_controller_adc_battery_current_target < ui8_adc_battery_current_filtered) - || (ui8_adc_motor_phase_current > ui8_adc_motor_phase_current_max) + || (ui8_adc_motor_phase_current > ui8_adc_motor_phase_current_max) || (ui16_hall_counter_total < (HALL_COUNTER_FREQ / MOTOR_OVER_SPEED_ERPS)) || (ui16_adc_voltage < ui16_adc_voltage_cut_off) || (ui8_brake_state)) { @@ -819,7 +819,7 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) } else if ((ui8_controller_duty_cycle_target > ui8_g_duty_cycle) && (ui8_controller_adc_battery_current_target > ui8_adc_battery_current_filtered)) { - // reset duty cycle ramp down counter (filter) + // reset duty cycle ramp down counter (filter) ui8_counter_duty_cycle_ramp_down = 0; // ramp up duty cycle