From e16b4afb836103a1d5f61b8a3262bbff7cd6c522 Mon Sep 17 00:00:00 2001 From: Leon Date: Mon, 20 May 2019 21:25:47 +0200 Subject: [PATCH 1/5] Fixed and improved button logic and config menu layout --- src/display/KT-LCD3/buttons.c | 4 +- src/display/KT-LCD3/compile.bat | 4 +- src/display/KT-LCD3/lcd.c | 601 ++++++++++++++++++-------------- src/display/KT-LCD3/main.h | 17 +- 4 files changed, 356 insertions(+), 270 deletions(-) diff --git a/src/display/KT-LCD3/buttons.c b/src/display/KT-LCD3/buttons.c index 66c458c8..8d270120 100644 --- a/src/display/KT-LCD3/buttons.c +++ b/src/display/KT-LCD3/buttons.c @@ -158,7 +158,7 @@ void buttons_clear_all_events (void) void buttons_clock (void) { // needed if the event is not cleared anywhere else - buttons_clear_onoff_click_long_click_event(); + //buttons_clear_onoff_click_long_click_event(); switch (ui8_onoff_button_state) { @@ -177,7 +177,7 @@ void buttons_clock (void) ui8_onoff_button_state_counter++; // event long click - if (ui8_onoff_button_state_counter > 200) // 2 seconds + if (ui8_onoff_button_state_counter > 120) // 1.2 seconds { buttons_set_events(ONOFF_LONG_CLICK); ui8_onoff_button_state = 2; diff --git a/src/display/KT-LCD3/compile.bat b/src/display/KT-LCD3/compile.bat index ba91163d..f23d6866 100644 --- a/src/display/KT-LCD3/compile.bat +++ b/src/display/KT-LCD3/compile.bat @@ -1,4 +1,6 @@ PATH = %PATH%;C:\SDCC\usr\local\bin;%~dp0..\..\..\tools\cygwin\bin make -f Makefile_windows clean -make -f Makefile_windows \ No newline at end of file +make -f Makefile_windows + +PAUSE \ No newline at end of file diff --git a/src/display/KT-LCD3/lcd.c b/src/display/KT-LCD3/lcd.c index 540c79b0..f210b14f 100644 --- a/src/display/KT-LCD3/lcd.c +++ b/src/display/KT-LCD3/lcd.c @@ -101,6 +101,7 @@ static uint8_t ui8_lcd_menu_flash_state; static uint8_t ui8_lcd_menu_flash_state_temperature; static uint8_t ui8_lcd_menu_config_submenu_number = 0; static uint8_t ui8_lcd_menu_config_submenu_active = 0; +static uint8_t ui8_lcd_menu_config_submenu_change_variable_enabled = 0; static uint8_t ui8_odometer_sub_field_state; uint8_t ui8_start_odometer_show_field_number = 0; @@ -164,9 +165,8 @@ uint8_t reset_variable_check (void); void lcd_execute_main_screen (void); void lcd_execute_menu_config (void); void lcd_execute_menu_config_power (void); -void lcd_execute_menu_config_submenu_wheel_config (void); +void lcd_execute_menu_config_submenu_basic_config (void); void lcd_execute_menu_config_submenu_battery (void); -void lcd_execute_menu_config_submenu_battery_soc (void); void lcd_execute_menu_config_submenu_assist_level (void); void lcd_execute_menu_config_submenu_walk_assist (void); void lcd_execute_menu_config_submenu_cruise (void); @@ -176,8 +176,7 @@ void lcd_execute_menu_config_submenu_motor_temperature (void); void lcd_execute_menu_config_submenu_offroad_mode (void); void lcd_execute_menu_config_submenu_technical (void); void update_menu_flashing_state (void); -void advance_on_submenu (uint8_t* ui8_p_state, uint8_t ui8_state_max_number); -void recede_on_submenu (uint8_t* ui8_p_state, uint8_t ui8_state_max_number); +void submenu_state_controller(uint8_t ui8_state_max_number); void advance_on_subfield (uint8_t* ui8_p_state, uint8_t ui8_state_max_number); void recede_on_subfield (uint8_t* ui8_p_state, uint8_t ui8_state_max_number); void odometer_increase_field_state (void); @@ -223,6 +222,7 @@ void lcd_enable_battery_power_1_symbol (uint8_t ui8_state); void lcd_enable_wheel_speed_point_symbol (uint8_t ui8_state); void lcd_enable_wheel_speed_point_symbol (uint8_t ui8_state); void lcd_enable_temperature_degrees_symbol (uint8_t ui8_state); +void lcd_enable_temperature_farneight_symbol (uint8_t ui8_state); // happens every 1 ms @@ -281,6 +281,7 @@ void lcd_clock (void) if (buttons_get_up_down_click_event () && ui8_lcd_menu != 1) { buttons_clear_up_down_click_event (); + ui8_lcd_menu = 1; } @@ -310,6 +311,7 @@ void lcd_clock (void) } low_pass_filter_battery_voltage_current_power (); + // filter using every 500 ms value if (ui8_lcd_menu_counter_500ms_state) { @@ -325,12 +327,6 @@ void lcd_clock (void) calc_battery_soc (); calc_distance (); automatic_power_off_management (); - - // clear the buttons events - buttons_clear_onoff_click_long_click_event(); - buttons_clear_up_click_long_click_event(); - buttons_clear_down_click_long_click_event(); - lcd_update (); // power off system: ONOFF long click event @@ -357,48 +353,12 @@ void lcd_execute_main_screen (void) void lcd_execute_menu_config (void) { - // button check when submenu is not active - if (!ui8_lcd_menu_config_submenu_active) - { - // leave config 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 (); - - return; - } - - // advance on submenu if button_up_click_event - advance_on_submenu (&ui8_lcd_menu_config_submenu_number, 11); // 11 sub menus, case 0 -> case 10 - - // recede on submenu if button_down_click_event - recede_on_submenu (&ui8_lcd_menu_config_submenu_number, 11); - - // check if we should enter a submenu - if (buttons_get_onoff_click_event ()) - { - buttons_clear_onoff_click_event (); - - ui8_lcd_menu_config_submenu_active = 1; - ui8_config_wh_x10_offset = 1; - } - - // print submenu number only half of the time - if (ui8_lcd_menu_flash_state) - { - lcd_print(ui8_lcd_menu_config_submenu_number, WHEEL_SPEED_FIELD, 0); - } - } - else // ui8_lcd_menu_config_submenu_active == 1 + if (ui8_lcd_menu_config_submenu_active) { switch (ui8_lcd_menu_config_submenu_number) { case 0: - lcd_execute_menu_config_submenu_wheel_config (); + lcd_execute_menu_config_submenu_basic_config (); break; case 1: @@ -406,38 +366,34 @@ void lcd_execute_menu_config (void) break; case 2: - lcd_execute_menu_config_submenu_battery_soc (); - break; - - case 3: lcd_execute_menu_config_submenu_assist_level (); break; - case 4: + case 3: lcd_execute_menu_config_submenu_walk_assist (); break; - case 5: + case 4: lcd_execute_menu_config_submenu_cruise (); break; - case 6: + case 5: lcd_execute_menu_config_main_screen_setup (); break; - case 7: + case 6: lcd_execute_menu_config_submenu_motor_startup_power_boost (); break; - case 8: + case 7: lcd_execute_menu_config_submenu_motor_temperature (); break; - case 9: + case 8: lcd_execute_menu_config_submenu_offroad_mode (); break; - case 10: + case 9: lcd_execute_menu_config_submenu_technical (); break; @@ -445,34 +401,66 @@ void lcd_execute_menu_config (void) ui8_lcd_menu_config_submenu_number = 0; break; } + } + else + { + // advance on submenu if button_up_click_event + if (buttons_get_up_click_event ()) + { + // clear button event + buttons_clear_up_click_event (); + + if (ui8_lcd_menu_config_submenu_number < 9) { ++ui8_lcd_menu_config_submenu_number; } + else { ui8_lcd_menu_config_submenu_number = 0; } + } - // leave config menu with a button_onoff_long_click + // recede on submenu if button_down_click_event + if (buttons_get_down_click_event ()) + { + // clear button event + buttons_clear_down_click_event (); + + if (ui8_lcd_menu_config_submenu_number > 0) { --ui8_lcd_menu_config_submenu_number; } + else { ui8_lcd_menu_config_submenu_number = 9; } + } + + // enter submenu if onoff click event + if (buttons_get_onoff_click_event ()) + { + buttons_clear_onoff_click_event (); + + ui8_lcd_menu_config_submenu_active = 1; + ui8_config_wh_x10_offset = 1; + } + + // leave config menu if button_onoff_long_click if (buttons_get_onoff_long_click_event ()) { buttons_clear_onoff_long_click_event (); - - ui8_lcd_menu_config_submenu_active = 0; - ui8_lcd_menu_config_submenu_state = 0; - // set backlight brightness after user has configured settings, looks nicer this way - if (ui8_lights_state == 0) { lcd_set_backlight_intensity (configuration_variables.ui8_lcd_backlight_off_brightness); } - else { lcd_set_backlight_intensity (configuration_variables.ui8_lcd_backlight_on_brightness); } + // switch to main screen + ui8_lcd_menu = 0; + + // save the updated variables on EEPROM + eeprom_write_variables (); + + return; + } + + // print submenu number only half of the time + if (ui8_lcd_menu_flash_state) + { + lcd_print(ui8_lcd_menu_config_submenu_number, WHEEL_SPEED_FIELD, 0); } } } -void lcd_execute_menu_config_submenu_wheel_config(void) +void lcd_execute_menu_config_submenu_basic_config(void) { var_number_t lcd_var_number; uint32_t ui32_temp; static uint8_t ui8_reset_to_defaults_counter; - - // advance on submenu on button_up_click_event - advance_on_submenu (&ui8_lcd_menu_config_submenu_state, 8); - - // recede on submenu if button_down_click_event - recede_on_submenu (&ui8_lcd_menu_config_submenu_number, 8); switch(ui8_lcd_menu_config_submenu_state) { @@ -490,18 +478,23 @@ void lcd_execute_menu_config_submenu_wheel_config(void) // clear previous number written on ODOMETER_FIELD ui8_lcd_frame_buffer[ui8_lcd_field_offset[ODOMETER_FIELD] - 1] &= NUMBERS_MASK; - - if (configuration_variables.ui8_units_type == 1 && ui8_lcd_menu_flash_state) - { - lcd_enable_mil_symbol(1); - lcd_enable_mph_symbol(1); - } - else if (configuration_variables.ui8_units_type == 0 && ui8_lcd_menu_flash_state) + + if (ui8_lcd_menu_flash_state || !ui8_lcd_menu_config_submenu_change_variable_enabled) { - lcd_enable_km_symbol(1); - lcd_enable_kmh_symbol(1); + if (configuration_variables.ui8_units_type == 1) + { + lcd_enable_mil_symbol(1); + lcd_enable_mph_symbol(1); + lcd_enable_temperature_farneight_symbol(1); + } + else + { + lcd_enable_km_symbol(1); + lcd_enable_kmh_symbol(1); + lcd_enable_temperature_degrees_symbol(1); + } } - + break; // menu to choose max wheel speed @@ -595,6 +588,10 @@ void lcd_execute_menu_config_submenu_wheel_config(void) lcd_enable_km_symbol(1); } + // set backlight brightness after user has configured settings, looks nicer this way + if (ui8_lights_state == 0) { lcd_set_backlight_intensity (configuration_variables.ui8_lcd_backlight_off_brightness); } + else { lcd_set_backlight_intensity (configuration_variables.ui8_lcd_backlight_on_brightness); } + break; // backlight off brightness @@ -683,7 +680,9 @@ void lcd_execute_menu_config_submenu_wheel_config(void) break; } - if (ui8_lcd_menu_config_submenu_state > 1) + submenu_state_controller(7); // 7 sub menus + + if (ui8_lcd_menu_config_submenu_state > 1 && (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled)) { lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); } @@ -694,12 +693,6 @@ void lcd_execute_menu_config_submenu_battery (void) { var_number_t lcd_var_number; - // advance on submenu on button_up_click_event - advance_on_submenu (&ui8_lcd_menu_config_submenu_state, 5); - - // recede on submenu if button_down_click_event - recede_on_submenu (&ui8_lcd_menu_config_submenu_number, 5); - switch (ui8_lcd_menu_config_submenu_state) { // battery max current @@ -755,26 +748,9 @@ void lcd_execute_menu_config_submenu_battery (void) lcd_print (ui16_battery_voltage_soc_x10, ODOMETER_FIELD, 1); lcd_enable_vol_symbol(1); break; - } - - lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); -} - - -void lcd_execute_menu_config_submenu_battery_soc (void) -{ - var_number_t lcd_var_number; - - // advance on submenu on button_up_click_event - advance_on_submenu (&ui8_lcd_menu_config_submenu_state, 4); - - // recede on submenu if button_down_click_event - recede_on_submenu (&ui8_lcd_menu_config_submenu_number, 4); - - switch (ui8_lcd_menu_config_submenu_state) - { + // menu to enable/disable show of numeric watt-hour value and type of representation - case 0: + case 5: lcd_var_number.p_var_number = &configuration_variables.ui8_battery_SOC_function_enabled; lcd_var_number.ui8_size = 8; lcd_var_number.ui8_decimal_digit = 0; @@ -786,7 +762,7 @@ void lcd_execute_menu_config_submenu_battery_soc (void) break; // menu to set battery_voltage_reset_wh_counter - case 1: + case 6: lcd_var_number.p_var_number = &configuration_variables.ui16_battery_voltage_reset_wh_counter_x10; lcd_var_number.ui8_size = 16; lcd_var_number.ui8_decimal_digit = 1; @@ -798,7 +774,7 @@ void lcd_execute_menu_config_submenu_battery_soc (void) break; // menu to set battery capacity in watt-hours - case 2: + case 7: lcd_var_number.p_var_number = &configuration_variables.ui32_wh_x10_100_percent; lcd_var_number.ui8_size = 32; lcd_var_number.ui8_decimal_digit = 1; @@ -810,7 +786,7 @@ void lcd_execute_menu_config_submenu_battery_soc (void) break; // menu to set current watt hour value - case 3: + case 8: // on the very first time, use current value of ui32_wh_x10 if (ui8_config_wh_x10_offset) { @@ -832,8 +808,13 @@ void lcd_execute_menu_config_submenu_battery_soc (void) lcd_configurations_print_number(&lcd_var_number); break; } - - lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + + submenu_state_controller(8); // 8 sub menus + + if (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + } } @@ -841,28 +822,29 @@ void lcd_execute_menu_config_submenu_assist_level (void) { var_number_t lcd_var_number; - // advance on submenu on button_up_click_event - advance_on_submenu (&ui8_lcd_menu_config_submenu_state, (configuration_variables.ui8_number_of_assist_levels + 1)); - - // recede on submenu if button_down_click_event - recede_on_submenu (&ui8_lcd_menu_config_submenu_number, (configuration_variables.ui8_number_of_assist_levels + 1)); - // number of assist levels: 1 to 9 if (ui8_lcd_menu_config_submenu_state == 0) { lcd_var_number.p_var_number = &configuration_variables.ui8_number_of_assist_levels; lcd_var_number.ui8_size = 8; - lcd_var_number.ui8_decimal_digit = 0; + lcd_var_number.ui8_decimal_digit = 1; lcd_var_number.ui32_max_value = 9; lcd_var_number.ui32_min_value = 1; lcd_var_number.ui32_increment_step = 1; - lcd_var_number.ui8_odometer_field = ODOMETER_FIELD; + lcd_var_number.ui8_odometer_field = ASSIST_LEVEL_FIELD; lcd_configurations_print_number(&lcd_var_number); - lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + if (ui8_lcd_menu_flash_state || !ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_enable_assist_symbol (1); + } + + if (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + } } - // value of each assist level factor - else + else // value of each assist level factor { lcd_var_number.p_var_number = &configuration_variables.ui8_assist_level_factor[(ui8_lcd_menu_config_submenu_state - 1)]; lcd_var_number.ui8_size = 8; @@ -873,9 +855,14 @@ void lcd_execute_menu_config_submenu_assist_level (void) lcd_var_number.ui8_odometer_field = ODOMETER_FIELD; lcd_configurations_print_number(&lcd_var_number); - lcd_enable_assist_symbol (1); - lcd_print(ui8_lcd_menu_config_submenu_state, ASSIST_LEVEL_FIELD, 1); + if (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_enable_assist_symbol (1); + lcd_print(ui8_lcd_menu_config_submenu_state, ASSIST_LEVEL_FIELD, 1); + } } + + submenu_state_controller(configuration_variables.ui8_number_of_assist_levels); } @@ -883,12 +870,6 @@ void lcd_execute_menu_config_submenu_walk_assist (void) { var_number_t lcd_var_number; - // advance on submenu on button_up_click_event - advance_on_submenu (&ui8_lcd_menu_config_submenu_state, (configuration_variables.ui8_number_of_assist_levels + 2)); - - // recede on submenu if button_down_click_event - recede_on_submenu (&ui8_lcd_menu_config_submenu_number, (configuration_variables.ui8_number_of_assist_levels + 2)); - // enable/disable walk assist function if (ui8_lcd_menu_config_submenu_state == 0) { @@ -901,15 +882,17 @@ void lcd_execute_menu_config_submenu_walk_assist (void) lcd_var_number.ui8_odometer_field = ODOMETER_FIELD; lcd_configurations_print_number(&lcd_var_number); - if (configuration_variables.ui8_walk_assist_function_enabled) + if (configuration_variables.ui8_walk_assist_function_enabled && (ui8_lcd_menu_flash_state || !ui8_lcd_menu_config_submenu_change_variable_enabled)) { lcd_enable_walk_symbol (1); } - lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + if (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + } } - // value of each walk assist power value - else + else // value of each walk assist power value { lcd_var_number.p_var_number = &configuration_variables.ui8_walk_assist_level_factor[(ui8_lcd_menu_config_submenu_state - 1)]; lcd_var_number.ui8_size = 8; @@ -921,9 +904,15 @@ void lcd_execute_menu_config_submenu_walk_assist (void) lcd_configurations_print_number(&lcd_var_number); lcd_enable_walk_symbol (1); - lcd_enable_assist_symbol (1); - lcd_print(ui8_lcd_menu_config_submenu_state - 1, ASSIST_LEVEL_FIELD, 1); + + if (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_enable_assist_symbol (1); + lcd_print(ui8_lcd_menu_config_submenu_state - 1, ASSIST_LEVEL_FIELD, 1); + } } + + submenu_state_controller(configuration_variables.ui8_number_of_assist_levels + 1); } @@ -931,12 +920,6 @@ void lcd_execute_menu_config_submenu_cruise (void) { var_number_t lcd_var_number; - // advance on submenu on button_up_click_event - advance_on_submenu (&ui8_lcd_menu_config_submenu_state, 4); - - // recede on submenu if button_down_click_event - recede_on_submenu (&ui8_lcd_menu_config_submenu_number, 4); - switch (ui8_lcd_menu_config_submenu_state) { // cruise function enable/disable @@ -951,13 +934,16 @@ void lcd_execute_menu_config_submenu_cruise (void) lcd_var_number.ui8_odometer_field = ODOMETER_FIELD; lcd_configurations_print_number(&lcd_var_number); - if (configuration_variables.ui8_cruise_function_enabled) + if (configuration_variables.ui8_cruise_function_enabled && (ui8_lcd_menu_flash_state || !ui8_lcd_menu_config_submenu_change_variable_enabled)) { lcd_enable_cruise_symbol (1); } - lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); - + if (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + } + break; // enable/disable target speed for cruise @@ -974,8 +960,11 @@ void lcd_execute_menu_config_submenu_cruise (void) lcd_enable_cruise_symbol (1); - lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); - + if (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + } + break; // set cruise target speed @@ -1032,21 +1021,21 @@ void lcd_execute_menu_config_submenu_cruise (void) lcd_enable_cruise_symbol (1); - lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + if (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + } + break; } + + submenu_state_controller(3); } void lcd_execute_menu_config_main_screen_setup (void) { var_number_t lcd_var_number; - - // advance on submenu on button_up_click_event - advance_on_submenu (&ui8_lcd_menu_config_submenu_state, 11); - - // recede on submenu if button_down_click_event - recede_on_submenu (&ui8_lcd_menu_config_submenu_number, 11); switch (ui8_lcd_menu_config_submenu_state) { @@ -1182,8 +1171,13 @@ void lcd_execute_menu_config_main_screen_setup (void) lcd_configurations_print_number(&lcd_var_number); break; } + + submenu_state_controller(10); - lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + if (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + } } @@ -1192,12 +1186,6 @@ void lcd_execute_menu_config_submenu_motor_startup_power_boost (void) var_number_t lcd_var_number; uint8_t ui8_temp; - // advance on submenu on button_up_click_event - advance_on_submenu (&ui8_lcd_menu_config_submenu_state, (configuration_variables.ui8_number_of_assist_levels + 5)); - - // recede on submenu if button_down_click_event - recede_on_submenu (&ui8_lcd_menu_config_submenu_number, (configuration_variables.ui8_number_of_assist_levels + 5)); - // feature enable or disable if (ui8_lcd_menu_config_submenu_state == 0) { @@ -1277,9 +1265,20 @@ void lcd_execute_menu_config_submenu_motor_startup_power_boost (void) lcd_var_number.ui32_increment_step = 1; lcd_var_number.ui8_odometer_field = ODOMETER_FIELD; lcd_configurations_print_number(&lcd_var_number); + + if (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_enable_assist_symbol(1); + lcd_print(ui8_lcd_menu_config_submenu_state - 4, ASSIST_LEVEL_FIELD, 1); + } } - lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + submenu_state_controller(configuration_variables.ui8_number_of_assist_levels + 4); + + if (ui8_lcd_menu_config_submenu_state < 5 && (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled)) + { + lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + } } @@ -1288,12 +1287,6 @@ void lcd_execute_menu_config_submenu_motor_temperature (void) var_number_t lcd_var_number; uint16_t ui16_temp; - // advance on submenu on button_up_click_event - advance_on_submenu (&ui8_lcd_menu_config_submenu_state, 7); - - // recede on submenu if button_down_click_event - recede_on_submenu (&ui8_lcd_menu_config_submenu_number, 7); - switch (ui8_lcd_menu_config_submenu_state) { // motor voltage type @@ -1330,8 +1323,12 @@ void lcd_execute_menu_config_submenu_motor_temperature (void) lcd_configurations_print_number(&lcd_var_number); configuration_variables.ui8_target_max_battery_power_div25 = (uint8_t) (ui16_temp / 25); - lcd_enable_w_symbol (1); - lcd_enable_motor_symbol (1); + if (ui8_lcd_menu_flash_state || !ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_enable_w_symbol (1); + lcd_enable_motor_symbol (1); + } + break; // ramp up, amps per second @@ -1380,6 +1377,9 @@ void lcd_execute_menu_config_submenu_motor_temperature (void) lcd_var_number.ui32_increment_step = 1; lcd_var_number.ui8_odometer_field = ODOMETER_FIELD; lcd_configurations_print_number(&lcd_var_number); + + lcd_enable_temperature_degrees_symbol (1); + break; // motor temperature limit max @@ -1392,10 +1392,18 @@ void lcd_execute_menu_config_submenu_motor_temperature (void) lcd_var_number.ui32_increment_step = 1; lcd_var_number.ui8_odometer_field = ODOMETER_FIELD; lcd_configurations_print_number(&lcd_var_number); + + lcd_enable_temperature_degrees_symbol (1); + break; } - lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + submenu_state_controller(6); + + if (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + } } @@ -1403,12 +1411,6 @@ void lcd_execute_menu_config_submenu_offroad_mode (void) { var_number_t lcd_var_number; uint16_t ui16_temp; - - // advance on submenu on button_up_click_event - advance_on_submenu (&ui8_lcd_menu_config_submenu_state, 5); - - // recede on submenu if button_down_click_event - recede_on_submenu (&ui8_lcd_menu_config_submenu_number, 5); switch (ui8_lcd_menu_config_submenu_state) { @@ -1444,7 +1446,7 @@ void lcd_execute_menu_config_submenu_offroad_mode (void) lcd_var_number.ui32_max_value = 99; lcd_var_number.ui32_min_value = 1; lcd_var_number.ui32_increment_step = 1; - lcd_var_number.ui8_odometer_field = ODOMETER_FIELD; + lcd_var_number.ui8_odometer_field = WHEEL_SPEED_FIELD; lcd_configurations_print_number(&lcd_var_number); lcd_enable_kmh_symbol (1); @@ -1472,26 +1474,31 @@ void lcd_execute_menu_config_submenu_offroad_mode (void) lcd_var_number.ui32_max_value = 1000; lcd_var_number.ui32_min_value = 0; lcd_var_number.ui32_increment_step = 25; - lcd_var_number.ui8_odometer_field = ODOMETER_FIELD; + lcd_var_number.ui8_odometer_field = BATTERY_POWER_FIELD; lcd_configurations_print_number(&lcd_var_number); configuration_variables.ui8_offroad_power_limit_div25 = (uint8_t) (ui16_temp / 25); - lcd_enable_w_symbol(1); + + if (ui8_lcd_menu_flash_state || !ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_enable_w_symbol (1); + lcd_enable_motor_symbol (1); + } + break; } - lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + submenu_state_controller(4); + + if (ui8_lcd_menu_config_submenu_state != 2 && (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled)) + { + lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + } } void lcd_execute_menu_config_submenu_technical (void) { - // advance on submenu on button_up_click_event - advance_on_submenu (&ui8_lcd_menu_config_submenu_state, 9); - - // recede on submenu if button_down_click_event - recede_on_submenu (&ui8_lcd_menu_config_submenu_number, 9); - switch (ui8_lcd_menu_config_submenu_state) { case 0: @@ -1531,7 +1538,12 @@ void lcd_execute_menu_config_submenu_technical (void) break; } - lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + submenu_state_controller(8); + + if (ui8_lcd_menu_flash_state || ui8_lcd_menu_config_submenu_change_variable_enabled) + { + lcd_print(ui8_lcd_menu_config_submenu_state, WHEEL_SPEED_FIELD, 0); + } } @@ -1917,11 +1929,8 @@ void assist_level_state (void) // clear button event buttons_clear_up_click_event (); - // increment assist level - configuration_variables.ui8_assist_level++; - - // check if assist level variable is out of bounds - if (configuration_variables.ui8_assist_level > configuration_variables.ui8_number_of_assist_levels) + // increment assist level and check if is out of bounds + if (++configuration_variables.ui8_assist_level > configuration_variables.ui8_number_of_assist_levels) { // set assist level to max configuration_variables.ui8_assist_level = configuration_variables.ui8_number_of_assist_levels; @@ -1938,7 +1947,7 @@ void assist_level_state (void) if (configuration_variables.ui8_assist_level > 0) { // decrement assist level - configuration_variables.ui8_assist_level--; + --configuration_variables.ui8_assist_level; } } @@ -3477,14 +3486,81 @@ void update_menu_flashing_state(void) } +void submenu_state_controller (uint8_t ui8_state_max_number) +{ + if (ui8_lcd_menu_config_submenu_change_variable_enabled) + { + // clear onoff click event if it happened + if (buttons_get_onoff_click_event ()) + { + buttons_clear_onoff_click_event (); + } + + // stop changing variables if long onoff click + if (buttons_get_onoff_long_click_event ()) + { + buttons_clear_onoff_long_click_event (); + + ui8_lcd_menu_config_submenu_change_variable_enabled = 0; + } + } + else + { + // change variables if onoff click event + if (buttons_get_onoff_click_event ()) + { + buttons_clear_onoff_click_event (); + + ui8_lcd_menu_config_submenu_change_variable_enabled = 1; + } + else + { + // advance on submenus on button_up_click_event + if (buttons_get_up_click_event ()) + { + // clear button event + buttons_clear_up_click_event (); + + if (ui8_lcd_menu_config_submenu_state < ui8_state_max_number) { ++ui8_lcd_menu_config_submenu_state; } + else { ui8_lcd_menu_config_submenu_state = 0; } + } + + // recede on submenus on button_down_click_event + if (buttons_get_down_click_event ()) + { + // clear button event + buttons_clear_down_click_event (); + + if (ui8_lcd_menu_config_submenu_state > 0) { --ui8_lcd_menu_config_submenu_state; } + else { ui8_lcd_menu_config_submenu_state = ui8_state_max_number; } + } + + // leave config menu with a button_onoff_long_click + if (buttons_get_onoff_long_click_event ()) + { + buttons_clear_onoff_long_click_event (); + + ui8_lcd_menu_config_submenu_active = 0; + ui8_lcd_menu_config_submenu_state = 0; + + // set backlight brightness after user has configured settings, looks nicer this way + if (ui8_lights_state == 0) { lcd_set_backlight_intensity (configuration_variables.ui8_lcd_backlight_off_brightness); } + else { lcd_set_backlight_intensity (configuration_variables.ui8_lcd_backlight_on_brightness); } + } + } + } +} + void advance_on_submenu (uint8_t* ui8_p_state, uint8_t ui8_state_max_number) { // advance on submenus on button_up_click_event if (buttons_get_up_click_event ()) { + // clear button event buttons_clear_up_click_event (); - - *ui8_p_state = (*ui8_p_state + 1) % ui8_state_max_number; + + if (*ui8_p_state < ui8_state_max_number) { ++*ui8_p_state; } + else { *ui8_p_state = 0; } } } @@ -3494,9 +3570,11 @@ void recede_on_submenu (uint8_t* ui8_p_state, uint8_t ui8_state_max_number) // recede on submenus on button_down_click_event if (buttons_get_down_click_event ()) { + // clear button event buttons_clear_down_click_event (); - *ui8_p_state = (*ui8_p_state - 1) % ui8_state_max_number; + if (*ui8_p_state > 0) { --*ui8_p_state; } + else { *ui8_p_state = ui8_state_max_number; } } } @@ -3509,7 +3587,8 @@ void advance_on_subfield (uint8_t* ui8_p_state, uint8_t ui8_state_max_number) // clear button event buttons_clear_up_click_long_click_event (); - *ui8_p_state = (*ui8_p_state + 1) % ui8_state_max_number; + if (*ui8_p_state < ui8_state_max_number) { ++*ui8_p_state; } + else { *ui8_p_state = 0; } odometer_start_show_field_number (); } @@ -3523,7 +3602,8 @@ void recede_on_subfield (uint8_t* ui8_p_state, uint8_t ui8_state_max_number) // clear button event buttons_clear_down_click_long_click_event (); - *ui8_p_state = (*ui8_p_state - 1) % ui8_state_max_number; + if (*ui8_p_state > 0) { --*ui8_p_state; } + else { *ui8_p_state = ui8_state_max_number; } odometer_start_show_field_number (); } @@ -3573,68 +3653,79 @@ void lcd_configurations_print_number(var_number_t* p_lcd_var_number) { ui32_p_var = ((uint32_t *) p_lcd_var_number->p_var_number); } - - // if LONG CLICK, keep track of long click so variable is increased automatically 10x every second - if(buttons_get_up_long_click_event() || buttons_get_down_long_click_event()) - { - ui8_long_click_started = 1; - } - - // trigger at every 100 ms if UP/DOWN LONG CLICK - if((ui8_long_click_started == 1) && (buttons_get_up_state() || buttons_get_down_state())) + + if (ui8_lcd_menu_config_submenu_change_variable_enabled) { - if(++ui8_long_click_counter >= 10) + // if LONG CLICK, keep track of long click so variable is increased automatically 10x every second + if(buttons_get_up_long_click_event() || buttons_get_down_long_click_event()) { - ui8_long_click_counter = 0; - ui8_long_click_trigger = 1; + ui8_long_click_started = 1; } - } - else - { - ui8_long_click_started = 0; - ui8_long_click_counter = 0; - } - // increase - if(buttons_get_up_click_event() || (buttons_get_up_state() && ui8_long_click_trigger)) - { - if(p_lcd_var_number->ui8_size == 8) - { - if((*ui8_p_var) <= (p_lcd_var_number->ui32_max_value - p_lcd_var_number->ui32_increment_step)) { (*ui8_p_var) += p_lcd_var_number->ui32_increment_step; } - else { (*ui8_p_var) = (uint8_t) p_lcd_var_number->ui32_max_value; } - } - else if(p_lcd_var_number->ui8_size == 16) + // trigger at every 100 ms if UP/DOWN LONG CLICK + if((ui8_long_click_started == 1) && (buttons_get_up_state() || buttons_get_down_state())) { - if((*ui16_p_var) <= (p_lcd_var_number->ui32_max_value - p_lcd_var_number->ui32_increment_step)) { (*ui16_p_var) += p_lcd_var_number->ui32_increment_step; } - else { (*ui16_p_var) = (uint16_t) p_lcd_var_number->ui32_max_value; } + if(++ui8_long_click_counter >= 10) + { + ui8_long_click_counter = 0; + ui8_long_click_trigger = 1; + } } - else if(p_lcd_var_number->ui8_size == 32) + else { - if((*ui32_p_var) <= (p_lcd_var_number->ui32_max_value - p_lcd_var_number->ui32_increment_step)) { (*ui32_p_var) += p_lcd_var_number->ui32_increment_step; } - else { (*ui32_p_var) = p_lcd_var_number->ui32_max_value; } + ui8_long_click_started = 0; + ui8_long_click_counter = 0; } - } - // decrease - if(buttons_get_down_click_event() || (buttons_get_down_state() && ui8_long_click_trigger)) - { - if(p_lcd_var_number->ui8_size == 8) + // increase + if(buttons_get_up_click_event() || (buttons_get_up_state() && ui8_long_click_trigger)) { - if((*ui8_p_var) >= (p_lcd_var_number->ui32_min_value + p_lcd_var_number->ui32_increment_step)) { (*ui8_p_var) -= p_lcd_var_number->ui32_increment_step; } - else { (*ui8_p_var) = (uint8_t) p_lcd_var_number->ui32_min_value; } - } - else if(p_lcd_var_number->ui8_size == 16) - { - if((*ui16_p_var) >= (p_lcd_var_number->ui32_min_value + p_lcd_var_number->ui32_increment_step)) { (*ui16_p_var) -= p_lcd_var_number->ui32_increment_step; } - else { (*ui16_p_var) = (uint16_t) p_lcd_var_number->ui32_min_value; } + if(p_lcd_var_number->ui8_size == 8) + { + if((*ui8_p_var) <= (p_lcd_var_number->ui32_max_value - p_lcd_var_number->ui32_increment_step)) { (*ui8_p_var) += p_lcd_var_number->ui32_increment_step; } + else { (*ui8_p_var) = (uint8_t) p_lcd_var_number->ui32_max_value; } + } + else if(p_lcd_var_number->ui8_size == 16) + { + if((*ui16_p_var) <= (p_lcd_var_number->ui32_max_value - p_lcd_var_number->ui32_increment_step)) { (*ui16_p_var) += p_lcd_var_number->ui32_increment_step; } + else { (*ui16_p_var) = (uint16_t) p_lcd_var_number->ui32_max_value; } + } + else if(p_lcd_var_number->ui8_size == 32) + { + if((*ui32_p_var) <= (p_lcd_var_number->ui32_max_value - p_lcd_var_number->ui32_increment_step)) { (*ui32_p_var) += p_lcd_var_number->ui32_increment_step; } + else { (*ui32_p_var) = p_lcd_var_number->ui32_max_value; } + } } - else if(p_lcd_var_number->ui8_size == 32) + + // decrease + if(buttons_get_down_click_event() || (buttons_get_down_state() && ui8_long_click_trigger)) { - if((*ui32_p_var) >= (p_lcd_var_number->ui32_min_value + p_lcd_var_number->ui32_increment_step)) { (*ui32_p_var) -= p_lcd_var_number->ui32_increment_step; } - else { (*ui32_p_var) = p_lcd_var_number->ui32_min_value; } + if(p_lcd_var_number->ui8_size == 8) + { + if((*ui8_p_var) >= (p_lcd_var_number->ui32_min_value + p_lcd_var_number->ui32_increment_step)) { (*ui8_p_var) -= p_lcd_var_number->ui32_increment_step; } + else { (*ui8_p_var) = (uint8_t) p_lcd_var_number->ui32_min_value; } + } + else if(p_lcd_var_number->ui8_size == 16) + { + if((*ui16_p_var) >= (p_lcd_var_number->ui32_min_value + p_lcd_var_number->ui32_increment_step)) { (*ui16_p_var) -= p_lcd_var_number->ui32_increment_step; } + else { (*ui16_p_var) = (uint16_t) p_lcd_var_number->ui32_min_value; } + } + else if(p_lcd_var_number->ui8_size == 32) + { + if((*ui32_p_var) >= (p_lcd_var_number->ui32_min_value + p_lcd_var_number->ui32_increment_step)) { (*ui32_p_var) -= p_lcd_var_number->ui32_increment_step; } + else { (*ui32_p_var) = p_lcd_var_number->ui32_min_value; } + } } + + // clear button events + buttons_clear_up_click_event(); + buttons_clear_down_click_event(); + buttons_clear_up_click_long_click_event(); + buttons_clear_up_long_click_event(); + buttons_clear_down_click_long_click_event(); + buttons_clear_down_long_click_event(); } - + if(p_lcd_var_number->ui8_size == 8) { ui32_value = (uint32_t) (*ui8_p_var); @@ -3649,16 +3740,8 @@ void lcd_configurations_print_number(var_number_t* p_lcd_var_number) } // draw only at every ui8_lcd_menu_flash_state -- will flash the number on the LCD - if(ui8_lcd_menu_flash_state) + if(ui8_lcd_menu_flash_state || !ui8_lcd_menu_config_submenu_change_variable_enabled) { lcd_print(ui32_value, p_lcd_var_number->ui8_odometer_field, p_lcd_var_number->ui8_decimal_digit); } - - // clear button events - buttons_clear_up_click_event(); - buttons_clear_up_click_long_click_event(); - buttons_clear_up_long_click_event(); - buttons_clear_down_click_event(); - buttons_clear_down_click_long_click_event(); - buttons_clear_down_long_click_event(); } \ No newline at end of file diff --git a/src/display/KT-LCD3/main.h b/src/display/KT-LCD3/main.h index cef2a15e..a3d9c2c5 100644 --- a/src/display/KT-LCD3/main.h +++ b/src/display/KT-LCD3/main.h @@ -58,6 +58,7 @@ // default values for assist levels +#define DEFAULT_VALUE_ASSIST_LEVEL_FACTOR_0 0 // 0 #define DEFAULT_VALUE_ASSIST_LEVEL_FACTOR_1 3 // 0.3 #define DEFAULT_VALUE_ASSIST_LEVEL_FACTOR_2 6 // 0.6 #define DEFAULT_VALUE_ASSIST_LEVEL_FACTOR_3 9 @@ -73,15 +74,15 @@ // default values for BOOST function #define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_FEATURE_ENABLED 0 // disabled by default #define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_STATE 1 -#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_1 4 -#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_2 7 -#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_3 10 -#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_4 13 -#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_5 16 -#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_6 19 -#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_7 22 +#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_1 1 +#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_2 2 +#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_3 4 +#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_4 7 // 0.7 +#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_5 12 // 1.2 +#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_6 18 +#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_7 23 #define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_8 25 -#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_9 28 +#define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_ASSIST_LEVEL_9 30 #define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_TIME 20 // 2.0 seconds #define DEFAULT_VALUE_STARTUP_MOTOR_POWER_BOOST_FADE_TIME 35 // 3.5 seconds From e9a43dd5886318ea20f4661475ab221d3b1eab70 Mon Sep 17 00:00:00 2001 From: Leon Date: Wed, 22 May 2019 12:59:12 +0200 Subject: [PATCH 2/5] More modular UART for future displays and overall clean up --- src/controller/ebike_app.c | 64 ++++++++++++++++++-------------------- src/display/KT-LCD3/lcd.c | 51 +++--------------------------- src/display/KT-LCD3/uart.c | 31 ++++++++++-------- 3 files changed, 53 insertions(+), 93 deletions(-) diff --git a/src/controller/ebike_app.c b/src/controller/ebike_app.c index fee8a471..ee895d69 100755 --- a/src/controller/ebike_app.c +++ b/src/controller/ebike_app.c @@ -87,11 +87,13 @@ 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 9 // change this value depending on how many data bytes there is to receive +#define UART_NUMBER_DATA_BYTES_TO_SEND 23 // change this value depending on how many data bytes there is to send + volatile uint8_t ui8_received_package_flag = 0; -volatile uint8_t ui8_rx_buffer[11]; +volatile uint8_t ui8_rx_buffer[UART_NUMBER_DATA_BYTES_TO_RECEIVE + 3]; volatile uint8_t ui8_rx_counter = 0; -volatile uint8_t ui8_tx_buffer[26]; -volatile uint8_t ui8_tx_counter = 0; +volatile uint8_t ui8_tx_buffer[UART_NUMBER_DATA_BYTES_TO_SEND + 3]; volatile uint8_t ui8_i; volatile uint8_t ui8_checksum; volatile uint8_t ui8_byte_received; @@ -124,6 +126,7 @@ 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); @@ -390,23 +393,7 @@ static void ebike_control_motor (void) ui8_g_duty_cycle = 0; } - /************************************************************************************************************* - NOTE: - - If the battery_target_current == 0 AND configuration_variables.ui8_walk_assist == 1 AND - wheel speed is below threshold for walk assist function AND brake is not set AND there are no - errors detected in function "safe_tests", set the target duty cycle to walk assist target PWM. - apply_walk_assist - If the battery_target_current == 0 AND configuration_variables.ui8_walk_assist == 1 AND - wheel speed is above threshold for cruise function AND brake is not set AND there are no - errors detected in function "safe_tests", set the target duty cycle to cruise target PWM. - - If the battery_target_current == 0 AND ui8_startup_enable == 0 AND brake is not set AND there are no - errors detected in function "safe_tests", set the target duty cycle to max (255) and the current will be - controlled by the battery current controller. Else set the target duty cycle to 0. - - *************************************************************************************************************/ - + // set target motor PWM if(m_configuration_variables.ui8_walk_assist && ui8_m_brake_is_set == 0 && ui8_m_motor_enabled) { if(ui16_wheel_speed_x10 < WALK_ASSIST_CRUISE_THRESHOLD_SPEED_X10) @@ -431,20 +418,32 @@ static void ebike_control_motor (void) static void communications_controller (void) { - uint32_t ui32_temp; - #ifndef DEBUG_UART + + uart_receive_package (); + + uart_send_package (); + +#endif +} + + +static void uart_receive_package(void) +{ + uint32_t ui32_temp; + if (ui8_received_package_flag) { // verify crc of the package ui16_crc_rx = 0xffff; - for (ui8_i = 0; ui8_i < 9; ui8_i++) + + for (ui8_i = 0; ui8_i <= UART_NUMBER_DATA_BYTES_TO_RECEIVE; ui8_i++) { crc16 (ui8_rx_buffer[ui8_i], &ui16_crc_rx); } - // see if CRC is ok... - if (((((uint16_t) ui8_rx_buffer [10]) << 8) + ((uint16_t) ui8_rx_buffer [9])) == ui16_crc_rx) + // if CRC is ok read the package + 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]; @@ -607,13 +606,10 @@ static void communications_controller (void) // enable UART2 receive interrupt as we are now ready to receive a new package UART2->CR2 |= (1 << 5); } - - uart_send_package (); -#endif } static void uart_send_package(void) -{ +{ uint16_t ui16_temp; // send the data to the LCD @@ -723,15 +719,17 @@ static void uart_send_package(void) // prepare crc of the package ui16_crc_tx = 0xffff; - for (ui8_i = 0; ui8_i <= 23; ui8_i++) + + for (ui8_i = 0; ui8_i <= UART_NUMBER_DATA_BYTES_TO_SEND; ui8_i++) { crc16 (ui8_tx_buffer[ui8_i], &ui16_crc_tx); } - ui8_tx_buffer[24] = (uint8_t) (ui16_crc_tx & 0xff); - ui8_tx_buffer[25] = (uint8_t) (ui16_crc_tx >> 8) & 0xff; + + ui8_tx_buffer[UART_NUMBER_DATA_BYTES_TO_SEND + 1] = (uint8_t) (ui16_crc_tx & 0xff); + ui8_tx_buffer[UART_NUMBER_DATA_BYTES_TO_SEND + 2] = (uint8_t) (ui16_crc_tx >> 8) & 0xff; // send the full package to UART - for (ui8_i = 0; ui8_i <= 25; ui8_i++) + for (ui8_i = 0; ui8_i <= UART_NUMBER_DATA_BYTES_TO_SEND + 2; ui8_i++) { putchar (ui8_tx_buffer[ui8_i]); } diff --git a/src/display/KT-LCD3/lcd.c b/src/display/KT-LCD3/lcd.c index f210b14f..2b772dc0 100644 --- a/src/display/KT-LCD3/lcd.c +++ b/src/display/KT-LCD3/lcd.c @@ -178,7 +178,6 @@ void lcd_execute_menu_config_submenu_technical (void); void update_menu_flashing_state (void); void submenu_state_controller(uint8_t ui8_state_max_number); void advance_on_subfield (uint8_t* ui8_p_state, uint8_t ui8_state_max_number); -void recede_on_subfield (uint8_t* ui8_p_state, uint8_t ui8_state_max_number); void odometer_increase_field_state (void); @@ -1164,7 +1163,7 @@ void lcd_execute_menu_config_main_screen_setup (void) lcd_var_number.p_var_number = &configuration_variables.ui8_temperature_field_state; lcd_var_number.ui8_size = 8; lcd_var_number.ui8_decimal_digit = 0; - lcd_var_number.ui32_max_value = 5; + lcd_var_number.ui32_max_value = 6; lcd_var_number.ui32_min_value = 0; lcd_var_number.ui32_increment_step = 1; lcd_var_number.ui8_odometer_field = ODOMETER_FIELD; @@ -1672,8 +1671,8 @@ void temperature (void) case 5: lcd_print (ui8_pedal_cadence_filtered, TEMPERATURE_FIELD, 1); break; -/* - // average wheel speed since power on NO PROGRAM SPACE FOR THIS + + // average wheel speed since power on case 6: // check in what unit of measurement to display average wheel speed if (configuration_variables.ui8_units_type) @@ -1687,7 +1686,7 @@ void temperature (void) lcd_print (ui8_average_measured_wheel_speed_x10/10, TEMPERATURE_FIELD, 1); } break; - */ + // show nothing default: break; @@ -3551,33 +3550,6 @@ void submenu_state_controller (uint8_t ui8_state_max_number) } } -void advance_on_submenu (uint8_t* ui8_p_state, uint8_t ui8_state_max_number) -{ - // advance on submenus on button_up_click_event - if (buttons_get_up_click_event ()) - { - // clear button event - buttons_clear_up_click_event (); - - if (*ui8_p_state < ui8_state_max_number) { ++*ui8_p_state; } - else { *ui8_p_state = 0; } - } -} - - -void recede_on_submenu (uint8_t* ui8_p_state, uint8_t ui8_state_max_number) -{ - // recede on submenus on button_down_click_event - if (buttons_get_down_click_event ()) - { - // clear button event - buttons_clear_down_click_event (); - - if (*ui8_p_state > 0) { --*ui8_p_state; } - else { *ui8_p_state = ui8_state_max_number; } - } -} - void advance_on_subfield (uint8_t* ui8_p_state, uint8_t ui8_state_max_number) { @@ -3594,21 +3566,6 @@ void advance_on_subfield (uint8_t* ui8_p_state, uint8_t ui8_state_max_number) } } -void recede_on_subfield (uint8_t* ui8_p_state, uint8_t ui8_state_max_number) -{ - // if click down - click long down event - if (buttons_get_down_click_long_click_event ()) - { - // clear button event - buttons_clear_down_click_long_click_event (); - - if (*ui8_p_state > 0) { --*ui8_p_state; } - else { *ui8_p_state = ui8_state_max_number; } - - odometer_start_show_field_number (); - } -} - void lcd_power_off (uint8_t SaveToEEPROM) { diff --git a/src/display/KT-LCD3/uart.c b/src/display/KT-LCD3/uart.c index eae81d10..052ca660 100644 --- a/src/display/KT-LCD3/uart.c +++ b/src/display/KT-LCD3/uart.c @@ -15,15 +15,16 @@ #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 +#define UART_NUMBER_DATA_BYTES_TO_SEND 9 // change this value depending on how many data bytes there is to send + volatile uint8_t ui8_received_package_flag = 0; -volatile uint8_t ui8_rx_buffer[26]; +volatile uint8_t ui8_rx_buffer[UART_NUMBER_DATA_BYTES_TO_RECEIVE + 3]; volatile uint8_t ui8_rx_counter = 0; -volatile uint8_t ui8_tx_buffer[11]; -volatile uint8_t ui8_tx_counter = 0; +volatile uint8_t ui8_tx_buffer[UART_NUMBER_DATA_BYTES_TO_SEND + 3]; volatile uint8_t ui8_i; static uint16_t ui16_crc_rx; static uint16_t ui16_crc_tx; -static uint8_t ui8_lcd_variable_id = 0; static uint8_t ui8_master_comm_package_id = 0; static uint8_t ui8_slave_comm_package_id = 0; volatile uint8_t ui8_byte_received; @@ -75,7 +76,7 @@ void UART2_IRQHandler(void) __interrupt(UART2_IRQHANDLER) ui8_rx_counter++; // see if is the last byte of the package - if (ui8_rx_counter > 27) + if (ui8_rx_counter > UART_NUMBER_DATA_BYTES_TO_RECEIVE + 4) { ui8_rx_counter = 0; ui8_state_machine = 0; @@ -103,12 +104,14 @@ void uart_data_clock (void) // validation of the package data // last byte is the checksum ui16_crc_rx = 0xffff; - for (ui8_i = 0; ui8_i <= 23; ui8_i++) + + for (ui8_i = 0; ui8_i <= UART_NUMBER_DATA_BYTES_TO_RECEIVE; ui8_i++) { crc16 (ui8_rx_buffer[ui8_i], &ui16_crc_rx); } - - if (((((uint16_t) ui8_rx_buffer [25]) << 8) + ((uint16_t) ui8_rx_buffer [24])) == ui16_crc_rx) + + // if CRC is ok read the package + 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) { p_motor_controller_data = lcd_get_motor_controller_data (); p_configuration_variables = get_configuration_variables (); @@ -298,21 +301,23 @@ void uart_data_clock (void) break; default: - ui8_lcd_variable_id = 0; + // nothing break; } // prepare crc of the package ui16_crc_tx = 0xffff; - for (ui8_i = 0; ui8_i <= 8; ui8_i++) + + for (ui8_i = 0; ui8_i <= UART_NUMBER_DATA_BYTES_TO_SEND; ui8_i++) { crc16 (ui8_tx_buffer[ui8_i], &ui16_crc_tx); } - ui8_tx_buffer[9] = (uint8_t) (ui16_crc_tx & 0xff); - ui8_tx_buffer[10] = (uint8_t) (ui16_crc_tx >> 8) & 0xff; + + ui8_tx_buffer[UART_NUMBER_DATA_BYTES_TO_SEND + 1] = (uint8_t) (ui16_crc_tx & 0xff); + ui8_tx_buffer[UART_NUMBER_DATA_BYTES_TO_SEND + 2] = (uint8_t) (ui16_crc_tx >> 8) & 0xff; // send the full package to UART - for (ui8_i = 0; ui8_i <= 10; ui8_i++) + for (ui8_i = 0; ui8_i <= UART_NUMBER_DATA_BYTES_TO_SEND + 2; ui8_i++) { putchar (ui8_tx_buffer[ui8_i]); } From e7f97c4f974eb88685188ba48b3cd950ce1a2b6c Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 24 May 2019 03:52:53 +0200 Subject: [PATCH 3/5] overall improvements and bug fixes --- src/common/common.h | 7 +- src/controller/compile.bat | 4 +- src/controller/ebike_app.c | 165 ++++++++++++++++++++++++++----------- src/controller/ebike_app.h | 2 +- src/controller/main.h | 4 +- src/controller/motor.c | 6 +- src/display/KT-LCD3/lcd.c | 2 +- src/display/KT-LCD3/uart.c | 25 ++++-- 8 files changed, 149 insertions(+), 66 deletions(-) diff --git a/src/common/common.h b/src/common/common.h index e4bcfe12..5497f190 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -9,7 +9,10 @@ #ifndef COMMON_COMMON_H_ #define COMMON_COMMON_H_ -#define ERROR_STATE_NO_ERRORS 0 -#define ERROR_STATE_EBIKE_WHEEL_BLOCKED 1 +#define NO_ERROR 0 +#define ERROR_MOTOR_BLOCKED 1 +#define ERROR_TORQUE_APPLIED_DURING_POWER_ON 2 +#define ERROR_BRAKE_APPLIED_DURING_POWER_ON 3 +#define ERROR_THROTTLE_APPLIED_DURING_POWER_ON 4 #endif /* COMMON_COMMON_H_ */ diff --git a/src/controller/compile.bat b/src/controller/compile.bat index 209339f1..eda79e45 100644 --- a/src/controller/compile.bat +++ b/src/controller/compile.bat @@ -3,4 +3,6 @@ PATH = %PATH%;C:\SDCC\usr\local\bin;%~dp0..\..\tools\cygwin\bin make -f Makefile_windows clean :: pass batch file parameters, e.g. THROTTLE=0 -make -f Makefile_windows %* \ No newline at end of file +make -f Makefile_windows %* + +PAUSE \ No newline at end of file diff --git a/src/controller/ebike_app.c b/src/controller/ebike_app.c index ee895d69..fd212af8 100755 --- a/src/controller/ebike_app.c +++ b/src/controller/ebike_app.c @@ -87,15 +87,14 @@ 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 9 // change this value depending on how many data bytes there is to receive -#define UART_NUMBER_DATA_BYTES_TO_SEND 23 // change this value depending on how many data bytes there is to send +#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 ) volatile uint8_t ui8_received_package_flag = 0; volatile uint8_t ui8_rx_buffer[UART_NUMBER_DATA_BYTES_TO_RECEIVE + 3]; volatile uint8_t ui8_rx_counter = 0; volatile uint8_t ui8_tx_buffer[UART_NUMBER_DATA_BYTES_TO_SEND + 3]; volatile uint8_t ui8_i; -volatile uint8_t ui8_checksum; volatile uint8_t ui8_byte_received; volatile uint8_t ui8_state_machine = 0; volatile uint8_t ui8_uart_received_first_package = 0; @@ -112,11 +111,6 @@ uint16_t ui16_adc_motor_temperatured_accumulated = 0; uint8_t ui8_m_adc_battery_target_current; - -// safe tests -uint8_t safe_tests_state_machine = 0; -uint8_t safe_tests_state_machine_counter = 0; - static uint8_t ui8_m_motor_enabled = 1; static uint8_t ui8_m_brake_is_set = 0; @@ -150,8 +144,7 @@ static void boost_run_statemachine (void); static uint8_t apply_boost (uint8_t ui8_pas_cadence, uint8_t ui8_max_current_boost_state, uint8_t *ui8_target_current); static void apply_boost_fade_out (uint8_t *ui8_target_current); -static void safe_tests(void); - +static void check_system(void); void ebike_app_init (void) { @@ -171,6 +164,7 @@ void ebike_app_controller (void) calc_motor_temperature(); ebike_control_motor(); communications_controller(); + check_system(); } @@ -352,11 +346,10 @@ static void ebike_control_motor (void) } // execute some safe tests - safe_tests(); + //safe_tests(); // let's force our target current to 0 if brake is set or if there are errors - if(ui8_m_brake_is_set || - m_configuration_variables.ui8_error_states != ERROR_STATE_NO_ERRORS) + if(ui8_m_brake_is_set || m_configuration_variables.ui8_system_state != NO_ERROR) { ui8_m_adc_battery_target_current = 0; } @@ -429,12 +422,12 @@ static void communications_controller (void) static void uart_receive_package(void) -{ +{ uint32_t ui32_temp; if (ui8_received_package_flag) { - // verify crc of the package + // validation of the package data ui16_crc_rx = 0xffff; for (ui8_i = 0; ui8_i <= UART_NUMBER_DATA_BYTES_TO_RECEIVE; ui8_i++) @@ -442,7 +435,7 @@ static void uart_receive_package(void) crc16 (ui8_rx_buffer[ui8_i], &ui16_crc_rx); } - // if CRC is ok read the package + // 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]; @@ -609,17 +602,18 @@ static void uart_receive_package(void) } static void uart_send_package(void) -{ +{ uint16_t ui16_temp; - // send the data to the LCD // 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; - ui16_temp = motor_get_adc_battery_voltage_filtered_10b(); // 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; @@ -680,7 +674,7 @@ static void uart_send_package(void) { case 0: // error states - ui8_tx_buffer[19] = m_configuration_variables.ui8_error_states; + ui8_tx_buffer[19] = m_configuration_variables.ui8_system_state; break; case 1: @@ -1228,10 +1222,12 @@ void UART2_IRQHandler(void) __interrupt(UART2_IRQHANDLER) case 1: ui8_rx_buffer [ui8_rx_counter] = ui8_byte_received; + + // increment index for next byte ui8_rx_counter++; - // see if is the last byte of the package - if (ui8_rx_counter > 12) + // reset if it is the last byte of the package and index is out of bounds + if (ui8_rx_counter >= UART_NUMBER_DATA_BYTES_TO_RECEIVE + 3) { ui8_rx_counter = 0; ui8_state_machine = 0; @@ -1253,68 +1249,136 @@ struct_configuration_variables* get_configuration_variables (void) } +void check_system() +{ + #define MOTOR_BLOCKED_COUNTER_THRESHOLD 50 // 50 => 5 seconds + #define MOTOR_BLOCKED_BATTERY_CURRENT_THRESHOLD 1 // 1 => 1 * 0.826 ampere + #define MOTOR_BLOCKED_ERPS_THRESHOLD 20 // 20 ERPS + #define MOTOR_BLOCKED_RESET_COUNTER_THRESHOLD 100 // 100 => 10 seconds + + static uint8_t ui8_motor_blocked_counter; + static uint8_t ui8_motor_blocked_reset_counter = 20; + + // if the motor blocked error is enabled start resetting it + if (m_configuration_variables.ui8_system_state == ERROR_MOTOR_BLOCKED) + { + // increment motor blocked reset counter with 100 milliseconds + ui8_motor_blocked_reset_counter++; + + // check if the counter has counted to the set threshold for reset + if (ui8_motor_blocked_reset_counter > MOTOR_BLOCKED_RESET_COUNTER_THRESHOLD) + { + // reset motor blocked error code + //m_configuration_variables.ui8_system_state == NO_ERROR; + } + } + else + { + // if battery current is over the current threshold and the motor ERPS is below threshold start setting motor blocked error code + if ((motor_get_adc_battery_current_filtered_10b() > MOTOR_BLOCKED_BATTERY_CURRENT_THRESHOLD) && (ui16_motor_get_motor_speed_erps() < MOTOR_BLOCKED_ERPS_THRESHOLD)) + { + // increment motor blocked counter with 100 milliseconds + ui8_motor_blocked_counter++; + + // check if motor is blocked more than some safe time threshold + if (ui8_motor_blocked_counter > MOTOR_BLOCKED_COUNTER_THRESHOLD) + { + // set motor blocked error code + m_configuration_variables.ui8_system_state = ERROR_MOTOR_BLOCKED; + + // reset the counter that clears the motor blocked error + ui8_motor_blocked_reset_counter = 0; + } + } + else + { + // current is below the threshold and/or motor ERPS is above the threshold so reset the counter + ui8_motor_blocked_counter = 0; + } + } +} + +/* static void safe_tests(void) { - // enabe only next state machine if user has startup without pedal rotation + #define SAFE_TEST_THROTTLE_THRESHOLD 0 + #define SAFE_TEST_TORQUE_SENSOR_THRESHOLD 12 + + static uint8_t safe_tests_state_machine = 0; // added + static uint8_t safe_tests_state_machine_counter = 0; // added + + // enable only next state machine if user has startup without pedal rotation if(m_configuration_variables.ui8_motor_assistance_startup_without_pedal_rotation || - (ui8_m_brake_is_set == 0) || - m_configuration_variables.ui8_assist_level_factor_x10 || - !m_configuration_variables.ui8_walk_assist) + (ui8_m_brake_is_set == 0) || + m_configuration_variables.ui8_assist_level_factor_x10 || + !m_configuration_variables.ui8_walk_assist) { switch(safe_tests_state_machine) { - // start when torque sensor or throttle or walk assist / cruise case 0: - if(ui8_torque_sensor > 12 || - ui8_throttle) + + // start when torque sensor or throttle is above threshold + if(ui8_torque_sensor > SAFE_TEST_TORQUE_SENSOR_THRESHOLD || ui8_throttle > SAFE_TEST_THROTTLE_THRESHOLD) { + // reset counter and go to next state safe_tests_state_machine_counter = 0; safe_tests_state_machine = 1; + break; } + break; - // wait during 5 seconds for bicyle wheel speed > 4km/h, if not we have an error + case 1: + + // increment state machine timer with 100 milliseconds safe_tests_state_machine_counter++; - - // timeout of 10 seconds, not less to be higher than value on torque_sensor_read () - // hopefully, 10 seconds is safe enough value, mosfets may not burn in 10 seconds if ebike wheel is blocked - if(safe_tests_state_machine_counter > 100) + + // if some time has passed without any wheel rotation return an error state + if(safe_tests_state_machine_counter > 100) // hopefully, 10 seconds is safe enough value, mosfets may not burn in 10 seconds if ebike wheel is blocked { - m_configuration_variables.ui8_error_states |= ERROR_STATE_EBIKE_WHEEL_BLOCKED; + // set error code + m_configuration_variables.ui8_system_state = ERROR_STATE_EBIKE_WHEEL_BLOCKED; + + // reset counter and go to next state safe_tests_state_machine_counter = 0; safe_tests_state_machine = 2; + break; } - // bicycle wheel is rotating so we are safe - if(ui16_wheel_speed_x10 > 40) // seems that 4 km/h may be the min value we can measure for the bicycle wheel speed + // if wheel speed is over some value everything is safe + if(ui16_wheel_speed_x10 > 40) // seems that 4 km/h may be the minimum value possible to measure for the bicycle wheel speed { + // reset counter and go to next state safe_tests_state_machine_counter = 0; safe_tests_state_machine = 3; + break; } - // if release of: torque sensor AND throttle AND walk assist / cruise -> restart - if(ui8_torque_sensor < 12 && - ui8_throttle == 0) + // if torque sensor or throttle is below threshold reset state machine + if(ui8_torque_sensor <= SAFE_TEST_TORQUE_SENSOR_THRESHOLD && ui8_throttle <= SAFE_TEST_THROTTLE_THRESHOLD) { safe_tests_state_machine = 0; } + break; - // wait 3 consecutive seconds for torque sensor and throttle and walk assist / cruise == 0, then restart case 2: - if(ui8_torque_sensor < 12 && - ui8_throttle == 0) + + // wait 3 consecutive seconds for torque sensor and throttle and walk assist / cruise == 0, then restart + if(ui8_torque_sensor <= SAFE_TEST_TORQUE_SENSOR_THRESHOLD && ui8_throttle <= SAFE_TEST_THROTTLE_THRESHOLD) { safe_tests_state_machine_counter++; if(safe_tests_state_machine_counter > 30) { - m_configuration_variables.ui8_error_states &= ~ERROR_STATE_EBIKE_WHEEL_BLOCKED; + // reset error code and go to next state + m_configuration_variables.ui8_system_state = ERROR_STATE_NO_ERRORS; safe_tests_state_machine = 0; + break; } } @@ -1323,26 +1387,33 @@ static void safe_tests(void) { safe_tests_state_machine_counter = 0; } + break; - // wait for bicycle wheel to be stopped so we can start again our state machine case 3: + + // if bicycle wheel has stopped restart state machine if(ui16_wheel_speed_x10 == 0) { safe_tests_state_machine = 0; + break; } + break; default: + safe_tests_state_machine = 0; + break; } } else { - // keep reseting state machine - m_configuration_variables.ui8_error_states &= ~ERROR_STATE_EBIKE_WHEEL_BLOCKED; // disable error state in case it was enabled + // keep reseting state machine and reset all error codes safe_tests_state_machine = 0; + m_configuration_variables.ui8_system_state = ERROR_STATE_NO_ERRORS; } } +*/ diff --git a/src/controller/ebike_app.h b/src/controller/ebike_app.h index 4f4dce3a..248fe926 100755 --- a/src/controller/ebike_app.h +++ b/src/controller/ebike_app.h @@ -51,7 +51,7 @@ typedef struct _configuration_variables uint8_t ui8_offroad_speed_limit; uint8_t ui8_offroad_power_limit_enabled; uint8_t ui8_offroad_power_limit_div25; - uint8_t ui8_error_states; + uint8_t ui8_system_state; uint8_t ui8_ramp_up_amps_per_second_x10; } struct_configuration_variables; diff --git a/src/controller/main.h b/src/controller/main.h index 3f58e632..68f07449 100644 --- a/src/controller/main.h +++ b/src/controller/main.h @@ -52,9 +52,9 @@ // walk assist and cruise -#define WALK_ASSIST_CRUISE_THRESHOLD_SPEED_X10 80 // 8.0 km/h +#define WALK_ASSIST_CRUISE_THRESHOLD_SPEED_X10 80 // 8.0 km/h #define CRUISE_PID_KP 12 -#define CRUISE_PID_KI 1 +#define CRUISE_PID_KI 0.8 // 48 volt motor: 1, 36 volt motor: 0.9 #define CRUISE_PID_INTEGRAL_LIMIT 1000 #define CRUISE_PID_KD 0 diff --git a/src/controller/motor.c b/src/controller/motor.c index c2627140..4d8eaaf7 100755 --- a/src/controller/motor.c +++ b/src/controller/motor.c @@ -24,8 +24,8 @@ #include "watchdog.h" #include "math.h" -#define SVM_TABLE_LEN 256 -#define SIN_TABLE_LEN 60 +#define SVM_TABLE_LEN 256 +#define SIN_TABLE_LEN 60 uint8_t ui8_svm_table [SVM_TABLE_LEN] = { @@ -287,7 +287,7 @@ uint8_t ui8_svm_table [SVM_TABLE_LEN] = 238 , }; -uint8_t ui8_sin_table [SVM_TABLE_LEN] = +uint8_t ui8_sin_table [SIN_TABLE_LEN] = { 0 , 3 , diff --git a/src/display/KT-LCD3/lcd.c b/src/display/KT-LCD3/lcd.c index 2b772dc0..d39051a6 100644 --- a/src/display/KT-LCD3/lcd.c +++ b/src/display/KT-LCD3/lcd.c @@ -2180,7 +2180,7 @@ void odometer (void) } // if there are errors, show the error number on odometer field instead of any other information - if (motor_controller_data.ui8_error_states != ERROR_STATE_NO_ERRORS) + if (motor_controller_data.ui8_error_states != NO_ERROR) { if (ui8_lcd_menu_flash_state) { diff --git a/src/display/KT-LCD3/uart.c b/src/display/KT-LCD3/uart.c index 052ca660..872e701c 100644 --- a/src/display/KT-LCD3/uart.c +++ b/src/display/KT-LCD3/uart.c @@ -15,21 +15,22 @@ #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 -#define UART_NUMBER_DATA_BYTES_TO_SEND 9 // change this value depending on how many data bytes there is to send +#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 ) volatile uint8_t ui8_received_package_flag = 0; volatile uint8_t ui8_rx_buffer[UART_NUMBER_DATA_BYTES_TO_RECEIVE + 3]; volatile uint8_t ui8_rx_counter = 0; 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_byte_received; -volatile uint8_t ui8_state_machine = 0; -volatile uint8_t ui8_uart_received_first_package = 0; + void uart2_init (void) { @@ -73,10 +74,12 @@ void UART2_IRQHandler(void) __interrupt(UART2_IRQHANDLER) case 1: ui8_rx_buffer[ui8_rx_counter] = ui8_byte_received; + + // increment index for next byte ui8_rx_counter++; - // see if is the last byte of the package - if (ui8_rx_counter > UART_NUMBER_DATA_BYTES_TO_RECEIVE + 4) + // reset if it is the last byte of the package and index is out of bounds + if (ui8_rx_counter >= UART_NUMBER_DATA_BYTES_TO_RECEIVE + 3) { ui8_rx_counter = 0; ui8_state_machine = 0; @@ -102,7 +105,6 @@ void uart_data_clock (void) if (ui8_received_package_flag) { // validation of the package data - // last byte is the checksum ui16_crc_rx = 0xffff; for (ui8_i = 0; ui8_i <= UART_NUMBER_DATA_BYTES_TO_RECEIVE; ui8_i++) @@ -189,9 +191,14 @@ void uart_data_clock (void) // signal that we processed the full package ui8_received_package_flag = 0; - // now send the data to the motor controller + + // ----------------- now send the data to the motor controller ----------------- // + + // start up byte 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; From 68e635b6650f3436078abf14605be21c53e5c03f Mon Sep 17 00:00:00 2001 From: Leon Date: Sat, 25 May 2019 10:09:46 +0200 Subject: [PATCH 4/5] Point of no return, new check_system function --- src/controller/ebike_app.c | 15 ++++++--------- src/controller/ebike_app.h | 1 - 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/controller/ebike_app.c b/src/controller/ebike_app.c index fd212af8..b0e1c88f 100755 --- a/src/controller/ebike_app.c +++ b/src/controller/ebike_app.c @@ -59,6 +59,7 @@ static uint16_t ui16_received_target_wheel_speed_x10 = 0; static uint16_t ui16_target_wheel_speed_x10 = 0; // variables for various system functions +volatile uint8_t ui8_system_state = NO_ERROR; volatile uint16_t ui16_pas_pwm_cycles_ticks = (uint16_t) PAS_ABSOLUTE_MIN_CADENCE_PWM_CYCLE_TICKS; volatile uint8_t ui8_g_pedaling_direction = 0; uint8_t ui8_pas_cadence_rpm = 0; @@ -75,7 +76,6 @@ uint16_t ui16_startup_boost_fade_variable_x256; uint16_t ui16_startup_boost_fade_variable_step_amount_x256; - // variables for wheel speed volatile uint16_t ui16_wheel_speed_sensor_pwm_cycles_ticks = (uint16_t) WHEEL_SPEED_SENSOR_MAX_PWM_CYCLE_TICKS; uint8_t ui8_wheel_speed_max = 0; @@ -345,11 +345,8 @@ static void ebike_control_motor (void) m_configuration_variables.ui8_temperature_current_limiting_value = 255; } - // execute some safe tests - //safe_tests(); - // let's force our target current to 0 if brake is set or if there are errors - if(ui8_m_brake_is_set || m_configuration_variables.ui8_system_state != NO_ERROR) + if(ui8_m_brake_is_set || ui8_system_state != NO_ERROR) { ui8_m_adc_battery_target_current = 0; } @@ -674,7 +671,7 @@ static void uart_send_package(void) { case 0: // error states - ui8_tx_buffer[19] = m_configuration_variables.ui8_system_state; + ui8_tx_buffer[19] = ui8_system_state; break; case 1: @@ -1260,7 +1257,7 @@ void check_system() static uint8_t ui8_motor_blocked_reset_counter = 20; // if the motor blocked error is enabled start resetting it - if (m_configuration_variables.ui8_system_state == ERROR_MOTOR_BLOCKED) + if (ui8_system_state == ERROR_MOTOR_BLOCKED) { // increment motor blocked reset counter with 100 milliseconds ui8_motor_blocked_reset_counter++; @@ -1269,7 +1266,7 @@ void check_system() if (ui8_motor_blocked_reset_counter > MOTOR_BLOCKED_RESET_COUNTER_THRESHOLD) { // reset motor blocked error code - //m_configuration_variables.ui8_system_state == NO_ERROR; + ui8_system_state == NO_ERROR; } } else @@ -1284,7 +1281,7 @@ void check_system() if (ui8_motor_blocked_counter > MOTOR_BLOCKED_COUNTER_THRESHOLD) { // set motor blocked error code - m_configuration_variables.ui8_system_state = ERROR_MOTOR_BLOCKED; + ui8_system_state = ERROR_MOTOR_BLOCKED; // reset the counter that clears the motor blocked error ui8_motor_blocked_reset_counter = 0; diff --git a/src/controller/ebike_app.h b/src/controller/ebike_app.h index 248fe926..fe0bb182 100755 --- a/src/controller/ebike_app.h +++ b/src/controller/ebike_app.h @@ -51,7 +51,6 @@ typedef struct _configuration_variables uint8_t ui8_offroad_speed_limit; uint8_t ui8_offroad_power_limit_enabled; uint8_t ui8_offroad_power_limit_div25; - uint8_t ui8_system_state; uint8_t ui8_ramp_up_amps_per_second_x10; } struct_configuration_variables; From f0e87b1649fe603aab846d72c292b132f78e02e8 Mon Sep 17 00:00:00 2001 From: Leon Date: Sat, 25 May 2019 22:55:31 +0200 Subject: [PATCH 5/5] Clean up and prepared for pull request --- src/common/common.h | 1 + src/controller/ebike_app.c | 149 ++++--------------------------------- src/controller/main.h | 4 +- 3 files changed, 19 insertions(+), 135 deletions(-) diff --git a/src/common/common.h b/src/common/common.h index 5497f190..7410308a 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -14,5 +14,6 @@ #define ERROR_TORQUE_APPLIED_DURING_POWER_ON 2 #define ERROR_BRAKE_APPLIED_DURING_POWER_ON 3 #define ERROR_THROTTLE_APPLIED_DURING_POWER_ON 4 +#define ERROR_NO_SPEED_SENSOR_DETECTED 5 #endif /* COMMON_COMMON_H_ */ diff --git a/src/controller/ebike_app.c b/src/controller/ebike_app.c index b0e1c88f..07d1ceb1 100755 --- a/src/controller/ebike_app.c +++ b/src/controller/ebike_app.c @@ -138,13 +138,13 @@ static void apply_walk_assist(uint8_t *ui8_p_adc_target_current); static void apply_cruise (uint8_t *ui8_target_current); static void apply_throttle(uint8_t ui8_throttle_value, uint8_t *ui8_target_current); +static void check_system(void); // variables for BOOST function static void boost_run_statemachine (void); static uint8_t apply_boost (uint8_t ui8_pas_cadence, uint8_t ui8_max_current_boost_state, uint8_t *ui8_target_current); static void apply_boost_fade_out (uint8_t *ui8_target_current); -static void check_system(void); void ebike_app_init (void) { @@ -1248,13 +1248,13 @@ struct_configuration_variables* get_configuration_variables (void) void check_system() { - #define MOTOR_BLOCKED_COUNTER_THRESHOLD 50 // 50 => 5 seconds - #define MOTOR_BLOCKED_BATTERY_CURRENT_THRESHOLD 1 // 1 => 1 * 0.826 ampere - #define MOTOR_BLOCKED_ERPS_THRESHOLD 20 // 20 ERPS - #define MOTOR_BLOCKED_RESET_COUNTER_THRESHOLD 100 // 100 => 10 seconds + #define MOTOR_BLOCKED_COUNTER_THRESHOLD 50 // 50 => 5 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 static uint8_t ui8_motor_blocked_counter; - static uint8_t ui8_motor_blocked_reset_counter = 20; + static uint8_t ui8_motor_blocked_reset_counter; // if the motor blocked error is enabled start resetting it if (ui8_system_state == ERROR_MOTOR_BLOCKED) @@ -1266,25 +1266,28 @@ void check_system() if (ui8_motor_blocked_reset_counter > MOTOR_BLOCKED_RESET_COUNTER_THRESHOLD) { // reset motor blocked error code - ui8_system_state == NO_ERROR; + ui8_system_state = NO_ERROR; + + // reset the counter that clears the motor blocked error + ui8_motor_blocked_reset_counter = 0; } } else { - // if battery current is over the current threshold and the motor ERPS is below threshold start setting motor blocked error code - if ((motor_get_adc_battery_current_filtered_10b() > MOTOR_BLOCKED_BATTERY_CURRENT_THRESHOLD) && (ui16_motor_get_motor_speed_erps() < MOTOR_BLOCKED_ERPS_THRESHOLD)) + // if battery current (x5) is over the current threshold (x5) and the motor ERPS is below threshold start setting motor blocked error code + if ((motor_get_adc_battery_current_filtered_10b() > MOTOR_BLOCKED_BATTERY_CURRENT_THRESHOLD_X5) && (ui16_motor_get_motor_speed_erps() < MOTOR_BLOCKED_ERPS_THRESHOLD)) { // increment motor blocked counter with 100 milliseconds ui8_motor_blocked_counter++; - // check if motor is blocked more than some safe time threshold + // check if motor is blocked for more than some safe threshold if (ui8_motor_blocked_counter > MOTOR_BLOCKED_COUNTER_THRESHOLD) { // set motor blocked error code ui8_system_state = ERROR_MOTOR_BLOCKED; - // reset the counter that clears the motor blocked error - ui8_motor_blocked_reset_counter = 0; + // reset motor blocked counter as the error code is set + ui8_motor_blocked_counter = 0; } } else @@ -1293,124 +1296,4 @@ void check_system() ui8_motor_blocked_counter = 0; } } -} - -/* -static void safe_tests(void) -{ - #define SAFE_TEST_THROTTLE_THRESHOLD 0 - #define SAFE_TEST_TORQUE_SENSOR_THRESHOLD 12 - - static uint8_t safe_tests_state_machine = 0; // added - static uint8_t safe_tests_state_machine_counter = 0; // added - - // enable only next state machine if user has startup without pedal rotation - if(m_configuration_variables.ui8_motor_assistance_startup_without_pedal_rotation || - (ui8_m_brake_is_set == 0) || - m_configuration_variables.ui8_assist_level_factor_x10 || - !m_configuration_variables.ui8_walk_assist) - { - switch(safe_tests_state_machine) - { - case 0: - - // start when torque sensor or throttle is above threshold - if(ui8_torque_sensor > SAFE_TEST_TORQUE_SENSOR_THRESHOLD || ui8_throttle > SAFE_TEST_THROTTLE_THRESHOLD) - { - // reset counter and go to next state - safe_tests_state_machine_counter = 0; - safe_tests_state_machine = 1; - - break; - } - - break; - - - case 1: - - // increment state machine timer with 100 milliseconds - safe_tests_state_machine_counter++; - - // if some time has passed without any wheel rotation return an error state - if(safe_tests_state_machine_counter > 100) // hopefully, 10 seconds is safe enough value, mosfets may not burn in 10 seconds if ebike wheel is blocked - { - // set error code - m_configuration_variables.ui8_system_state = ERROR_STATE_EBIKE_WHEEL_BLOCKED; - - // reset counter and go to next state - safe_tests_state_machine_counter = 0; - safe_tests_state_machine = 2; - - break; - } - - // if wheel speed is over some value everything is safe - if(ui16_wheel_speed_x10 > 40) // seems that 4 km/h may be the minimum value possible to measure for the bicycle wheel speed - { - // reset counter and go to next state - safe_tests_state_machine_counter = 0; - safe_tests_state_machine = 3; - - break; - } - - // if torque sensor or throttle is below threshold reset state machine - if(ui8_torque_sensor <= SAFE_TEST_TORQUE_SENSOR_THRESHOLD && ui8_throttle <= SAFE_TEST_THROTTLE_THRESHOLD) - { - safe_tests_state_machine = 0; - } - - break; - - case 2: - - // wait 3 consecutive seconds for torque sensor and throttle and walk assist / cruise == 0, then restart - if(ui8_torque_sensor <= SAFE_TEST_TORQUE_SENSOR_THRESHOLD && ui8_throttle <= SAFE_TEST_THROTTLE_THRESHOLD) - { - safe_tests_state_machine_counter++; - - if(safe_tests_state_machine_counter > 30) - { - // reset error code and go to next state - m_configuration_variables.ui8_system_state = ERROR_STATE_NO_ERRORS; - safe_tests_state_machine = 0; - - break; - } - } - // keep reseting the counter so we keep on this state - else - { - safe_tests_state_machine_counter = 0; - } - - break; - - case 3: - - // if bicycle wheel has stopped restart state machine - if(ui16_wheel_speed_x10 == 0) - { - safe_tests_state_machine = 0; - - break; - } - - break; - - default: - - safe_tests_state_machine = 0; - - break; - } - } - else - { - // keep reseting state machine and reset all error codes - safe_tests_state_machine = 0; - m_configuration_variables.ui8_system_state = ERROR_STATE_NO_ERRORS; - } -} -*/ +} \ No newline at end of file diff --git a/src/controller/main.h b/src/controller/main.h index 68f07449..f1b6446d 100644 --- a/src/controller/main.h +++ b/src/controller/main.h @@ -53,8 +53,8 @@ // walk assist and cruise #define WALK_ASSIST_CRUISE_THRESHOLD_SPEED_X10 80 // 8.0 km/h -#define CRUISE_PID_KP 12 -#define CRUISE_PID_KI 0.8 // 48 volt motor: 1, 36 volt motor: 0.9 +#define CRUISE_PID_KP 14 // 48 volt motor: 12, 36 volt motor: 14 +#define CRUISE_PID_KI 0.7 // 48 volt motor: 1, 36 volt motor: 0.7 #define CRUISE_PID_INTEGRAL_LIMIT 1000 #define CRUISE_PID_KD 0