From fa6b381be7c66c3cfb3d9008a68d55bd0427037e Mon Sep 17 00:00:00 2001 From: Leon Date: Mon, 27 May 2019 16:13:05 +0200 Subject: [PATCH] Improved logic for Offroad mode between display and TSDZ2, also improved UART code --- src/controller/ebike_app.c | 345 ++++++++++++++----------------------- src/display/KT-LCD3/lcd.c | 28 ++- src/display/KT-LCD3/uart.c | 234 ++++++++++++------------- 3 files changed, 266 insertions(+), 341 deletions(-) diff --git a/src/controller/ebike_app.c b/src/controller/ebike_app.c index 07d1ceb1..ae1ad457 100755 --- a/src/controller/ebike_app.c +++ b/src/controller/ebike_app.c @@ -37,7 +37,6 @@ uint8_t ui8_target_battery_max_power_x10 = ADC_BATTERY_CURRENT_MAX; volatile uint8_t ui8_throttle = 0; -volatile uint8_t ui8_torque_sensor_value1 = 0; volatile uint8_t ui8_torque_sensor = 0; volatile uint8_t ui8_torque_sensor_raw = 0; volatile uint8_t ui8_g_adc_torque_sensor_min_value; @@ -86,9 +85,9 @@ volatile uint32_t ui32_wheel_speed_sensor_tick_counter = 0; volatile struct_configuration_variables m_configuration_variables; -// variables for UART -#define UART_NUMBER_DATA_BYTES_TO_RECEIVE 8 // change this value depending on how many data bytes there is to receive ( Package = one start byte + data bytes + two bytes 16 bit CRC ) -#define UART_NUMBER_DATA_BYTES_TO_SEND 23 // change this value depending on how many data bytes there is to send ( Package = one start byte + data bytes + two bytes 16 bit CRC ) +// UART +#define UART_NUMBER_DATA_BYTES_TO_RECEIVE 6 // change this value depending on how many data bytes there is to receive ( Package = one start byte + data bytes + two bytes 16 bit CRC ) +#define UART_NUMBER_DATA_BYTES_TO_SEND 25 // change this value depending on how many data bytes there is to send ( Package = one start byte + data bytes + two bytes 16 bit CRC ) volatile uint8_t ui8_received_package_flag = 0; volatile uint8_t ui8_rx_buffer[UART_NUMBER_DATA_BYTES_TO_RECEIVE + 3]; @@ -97,11 +96,13 @@ volatile uint8_t ui8_tx_buffer[UART_NUMBER_DATA_BYTES_TO_SEND + 3]; volatile uint8_t ui8_i; volatile uint8_t ui8_byte_received; volatile uint8_t ui8_state_machine = 0; -volatile uint8_t ui8_uart_received_first_package = 0; static uint16_t ui16_crc_rx; static uint16_t ui16_crc_tx; -static uint8_t ui8_master_comm_package_id = 0; -static uint8_t ui8_slave_comm_package_id = 0; +volatile uint8_t ui8_message_ID = 0; + +static void communications_controller (void); +static void uart_receive_package (void); +static void uart_send_package (void); uint8_t ui8_tstr_state_machine = STATE_NO_PEDALLING; @@ -119,9 +120,6 @@ static void ebike_control_motor (void); static void ebike_app_set_battery_max_current (uint8_t ui8_value); static void ebike_app_set_target_adc_battery_max_current (uint8_t ui8_value); -static void communications_controller (void); -static void uart_receive_package (void); -static void uart_send_package (void); static void throttle_read (void); static void read_pas_cadence (void); @@ -131,7 +129,6 @@ static void calc_wheel_speed (void); static void calc_motor_temperature (void); static uint16_t calc_filtered_battery_voltage (void); -static void apply_offroad_mode (uint16_t ui16_battery_voltage, uint8_t *ui8_max_speed, uint8_t *ui8_target_current); static void apply_speed_limit (uint16_t ui16_speed_x10, uint8_t ui8_max_speed, uint8_t *ui8_target_current); static void apply_temperature_limiting (uint8_t *ui8_target_current); static void apply_walk_assist(uint8_t *ui8_p_adc_target_current); @@ -176,7 +173,6 @@ static void ebike_control_motor (void) uint8_t ui8_adc_max_battery_current = 0; uint8_t ui8_adc_max_battery_power_current = 0; uint8_t ui8_boost_enabled_and_applied = 0; - uint8_t ui8_tmp_max_speed; uint16_t ui16_battery_voltage_filtered = calc_filtered_battery_voltage (); @@ -276,14 +272,11 @@ static void ebike_control_motor (void) } - /* Apply throttle if this feature is enabled by the user and motor temperature limit function is not enabled */ - if(m_configuration_variables.ui8_temperature_limit_feature_enabled == 2) - { - /* Throttle */ - apply_throttle(ui8_throttle, &ui8_m_adc_battery_target_current); - } + // apply throttle if enabled + apply_throttle(ui8_throttle, &ui8_m_adc_battery_target_current); + - /* Walk assist / Cruise */ + // walk assist or cruise if(m_configuration_variables.ui8_walk_assist) { // enable walk assist or cruise function depending on speed @@ -304,20 +297,8 @@ static void ebike_control_motor (void) ui8_initialize_cruise_PID = 1; } - - // get wheel speed and set in ui8_temp_max_speed - ui8_tmp_max_speed = m_configuration_variables.ui8_wheel_max_speed; - - - /* Offroad mode (limit speed if offroad mode is not active) */ - if(m_configuration_variables.ui8_offroad_feature_enabled) - { - apply_offroad_mode(ui16_battery_voltage_filtered, &ui8_tmp_max_speed, &ui8_m_adc_battery_target_current); - } - - - /* Speed limit */ - apply_speed_limit(ui16_wheel_speed_x10, ui8_tmp_max_speed, &ui8_m_adc_battery_target_current); + // speed limit + apply_speed_limit(ui16_wheel_speed_x10, m_configuration_variables.ui8_wheel_max_speed, &ui8_m_adc_battery_target_current); /* User configured max power on display */ @@ -334,16 +315,9 @@ static void ebike_control_motor (void) } - /* Limit current if motor temperature too high and this feature is enabled by the user */ - if(m_configuration_variables.ui8_temperature_limit_feature_enabled == 1) - { - apply_temperature_limiting(&ui8_m_adc_battery_target_current); - } - else - { - // keep ui8_temperature_current_limiting_value = 255 because 255 means no current limiting happening, otherwise temperature symbol on display will be blinking - m_configuration_variables.ui8_temperature_current_limiting_value = 255; - } + // limit current if motor temperature is too high and this feature is enabled by the user + apply_temperature_limiting(&ui8_m_adc_battery_target_current); + // let's force our target current to 0 if brake is set or if there are errors if(ui8_m_brake_is_set || ui8_system_state != NO_ERROR) @@ -435,45 +409,28 @@ static void uart_receive_package(void) // if CRC is correct read the package (16 bit value and therefore last two bytes) if (((((uint16_t) ui8_rx_buffer [UART_NUMBER_DATA_BYTES_TO_RECEIVE + 2]) << 8) + ((uint16_t) ui8_rx_buffer [UART_NUMBER_DATA_BYTES_TO_RECEIVE + 1])) == ui16_crc_rx) { - ui8_master_comm_package_id = ui8_rx_buffer [1]; - - // send a variable for each package sent but first verify if the last one was received otherwise, keep repeating - // keep cycling so all variables are sent - #define VARIABLE_ID_MAX_NUMBER 5 - if ((ui8_rx_buffer [2]) == ui8_slave_comm_package_id) // last package data ID was receipt, so send the next one - { - ui8_slave_comm_package_id = (ui8_slave_comm_package_id + 1) % VARIABLE_ID_MAX_NUMBER; - } + ui8_message_ID = ui8_rx_buffer [1]; // assist level - m_configuration_variables.ui8_assist_level_factor_x10 = ui8_rx_buffer [3]; + m_configuration_variables.ui8_assist_level_factor_x10 = ui8_rx_buffer [2]; // lights state - m_configuration_variables.ui8_lights = (ui8_rx_buffer [4] & (1 << 0)) ? 1: 0; + m_configuration_variables.ui8_lights = (ui8_rx_buffer [3] & (1 << 0)) ? 1: 0; // set lights lights_set_state (m_configuration_variables.ui8_lights); // walk assist / cruise function - m_configuration_variables.ui8_walk_assist = (ui8_rx_buffer [4] & (1 << 1)) ? 1: 0; - - // offroad mode - m_configuration_variables.ui8_offroad_mode = (ui8_rx_buffer [4]) & (1 << 2) ? 1: 0; - - // battery max current - m_configuration_variables.ui8_battery_max_current = ui8_rx_buffer [5]; - - // set max current from battery - ebike_app_set_battery_max_current (m_configuration_variables.ui8_battery_max_current); + m_configuration_variables.ui8_walk_assist = (ui8_rx_buffer [3] & (1 << 1)) ? 1: 0; - // target battery max power - m_configuration_variables.ui8_target_battery_max_power_div25 = ui8_rx_buffer [6]; + // battery max power target + m_configuration_variables.ui8_target_battery_max_power_div25 = ui8_rx_buffer [4]; - switch (ui8_master_comm_package_id) + switch (ui8_message_ID) { case 0: // battery low voltage cut-off - m_configuration_variables.ui16_battery_low_voltage_cut_off_x10 = (((uint16_t) ui8_rx_buffer [8]) << 8) + ((uint16_t) ui8_rx_buffer [7]); + m_configuration_variables.ui16_battery_low_voltage_cut_off_x10 = (((uint16_t) ui8_rx_buffer [6]) << 8) + ((uint16_t) ui8_rx_buffer [5]); // calc the value in ADC steps and set it up ui32_temp = ((uint32_t) m_configuration_variables.ui16_battery_low_voltage_cut_off_x10 << 8) / ((uint32_t) ADC8BITS_BATTERY_VOLTAGE_PER_ADC_STEP_INVERSE_X256); @@ -483,75 +440,70 @@ static void uart_receive_package(void) case 1: // wheel perimeter - m_configuration_variables.ui16_wheel_perimeter = (((uint16_t) ui8_rx_buffer [8]) << 8) + ((uint16_t) ui8_rx_buffer [7]); + m_configuration_variables.ui16_wheel_perimeter = (((uint16_t) ui8_rx_buffer [6]) << 8) + ((uint16_t) ui8_rx_buffer [5]); break; case 2: // wheel max speed - m_configuration_variables.ui8_wheel_max_speed = ui8_rx_buffer [7]; + m_configuration_variables.ui8_wheel_max_speed = ui8_rx_buffer [5]; + + // battery max current + m_configuration_variables.ui8_battery_max_current = ui8_rx_buffer [6]; + + // set max current from battery + ebike_app_set_battery_max_current (m_configuration_variables.ui8_battery_max_current); break; case 3: // type of motor (36 volt, 48 volt or some experimental type) - m_configuration_variables.ui8_motor_type = (ui8_rx_buffer [7] & 3); + m_configuration_variables.ui8_motor_type = (ui8_rx_buffer [5] & 3); // motor assistance without pedal rotation enable/disable when startup - m_configuration_variables.ui8_motor_assistance_startup_without_pedal_rotation = (ui8_rx_buffer [7] & 4) >> 2; + m_configuration_variables.ui8_motor_assistance_startup_without_pedal_rotation = (ui8_rx_buffer [5] & 4) >> 2; // motor temperature limit function enable/disable - m_configuration_variables.ui8_temperature_limit_feature_enabled = (ui8_rx_buffer [7] & 8) >> 3; + m_configuration_variables.ui8_temperature_limit_feature_enabled = (ui8_rx_buffer [5] & 8) >> 3; // startup motor boost state - m_configuration_variables.ui8_startup_motor_power_boost_state = (ui8_rx_buffer [8] & 1); + m_configuration_variables.ui8_startup_motor_power_boost_state = (ui8_rx_buffer [6] & 1); // startup power boost max power limit - m_configuration_variables.ui8_startup_motor_power_boost_limit_to_max_power = (ui8_rx_buffer [8] & 2) >> 1; + m_configuration_variables.ui8_startup_motor_power_boost_limit_to_max_power = (ui8_rx_buffer [6] & 2) >> 1; break; case 4: // startup motor power boost - m_configuration_variables.ui8_startup_motor_power_boost_assist_level = ui8_rx_buffer [7]; + m_configuration_variables.ui8_startup_motor_power_boost_assist_level = ui8_rx_buffer [5]; // startup motor power boost time - m_configuration_variables.ui8_startup_motor_power_boost_time = ui8_rx_buffer [8]; + m_configuration_variables.ui8_startup_motor_power_boost_time = ui8_rx_buffer [6]; break; case 5: // startup motor power boost fade time - m_configuration_variables.ui8_startup_motor_power_boost_fade_time = ui8_rx_buffer [7]; - m_configuration_variables.ui8_startup_motor_power_boost_feature_enabled = (ui8_rx_buffer [8] & 1); + m_configuration_variables.ui8_startup_motor_power_boost_fade_time = ui8_rx_buffer [5]; + + // startup motor boost enabled + m_configuration_variables.ui8_startup_motor_power_boost_feature_enabled = (ui8_rx_buffer [6] & 1); break; case 6: - // motor temperature min and max values to limit - m_configuration_variables.ui8_motor_temperature_min_value_to_limit = ui8_rx_buffer [7]; - m_configuration_variables.ui8_motor_temperature_max_value_to_limit = ui8_rx_buffer [8]; - break; - - case 7: - // offroad mode configuration - m_configuration_variables.ui8_offroad_feature_enabled = (ui8_rx_buffer [7] & 1); - m_configuration_variables.ui8_offroad_enabled_on_startup = (ui8_rx_buffer [7] & 2) >> 1; + // motor over temperature min value limit + m_configuration_variables.ui8_motor_temperature_min_value_to_limit = ui8_rx_buffer [5]; - // offroad mode speed limit - m_configuration_variables.ui8_offroad_speed_limit = ui8_rx_buffer [8]; - break; - - case 8: - // offroad mode power limit configuration - m_configuration_variables.ui8_offroad_power_limit_enabled = (ui8_rx_buffer [7] & 1); - m_configuration_variables.ui8_offroad_power_limit_div25 = ui8_rx_buffer [8]; + // motor over temperature max value limit + m_configuration_variables.ui8_motor_temperature_max_value_to_limit = ui8_rx_buffer [6]; break; - case 9: + case 7: // ramp up, amps per second - m_configuration_variables.ui8_ramp_up_amps_per_second_x10 = ui8_rx_buffer [7]; + m_configuration_variables.ui8_ramp_up_amps_per_second_x10 = ui8_rx_buffer [5]; // check that value seems correct if (m_configuration_variables.ui8_ramp_up_amps_per_second_x10 < 4 || m_configuration_variables.ui8_ramp_up_amps_per_second_x10 > 100) { // value is not valid, set to default - m_configuration_variables.ui8_ramp_up_amps_per_second_x10 = 50; + m_configuration_variables.ui8_ramp_up_amps_per_second_x10 = DEFAULT_VALUE_RAMP_UP_AMPS_PER_SECOND_X10; } // calculate current step for ramp up @@ -576,11 +528,11 @@ static void uart_receive_package(void) ---------------------------------------------------------*/ // received target speed for cruise - ui16_received_target_wheel_speed_x10 = (uint16_t) (ui8_rx_buffer [8] * 10); + ui16_received_target_wheel_speed_x10 = (uint16_t) (ui8_rx_buffer [6] * 10); break; default: - // nothing + // nothing, should display error code break; } @@ -589,8 +541,6 @@ static void uart_receive_package(void) // signal that we processed the full package ui8_received_package_flag = 0; - - ui8_uart_received_first_package = 1; } // enable UART2 receive interrupt as we are now ready to receive a new package @@ -604,109 +554,85 @@ static void uart_send_package(void) // start up byte ui8_tx_buffer[0] = 0x43; - - // message ID - ui8_tx_buffer[1] = ui8_master_comm_package_id; - ui8_tx_buffer[2] = ui8_slave_comm_package_id; - // adc 10 bits battery voltage + // ADC 10 bits battery voltage ui16_temp = motor_get_adc_battery_voltage_filtered_10b(); - ui8_tx_buffer[3] = (ui16_temp & 0xff); - ui8_tx_buffer[4] = ((uint8_t) (ui16_temp >> 4)) & 0x30; + ui8_tx_buffer[1] = (ui16_temp & 0xff); + ui8_tx_buffer[2] = ((uint8_t) (ui16_temp >> 4)) & 0x30; // battery current x5 - ui8_tx_buffer[5] = (uint8_t) ((float) motor_get_adc_battery_current_filtered_10b() * 0.826); + ui8_tx_buffer[3] = (uint8_t) ((float) motor_get_adc_battery_current_filtered_10b() * 0.826); // wheel speed - ui8_tx_buffer[6] = (uint8_t) (ui16_wheel_speed_x10 & 0xff); - ui8_tx_buffer[7] = (uint8_t) (ui16_wheel_speed_x10 >> 8); + ui8_tx_buffer[4] = (uint8_t) (ui16_wheel_speed_x10 & 0xff); + ui8_tx_buffer[5] = (uint8_t) (ui16_wheel_speed_x10 >> 8); // brake state if(motor_controller_state_is_set(MOTOR_CONTROLLER_STATE_BRAKE)) { - ui8_tx_buffer[8] |= 1; + ui8_tx_buffer[6] |= 1; } else { - ui8_tx_buffer[8] &= ~1; + ui8_tx_buffer[6] &= ~1; } + // throttle value from ADC + ui8_tx_buffer[7] = UI8_ADC_THROTTLE; + + // adjusted throttle value or temperature limit depending on user setup if(m_configuration_variables.ui8_temperature_limit_feature_enabled == 1) { - ui8_tx_buffer[9] = UI8_ADC_THROTTLE; - ui8_tx_buffer[10] = m_configuration_variables.ui8_motor_temperature; + // temperature value + ui8_tx_buffer[8] = m_configuration_variables.ui8_motor_temperature; } else { - // ADC throttle - ui8_tx_buffer[9] = UI8_ADC_THROTTLE; // throttle value with offset removed and mapped to 255 - ui8_tx_buffer[10] = ui8_throttle; + ui8_tx_buffer[8] = ui8_throttle; } // ADC torque_sensor - ui8_tx_buffer[11] = UI8_ADC_TORQUE_SENSOR; + ui8_tx_buffer[9] = UI8_ADC_TORQUE_SENSOR; // torque sensor value with offset removed and mapped to 255 - ui8_tx_buffer[12] = ui8_torque_sensor; + ui8_tx_buffer[10] = ui8_torque_sensor; // PAS cadence - ui8_tx_buffer[13] = ui8_pas_cadence_rpm; + ui8_tx_buffer[11] = ui8_pas_cadence_rpm; // pedal human power mapped to 255 - ui8_tx_buffer[14] = ui8_pedal_human_power; + ui8_tx_buffer[12] = ui8_pedal_human_power; // PWM duty_cycle - ui8_tx_buffer[15] = ui8_g_duty_cycle; + ui8_tx_buffer[13] = ui8_g_duty_cycle; // motor speed in ERPS ui16_temp = ui16_motor_get_motor_speed_erps(); - ui8_tx_buffer[16] = (uint8_t) (ui16_temp & 0xff); - ui8_tx_buffer[17] = (uint8_t) (ui16_temp >> 8); + ui8_tx_buffer[14] = (uint8_t) (ui16_temp & 0xff); + ui8_tx_buffer[15] = (uint8_t) (ui16_temp >> 8); // FOC angle - ui8_tx_buffer[18] = ui8_g_foc_angle; - - switch (ui8_slave_comm_package_id) - { - case 0: - // error states - ui8_tx_buffer[19] = ui8_system_state; - break; - - case 1: - // temperature actual limiting value - ui8_tx_buffer[19] = m_configuration_variables.ui8_temperature_current_limiting_value; - break; - - case 2: - // wheel_speed_sensor_tick_counter - ui8_tx_buffer[19] = (uint8_t) (ui32_wheel_speed_sensor_tick_counter & 0xff); - break; - - case 3: - // wheel_speed_sensor_tick_counter - ui8_tx_buffer[19] = (uint8_t) ((ui32_wheel_speed_sensor_tick_counter >> 8) & 0xff); - break; - - case 4: - // wheel_speed_sensor_tick_counter - ui8_tx_buffer[19] = (uint8_t) ((ui32_wheel_speed_sensor_tick_counter >> 16) & 0xff); - break; - - default: - // keep at 0 - ui8_tx_buffer[19] = 0; - break; - } + ui8_tx_buffer[16] = ui8_g_foc_angle; + + // system state + ui8_tx_buffer[17] = ui8_system_state; + + // temperature actual limiting value + ui8_tx_buffer[18] = m_configuration_variables.ui8_temperature_current_limiting_value; + + // wheel_speed_sensor_tick_counter + ui8_tx_buffer[19] = (uint8_t) (ui32_wheel_speed_sensor_tick_counter & 0xff); + ui8_tx_buffer[20] = (uint8_t) ((ui32_wheel_speed_sensor_tick_counter >> 8) & 0xff); + ui8_tx_buffer[21] = (uint8_t) ((ui32_wheel_speed_sensor_tick_counter >> 16) & 0xff); // ui16_pedal_torque_x10 - ui8_tx_buffer[20] = (uint8_t) (ui16_pedal_torque_x10 & 0xff); - ui8_tx_buffer[21] = (uint8_t) (ui16_pedal_torque_x10 >> 8); + ui8_tx_buffer[22] = (uint8_t) (ui16_pedal_torque_x10 & 0xff); + ui8_tx_buffer[23] = (uint8_t) (ui16_pedal_torque_x10 >> 8); // ui16_pedal_power_x10 - ui8_tx_buffer[22] = (uint8_t) (ui16_pedal_power_x10 & 0xff); - ui8_tx_buffer[23] = (uint8_t) (ui16_pedal_power_x10 >> 8); + ui8_tx_buffer[24] = (uint8_t) (ui16_pedal_power_x10 & 0xff); + ui8_tx_buffer[25] = (uint8_t) (ui16_pedal_power_x10 >> 8); // prepare crc of the package ui16_crc_tx = 0xffff; @@ -817,22 +743,6 @@ static uint16_t calc_filtered_battery_voltage (void) } -static void apply_offroad_mode(uint16_t ui16_battery_voltage, uint8_t *ui8_max_speed, uint8_t *ui8_target_current) -{ - if (!m_configuration_variables.ui8_offroad_mode) - { - // limit speed if offroad mode is not active - *ui8_max_speed = m_configuration_variables.ui8_offroad_speed_limit; - - if (m_configuration_variables.ui8_offroad_power_limit_enabled && m_configuration_variables.ui8_offroad_power_limit_div25 > 0) - { - uint8_t ui8_offroad_mode_max_current = (uint8_t) (((((uint32_t) m_configuration_variables.ui8_offroad_power_limit_div25) * 160) / ((uint32_t) ui16_battery_voltage)) >> 2); - *ui8_target_current = ui8_min (ui8_offroad_mode_max_current, *ui8_target_current); - } - } -} - - static void apply_speed_limit(uint16_t ui16_speed_x10, uint8_t ui8_max_speed, uint8_t *ui8_target_current) { *ui8_target_current = (uint8_t) (map ((uint32_t) ui16_speed_x10, @@ -845,46 +755,59 @@ static void apply_speed_limit(uint16_t ui16_speed_x10, uint8_t ui8_max_speed, ui static void apply_throttle(uint8_t ui8_throttle_value, uint8_t *ui8_target_current) { - // overide ui8_adc_battery_current_max with throttle value only when user is using throttle - if(ui8_throttle_value) + // apply throttle if it is enabled and the motor temperature limit function is not enabled instead + if (m_configuration_variables.ui8_temperature_limit_feature_enabled == 2) { - uint8_t ui8_temp = (uint8_t) (map ((uint32_t) ui8_throttle_value, - (uint32_t) 0, - (uint32_t) 255, - (uint32_t) 0, - (uint32_t) ui8_adc_battery_current_max)); - - // set target current - *ui8_target_current = ui8_temp; + // overide ui8_adc_battery_current_max with throttle value only when user is using throttle + if(ui8_throttle_value) + { + uint8_t ui8_temp = (uint8_t) (map ((uint32_t) ui8_throttle_value, + (uint32_t) 0, + (uint32_t) 255, + (uint32_t) 0, + (uint32_t) ui8_adc_battery_current_max)); + + // set target current + *ui8_target_current = ui8_temp; + } } } static void apply_temperature_limiting(uint8_t *ui8_target_current) { - // min temperature value can't be equal or higher than max temperature value... - if (m_configuration_variables.ui8_motor_temperature_min_value_to_limit >= m_configuration_variables.ui8_motor_temperature_max_value_to_limit) + // apply motor temperature protection if it is enabled and the throttle function is not enabled instead + if (m_configuration_variables.ui8_temperature_limit_feature_enabled == 1) { - *ui8_target_current = 0; - m_configuration_variables.ui8_temperature_current_limiting_value = 0; + // min temperature value can't be equal or higher than max temperature value... + if (m_configuration_variables.ui8_motor_temperature_min_value_to_limit >= m_configuration_variables.ui8_motor_temperature_max_value_to_limit) + { + *ui8_target_current = 0; + m_configuration_variables.ui8_temperature_current_limiting_value = 0; + } + else + { + // reduce motor current if over temperature + *ui8_target_current = + (uint8_t) (map ((uint32_t) m_configuration_variables.ui16_motor_temperature_x2, + (uint32_t) (((uint16_t) m_configuration_variables.ui8_motor_temperature_min_value_to_limit) << 1), + (uint32_t) (((uint16_t) m_configuration_variables.ui8_motor_temperature_max_value_to_limit) << 1), + (uint32_t) *ui8_target_current, + (uint32_t) 0)); + + // get a value linear to the current limitation, just to show to user + m_configuration_variables.ui8_temperature_current_limiting_value = + (uint8_t) (map ((uint32_t) m_configuration_variables.ui16_motor_temperature_x2, + (uint32_t) (((uint16_t) m_configuration_variables.ui8_motor_temperature_min_value_to_limit) << 1), + (uint32_t) (((uint16_t) m_configuration_variables.ui8_motor_temperature_max_value_to_limit) << 1), + (uint32_t) 255, + (uint32_t) 0)); + } } else { - // reduce motor current if over temperature - *ui8_target_current = - (uint8_t) (map ((uint32_t) m_configuration_variables.ui16_motor_temperature_x2, - (uint32_t) (((uint16_t) m_configuration_variables.ui8_motor_temperature_min_value_to_limit) << 1), - (uint32_t) (((uint16_t) m_configuration_variables.ui8_motor_temperature_max_value_to_limit) << 1), - (uint32_t) *ui8_target_current, - (uint32_t) 0)); - - // get a value linear to the current limitation, just to show to user - m_configuration_variables.ui8_temperature_current_limiting_value = - (uint8_t) (map ((uint32_t) m_configuration_variables.ui16_motor_temperature_x2, - (uint32_t) (((uint16_t) m_configuration_variables.ui8_motor_temperature_min_value_to_limit) << 1), - (uint32_t) (((uint16_t) m_configuration_variables.ui8_motor_temperature_max_value_to_limit) << 1), - (uint32_t) 255, - (uint32_t) 0)); + // keep ui8_temperature_current_limiting_value = 255 because 255 means no current limiting happening, otherwise temperature symbol on display will be blinking + m_configuration_variables.ui8_temperature_current_limiting_value = 255; } } @@ -1248,7 +1171,7 @@ struct_configuration_variables* get_configuration_variables (void) void check_system() { - #define MOTOR_BLOCKED_COUNTER_THRESHOLD 50 // 50 => 5 seconds + #define MOTOR_BLOCKED_COUNTER_THRESHOLD 30 // 30 => 3 seconds #define MOTOR_BLOCKED_BATTERY_CURRENT_THRESHOLD_X5 8 // 8 => (8 * 0.826) / 5 = 1.3216 ampere => (X) units = ((X * 0.826) / 5) ampere #define MOTOR_BLOCKED_ERPS_THRESHOLD 10 // 10 ERPS #define MOTOR_BLOCKED_RESET_COUNTER_THRESHOLD 100 // 100 => 10 seconds diff --git a/src/display/KT-LCD3/lcd.c b/src/display/KT-LCD3/lcd.c index d39051a6..49738f99 100644 --- a/src/display/KT-LCD3/lcd.c +++ b/src/display/KT-LCD3/lcd.c @@ -1437,7 +1437,7 @@ void lcd_execute_menu_config_submenu_offroad_mode (void) lcd_configurations_print_number(&lcd_var_number); break; - // offroad speed limit (when offroad mode is off) + // offroad speed limit case 2: lcd_var_number.p_var_number = &configuration_variables.ui8_offroad_speed_limit; lcd_var_number.ui8_size = 8; @@ -1463,7 +1463,7 @@ void lcd_execute_menu_config_submenu_offroad_mode (void) lcd_configurations_print_number(&lcd_var_number); break; - // power limit (W) + // offroad power limit (W) case 4: ui16_temp = ((uint16_t) configuration_variables.ui8_offroad_power_limit_div25) * 25; @@ -1550,19 +1550,6 @@ void lcd_execute_menu_config_power (void) { var_number_t lcd_var_number; uint16_t ui16_temp; - - // because this click event can happen and will block the detection of button_onoff_long_click_event - buttons_clear_onoff_click_event (); - - // leave this menu with a button_onoff_long_click - if (buttons_get_onoff_long_click_event ()) - { - buttons_clear_all_events (); - ui8_lcd_menu = 0; - - // save the updated variables on EEPROM - eeprom_write_variables (); - } ui16_temp = ((uint16_t) configuration_variables.ui8_target_max_battery_power_div25) * 25; lcd_var_number.p_var_number = &ui16_temp; @@ -1586,6 +1573,17 @@ void lcd_execute_menu_config_power (void) lcd_enable_w_symbol (1); lcd_enable_motor_symbol (1); + + // leave this power menu with a button_onoff_long_click + if (buttons_get_onoff_long_click_event ()) + { + buttons_clear_onoff_long_click_event (); + + ui8_lcd_menu = 0; + + // save the updated variables on EEPROM + eeprom_write_variables (); + } } diff --git a/src/display/KT-LCD3/uart.c b/src/display/KT-LCD3/uart.c index 872e701c..b7995504 100644 --- a/src/display/KT-LCD3/uart.c +++ b/src/display/KT-LCD3/uart.c @@ -15,8 +15,9 @@ #include "lcd.h" #include "utils.h" -#define UART_NUMBER_DATA_BYTES_TO_RECEIVE 23 // change this value depending on how many data bytes there is to receive ( Package = one start byte + data bytes + two bytes 16 bit CRC ) -#define UART_NUMBER_DATA_BYTES_TO_SEND 8 // change this value depending on how many data bytes there is to send ( Package = one start byte + data bytes + two bytes 16 bit CRC ) +#define UART_NUMBER_DATA_BYTES_TO_RECEIVE 25 // change this value depending on how many data bytes there is to receive ( Package = one start byte + data bytes + two bytes 16 bit CRC ) +#define UART_NUMBER_DATA_BYTES_TO_SEND 6 // change this value depending on how many data bytes there is to send ( Package = one start byte + data bytes + two bytes 16 bit CRC ) +#define UART_MAX_NUMBER_MESSAGE_ID 7 volatile uint8_t ui8_received_package_flag = 0; volatile uint8_t ui8_rx_buffer[UART_NUMBER_DATA_BYTES_TO_RECEIVE + 3]; @@ -28,8 +29,7 @@ volatile uint8_t ui8_state_machine = 0; volatile uint8_t ui8_uart_received_first_package = 0; static uint16_t ui16_crc_rx; static uint16_t ui16_crc_tx; -static uint8_t ui8_master_comm_package_id = 0; -static uint8_t ui8_slave_comm_package_id = 0; +static uint8_t ui8_message_ID = 0; void uart2_init (void) @@ -117,76 +117,76 @@ void uart_data_clock (void) { p_motor_controller_data = lcd_get_motor_controller_data (); p_configuration_variables = get_configuration_variables (); - - // send a variable for each package sent but first verify if the last one was received otherwise, keep repeating - // keep cycling so all variables are sent - #define VARIABLE_ID_MAX_NUMBER 10 - if ((ui8_rx_buffer [1]) == ui8_master_comm_package_id) // last package data ID was receipt, so send the next one - { - ui8_master_comm_package_id = (ui8_master_comm_package_id + 1) % VARIABLE_ID_MAX_NUMBER; - } - - ui8_slave_comm_package_id = ui8_rx_buffer[2]; - - p_motor_controller_data->ui16_adc_battery_voltage = ui8_rx_buffer[3]; - p_motor_controller_data->ui16_adc_battery_voltage |= ((uint16_t) (ui8_rx_buffer[4] & 0x30)) << 4; - p_motor_controller_data->ui8_battery_current_x5 = ui8_rx_buffer[5]; - p_motor_controller_data->ui16_wheel_speed_x10 = (((uint16_t) ui8_rx_buffer [7]) << 8) + ((uint16_t) ui8_rx_buffer [6]); - p_motor_controller_data->ui8_motor_controller_state_2 = ui8_rx_buffer[8]; + + // ADC 10 bits battery voltage + p_motor_controller_data->ui16_adc_battery_voltage = ui8_rx_buffer[1]; + p_motor_controller_data->ui16_adc_battery_voltage |= ((uint16_t) (ui8_rx_buffer[2] & 0x30)) << 4; + + // battery current x5 + p_motor_controller_data->ui8_battery_current_x5 = ui8_rx_buffer[3]; + + // wheel speed + p_motor_controller_data->ui16_wheel_speed_x10 = (((uint16_t) ui8_rx_buffer [4]) << 8) + ((uint16_t) ui8_rx_buffer [5]); + + // brake state + p_motor_controller_data->ui8_motor_controller_state_2 = ui8_rx_buffer[6]; + + // set brake state p_motor_controller_data->ui8_braking = p_motor_controller_data->ui8_motor_controller_state_2 & 1; - + + // throttle value from ADC + p_motor_controller_data->ui8_adc_throttle = ui8_rx_buffer[7]; + + // adjusted throttle value or temperature limit depending on user setup if (p_configuration_variables->ui8_temperature_limit_feature_enabled == 1) { - p_motor_controller_data->ui8_adc_throttle = ui8_rx_buffer[9]; - p_motor_controller_data->ui8_motor_temperature = ui8_rx_buffer[10]; + // temperature value + p_motor_controller_data->ui8_motor_temperature = ui8_rx_buffer[8]; } else { - p_motor_controller_data->ui8_adc_throttle = ui8_rx_buffer[9]; - p_motor_controller_data->ui8_throttle = ui8_rx_buffer[10]; - } - - p_motor_controller_data->ui8_adc_pedal_torque_sensor = ui8_rx_buffer[11]; - p_motor_controller_data->ui8_pedal_torque_sensor = ui8_rx_buffer[12]; - p_motor_controller_data->ui8_pedal_cadence = ui8_rx_buffer[13]; - p_motor_controller_data->ui8_pedal_human_power = ui8_rx_buffer[14]; - p_motor_controller_data->ui8_duty_cycle = ui8_rx_buffer[15]; - p_motor_controller_data->ui16_motor_speed_erps = (((uint16_t) ui8_rx_buffer [17]) << 8) + ((uint16_t) ui8_rx_buffer [16]); - p_motor_controller_data->ui8_foc_angle = ui8_rx_buffer[18]; - - switch (ui8_slave_comm_package_id) - { - case 0: - // error states - p_motor_controller_data->ui8_error_states = ui8_rx_buffer[19]; - break; - - case 1: - // temperature actual limiting value - p_motor_controller_data->ui8_temperature_current_limiting_value = ui8_rx_buffer[19]; - break; - - case 2: - // wheel_speed_sensor_tick_counter - ui32_wss_tick_temp = ((uint32_t) ui8_rx_buffer[19]); - break; - - case 3: - // wheel_speed_sensor_tick_counter - ui32_wss_tick_temp |= (((uint32_t) ui8_rx_buffer[19]) << 8); - break; - - case 4: - // wheel_speed_sensor_tick_counter - ui32_wss_tick_temp |= (((uint32_t) ui8_rx_buffer[19]) << 16); - p_motor_controller_data->ui32_wheel_speed_sensor_tick_counter = ui32_wss_tick_temp; - break; + // throttle value with offset removed and mapped to 255 + p_motor_controller_data->ui8_throttle = ui8_rx_buffer[8]; } + + // ADC torque_sensor + p_motor_controller_data->ui8_adc_pedal_torque_sensor = ui8_rx_buffer[9]; + + // torque sensor value with offset removed and mapped to 255 + p_motor_controller_data->ui8_pedal_torque_sensor = ui8_rx_buffer[10]; + + // PAS cadence + p_motor_controller_data->ui8_pedal_cadence = ui8_rx_buffer[11]; + + // pedal human power mapped to 255 + p_motor_controller_data->ui8_pedal_human_power = ui8_rx_buffer[12]; + + // PWM duty_cycle + p_motor_controller_data->ui8_duty_cycle = ui8_rx_buffer[13]; + + // motor speed in ERPS + p_motor_controller_data->ui16_motor_speed_erps = (((uint16_t) ui8_rx_buffer [15]) << 8) + ((uint16_t) ui8_rx_buffer [14]); + + // FOC angle + p_motor_controller_data->ui8_foc_angle = ui8_rx_buffer[16]; + + // controller system state + p_motor_controller_data->ui8_error_states = ui8_rx_buffer[17]; + + // temperature actual limiting value + p_motor_controller_data->ui8_temperature_current_limiting_value = ui8_rx_buffer[18]; + + // wheel_speed_sensor_tick_counter + ui32_wss_tick_temp = ((uint32_t) ui8_rx_buffer[19]); + ui32_wss_tick_temp |= (((uint32_t) ui8_rx_buffer[20]) << 8); + ui32_wss_tick_temp |= (((uint32_t) ui8_rx_buffer[21]) << 16); + p_motor_controller_data->ui32_wheel_speed_sensor_tick_counter = ui32_wss_tick_temp; // ui16_pedal_torque_x10 - p_motor_controller_data->ui16_pedal_torque_x10 = (((uint16_t) ui8_rx_buffer [21]) << 8) + ((uint16_t) ui8_rx_buffer [20]); + p_motor_controller_data->ui16_pedal_torque_x10 = (((uint16_t) ui8_rx_buffer [23]) << 8) + ((uint16_t) ui8_rx_buffer [22]); + // ui16_pedal_power_x10 - p_motor_controller_data->ui16_pedal_power_x10 = (((uint16_t) ui8_rx_buffer [23]) << 8) + ((uint16_t) ui8_rx_buffer [22]); + p_motor_controller_data->ui16_pedal_power_x10 = (((uint16_t) ui8_rx_buffer [25]) << 8) + ((uint16_t) ui8_rx_buffer [24]); // signal that we processed the full package ui8_received_package_flag = 0; @@ -199,111 +199,114 @@ void uart_data_clock (void) ui8_tx_buffer[0] = 0x59; // message ID - ui8_tx_buffer[1] = ui8_master_comm_package_id; - ui8_tx_buffer[2] = ui8_slave_comm_package_id; + ui8_tx_buffer[1] = ui8_message_ID; // assist level if (p_motor_controller_data->ui8_walk_assist_level) // if walk assist function is enabled, send walk assist level factor { - ui8_tx_buffer[3] = p_configuration_variables->ui8_walk_assist_level_factor [(p_configuration_variables->ui8_assist_level)]; + ui8_tx_buffer[2] = p_configuration_variables->ui8_walk_assist_level_factor [(p_configuration_variables->ui8_assist_level)]; } else if (p_configuration_variables->ui8_assist_level) // send assist level factor for normal operation { - ui8_tx_buffer[3] = p_configuration_variables->ui8_assist_level_factor [((p_configuration_variables->ui8_assist_level) - 1)]; + ui8_tx_buffer[2] = p_configuration_variables->ui8_assist_level_factor [((p_configuration_variables->ui8_assist_level) - 1)]; } else // send nothing { - ui8_tx_buffer[3] = 0; + ui8_tx_buffer[2] = 0; } // set lights state // walk assist level state - // set offroad state - ui8_tx_buffer[4] = ((p_motor_controller_data->ui8_lights & 1) | - ((p_motor_controller_data->ui8_walk_assist_level & 1) << 1) | - ((p_motor_controller_data->ui8_offroad_mode & 1) << 2)); - - // battery max current in amps - ui8_tx_buffer[5] = p_configuration_variables->ui8_battery_max_current; - - // battery power - ui8_tx_buffer[6] = p_configuration_variables->ui8_target_max_battery_power_div25; - - switch (ui8_master_comm_package_id) + ui8_tx_buffer[3] = ((p_motor_controller_data->ui8_lights & 1) | + ((p_motor_controller_data->ui8_walk_assist_level & 1) << 1)); + + // battery power limit + if (p_configuration_variables->ui8_offroad_feature_enabled && p_configuration_variables->ui8_offroad_power_limit_enabled) + { + ui8_tx_buffer[4] = p_configuration_variables->ui8_offroad_power_limit_div25; + } + else + { + ui8_tx_buffer[4] = p_configuration_variables->ui8_target_max_battery_power_div25; + } + + switch (ui8_message_ID) { case 0: // battery low voltage cut-off - ui8_tx_buffer[7] = (uint8_t) (p_configuration_variables->ui16_battery_low_voltage_cut_off_x10 & 0xff); - ui8_tx_buffer[8] = (uint8_t) (p_configuration_variables->ui16_battery_low_voltage_cut_off_x10 >> 8); + ui8_tx_buffer[5] = (uint8_t) (p_configuration_variables->ui16_battery_low_voltage_cut_off_x10 & 0xff); + ui8_tx_buffer[6] = (uint8_t) (p_configuration_variables->ui16_battery_low_voltage_cut_off_x10 >> 8); break; case 1: // wheel perimeter - ui8_tx_buffer[7] = (uint8_t) (p_configuration_variables->ui16_wheel_perimeter & 0xff); - ui8_tx_buffer[8] = (uint8_t) (p_configuration_variables->ui16_wheel_perimeter >> 8); + ui8_tx_buffer[5] = (uint8_t) (p_configuration_variables->ui16_wheel_perimeter & 0xff); + ui8_tx_buffer[6] = (uint8_t) (p_configuration_variables->ui16_wheel_perimeter >> 8); break; case 2: // wheel max speed - ui8_tx_buffer[7] = p_configuration_variables->ui8_wheel_max_speed; + if (p_configuration_variables->ui8_offroad_feature_enabled) + { + ui8_tx_buffer[5] = p_configuration_variables->ui8_offroad_speed_limit; + } + else + { + ui8_tx_buffer[5] = p_configuration_variables->ui8_wheel_max_speed; + } + + // battery max current in amps + ui8_tx_buffer[6] = p_configuration_variables->ui8_battery_max_current; break; case 3: // set motor type // enable/disable motor assistance without pedal rotation // enable/disable motor temperature limit function - ui8_tx_buffer[7] = ((p_configuration_variables->ui8_motor_type & 3) | + ui8_tx_buffer[5] = ((p_configuration_variables->ui8_motor_type & 3) | ((p_configuration_variables->ui8_motor_assistance_startup_without_pedal_rotation & 1) << 2) | ((p_configuration_variables->ui8_temperature_limit_feature_enabled & 3) << 3)); // motor power boost startup state - ui8_tx_buffer[8] = p_configuration_variables->ui8_startup_motor_power_boost_state; + ui8_tx_buffer[6] = p_configuration_variables->ui8_startup_motor_power_boost_state; break; case 4: // startup motor power boost - ui8_tx_buffer[7] = p_configuration_variables->ui8_startup_motor_power_boost_factor [((p_configuration_variables->ui8_assist_level) - 1)]; + ui8_tx_buffer[5] = p_configuration_variables->ui8_startup_motor_power_boost_factor [((p_configuration_variables->ui8_assist_level) - 1)]; + // startup motor power boost time - ui8_tx_buffer[8] = p_configuration_variables->ui8_startup_motor_power_boost_time; + ui8_tx_buffer[6] = p_configuration_variables->ui8_startup_motor_power_boost_time; break; case 5: // startup motor power boost fade time - ui8_tx_buffer[7] = p_configuration_variables->ui8_startup_motor_power_boost_fade_time; + ui8_tx_buffer[5] = p_configuration_variables->ui8_startup_motor_power_boost_fade_time; + // boost feature enabled - ui8_tx_buffer[8] = (p_configuration_variables->ui8_startup_motor_power_boost_feature_enabled & 1) ? 1 : 0; + ui8_tx_buffer[6] = (p_configuration_variables->ui8_startup_motor_power_boost_feature_enabled & 1) ? 1 : 0; break; case 6: - // motor over temperature min and max values to limit - ui8_tx_buffer[7] = p_configuration_variables->ui8_motor_temperature_min_value_to_limit; - ui8_tx_buffer[8] = p_configuration_variables->ui8_motor_temperature_max_value_to_limit; - break; - - case 7: - // offroad mode configuration - ui8_tx_buffer[7] = ((p_configuration_variables->ui8_offroad_feature_enabled & 1) | - ((p_configuration_variables->ui8_offroad_enabled_on_startup & 1) << 1)); - ui8_tx_buffer[8] = p_configuration_variables->ui8_offroad_speed_limit; - break; - - case 8: - // offroad mode power limit configuration - ui8_tx_buffer[7] = p_configuration_variables->ui8_offroad_power_limit_enabled & 1; - ui8_tx_buffer[8] = p_configuration_variables->ui8_offroad_power_limit_div25; + // motor over temperature min value limit + ui8_tx_buffer[5] = p_configuration_variables->ui8_motor_temperature_min_value_to_limit; + + // motor over temperature max value limit + ui8_tx_buffer[6] = p_configuration_variables->ui8_motor_temperature_max_value_to_limit; break; - case 9: + case 7: // ramp up, amps per second - ui8_tx_buffer[7] = p_configuration_variables->ui8_ramp_up_amps_per_second_x10; + ui8_tx_buffer[5] = p_configuration_variables->ui8_ramp_up_amps_per_second_x10; + // cruise target speed if (p_configuration_variables->ui8_cruise_function_set_target_speed_enabled) { - ui8_tx_buffer[8] = p_configuration_variables->ui8_cruise_function_target_speed_kph; + ui8_tx_buffer[6] = p_configuration_variables->ui8_cruise_function_target_speed_kph; } else { - ui8_tx_buffer[8] = 0; + ui8_tx_buffer[6] = 0; } break; @@ -328,11 +331,12 @@ void uart_data_clock (void) { putchar (ui8_tx_buffer[ui8_i]); } + + // increment message ID for next package + if (++ui8_message_ID > UART_MAX_NUMBER_MESSAGE_ID) { ui8_message_ID = 0; } // let's wait for 10 packages, seems that first ADC battery voltage is an incorrect value - ui8_uart_received_first_package++; - if (ui8_uart_received_first_package > 10) - ui8_uart_received_first_package = 10; + if (++ui8_uart_received_first_package > 10) { ui8_uart_received_first_package = 10; } } // enable UART2 receive interrupt as we are now ready to receive a new package