diff --git a/src/common/common.h b/src/common/common.h index e4bcfe12..7410308a 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -9,7 +9,11 @@ #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 +#define ERROR_NO_SPEED_SENSOR_DETECTED 5 #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 fee8a471..07d1ceb1 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; @@ -87,13 +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 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[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; volatile uint8_t ui8_state_machine = 0; volatile uint8_t ui8_uart_received_first_package = 0; @@ -110,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; @@ -124,6 +120,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); @@ -141,14 +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 safe_tests(void); - void ebike_app_init (void) { @@ -168,6 +164,7 @@ void ebike_app_controller (void) calc_motor_temperature(); ebike_control_motor(); communications_controller(); + check_system(); } @@ -348,12 +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_error_states != ERROR_STATE_NO_ERRORS) + if(ui8_m_brake_is_set || ui8_system_state != NO_ERROR) { ui8_m_adc_battery_target_current = 0; } @@ -390,23 +383,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 +408,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 + // validation of the package data 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 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]; @@ -607,23 +596,21 @@ 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 // 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; @@ -684,7 +671,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] = ui8_system_state; break; case 1: @@ -723,15 +710,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]); } @@ -1230,10 +1219,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; @@ -1255,96 +1246,54 @@ struct_configuration_variables* get_configuration_variables (void) } -static void safe_tests(void) +void check_system() { - // enabe 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) + #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; + + // if the motor blocked error is enabled start resetting it + if (ui8_system_state == ERROR_MOTOR_BLOCKED) { - switch(safe_tests_state_machine) + // 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) { - // start when torque sensor or throttle or walk assist / cruise - case 0: - if(ui8_torque_sensor > 12 || - ui8_throttle) - { - 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: - 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) - { - m_configuration_variables.ui8_error_states |= ERROR_STATE_EBIKE_WHEEL_BLOCKED; - 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 - { - 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) - { - 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) - { - safe_tests_state_machine_counter++; - - if(safe_tests_state_machine_counter > 30) - { - m_configuration_variables.ui8_error_states &= ~ERROR_STATE_EBIKE_WHEEL_BLOCKED; - safe_tests_state_machine = 0; - break; - } - } - // keep reseting the counter so we keep on this state - else - { - 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(ui16_wheel_speed_x10 == 0) - { - safe_tests_state_machine = 0; - break; - } - break; - - default: - safe_tests_state_machine = 0; - break; + // reset motor blocked error code + ui8_system_state = NO_ERROR; + + // reset the counter that clears the motor blocked error + ui8_motor_blocked_reset_counter = 0; } } else { - // keep reseting state machine - m_configuration_variables.ui8_error_states &= ~ERROR_STATE_EBIKE_WHEEL_BLOCKED; // disable error state in case it was enabled - safe_tests_state_machine = 0; + // 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 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 motor blocked counter as the error code is set + ui8_motor_blocked_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; + } } -} +} \ No newline at end of file diff --git a/src/controller/ebike_app.h b/src/controller/ebike_app.h index 4f4dce3a..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_error_states; 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..f1b6446d 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 CRUISE_PID_KP 12 -#define CRUISE_PID_KI 1 +#define WALK_ASSIST_CRUISE_THRESHOLD_SPEED_X10 80 // 8.0 km/h +#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 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/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..d39051a6 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,10 +176,8 @@ 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 +221,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 +280,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 +310,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 +326,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 +352,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 +365,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 +400,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; } + } + + // recede on submenu if button_down_click_event + if (buttons_get_down_click_event ()) + { + // clear button event + buttons_clear_down_click_event (); - // leave config menu with a button_onoff_long_click + 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 +477,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 +587,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 +679,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 +692,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 +747,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 +761,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 +773,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 +785,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 +807,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 +821,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 +854,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 +869,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 +881,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 +903,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 +919,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 +933,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 +959,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 +1020,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) { @@ -1175,15 +1163,20 @@ 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; 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 +1185,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 +1264,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 +1286,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 +1322,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 +1376,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 +1391,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 +1410,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 +1445,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 +1473,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 +1537,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); + } } @@ -1660,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) @@ -1675,7 +1686,7 @@ void temperature (void) lcd_print (ui8_average_measured_wheel_speed_x10/10, TEMPERATURE_FIELD, 1); } break; - */ + // show nothing default: break; @@ -1917,11 +1928,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 +1946,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; } } @@ -2172,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) { @@ -3477,26 +3485,68 @@ void update_menu_flashing_state(void) } -void advance_on_submenu (uint8_t* ui8_p_state, uint8_t ui8_state_max_number) +void submenu_state_controller (uint8_t ui8_state_max_number) { - // advance on submenus on button_up_click_event - if (buttons_get_up_click_event ()) + if (ui8_lcd_menu_config_submenu_change_variable_enabled) { - buttons_clear_up_click_event (); - - *ui8_p_state = (*ui8_p_state + 1) % ui8_state_max_number; + // 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 (); -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 ()) - { - 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_p_state = (*ui8_p_state - 1) % ui8_state_max_number; + 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); } + } + } } } @@ -3509,21 +3559,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; - - odometer_start_show_field_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 (); - - *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 (); } @@ -3573,68 +3610,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) + // 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_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; } + 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 +3697,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 diff --git a/src/display/KT-LCD3/uart.c b/src/display/KT-LCD3/uart.c index eae81d10..872e701c 100644 --- a/src/display/KT-LCD3/uart.c +++ b/src/display/KT-LCD3/uart.c @@ -15,20 +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 ( 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[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; +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_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; -volatile uint8_t ui8_state_machine = 0; -volatile uint8_t ui8_uart_received_first_package = 0; + void uart2_init (void) { @@ -72,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 > 27) + // 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; @@ -101,14 +105,15 @@ 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 <= 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 (); @@ -186,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; @@ -298,21 +308,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]); }