From ccdcb6bf973dfa1523f6ba47d63f2e7bfc9c5d32 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Sat, 11 Nov 2023 20:06:21 +0000 Subject: [PATCH] Use high UINT16_MAX instead of 0 to express stop speed tick period - removes need for for CADENCE_TICKS_STARTUP in motor.c and div by 0 checks in ebike.c. Use more constants. Small cleanups. WHEEL_SPEED_SENSOR_TICKS_COUNTER_MIN and MAX calculated based on the wheel size. --- src/controller/ebike_app.c | 45 ++++++++++----------------------- src/controller/main.h | 52 ++++++++++++++++++++------------------ src/controller/motor.c | 33 ++++++++++++------------ 3 files changed, 58 insertions(+), 72 deletions(-) diff --git a/src/controller/ebike_app.c b/src/controller/ebike_app.c index e2c0e8d3..daaeb2d8 100755 --- a/src/controller/ebike_app.c +++ b/src/controller/ebike_app.c @@ -763,7 +763,7 @@ static void ebike_control_motor(void) } } - //voltage based control assumes the winding resistance is constant - this limitation is ignored for simplicity + //voltage based control assumes the winding resistance is constant for simplicity uint32_t smooth_start_voltage_target_x100 = smooth_start_voltage_limit_x100 + smooth_start_voltage_limit_blend_x100; smooth_start_voltage_target_x100 += (ui16_motor_bemf_voltage_x1000 / (10U + SMOOTH_START_BEMF_REDUCE_FACTOR)); if (smooth_start_voltage_target_x100 > UINT16_MAX){ @@ -1545,43 +1545,26 @@ static void calc_wheel_speed(void) } -static void calc_cadence(void) -{ - // get the cadence sensor ticks - uint16_t ui16_cadence_sensor_ticks_temp = ui16_cadence_sensor_ticks; - - // adjust cadence sensor ticks counter min depending on wheel speed +/*------------------------------------------------------------------------------------------------- + NOTE: regarding the cadence calculation + Cadence is calculated by counting how many ticks there are between two LOW to HIGH transitions. + Formula for calculating the cadence in RPM: + (1) Cadence in RPM = (60 * PWM_CYCLES_SECOND) / CADENCE_SENSOR_NUMBER_MAGNETS) / ticks + -------------------------------------------------------------------------------------------------*/ +static void calc_cadence(void){ + // adjust cadence sensor ticks counter min depending on wheel speed - read in motor.c ui16_cadence_ticks_count_min_speed_adj = map_ui16(ui16_wheel_speed_x10, 40, 400, CADENCE_SENSOR_CALC_COUNTER_MIN, CADENCE_SENSOR_TICKS_COUNTER_MIN_AT_SPEED); - // calculate cadence in RPM and avoid zero division - // !!!warning if PWM_CYCLES_SECOND > 21845 - if (ui16_cadence_sensor_ticks_temp) { - ui8_pedal_cadence_RPM = (uint8_t)((PWM_CYCLES_SECOND * 3U) / ui16_cadence_sensor_ticks_temp); - - if(ui8_pedal_cadence_RPM > 120) {ui8_pedal_cadence_RPM = 120;} + // calculate cadence in RPM + ui8_pedal_cadence_RPM = (uint8_t)(CADENCE_RPM_TICK_NUM / ui16_cadence_sensor_ticks); + if(ui8_pedal_cadence_RPM > CADENCE_MAX_RPM) { + ui8_pedal_cadence_RPM = CADENCE_MAX_RPM; } - else { - ui8_pedal_cadence_RPM = 0; - } - - /*------------------------------------------------------------------------------------------------- - - NOTE: regarding the cadence calculation - - Cadence is calculated by counting how many ticks there are between two LOW to HIGH transitions. - - Formula for calculating the cadence in RPM: - - (1) Cadence in RPM = (60 * PWM_CYCLES_SECOND) / CADENCE_SENSOR_NUMBER_MAGNETS) / ticks - - (2) Cadence in RPM = (PWM_CYCLES_SECOND * 3) / ticks - - -------------------------------------------------------------------------------------------------*/ -} +} static void get_battery_voltage_filtered(void) diff --git a/src/controller/main.h b/src/controller/main.h index 395745f1..2a862c70 100644 --- a/src/controller/main.h +++ b/src/controller/main.h @@ -16,9 +16,9 @@ // PWM related values // motor -#define PWM_CYCLES_SECOND 19047U // 52us (PWM period) +#define PWM_CYCLES_SECOND 19047U // 52us (PWM period) - !! has to be less than 21845 #define PWM_CYCLES_COUNTER_MAX 3800U // 5 erps minimum speed -> 1/5 = 200 ms; 200 ms / 50 us = 4000 (3125 at 15.625KHz) -#define DOUBLE_PWM_CYCLES_SECOND 38094 // 25us (2 irq x PWM period) +#define DOUBLE_PWM_CYCLES_SECOND 38094U // 25us (2 irq x PWM period) // ramp up/down PWM cycles count #define PWM_DUTY_CYCLE_RAMP_UP_INVERSE_STEP_CADENCE_OFFSET 60 // PWM_DUTY_CYCLE_RAMP_UP_INVERSE_STEP offset for cadence assist mode //#define PWM_DUTY_CYCLE_RAMP_UP_INVERSE_STEP_DEFAULT 195 // 160 -> 160 * 64 us for every duty cycle increment at 15.625KHz @@ -34,16 +34,34 @@ #define THROTTLE_DUTY_CYCLE_RAMP_UP_INVERSE_STEP_MIN 49 // 40 at 15.625KHz #define MOTOR_SPEED_FIELD_WEAKEANING_MIN 300 // ERPS +// cadence sensor +#define CADENCE_SENSOR_NUMBER_MAGNETS 20U -// cadence -#define CADENCE_SENSOR_CALC_COUNTER_MIN 4266 // 3500 at 15.625KHz -#define CADENCE_SENSOR_TICKS_COUNTER_MIN_AT_SPEED 341 // 280 at 15.625KHz -#define CADENCE_TICKS_STARTUP 7618 // ui16_cadence_sensor_ticks value for startup. About 7-8 RPM (6250 at 15.625KHz) -#define CADENCE_SENSOR_STANDARD_MODE_SCHMITT_TRIGGER_THRESHOLD 0 // software based Schmitt trigger to stop motor jitter when at resolution limits (350 at 15.625KHz) -// Wheel speed sensor -#define WHEEL_SPEED_SENSOR_TICKS_COUNTER_MAX 165 // (135 at 15,625KHz) something like 200 m/h with a 6'' wheel -#define WHEEL_SPEED_SENSOR_TICKS_COUNTER_MIN 39976 // could be a bigger number but will make for a slow detection of stopped wheel speed +/*------------------------------------------------------------------------------- + NOTE: regarding the cadence sensor + + CADENCE_SENSOR_NUMBER_MAGNETS = 20, this is the number of magnets used for + the cadence sensor. Was validated on August 2018 by Casainho and jbalat + Cadence is calculated by counting how much time passes between two + transitions. Depending on if all transitions are measured or simply + transitions of the same kind it is important to adjust the calculation of + pedal cadence. + -------------------------------------------------------------------------------*/ +#define CADENCE_SENSOR_MIN_RPM 7U //next minimum value other than 0 +#define CADENCE_MAX_RPM 120U +#define CADENCE_SENSOR_CALC_COUNTER_MIN 4266U // 3500 at 15.625KHz +#define CADENCE_SENSOR_TICKS_COUNTER_MIN_AT_SPEED 341U // 280 at 15.625KHz +#define CADENCE_COUNTER_RESET 0U +#define CADENCE_COUNTER_MAX UINT16_MAX +#define CADENCE_RPM_TICK_NUM (PWM_CYCLES_SECOND * (60U / CADENCE_SENSOR_NUMBER_MAGNETS)) +#define CADENCE_TICKS_STOP UINT16_MAX +#define CADENCE_SENSOR_STANDARD_MODE_SCHMITT_TRIGGER_THRESHOLD 0U // software based Schmitt trigger to stop motor jitter when at resolution limits (350 at 15.625KHz) +// Wheel speed sensor +#define MAX_PLAUSIBLE_WHEEL_SPEED 80U +#define MIN_PLAUSIBLE_WHEEL_SPEED 4U +#define WHEEL_SPEED_SENSOR_TICKS_COUNTER_MAX ((uint16_t)((uint32_t)WHEEL_PERIMETER * (HSE_VALUE / 420 /2) / MAX_PLAUSIBLE_WHEEL_SPEED * 60 / 1000 * 60 / 1000)) +#define WHEEL_SPEED_SENSOR_TICKS_COUNTER_MIN ((uint16_t)((uint32_t)WHEEL_PERIMETER * (HSE_VALUE / 420 /2) / MIN_PLAUSIBLE_WHEEL_SPEED * 60 / 1000 * 60 / 1000)) #define PWM_DUTY_CYCLE_MAX 255U #define PWM_DUTY_CYCLE_BITS 8 @@ -170,20 +188,6 @@ ---------------------------------------------------------*/ -// cadence sensor -#define CADENCE_SENSOR_NUMBER_MAGNETS 20U - -/*------------------------------------------------------------------------------- - NOTE: regarding the cadence sensor - - CADENCE_SENSOR_NUMBER_MAGNETS = 20, this is the number of magnets used for - the cadence sensor. Was validated on August 2018 by Casainho and jbalat - - Cadence is calculated by counting how much time passes between two - transitions. Depending on if all transitions are measured or simply - transitions of the same kind it is important to adjust the calculation of - pedal cadence. - -------------------------------------------------------------------------------*/ // default values diff --git a/src/controller/motor.c b/src/controller/motor.c index 87d30c49..0e18c35f 100755 --- a/src/controller/motor.c +++ b/src/controller/motor.c @@ -313,7 +313,7 @@ volatile uint8_t ui8_fw_angle = 0; volatile uint8_t ui8_fw_angle_max; volatile uint8_t ui8_controller_duty_cycle_target = 0; volatile uint8_t ui8_g_foc_angle = 0; -volatile uint8_t ui8_g_assist_level = 0; +volatile uint8_t ui8_g_assist_level = OFF; static uint8_t ui8_counter_duty_cycle_ramp_up = 0; static uint8_t ui8_counter_duty_cycle_ramp_down = 0; @@ -326,11 +326,11 @@ volatile uint8_t ui8_brake_state = 0; // cadence sensor #define NO_PAS_REF 5 -volatile uint16_t ui16_cadence_sensor_ticks = 0; -//volatile uint32_t ui32_crank_revolutions_x20 = 0; +volatile uint16_t ui16_cadence_sensor_ticks = CADENCE_TICKS_STOP; static uint16_t ui16_cadence_sensor_ticks_counter_min = CADENCE_SENSOR_CALC_COUNTER_MIN; static uint8_t ui8_pas_state_old = 4; -static uint16_t ui16_cadence_calc_counter, ui16_cadence_stop_counter; +static uint16_t ui16_cadence_calc_counter = CADENCE_COUNTER_RESET; +static uint16_t ui16_cadence_stop_counter = 0; static uint8_t ui8_cadence_calc_ref_state = NO_PAS_REF; const static uint8_t ui8_pas_old_valid_state[4] = { 0x01, 0x03, 0x00, 0x02 }; @@ -358,7 +358,7 @@ void calc_foc_angle(void); uint8_t asin_table(uint8_t ui8_inverted_angle_x128); void motor_controller(void) { - ui16_motor_speed_erps = ((uint16_t) DOUBLE_PWM_CYCLES_SECOND) / (ui16_PWM_cycles_counter_total); + ui16_motor_speed_erps = DOUBLE_PWM_CYCLES_SECOND / ui16_PWM_cycles_counter_total; read_battery_voltage(); calc_foc_angle(); } @@ -613,8 +613,8 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) ui16_adc_torque_sensor_check = UI16_ADC_10_BIT_TORQUE_SENSOR; if((ui16_adc_torque_sensor_check < ui16_adc_pedal_torque_offset_cal)||(!ui8_adc_battery_current_target)) { - if((ui16_motor_speed_erps) - &&(!ui16_cadence_sensor_ticks) + if((ui16_motor_speed_erps > 0) + &&(ui16_cadence_sensor_ticks == CADENCE_TICKS_STOP) #if OPTIONAL_ADC_FUNCTION == THROTTLE_CONTROL &&(UI8_ADC_THROTTLE < ADC_THROTTLE_MIN_VALUE) #endif @@ -651,7 +651,7 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) || (UI8_ADC_BATTERY_VOLTAGE < ui8_adc_battery_voltage_cut_off) || (ui8_fw_angle > ui8_fw_angle_max) || (ui8_brake_state) - || (!ui8_g_assist_level)) { + || (ui8_g_assist_level == OFF)){ // reset duty cycle ramp up counter (filter) ui8_counter_duty_cycle_ramp_up = 0; @@ -855,13 +855,13 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) if (ui8_pas_state != ui8_pas_state_old) { if (ui8_pas_state_old != ui8_pas_old_valid_state[ui8_pas_state]) { // wrong state sequence: backward rotation - ui16_cadence_sensor_ticks = 0; + ui16_cadence_sensor_ticks = CADENCE_TICKS_STOP; ui8_cadence_calc_ref_state = NO_PAS_REF; goto skip_cadence; } // motor fast stop - if(ui8_pedal_cadence_fast_stop && ui16_cadence_sensor_ticks) { + if(ui8_pedal_cadence_fast_stop && (ui16_cadence_sensor_ticks != CADENCE_TICKS_STOP)) { ui16_cadence_sensor_ticks_counter_min = ui16_cadence_sensor_ticks - (CADENCE_SENSOR_STANDARD_MODE_SCHMITT_TRIGGER_THRESHOLD >> 1); } else { @@ -875,16 +875,14 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) if (ui8_pas_state == ui8_cadence_calc_ref_state) { // ui16_cadence_calc_counter is valid for cadence calculation ui16_cadence_sensor_ticks = ui16_cadence_calc_counter; - ui16_cadence_calc_counter = 0; + ui16_cadence_calc_counter = CADENCE_COUNTER_RESET; // software based Schmitt trigger to stop motor jitter when at resolution limits ui16_cadence_sensor_ticks_counter_min += CADENCE_SENSOR_STANDARD_MODE_SCHMITT_TRIGGER_THRESHOLD; } else if (ui8_cadence_calc_ref_state == NO_PAS_REF) { // this is the new reference state for cadence calculation ui8_cadence_calc_ref_state = ui8_pas_state; - ui16_cadence_calc_counter = 0; - } else if (ui16_cadence_sensor_ticks == 0) { - // Waiting the second reference transition: set the cadence to 7 RPM for immediate start - ui16_cadence_sensor_ticks = CADENCE_TICKS_STARTUP; + ui16_cadence_calc_counter = CADENCE_COUNTER_RESET; + ui16_cadence_sensor_ticks = CADENCE_TICKS_STOP; } skip_cadence: @@ -900,10 +898,10 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) if (++ui16_cadence_stop_counter > ui16_cadence_sensor_ticks_counter_min) { // pedals stop detected - ui16_cadence_sensor_ticks = 0; + ui16_cadence_sensor_ticks = CADENCE_TICKS_STOP; ui16_cadence_stop_counter = 0; ui8_cadence_calc_ref_state = NO_PAS_REF; - } else if (ui8_cadence_calc_ref_state != NO_PAS_REF) { + } else if ((ui8_cadence_calc_ref_state != NO_PAS_REF) && (ui16_cadence_calc_counter < CADENCE_COUNTER_MAX)) { // increment cadence tick counter ++ui16_cadence_calc_counter; } @@ -941,6 +939,7 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) ui16_wheel_speed_sensor_ticks_counter = 0; ui8_wheel_speed_sensor_ticks_counter_started = 0; } else { + //update latest tick and reset the counter ui16_wheel_speed_sensor_ticks = ui16_wheel_speed_sensor_ticks_counter; ui16_wheel_speed_sensor_ticks_counter = 0; ++ui32_wheel_speed_sensor_ticks_total;