Skip to content

Commit

Permalink
Improved pedal cadence calculation. Corrected a bug with startup
Browse files Browse the repository at this point in the history
  • Loading branch information
casainho committed Mar 15, 2019
1 parent cb6ebed commit 27e2d9f
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 66 deletions.
75 changes: 45 additions & 30 deletions src/controller/ebike_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ static int16_t i16_control_output = 0;

// variables for various system functions
volatile uint16_t ui16_pas_pwm_cycles_ticks = (uint16_t) PAS_ABSOLUTE_MIN_CADENCE_PWM_CYCLE_TICKS;
volatile uint8_t ui8_pas_direction = 0;
volatile uint8_t ui8_pedaling_forward = 1;
uint8_t ui8_pas_cadence_rpm = 0;
uint16_t ui16_pedal_torque_x10;
uint16_t ui16_pedal_power_x10;
Expand Down Expand Up @@ -229,14 +229,25 @@ static void ebike_control_motor (void)

if (configuration_variables.ui8_assist_level_factor_x10 > 0)
{
ui32_temp = (uint32_t) ui16_pedal_power_x10 * (uint32_t) configuration_variables.ui8_assist_level_factor_x10;
ui32_temp /= 100;
// when ui8_motor_assistance_startup_without_pedal_rotation == 0 or cadence == 0
if((!configuration_variables.ui8_motor_assistance_startup_without_pedal_rotation) ||
(ui8_pas_cadence_rpm > 0))
{
ui32_temp = (uint32_t) ui16_pedal_power_x10 * (uint32_t) configuration_variables.ui8_assist_level_factor_x10;
ui32_temp /= 100;
}
else
{
ui32_temp = (uint32_t) ui16_pedal_torque_x10 * (uint32_t) configuration_variables.ui8_assist_level_factor_x10;
ui32_temp /= 100;
}

// 1.6 = 1 / 0.625 (each adc step for current)
// 1.6 * 8 = ~13
ui32_temp = (ui32_temp * 13) / ((uint32_t) ui16_battery_voltage_filtered);
ui8_adc_max_battery_current = ui32_temp >> 3;
ui8_limit_max(&ui8_adc_max_battery_current, 255);
ui8_adc_battery_target_current = ui8_adc_max_battery_current;
}

if (configuration_variables.ui8_target_battery_max_power_div25 > 0) //TODO: add real feature toggle for max power feature
Expand All @@ -251,27 +262,18 @@ static void ebike_control_motor (void)
ui8_startup_enable = configuration_variables.ui8_assist_level_factor_x10 && ui8_torque_sensor ? 1 : 0;

ui8_tmp_pas_cadence_rpm = ui8_pas_cadence_rpm;
// let's cheat next value, only to cheat apply_boost()
if (configuration_variables.ui8_motor_assistance_startup_without_pedal_rotation)
{
if (ui8_pas_cadence_rpm < 10) { ui8_tmp_pas_cadence_rpm = 10; }
}
else
{
if (ui8_pas_cadence_rpm < 10) { ui8_tmp_pas_cadence_rpm = 0; }
}

if (configuration_variables.ui8_startup_motor_power_boost_feature_enabled)
{
boost_run_statemachine ();
boost_run_statemachine ();
ui8_boost_enabled_and_applied = apply_boost (ui8_tmp_pas_cadence_rpm, ui8_adc_max_battery_current_boost_state, &ui8_adc_battery_target_current);
}

if (!ui8_boost_enabled_and_applied)
{
ui8_adc_battery_target_current = ui8_adc_max_battery_current;
}


/* Boost: make transition from boost to regular level */
if (configuration_variables.ui8_startup_motor_power_boost_feature_enabled)
{
Expand Down Expand Up @@ -377,17 +379,30 @@ static void ebike_control_motor (void)
*************************************************************************************************************/

if (ui8_adc_battery_target_current && configuration_variables.ui8_walk_assist && (ui16_wheel_speed_x10 < 80) && (!brake_is_set()) && configuration_variables.ui8_error_states == ERROR_STATE_NO_ERRORS)
if(ui8_adc_battery_target_current && // we must have a target positive current
(!brake_is_set()) && // brakes must not be pressed
ui8_pedaling_forward && // we must not be pedaling backwards
configuration_variables.ui8_error_states == ERROR_STATE_NO_ERRORS) // we must have no errors
{
motor_set_pwm_duty_cycle_target (ui8_walk_assist_target_PWM);
}
else if (ui8_adc_battery_target_current && configuration_variables.ui8_walk_assist && (ui16_wheel_speed_x10 > 80) && (!brake_is_set()) && configuration_variables.ui8_error_states == ERROR_STATE_NO_ERRORS)
{
motor_set_pwm_duty_cycle_target (ui8_cruise_target_PWM);
}
else if (ui8_adc_battery_target_current && ui8_startup_enable && (!brake_is_set()) && configuration_variables.ui8_error_states == ERROR_STATE_NO_ERRORS)
{
motor_set_pwm_duty_cycle_target (255);
// if user is pressing walk assist
if(configuration_variables.ui8_walk_assist)
{
// if wheel speed is less than 8 km/h, then implement walk assist
if(ui16_wheel_speed_x10 < 80)
{
motor_set_pwm_duty_cycle_target (ui8_walk_assist_target_PWM);
}
// if wheel speed is equal or over than 8 km/h, then implement cruise
else if(ui16_wheel_speed_x10 >= 80)
{
motor_set_pwm_duty_cycle_target (ui8_cruise_target_PWM);
}
}
// regular mode, max PWM duty_cycle where the current controllr on motor.c will limit the max current
else if(ui8_startup_enable)
{
motor_set_pwm_duty_cycle_target (255);
}
}
else
{
Expand Down Expand Up @@ -1100,7 +1115,7 @@ static void torque_sensor_read (void)

switch (ui8_tstr_state_machine)
{
// ebike is stopped, wait for throttle signal
// ebike is stopped, wait for torque sensor signal
case STATE_NO_PEDALLING:
if ((ui8_torque_sensor_raw > 0) && (!brake_is_set()))
{
Expand All @@ -1120,7 +1135,7 @@ static void torque_sensor_read (void)
if (ui16_wheel_speed_x10 == 0)
{
ui8_rtst_counter = 0;
ui8_tstr_state_machine = 0;
ui8_tstr_state_machine = STATE_NO_PEDALLING;
}
break;

Expand Down Expand Up @@ -1238,13 +1253,13 @@ static void safe_tests (void)
}
break;

// wait during 3 seconds for bicyle wheel speed > 4km/h, if not we have an error
// wait during 5 seconds for bicyle wheel speed > 4km/h, if not we have an error
case 1:
safe_tests_state_machine_counter++;

// timeout of 3 seconds, not less to be higher than value on torque_sensor_read ()
// 3 seconds should be safe enough value, mosfets should not burn in 3 seconds if ebike wheel is blocked
if (safe_tests_state_machine_counter > 30)
// timeout of 5 seconds, not less to be higher than value on torque_sensor_read ()
// hopefully, 5 seconds is safe enough value, mosfets may not burn in 5 seconds if ebike wheel is blocked
if (safe_tests_state_machine_counter > 50)
{
configuration_variables.ui8_error_states |= ERROR_STATE_EBIKE_WHEEL_BLOCKED;
safe_tests_state_machine_counter = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/controller/ebike_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ extern volatile uint8_t ui8_ebike_app_state;
extern volatile uint8_t ui8_adc_target_battery_max_current;

extern volatile uint16_t ui16_pas_pwm_cycles_ticks;
extern volatile uint8_t ui8_pas_direction;
extern volatile uint8_t ui8_pedaling_forward;
extern uint8_t ui8_pas_cadence_rpm;

extern volatile uint16_t ui16_wheel_speed_sensor_pwm_cycles_ticks;
Expand Down
4 changes: 2 additions & 2 deletions src/controller/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@
// PAS
#define PAS_NUMBER_MAGNETS 20 // see note below
#define PAS_NUMBER_MAGNETS_X2 (PAS_NUMBER_MAGNETS * 2)
#define PAS_ABSOLUTE_MAX_CADENCE_PWM_CYCLE_TICKS (6250 / PAS_NUMBER_MAGNETS) // max hard limit to 150RPM PAS cadence, see note below
#define PAS_ABSOLUTE_MIN_CADENCE_PWM_CYCLE_TICKS (93750 / PAS_NUMBER_MAGNETS) // min hard limit to 10RPM PAS cadence, see note below
#define PAS_ABSOLUTE_MAX_CADENCE_PWM_CYCLE_TICKS (6250 / PAS_NUMBER_MAGNETS) // max hard limit to 150 RPM PAS cadence, see note below
#define PAS_ABSOLUTE_MIN_CADENCE_PWM_CYCLE_TICKS (93750 / PAS_NUMBER_MAGNETS) // min hard limit to 10 RPM PAS cadence, see note below

/*---------------------------------------------------------
NOTE: regarding PAS
Expand Down
93 changes: 60 additions & 33 deletions src/controller/motor.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ volatile uint8_t ui8_adc_motor_phase_current_offset;

uint8_t ui8_pas_state;
uint8_t ui8_pas_state_old;
uint8_t ui8_pas_after_first_pulse = 0;
uint16_t ui16_pas_counter = (uint16_t) PAS_ABSOLUTE_MIN_CADENCE_PWM_CYCLE_TICKS;

volatile uint16_t ui16_torque_sensor_throttle_processed_value = 0;
Expand Down Expand Up @@ -816,60 +817,86 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER)
// consider only when PAS signal transition from 0 to 1
if (ui8_pas_state == 1)
{
// limit PAS cadence to be less than PAS_ABSOLUTE_MAX_CADENCE_PWM_CYCLE_TICKS
// also PAS cadence should be zero if rotating backwards
if ((ui16_pas_counter < ((uint16_t) PAS_ABSOLUTE_MAX_CADENCE_PWM_CYCLE_TICKS)) || (ui8_pas_direction))
// keep track of first pulse
if(!ui8_pas_after_first_pulse)
{
ui8_pas_after_first_pulse = 1;
ui16_pas_pwm_cycles_ticks = (uint16_t) PAS_ABSOLUTE_MIN_CADENCE_PWM_CYCLE_TICKS;
}
else
{
ui16_pas_pwm_cycles_ticks = ui16_pas_counter;
}
// limit PAS cadence to be less than PAS_ABSOLUTE_MAX_CADENCE_PWM_CYCLE_TICKS
// also PAS cadence should be zero if rotating backwards
if (ui16_pas_counter < ((uint16_t) PAS_ABSOLUTE_MAX_CADENCE_PWM_CYCLE_TICKS))
{
ui16_pas_pwm_cycles_ticks = (uint16_t) PAS_ABSOLUTE_MAX_CADENCE_PWM_CYCLE_TICKS;
}
else
{
ui16_pas_pwm_cycles_ticks = ui16_pas_counter;
}

ui16_pas_counter = 0;
// see the direction
if ((PAS2__PORT->IDR & PAS2__PIN) == 0)
{
ui8_pedaling_forward = 0;
}
else
{
ui8_pedaling_forward = 1;
}
}
}
else
{
// PAS cadence should be zero if rotating backwards
if ((PAS2__PORT->IDR & PAS2__PIN) != 0)
{
ui8_pas_direction = 1;
ui16_pas_pwm_cycles_ticks = (uint16_t) PAS_ABSOLUTE_MIN_CADENCE_PWM_CYCLE_TICKS;
}
else
// keep track of first pulse
if(ui8_pas_after_first_pulse)
{
ui8_pas_direction = 0;
// see the direction
if ((PAS2__PORT->IDR & PAS2__PIN) != 0)
{
ui8_pedaling_forward = 0;
}
else
{
ui8_pedaling_forward = 1;
}
}
}

// filter the torque signal, by saving the max value of each one pedal rotation
ui16_torque_sensor_throttle_value = ui16_adc_read_torque_sensor_10b () - 184;
if (ui16_torque_sensor_throttle_value > 800) ui16_torque_sensor_throttle_value = 0;
ui16_pas_counter = 0;

// NOTE: we are not using the next block of code to calculate the max torque signal one pedal rotation
// but lets save this because we may want to use it in future
// // filter the torque signal, by saving the max value of each one pedal rotation
// ui16_torque_sensor_throttle_value = ui16_adc_read_torque_sensor_10b () - 184;
// if (ui16_torque_sensor_throttle_value > 800) ui16_torque_sensor_throttle_value = 0;
//
// ui8_torque_sensor_pas_signal_change_counter++;
// if (ui8_torque_sensor_pas_signal_change_counter > (PAS_NUMBER_MAGNETS << 1)) // PAS_NUMBER_MAGNETS*2 means a full pedal rotation
// {
// ui8_torque_sensor_pas_signal_change_counter = 1; // this is the first cycle
// ui16_torque_sensor_throttle_processed_value = ui16_torque_sensor_throttle_max_value; // store the max value on the output variable of this algorithm
// ui16_torque_sensor_throttle_max_value = 0; // reset the max value
// }
// else
// {
// // store the max value
// if (ui16_torque_sensor_throttle_value > ui16_torque_sensor_throttle_max_value)
// {
// ui16_torque_sensor_throttle_max_value = ui16_torque_sensor_throttle_value;
// }
// }

ui8_torque_sensor_pas_signal_change_counter++;
if (ui8_torque_sensor_pas_signal_change_counter > (PAS_NUMBER_MAGNETS << 1)) // PAS_NUMBER_MAGNETS*2 means a full pedal rotation
{
ui8_torque_sensor_pas_signal_change_counter = 1; // this is the first cycle
ui16_torque_sensor_throttle_processed_value = ui16_torque_sensor_throttle_max_value; // store the max value on the output variable of this algorithm
ui16_torque_sensor_throttle_max_value = 0; // reset the max value
}
else
{
// store the max value
if (ui16_torque_sensor_throttle_value > ui16_torque_sensor_throttle_max_value)
{
ui16_torque_sensor_throttle_max_value = ui16_torque_sensor_throttle_value;
}
}
}

// limit min PAS cadence
if (ui16_pas_counter > ((uint16_t) PAS_ABSOLUTE_MIN_CADENCE_PWM_CYCLE_TICKS))
{
ui16_pas_pwm_cycles_ticks = (uint16_t) PAS_ABSOLUTE_MIN_CADENCE_PWM_CYCLE_TICKS;
ui16_pas_counter = 0;
ui8_pas_direction = 0;
ui8_pas_after_first_pulse = 0;
ui8_pedaling_forward = 1;

ui16_torque_sensor_throttle_processed_value = 0;
}
Expand Down

0 comments on commit 27e2d9f

Please sign in to comment.