From b74c3c6fb0a83b66e8d78e899f945d9b2a7e12e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ant=C3=B4nio=20Cardoso?= Date: Fri, 25 Feb 2022 01:56:33 -0300 Subject: [PATCH 01/11] Add finite state machine and can messages to control the Contactor --- firmware/src/can_app.c | 25 +++++++++++- firmware/src/can_app.h | 1 + firmware/src/machine.c | 93 +++++++++++++++++++++++++++++++++++++++++- firmware/src/machine.h | 28 +++++++++++++ 4 files changed, 145 insertions(+), 2 deletions(-) diff --git a/firmware/src/can_app.c b/firmware/src/can_app.c index 2cc7090..b4d470c 100644 --- a/firmware/src/can_app.c +++ b/firmware/src/can_app.c @@ -58,6 +58,7 @@ inline void can_app_send_state(void) msg.data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] = CAN_SIGNATURE_SELF; msg.data[CAN_MSG_GENERIC_STATE_STATE_BYTE] = (uint8_t) state_machine; + // msg.data[CAN_MSG_GENERIC_STATE_CONTACTOR_BYTE] = (uint8_t) state_contactor; // TODO: adicionar? msg.data[CAN_MSG_GENERIC_STATE_ERROR_BYTE] = error_flags.all; can_send_message(&msg); @@ -73,8 +74,26 @@ inline void can_app_send_motor(void) msg.data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] = CAN_SIGNATURE_SELF; msg.data[CAN_MSG_MAM19_MOTOR_D_BYTE] = control.D; msg.data[CAN_MSG_MAM19_MOTOR_I_BYTE] = control.I; + // msg.data[CAN_MSG_MAM19_MOTOR_R_BYTE] = control.R; // TODO: adicionar? - can_send_message(&msg); + can_send_message(&msg); +} + +inline void can_app_send_contactor_request(uint8_t request) +{ + can_t msg; + msg.id = CAN_MSG_MAM19_CONTACTOR_ID; + msg.length = CAN_MSG_MAM19_CONTACTOR_LENGTH; + msg.flags.rtr = 0; + + msg.data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] = CAN_SIGNATURE_SELF; + msg.data[CAN_MSG_MAM19_CONTACTOR_REQUEST_BYTE] = request; + + can_send_message(&msg); + + contactor.message_received = CONTACTOR_REQUEST_UNKNOWN; + contactor.message_sent = request; + contactor.timeout_clk_div = 0; } /** @@ -135,6 +154,10 @@ inline void can_app_extractor_mic19_motor(can_t *msg) CAN_MSG_MIC19_MOTOR_MOTOR_BYTE], CAN_MSG_MIC19_MOTOR_MOTOR_DMS_ON_BIT); + system_flags.reverse = bit_is_set(msg->data[ + CAN_MSG_MIC19_MOTOR_MOTOR_BYTE], + CAN_MSG_MIC19_MOTOR_MOTOR_REVERSE_BIT); + if(!mswi19_connected){ control.D_raw_target = msg->data[CAN_MSG_MIC19_MOTOR_D_BYTE]; } diff --git a/firmware/src/can_app.h b/firmware/src/can_app.h index 36a80e6..b608589 100644 --- a/firmware/src/can_app.h +++ b/firmware/src/can_app.h @@ -22,6 +22,7 @@ void can_app_print_msg(can_t *msg); void can_app_task(void); void can_app_send_state(void); void can_app_send_motor(void); +void can_app_send_contactor_request(uint8_t request); void can_app_extractor_mic19_state(can_t *msg); void can_app_extractor_mic19_motor(can_t *msg); void can_app_extractor_mswi19_state(can_t *msg); diff --git a/firmware/src/machine.c b/firmware/src/machine.c index 643d895..93f8c1c 100644 --- a/firmware/src/machine.c +++ b/firmware/src/machine.c @@ -9,6 +9,8 @@ uint8_t total_errors; // Contagem de ERROS uint8_t pwm_fault_count; uint8_t check_pwm_fault_times; uint8_t led_clk_div; +state_contactor_t state_contactor; +contactor_t contactor; /* * to-do: @@ -43,7 +45,18 @@ inline void check_idle_zero_pot(void) { system_flags.pot_zero_width = pwm_zero_width(control.D_raw_target); } - + +/** + * @brief checks if the reverse has changed + */ +inline void check_reverse(void) +{ + static uint8_t last_reverse = 0; + if(last_reverse != system_flags.reverse){ + set_state_contactor(); + } + last_reverse = system_flags.reverse; +} /** * @brief checks the quantity of the faults. @@ -144,6 +157,15 @@ inline void set_state_initializing(void) state_machine = STATE_INITIALIZING; } +/** +* @brief set contactor state +*/ +inline void set_state_contactor(void) +{ + state_contactor = STATE_CONTACTOR_WAITING_MOTOR; + state_machine = STATE_CONTACTOR; +} + /** * @brief set idle state */ @@ -174,6 +196,9 @@ inline void print_system_flags(void) VERBOSE_MSG_MACHINE(usart_send_string(" Pot_zero: ")); VERBOSE_MSG_MACHINE(usart_send_char(48+system_flags.pot_zero_width)); + + VERBOSE_MSG_MACHINE(usart_send_string(" Rev: ")); + VERBOSE_MSG_MACHINE(usart_send_char(48+system_flags.reverse)); } /** @@ -253,6 +278,68 @@ inline void task_initializing(void) } } +/** + * @brief + * - sets the duty-cycle to zero, + * - waits until the motor stops (based on some experimental time), + * - sends the switch task to the contactor, + * - waits until the contactor finishes its task, or timeout, + * - go to idle state, + */ +inline void task_change_contactor(void) +{ + set_pwm_off(); + + if(led_clk_div++ >= 100){ + cpl_led(); + led_clk_div = 0; + } + + switch(state_contactor){ + default: case STATE_CONTACTOR_WAITING_MOTOR: + if(contactor.motor_stop_clk_div++ >= 2000){ + state_contactor = STATE_CONTACTOR_SEND_REQUEST; + contactor.motor_stop_clk_div = 0; + } + + break; + case STATE_CONTACTOR_SEND_REQUEST: + contactor_request_t request = CONTACTOR_REQUEST_TURN_OFF; + + if(system_flags.motor_on){ + if(system_flags.reverse){ + request = CONTACTOR_REQUEST_SET_REVERSE; + }else{ + request = CONTACTOR_REQUEST_SET_FORWARD; + } + } + + can_app_send_contactor_request((uint8_t)request); + state_contactor = STATE_CONTACTOR_WAITING_RESPONSE; + contactor.timeout_clk_div = 0; + + break; + case STATE_CONTACTOR_WAITING_RESPONSE: + + if(contactor.message_sent == contactor.message_received){ + contactor.acknowledged = 1; + contactor.timeout_clk_div = 0; + } + + if(contactor.timeout_clk_div++ >= 1000){ + VERBOSE_MSG_MACHINE(usart_send_string("Contactor request timeout!\n")); + state_contactor = STATE_CONTACTOR_SEND_REQUEST; + } + + if(contactor.acknowledged){ + VERBOSE_MSG_MACHINE(usart_send_string("CHANGE CONTACTOR task done, going to IDLE STATE!\n")); + set_state_idle(); + } + + break; + } +} + /** * @brief waits for commands while checking the system: * - checks the deadman's switch state @@ -377,6 +464,10 @@ inline void machine_run(void) case STATE_INITIALIZING: task_initializing(); + break; + case STATE_CONTACTOR: + task_change_contactor(); + break; case STATE_IDLE: task_idle(); diff --git a/firmware/src/machine.h b/firmware/src/machine.h index 0c87866..caf9a4b 100644 --- a/firmware/src/machine.h +++ b/firmware/src/machine.h @@ -25,6 +25,7 @@ typedef enum state_machine{ STATE_INITIALIZING, + STATE_CONTACTOR, STATE_IDLE, STATE_RUNNING, STATE_ERROR, @@ -35,6 +36,7 @@ typedef union system_flags{ uint8_t motor_on :1; uint8_t dms :1; uint8_t pot_zero_width :1; + uint8_t reverse :1; }; uint8_t all__; } system_flags_t; @@ -64,6 +66,27 @@ typedef struct control{ }control_t; +typedef struct contactor{ + uint8_t message_sent; + uint8_t message_received; + uint8_t acknowledged; + uint16_t timeout_clk_div; + uint16_t motor_stop_clk_div; +}contactor_t; + +typedef enum state_contactor{ + STATE_CONTACTOR_WAITING_MOTOR, + STATE_CONTACTOR_SEND_REQUEST, + STATE_CONTACTOR_WAITING_RESPONSE, +}state_contactor_t; + +typedef enum contactor_request{ + CONTACTOR_REQUEST_TURN_OFF, + CONTACTOR_REQUEST_SET_FORWARD, + CONTACTOR_REQUEST_SET_REVERSE, + CONTACTOR_REQUEST_UNKNOWN = 0xFF, +}contactor_request_t; + // machine checks void check_idle_zero_pot(void); void check_idle_current(void); @@ -74,6 +97,7 @@ void check_running_voltage(void); void check_running_temperature(void); //void check_can(void); // transfered to can_app.h void check_pwm_fault(void); +void check_reverse(void); // debug functions void print_system_flags(void); @@ -82,6 +106,7 @@ void print_control(void); // machine tasks void task_initializing(void); +void task_change_contactor(void); void task_idle(void); void task_running(void); void task_error(void); @@ -91,6 +116,7 @@ void machine_init(void); void machine_run(void); void set_state_error(void); void set_state_initializing(void); +void set_state_contactor(void); void set_state_idle(void); void set_state_running(void); void set_initial_state(void); @@ -109,5 +135,7 @@ extern uint8_t check_pwm_fault_times; // other variables extern uint8_t led_clk_div; extern control_t control; +extern state_contactor_t state_contactor; +extern contactor_t contactor; #endif /* ifndef MACHINE_H */ From 736ab32b850dc60c200d16366c4e1a3b812fff20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ant=C3=B4nio=20Cardoso?= Date: Fri, 25 Feb 2022 02:21:28 -0300 Subject: [PATCH 02/11] Add reverse checks. --- firmware/src/machine.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/firmware/src/machine.c b/firmware/src/machine.c index 93f8c1c..292084f 100644 --- a/firmware/src/machine.c +++ b/firmware/src/machine.c @@ -288,6 +288,7 @@ inline void task_initializing(void) */ inline void task_change_contactor(void) { + check_reverse(); set_pwm_off(); if(led_clk_div++ >= 100){ @@ -353,7 +354,8 @@ inline void task_idle(void) cpl_led(); led_clk_div = 0; } - + + check_reverse(); check_idle_zero_pot(); //check_idle_current(); //check_idle_voltage(); @@ -376,6 +378,7 @@ inline void task_running(void) led_clk_div = 0; } + check_reverse(); //check_pwm_fault(); //check_running_current(); //check_running_voltage(); From de5a8ac219f507effff83ffa8d3f645dbcf6f520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ant=C3=B4nio=20Cardoso?= Date: Fri, 25 Feb 2022 16:54:48 -0300 Subject: [PATCH 03/11] Add extractor for Contactor messages, and error checking. --- firmware/src/can_app.c | 167 +++++++++++++++++++++++++++-------------- firmware/src/can_app.h | 8 ++ firmware/src/machine.h | 11 +-- 3 files changed, 126 insertions(+), 60 deletions(-) diff --git a/firmware/src/can_app.c b/firmware/src/can_app.c index b4d470c..26dfb31 100644 --- a/firmware/src/can_app.c +++ b/firmware/src/can_app.c @@ -3,6 +3,7 @@ uint8_t can_app_send_state_clk_div; uint8_t can_app_send_motor_clk_div; uint16_t can_app_checks_without_mic19_msg; +uint16_t can_app_checks_without_mac22_msg; uint16_t can_app_checks_without_mswi19_msg; uint8_t mswi19_connected; @@ -96,6 +97,24 @@ inline void can_app_send_contactor_request(uint8_t request) contactor.timeout_clk_div = 0; } +/** + * @brief extracts the specific MIC19 MOTOR message + * + * The msg is AAAAAAAABBBBBBBB + * A is the Signature of module + * B is the Response + * + * @param *msg pointer to the message to be extracted +*/ +inline void can_app_extractor_mac22_contactor_response(can_t *msg) +{ + if(msg->data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] == CAN_SIGNATURE_MAC22){ + can_app_checks_without_mac22_msg = 0; + + contactor.message_received = msg->data[CAN_MSG_MAC22_CONTACTOR_RESPONSE_BYTE]; + } +} + /** * @brief extracts the specific MIC19 STATE message * @param *msg pointer to the message to be extracted @@ -115,6 +134,21 @@ inline void can_app_extractor_mic19_state(can_t *msg) } } +inline void can_app_extractor_mac22_state(can_t *msg) +{ + if(msg->data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] == CAN_SIGNATURE_MAC22){ + // zerar contador + if(msg->data[CAN_MSG_GENERIC_STATE_ERROR_BYTE]){ + //ERROR!!! + } + /*if(contador == maximo)*/{ + //ERROR!!! + } + + + } +} + inline void can_app_extractor_mswi19_state(can_t *msg) { if(msg->data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] == CAN_SIGNATURE_MSWI19){ @@ -163,10 +197,6 @@ inline void can_app_extractor_mic19_motor(can_t *msg) } control.I_raw_target = msg->data[CAN_MSG_MIC19_MOTOR_I_BYTE]; - - } - if(msg->data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] == CAN_SIGNATURE_MSWI19){ - control.D_raw_target = msg->data[CAN_MSG_MIC19_MOTOR_D_BYTE]; } } @@ -175,25 +205,67 @@ inline void can_app_extractor_mswi19_motor(can_t *msg) if(msg->data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] == CAN_SIGNATURE_MSWI19){ can_app_checks_without_mswi19_msg = 0; mswi19_connected = 1; - /* - system_flags.motor_on = bit_is_set(msg->data[ - CAN_MSG_MSWI19_MOTOR_MOTOR_BYTE], - CAN_MSG_MSWI19_MOTOR_MOTOR_MOTOR_ON_BIT); - - system_flags.dms = bit_is_set(msg->data[ - CAN_MSG_MSWI19_MOTOR_MOTOR_BYTE], - CAN_MSG_MSWI19_MOTOR_MOTOR_DMS_ON_BIT); - */ - - control.D_raw_target = msg->data[CAN_MSG_MSWI19_MOTOR_D_BYTE]; + control.D_raw_target = msg->data[CAN_MSG_MSWI19_MOTOR_D_BYTE]; + } +} - /* - control.I_raw_target = msg->data[CAN_MSG_MSWI19_MOTOR_I_BYTE]; - */ +inline void can_app_msg_mic19_extractors_switch(can_t *msg) +{ + switch(msg->id){ + case CAN_MSG_MIC19_MOTOR_ID: + VERBOSE_MSG_CAN_APP(usart_send_string("got a motor msg from mic19: ")); + VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); + can_app_extractor_mic19_motor(msg); + break; + case CAN_MSG_MIC19_STATE_ID: + VERBOSE_MSG_CAN_APP(usart_send_string("got a state msg from mic19: ")); + VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); + can_app_extractor_mic19_state(msg); + break; + default: + VERBOSE_MSG_CAN_APP(usart_send_string("got a unknown msg from mic19: ")); + VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); + break; + } +} +inline void can_app_msg_mswi19_extractors_switch(can_t *msg) +{ + switch(msg->id){ + case CAN_MSG_MSWI19_MOTOR_ID: + VERBOSE_MSG_CAN_APP(usart_send_string("got a motor msg from mswi19: ")); + VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); + can_app_extractor_mswi19_motor(msg); + break; + case CAN_MSG_MSWI19_STATE_ID: + VERBOSE_MSG_CAN_APP(usart_send_string("got a state msg from mswi19: ")); + VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); + can_app_extractor_mswi19_state(msg); + break; + default: + VERBOSE_MSG_CAN_APP(usart_send_string("got a unknown msg from mswi19: ")); + VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); + break; } - if(msg->data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] == CAN_SIGNATURE_MSWI19){ - control.D_raw_target = msg->data[CAN_MSG_MSWI19_MOTOR_D_BYTE]; +} + +inline void can_app_msg_mac22_extractors_switch(can_t *msg) +{ + switch(msg->id){ + case CAN_MSG_MAC22_CONTACTOR_ID: + VERBOSE_MSG_CAN_APP(usart_send_string("got a motor msg from mac22: ")); + VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); + can_app_extractor_mac22_contactor_response(msg); + break; + case CAN_MSG_MAC22_STATE_ID: + VERBOSE_MSG_CAN_APP(usart_send_string("got a state msg from mac22: ")); + VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); + can_app_extractor_mac22_state(msg); + break; + default: + VERBOSE_MSG_CAN_APP(usart_send_string("got a unknown msg from mac22: ")); + VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); + break; } } @@ -203,42 +275,18 @@ inline void can_app_extractor_mswi19_motor(can_t *msg) */ inline void can_app_msg_extractors_switch(can_t *msg) { - if(msg->data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] == CAN_SIGNATURE_MIC19){ - switch(msg->id){ - case CAN_MSG_MIC19_MOTOR_ID: - VERBOSE_MSG_CAN_APP(usart_send_string("got a motor msg from mic19: ")); - VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); - can_app_extractor_mic19_motor(msg); - break; - case CAN_MSG_MIC19_STATE_ID: - VERBOSE_MSG_CAN_APP(usart_send_string("got a state msg from mic19: ")); - VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); - can_app_extractor_mic19_state(msg); - break; - default: - VERBOSE_MSG_CAN_APP(usart_send_string("got a unknown msg from mic19: ")); - VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); - break; - } + switch(msg->data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE]){ + case CAN_SIGNATURE_MIC19: + can_app_msg_mic19_extractors_switch(msg); + break; + case CAN_SIGNATURE_MSWI19: + can_app_msg_mswi19_extractors_switch(msg); + break; + case CAN_SIGNATURE_MAC22: + can_app_msg_mac22_extractors_switch(msg); + break; + default: break; } - if(msg->data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] == CAN_SIGNATURE_MSWI19){ - switch(msg->id){ - case CAN_MSG_MSWI19_MOTOR_ID: - VERBOSE_MSG_CAN_APP(usart_send_string("got a motor msg from mswi19: ")); - VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); - can_app_extractor_mswi19_motor(msg); - break; - case CAN_MSG_MSWI19_STATE_ID: - VERBOSE_MSG_CAN_APP(usart_send_string("got a state msg from mswi19: ")); - VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); - can_app_extractor_mswi19_state(msg); - break; - default: - VERBOSE_MSG_CAN_APP(usart_send_string("got a unknown msg from mswi19: ")); - VERBOSE_MSG_CAN_APP(can_app_print_msg(msg)); - break; - } - } } /** @@ -263,6 +311,15 @@ inline void check_can(void) mswi19_connected = 0; } + if(can_app_checks_without_mac22_msg++ >= CAN_APP_CHECKS_WITHOUT_MSWI19_MSG){ + VERBOSE_MSG_CAN_APP(usart_send_string("Error: too many cycles without mac22 messages.\n")); + can_app_checks_without_mac22_msg = 0; + #ifdef SET_ERROR_WHEN_NO_STATE_MESSAGES_FROM_MAC22 + error_flags.no_contactor = 1; + set_state_error(); + #endif + } + if(can_check_message()){ can_t msg; if(can_get_message(&msg)){ diff --git a/firmware/src/can_app.h b/firmware/src/can_app.h index b608589..7b0ce83 100644 --- a/firmware/src/can_app.h +++ b/firmware/src/can_app.h @@ -27,7 +27,12 @@ void can_app_extractor_mic19_state(can_t *msg); void can_app_extractor_mic19_motor(can_t *msg); void can_app_extractor_mswi19_state(can_t *msg); void can_app_extractor_mswi19_motor(can_t *msg); +void can_app_extractor_mac22_state(can_t *msg); +void can_app_extractor_mac22_contactor_response(can_t *msg); void can_app_msg_extractors_switch(can_t *msg); +void can_app_msg_mic19_extractors_switch(can_t *msg); +void can_app_msg_mswi19_extractors_switch(can_t *msg); +void can_app_msg_mac22_extractors_switch(can_t *msg); void check_can(void); #define CAN_APP_SEND_STATE_CLK_DIV 100 @@ -35,6 +40,9 @@ void check_can(void); extern uint8_t can_app_send_state_clk_div; extern uint8_t can_app_send_motor_clk_div; +// #define SET_ERROR_WHEN_NO_STATE_MESSAGES_FROM_MAC22 // Date: Fri, 25 Feb 2022 16:58:14 -0300 Subject: [PATCH 04/11] Use pwm_reset() instead of turn_pwm_off(). --- firmware/src/machine.c | 7 +++---- firmware/src/pwm.c | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/src/machine.c b/firmware/src/machine.c index 292084f..8ddce39 100644 --- a/firmware/src/machine.c +++ b/firmware/src/machine.c @@ -162,6 +162,7 @@ inline void set_state_initializing(void) */ inline void set_state_contactor(void) { + pwm_reset(); state_contactor = STATE_CONTACTOR_WAITING_MOTOR; state_machine = STATE_CONTACTOR; } @@ -171,6 +172,7 @@ inline void set_state_contactor(void) */ inline void set_state_idle(void) { + pwm_reset(); state_machine = STATE_IDLE; } @@ -259,8 +261,7 @@ inline void print_control(void) inline void task_initializing(void) { set_led(); - set_pwm_off(); - pwm_fault_count = 0; + pwm_reset(); //check_buffers(); //check_idle_current(); @@ -289,7 +290,6 @@ inline void task_initializing(void) inline void task_change_contactor(void) { check_reverse(); - set_pwm_off(); if(led_clk_div++ >= 100){ cpl_led(); @@ -387,7 +387,6 @@ inline void task_running(void) if(system_flags.motor_on && system_flags.dms){ pwm_compute(); }else{ - pwm_reset(); set_state_idle(); } diff --git a/firmware/src/pwm.c b/firmware/src/pwm.c index a38f755..fe37dd6 100644 --- a/firmware/src/pwm.c +++ b/firmware/src/pwm.c @@ -39,6 +39,7 @@ void pwm_init(void) inline void pwm_reset(void) { set_pwm_off(); + pwm_fault_count = 0; control.D_raw = control.D_raw_target = control.D = 0; control.I_raw = control.I_raw_target = control.I = 0; VERBOSE_MSG_PWM(usart_send_string("PWM turned off!\n")); From 85258c101f344c57435abb01d3cfd3e0cb8fdfd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ant=C3=B4nio=20Cardoso?= Date: Fri, 25 Feb 2022 17:06:06 -0300 Subject: [PATCH 05/11] Add Finite State Machine and MAM17/MAC22 Communication Diagrams --- system_diagrams.drawio | 266 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 system_diagrams.drawio diff --git a/system_diagrams.drawio b/system_diagrams.drawio new file mode 100644 index 0000000..dcae319 --- /dev/null +++ b/system_diagrams.drawio @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 5b19262c9f518499e4dea645d4837ea7c283ff56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ant=C3=B4nio=20Cardoso?= Date: Sat, 26 Feb 2022 02:48:35 -0300 Subject: [PATCH 06/11] Fix places where MIC was used it place of MAC --- firmware/src/can_app.c | 4 ++-- firmware/src/can_app.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/src/can_app.c b/firmware/src/can_app.c index 26dfb31..97f28a4 100644 --- a/firmware/src/can_app.c +++ b/firmware/src/can_app.c @@ -295,7 +295,7 @@ inline void can_app_msg_extractors_switch(can_t *msg) inline void check_can(void) { // If no messages is received from mic19 for - // CAN_APP_CHECKS_WITHOUT_MIC19_MSG cycles, than it go to a specific error state. + // CAN_APP_CHECKS_WITHOUT_MIC19_MSG cycles, than it go to a specific error state. //VERBOSE_MSG_CAN_APP(usart_send_string("checks: ")); //VERBOSE_MSG_CAN_APP(usart_send_uint16(can_app_checks_without_mic19_msg)); if(can_app_checks_without_mic19_msg++ >= CAN_APP_CHECKS_WITHOUT_MIC19_MSG){ @@ -311,7 +311,7 @@ inline void check_can(void) mswi19_connected = 0; } - if(can_app_checks_without_mac22_msg++ >= CAN_APP_CHECKS_WITHOUT_MSWI19_MSG){ + if(can_app_checks_without_mac22_msg++ >= CAN_APP_CHECKS_WITHOUT_MAC22_MSG){ VERBOSE_MSG_CAN_APP(usart_send_string("Error: too many cycles without mac22 messages.\n")); can_app_checks_without_mac22_msg = 0; #ifdef SET_ERROR_WHEN_NO_STATE_MESSAGES_FROM_MAC22 diff --git a/firmware/src/can_app.h b/firmware/src/can_app.h index 7b0ce83..eea9cc9 100644 --- a/firmware/src/can_app.h +++ b/firmware/src/can_app.h @@ -42,7 +42,7 @@ extern uint8_t can_app_send_state_clk_div; extern uint8_t can_app_send_motor_clk_div; // #define SET_ERROR_WHEN_NO_STATE_MESSAGES_FROM_MAC22 // Date: Sat, 26 Feb 2022 16:11:02 -0300 Subject: [PATCH 07/11] Use state msgs to reset can error counter --- firmware/src/can_app.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/src/can_app.c b/firmware/src/can_app.c index 97f28a4..688393d 100644 --- a/firmware/src/can_app.c +++ b/firmware/src/can_app.c @@ -122,7 +122,7 @@ inline void can_app_extractor_mac22_contactor_response(can_t *msg) inline void can_app_extractor_mic19_state(can_t *msg) { if(msg->data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] == CAN_SIGNATURE_MIC19){ - // zerar contador + can_app_checks_without_mic19_msg = 0; if(msg->data[CAN_MSG_GENERIC_STATE_ERROR_BYTE]){ //ERROR!!! } @@ -137,7 +137,7 @@ inline void can_app_extractor_mic19_state(can_t *msg) inline void can_app_extractor_mac22_state(can_t *msg) { if(msg->data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] == CAN_SIGNATURE_MAC22){ - // zerar contador + can_app_checks_without_mac22_msg = 0; if(msg->data[CAN_MSG_GENERIC_STATE_ERROR_BYTE]){ //ERROR!!! } @@ -152,7 +152,7 @@ inline void can_app_extractor_mac22_state(can_t *msg) inline void can_app_extractor_mswi19_state(can_t *msg) { if(msg->data[CAN_MSG_GENERIC_STATE_SIGNATURE_BYTE] == CAN_SIGNATURE_MSWI19){ - // zerar contador + can_app_checks_without_mswi19_msg = 0; if(msg->data[CAN_MSG_GENERIC_STATE_ERROR_BYTE]){ //ERROR!!! } From 6d681fd3d444cec7b65a40801adc7abe62bbfec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ant=C3=B4nio=20Cardoso?= Date: Sat, 26 Feb 2022 16:12:20 -0300 Subject: [PATCH 08/11] Timeout transition goes to SEND_REQUEST, not WAITING_MOTOR. --- system_diagrams.drawio | 127 ++++++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 58 deletions(-) diff --git a/system_diagrams.drawio b/system_diagrams.drawio index dcae319..59f64cb 100644 --- a/system_diagrams.drawio +++ b/system_diagrams.drawio @@ -1,45 +1,45 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -49,7 +49,7 @@ - + @@ -59,55 +59,55 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -118,16 +118,16 @@ - + - + - + - + @@ -138,80 +138,80 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -221,10 +221,10 @@ - + - + @@ -235,7 +235,7 @@ - + @@ -246,7 +246,7 @@ - + @@ -257,9 +257,20 @@ - + + + + + + + + + + + + From 8404296f66f2632814767958fba16eb7fe58c5f1 Mon Sep 17 00:00:00 2001 From: alejopm03 Date: Sat, 26 Feb 2022 21:32:41 -0300 Subject: [PATCH 09/11] FIX: machine state, can filters -is working- --- firmware/src/can_filters.h | 4 ++-- firmware/src/machine.c | 26 +++++++++++++++++--------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/firmware/src/can_filters.h b/firmware/src/can_filters.h index c8c0aa2..9bb0510 100644 --- a/firmware/src/can_filters.h +++ b/firmware/src/can_filters.h @@ -74,8 +74,8 @@ const uint8_t can_filter[] PROGMEM = // Group 1 MCP2515_FILTER(CAN_MSG_MIC19_STATE_ID), // Filter 2 MCP2515_FILTER(CAN_MSG_MIC19_MOTOR_ID), // Filter 3 - MCP2515_FILTER(CAN_MSG_MIC19_STATE_ID), // Filter 4 - MCP2515_FILTER(CAN_MSG_MIC19_MOTOR_ID), // Filter 5 + MCP2515_FILTER(CAN_MSG_MAC22_STATE_ID), // Filter 4 + MCP2515_FILTER(CAN_MSG_MAC22_CONTACTOR_ID), // Filter 5 MCP2515_FILTER(CAN_MASK_MIC19), // Mask 0 (for group 0) MCP2515_FILTER(CAN_MASK_MIC19), // Mask 1 (for group 1) diff --git a/firmware/src/machine.c b/firmware/src/machine.c index 8ddce39..f8c2d3f 100644 --- a/firmware/src/machine.c +++ b/firmware/src/machine.c @@ -2,6 +2,7 @@ control_t control; state_machine_t state_machine; +state_machine_t last_state; system_flags_t system_flags; error_flags_t error_flags; volatile uint8_t machine_clk; @@ -162,7 +163,8 @@ inline void set_state_initializing(void) */ inline void set_state_contactor(void) { - pwm_reset(); + usart_send_string("SET STATE CONTACTOR\n"); + set_pwm_off(); state_contactor = STATE_CONTACTOR_WAITING_MOTOR; state_machine = STATE_CONTACTOR; } @@ -172,7 +174,8 @@ inline void set_state_contactor(void) */ inline void set_state_idle(void) { - pwm_reset(); + set_pwm_off(); + pwm_zero_width(PWM_D_MIN_THRESHHOLD + 1); //reset pwm_zero_width state state_machine = STATE_IDLE; } @@ -181,7 +184,7 @@ inline void set_state_idle(void) */ inline void set_state_running(void) { - pwm_reset(); + usart_send_string("SET STATE RUNNING\n"); state_machine = STATE_RUNNING; } @@ -190,7 +193,7 @@ inline void set_state_running(void) */ inline void print_system_flags(void) { - VERBOSE_MSG_MACHINE(usart_send_string("Motor Sw: ")); + VERBOSE_MSG_MACHINE(usart_send_string(" Motor Sw: ")); VERBOSE_MSG_MACHINE(usart_send_char(48+system_flags.motor_on)); VERBOSE_MSG_MACHINE(usart_send_string(" DMS Sw: ")); @@ -208,7 +211,7 @@ inline void print_system_flags(void) */ inline void print_error_flags(void) { - VERBOSE_MSG_MACHINE(usart_send_string("\nOvrI: ")); + VERBOSE_MSG_MACHINE(usart_send_string("\n OvrI: ")); VERBOSE_MSG_MACHINE(usart_send_char(48+error_flags.overcurrent)); VERBOSE_MSG_MACHINE(usart_send_string(" OvrV: ")); @@ -219,6 +222,7 @@ inline void print_error_flags(void) VERBOSE_MSG_MACHINE(usart_send_string(" NOCAN: ")); VERBOSE_MSG_MACHINE(usart_send_char(48+error_flags.no_canbus)); + VERBOSE_MSG_MACHINE(usart_send_char(' ')); } /** @@ -289,7 +293,7 @@ inline void task_initializing(void) */ inline void task_change_contactor(void) { - check_reverse(); + set_pwm_off(); if(led_clk_div++ >= 100){ cpl_led(); @@ -298,7 +302,7 @@ inline void task_change_contactor(void) switch(state_contactor){ default: case STATE_CONTACTOR_WAITING_MOTOR: - if(contactor.motor_stop_clk_div++ >= 2000){ + if(contactor.motor_stop_clk_div++ >= 200){ state_contactor = STATE_CONTACTOR_SEND_REQUEST; contactor.motor_stop_clk_div = 0; } @@ -327,7 +331,7 @@ inline void task_change_contactor(void) contactor.timeout_clk_div = 0; } - if(contactor.timeout_clk_div++ >= 1000){ + if(contactor.timeout_clk_div++ >= 500){ VERBOSE_MSG_MACHINE(usart_send_string("Contactor request timeout!\n")); state_contactor = STATE_CONTACTOR_SEND_REQUEST; } @@ -365,8 +369,10 @@ inline void task_idle(void) VERBOSE_MSG_MACHINE(usart_send_string("Enjoy, the system is at its RUNNING STATE!!\n")); set_state_running(); } -} + if(!system_flags.motor_on) + set_state_contactor(); +} /** * @brief running task checks the system and apply the control action to pwm. @@ -387,6 +393,7 @@ inline void task_running(void) if(system_flags.motor_on && system_flags.dms){ pwm_compute(); }else{ + usart_send_string("going to idle"); set_state_idle(); } @@ -394,6 +401,7 @@ inline void task_running(void) void set_initial_state(void) { + can_app_send_contactor_request(CONTACTOR_REQUEST_TURN_OFF); system_flags.all__ = 0; error_flags.all = 0; From 5940b774d243a44db461c1e1a69fdcf5cf105a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ant=C3=B4nio=20Cardoso?= Date: Wed, 9 Mar 2022 23:35:47 -0300 Subject: [PATCH 10/11] Make the motor waiting time proportinal to last duty cycle value. --- firmware/src/machine.c | 12 +++- pwm_signals.ipynb | 138 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 pwm_signals.ipynb diff --git a/firmware/src/machine.c b/firmware/src/machine.c index f8c2d3f..556bca6 100644 --- a/firmware/src/machine.c +++ b/firmware/src/machine.c @@ -12,6 +12,7 @@ uint8_t check_pwm_fault_times; uint8_t led_clk_div; state_contactor_t state_contactor; contactor_t contactor; +uint16_t pwm_last_value; // Used to know the OCR1A before each call of set_state_contactor() /* * to-do: @@ -164,6 +165,7 @@ inline void set_state_initializing(void) inline void set_state_contactor(void) { usart_send_string("SET STATE CONTACTOR\n"); + pwm_last_value = OCR1A; set_pwm_off(); state_contactor = STATE_CONTACTOR_WAITING_MOTOR; state_machine = STATE_CONTACTOR; @@ -300,9 +302,17 @@ inline void task_change_contactor(void) led_clk_div = 0; } + uint16_t motor_clk_div_max = 0; + { + // Calculated in pwm_signals.ipynb as y = a*x +b + const int a = 4; + const int b = 375; + motor_clk_div_max = a * pwm_last_value + b; + } + switch(state_contactor){ default: case STATE_CONTACTOR_WAITING_MOTOR: - if(contactor.motor_stop_clk_div++ >= 200){ + if(contactor.motor_stop_clk_div++ >= motor_clk_div_max){ state_contactor = STATE_CONTACTOR_SEND_REQUEST; contactor.motor_stop_clk_div = 0; } diff --git a/pwm_signals.ipynb b/pwm_signals.ipynb new file mode 100644 index 0000000..c039600 --- /dev/null +++ b/pwm_signals.ipynb @@ -0,0 +1,138 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "PWM_D_MAX = int(640)\n", + "PWM_D_MAX_THRESHHOLD = int(634)\n", + "PWM_D_LIN_MULT = int(5)\n", + "PWM_D_LIN_DIV = int(1)\n", + "\n", + "\n", + "def pwm_compute(x: int):\n", + " # y = (a * x) >> b\n", + " y = PWM_D_LIN_MULT * x / 2**PWM_D_LIN_DIV\n", + " return y\n", + "\n", + "x = np.arange(255, dtype=int)\n", + "y = pwm_compute(x)\n", + "plt.plot(x, y); plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAD4CAYAAAAAczaOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAjsUlEQVR4nO3dd3xUZdr/8c9FJ/ROgISETqjCUFXsghUQC66rqKy4+7jrrvusEAQVO7quZV3LYvexshRBbIiCuIpiUEmDQOghgdAJhPT790fG32YxtGSSk8x836/XvDJzn3NmrjsnfHNyzsyFOecQEZHQUMPrAkREpPIo9EVEQohCX0QkhCj0RURCiEJfRCSE1PK6gBNp2bKli4qK8roMEZFqZdWqVbudc62OHq/yoR8VFUVcXJzXZYiIVCtmtqW0cZ3eEREJIQp9EZEQotAXEQkhJwx9M3vFzDLNLLGUZX8xM2dmLUuMTTWzVDNLMbORJcYHmlmCf9nfzcwCNw0RETkZJ3Ok/xow6uhBM4sALgC2lhiLAcYDvfzbPGdmNf2LnwcmAV39t188p4iIVKwThr5zbjmwt5RFTwKTgZId20YD7zrncp1zm4BUYLCZhQONnXMrXHGHtzeAMeUtXkRETk2Zzumb2eXAdufc6qMWtQe2lXic5h9r779/9Pixnn+SmcWZWdyuXbvKUqKIiJTilEPfzMKAacA9pS0uZcwdZ7xUzrlZzjmfc87XqtUvPlsgIhLUUnZk8dgna6mI1vdl+XBWZyAaWO2/FtsB+MHMBlN8BB9RYt0OQLp/vEMp4yIi4pdXUMRzy1J5dmkqjerV5tdDO9Kuaf2AvsYph75zLgFo/fNjM9sM+Jxzu81sIfC2mT0BtKP4gu1K51yhmWWZ2VDgO+AG4JlATEBEJBis3rafyXPiSdmZxej+7bjn0hhaNKwb8Nc5Yeib2TvA2UBLM0sD7nXOvVzaus65JDObDSQDBcBtzrlC/+LfUfxOoPrAx/6biEhIO5JXyBOfpfDyvzfRulE9Xp7g47yebSrs9ayq/3eJPp/PqfeOiASjbzbsJnZuAlv3ZvOrIZHEXtSDxvVqB+S5zWyVc8539HiVb7gmIhJsDubk88hHa3ln5VY6tgjjnVuGMqxzi0p5bYW+iEglWpK8k2nvJ7ArK5dJIzpxx/ndqF+n5ok3DBCFvohIJdhzKJf7Pkhm4ep0erRtxKzrffSLaFrpdSj0RUQqkHOOhavTmbEwiUO5Bfz5gm789qzO1KnlTb9Lhb6ISAVJ33+E6e8n8sXaTPpHNOWxK/vSrU0jT2tS6IuIBFhRkeOd77fyyEdrKSxy3H1pDDcOj6JmDe+bCyv0RUQCaNPuw8TOjee7TXs5vUsLHhnbl8gWYV6X9f8p9EVEAqCgsIhXvt7E3xavo06tGjw6rg9X+yKoav91iEJfRKSc1mQcZMrceOLTDnBBTBseHNObNo3reV1WqRT6IiJllFtQyLNfpPLcsg00DavNs78awMV92la5o/uSFPoiImXww9Z9TJkTz/rMQ1xxWnvuvjSGZg3qeF3WCSn0RUROQXZeAY9/uo5Xv9lEeON6vHrTIM7p3vrEG1YRCn0RkZP0depuYufFs23vEa4f2pHJo7rTKEAN0iqLQl9E5AQOHMnn4Q/X8F7cNqJbNuC9SUMZ0qlyGqQFmkJfROQ4FiftYPr7iew5nMdvz+rMn87vSr3aldcgLdAU+iIipdiVlcuMD5L4MD6DnuGNeXnCIPp0aOJ1WeWm0BcRKcE5x/wft3P/omSycwu5c2R3Jo3oRO2a3jRICzSFvoiI3/b9R5g2P4FlKbsYEFncIK1La28bpAWaQl9EQl5RkeOt77Yw8+O1OGDGZTFcP6xqNEgLNIW+iIS0jbsOETs3gZWb93Jm15Y8PLYPEc2rToO0QFPoi0hIKigs4sWvNvHkknXUq1WDv17ZlysHdqjSLRQCQaEvIiEnKf0AU+bGk7j9IKN6teX+Mb1o3ahqNkgLNIW+iISMnPxCnvliPS98uZFmYXV4/roBXNQn3OuyKpVCX0RCwqote5k8J54Nuw4zbkAH7r60J03Dqn6DtEBT6ItIUDucW8BfP03h9RWbadekPq/fPJizurXyuizPKPRFJGgtX7eLqfMSSD9whAnDovjLyO40rBvasRfasxeRoLQ/O48HP1zDnFVpdGrVgH/dOgxfVHOvy6oSFPoiElQ+Tsjg7gVJ7MvO47ZzOvOHc6t3g7RAU+iLSFDIzMrh3gVJfJy4g17tGvP6zYPo1a76N0gLNIW+iFRrzjnmrErjwQ/XcCS/kMmjunPLmcHTIC3QTvhdMbNXzCzTzBJLjP3VzNaaWbyZzTezpiWWTTWzVDNLMbORJcYHmlmCf9nfLdg/9iYiFW7b3mxueGUld86Jp1ubhnz8xzP5n7O7KPCP42S+M68Bo44a+wzo7ZzrC6wDpgKYWQwwHujl3+Y5M/v5ZNrzwCSgq/929HOKiJyUoiLHa19vYuRTy/lhyz4eGN2L9yYNo3Orhl6XVuWd8PSOc265mUUdNba4xMNvgSv990cD7zrncoFNZpYKDDazzUBj59wKADN7AxgDfFzeCYhIaEnNzGLK3ARWbdnHWd1a8dDY3nRoFrwN0gItEOf0bwbe899vT/EvgZ+l+cfy/fePHi+VmU2i+K8CIiMjA1CiiFR3+YVFzFq+kaeXrCesbk2euLofY09rH/QN0gKtXKFvZtOAAuCtn4dKWc0dZ7xUzrlZwCwAn893zPVEJDQkbj/A5DnxJGcc5JI+4cy4vBetGtX1uqxqqcyhb2YTgEuB85xzPwdzGhBRYrUOQLp/vEMp4yIix5STX8jTn69n1vKNNG9Qhxd+PZBRvdt6XVa1VqbQN7NRwBTgLOdcdolFC4G3zewJoB3FF2xXOucKzSzLzIYC3wE3AM+Ur3QRCWbfb97LlDnxbNx9mKt9HZh2cQxNwmp7XVa1d8LQN7N3gLOBlmaWBtxL8bt16gKf+c+nfeuc+61zLsnMZgPJFJ/2uc05V+h/qt9R/E6g+hRfwNVFXBH5hUO5BTz2yVreWLGFDs3q8+bEIZzRtaXXZQUN+8+ZmarJ5/O5uLg4r8sQkUqwNCWTafMSyDiYw03Do/nLyG6E1dFnSMvCzFY553xHj+u7KSKe23c4jwcWJTPvx+10ad2QOb8dzsCOzbwuKygp9EXEM845PkrYwb0LE9mfnc/t53bhtnO7ULeWGqRVFIW+iHgi82AO099PZHHyTvq0b8IbNw8hpl1jr8sKegp9EalUzjn+FZfGAx8mk1dQxNSLejDxjGhqqV9OpVDoi0il2bonm6nz4/k6dQ+Do5vz6Li+RLds4HVZIUWhLyIVrrDI8do3m3n80xRq1jAeHNObXw2OpEYNtVCobAp9EalQ63dmMXluPD9u3c853Vvx0Ng+tGta3+uyQpZCX0QqRF5BES98uYF/fJFKg7o1eeqa/ozu304N0jym0BeRgItP28/kOfGs3ZHFZf3ace9lMbRsqAZpVYFCX0QC5kheIU8tWceLX22kVaO6vHiDjwti2nhdlpSg0BeRgPh24x5i58azeU821w6OYOrFPWlcTw3SqhqFvoiUS1ZOPjM/Xstb320lsnkYb/9mCMO7qEFaVaXQF5Ey+2LtTqbNT2TnwRx+c0Y0/3thd+rXUQuFqkyhLyKnbO/hPO7/IIn3f0qnW5uGPHfdcE6LVIO06kChLyInzTnHB/EZzFiYRFZOPn88ryu3ndOFOrXUQqG6UOiLyEnZcaC4QdqSNTvp16EJj145hB5t1SCtulHoi8hxOed49/ttPPzhGvKLiph+SU9uOj2ammqhUC0p9EXkmLbsOUzs3ARWbNzDsE4tmDmuDx1bqEFadabQF5FfKCxyvPr1Jh5fnELtGjV45Io+jB8UoRYKQUChLyL/JWVHcYO01dv2c37P1jw4pg9tm9TzuiwJEIW+iADFDdKeXZrKc8tSaVSvNn+/9jQu6xuuo/sgo9AXEX7atp/Jc1azbuchxvRvxz2X9aJ5gzpelyUVQKEvEsKO5BXyt8UpvPL1Jto0rscrN/o4t4capAUzhb5IiPpmw25i5yawdW821w2JJPaiHjRSg7Sgp9AXCTEHc/J55KM1vLNyG1Etwnh30lCGdmrhdVlSSRT6IiFkSfJOpr2fwK6sXG4d0Yk/nd9NDdJCjEJfJATsPpTLfR8k88HqdHq0bcSLN/jo26Gp12WJBxT6IkHMOceCn9K574MkDuUW8OcLuvHbszqrQVoIU+iLBKn0/UeY/n4iX6zN5LTIpjw2ri9d2zTyuizxmEJfJMgUFTneXrmVmR+vpbDIcc+lMUwYHqUGaQLACf/GM7NXzCzTzBJLjDU3s8/MbL3/a7MSy6aaWaqZpZjZyBLjA80swb/s76aP+YkE3Kbdh7n2xW+Z/n4i/SKa8OmfRnDzGeqIKf9xMif2XgNGHTUWC3zunOsKfO5/jJnFAOOBXv5tnjOzn98a8DwwCejqvx39nCJSRgWFRfzzyw2Memo5yRkHeWxcX96cOITIFmFelyZVzAlP7zjnlptZ1FHDo4Gz/fdfB5YBU/zj7zrncoFNZpYKDDazzUBj59wKADN7AxgDfFzuGYiEuOT0g0yZG0/C9gNcGNOGB8b0pk1jNUiT0pX1nH4b51wGgHMuw8xa+8fbA9+WWC/NP5bvv3/0eKnMbBLFfxUQGRlZxhJFgltuQSH/+CKV55dtoGlYbZ791QAu7tNWDdLkuAJ9Ibe0nzZ3nPFSOedmAbMAfD7fMdcTCVWrtuxjytx4UjMPccWA9tx9SQzN1CBNTkJZQ3+nmYX7j/LDgUz/eBoQUWK9DkC6f7xDKeMicgqy8wr466cpvPbNZsIb1+PVmwZxTvfWJ95QxK+sn9BYCEzw358ALCgxPt7M6ppZNMUXbFf6TwVlmdlQ/7t2biixjYichH+v382FTy7n1a83c/3Qjiz+81kKfDllJzzSN7N3KL5o29LM0oB7gZnAbDObCGwFrgJwziWZ2WwgGSgAbnPOFfqf6ncUvxOoPsUXcHURV+QkHMjO56GPkpkdl0Z0ywbMvnUYg6Obe12WVFPmXNU+Ze7z+VxcXJzXZYh44pPEHdy9IJG9h/OYNKITfzyvK/Vqq0GanJiZrXLO+Y4e1ydyRaqgXVm5zFiYxIcJGcSEN+bVGwfRu30Tr8uSIKDQF6lCnHPM+2E79y9K5kheIXeO7M6kEZ2oXVMN0iQwFPoiVcT2/Ue4a14CX67bxcCOzXh0XF+6tG7odVkSZBT6Ih4rKnK8+d0WHv14LQ6YcVkMNwyLoob65UgFUOiLeGjDrkPEzo3n+837OLNrSx4e24eI5uqXIxVHoS/igfzCIl78aiNPLVlP/do1efyqfowb0F4tFKTCKfRFKlni9gNMmRtPUvpBLurdlvtG96J1IzVIk8qh0BepJDn5hTzzxXpe+HIjzcLq8Px1A7ioT7jXZUmIUeiLVIK4zXuZPDeejbsOc+XADky/pCdNw9QgTSqfQl+kAh3OLW6Q9vqKzbRrUp83bh7MiG6tvC5LQphCX6SCfLluF3fNSyD9wBEmDIvizpHdaVBX/+TEW/oJFAmw/dl5PLBoDXN/SKNzqwb869Zh+KLUIE2qBoW+SAB9nJDB3QuS2Jedx+/P6cLvz+2iBmlSpSj0RQIg82AO9yxI4pOkHfRq15jXbx5Er3ZqkCZVj0JfpBycc8xZlcYDi5LJKShiyqge3HJmNLXUIE2qKIW+SBlt25vNXfMT+Gr9bgZFNWPmuL50bqUGaVK1KfRFTlFhkeONFZv566cpGPDA6F5cN6SjGqRJtaDQFzkFqZlZTJmbwKot+zirWysevqIP7ZvW97oskZOm0Bc5CfmFRfzzyw38/fNUwurW5Imr+zH2NDVIk+pHoS9yAonbD3DnnHjWZBzkkr7hzLisF60a1fW6LJEyUeiLHENOfiFPLVnPi19tpHmDOvzz+oGM7NXW67JEykWhL1KK7zbuIXZeApt2H+YaXwR3XdyTJmG1vS5LpNwU+iIlZOXk89gnKfzft1uIaF6fNycO4YyuLb0uSyRgFPoifktTMpk2L4GMgzncfHo0fxnZjbA6+iciwUU/0RLy9h3O44FFycz7cTtdWzdk7u+GMyCymddliVQIhb6ELOccHyZkcO+CJA4cyef2c7tw27ldqFtLDdIkeCn0JSTtPJjD9PcT+Sx5J33aN+HN3wyhZ3hjr8sSqXAKfQkpzjlmx23jwQ/XkFdQxNSLejDxDDVIk9Ch0JeQsXVPNrHz4vlmwx6GRDdn5ri+RLds4HVZIpVKoS9Br7DI8do3m3n80xRq1jAeGtubawdFqkGahKRyhb6Z3QH8BnBAAnATEAa8B0QBm4GrnXP7/OtPBSYChcDtzrlPy/P6IieybmcWk+fE89O2/ZzbozUPje1NeBM1SJPQVebQN7P2wO1AjHPuiJnNBsYDMcDnzrmZZhYLxAJTzCzGv7wX0A5YYmbdnHOF5Z6FyFHyCop4ftkG/rF0PQ3r1uLp8f25vF87NUiTkFfe0zu1gPpmlk/xEX46MBU427/8dWAZMAUYDbzrnMsFNplZKjAYWFHOGkT+y+pt+5kyN561O7K4rF87ZlwWQ4uGapAmAuUIfefcdjN7HNgKHAEWO+cWm1kb51yGf50MM2vt36Q98G2Jp0jzj/2CmU0CJgFERkaWtUQJMUfyCnlyyTpe+mojrRrV5cUbfFwQ08brskSqlPKc3mlG8dF7NLAf+JeZ/fp4m5Qy5kpb0Tk3C5gF4PP5Sl1HpKQVG/YwdV48m/dkc+3gSKZe3IPG9dQgTeRo5Tm9cz6wyTm3C8DM5gHDgZ1mFu4/yg8HMv3rpwERJbbvQPHpIJEyO5iTz8yP1/L2d1vp2CKMt28ZwvDOapAmcizlCf2twFAzC6P49M55QBxwGJgAzPR/XeBffyHwtpk9QfGF3K7AynK8voS4L9bu5K55iWRm5XDLmdH8+YLu1K+jFgoix1Oec/rfmdkc4AegAPiR4lMyDYHZZjaR4l8MV/nXT/K/wyfZv/5teueOlMWeQ7ncvyiZBT+l071NI164fiD9I5p6XZZItWDOVe1T5j6fz8XFxXldhlQBzjkWrk7nvg+SycrJ57ZzuvA/Z3ehTi21UBA5mpmtcs75jh7XJ3KlWsg4cITp8xP5fG0m/SKa8ti4vnRv28jrskSqHYW+VGlFRY53v9/GIx+tIb+oiOmX9OSm06OpqRYKImWi0Jcqa/Puw8TOi+fbjXsZ1qkFM8f1oWMLNUgTKQ+FvlQ5BYVFvPr1Zv72WQq1a9Rg5hV9uGZQhFooiASAQl+qlLU7DjJlTjyr0w5wfs/WPDimD22b1PO6LJGgodCXKiG3oJBnl27guaWpNKlfm2euPY1L+4br6F4kwBT64rkft+5jytx41u08xJj+7bjnsl40b1DH67JEgpJCXzyTnVfA3xav45WvN9G2cT1eudHHuT3UIE2kIin0xRPfpO4mdl4CW/dm8+uhkUwZ1YNGapAmUuEU+lKpDhzJ55GP1vDu99uIahHGu5OGMrRTC6/LEgkZCn2pNIuTdjD9/UR2H8rl1rM6ccf53ahXWw3SRCqTQl8q3O5DucxYmMSi+Ax6tG3ESxN89O3Q1OuyREKSQl8qjHOO93/azn0fJJOdW8j/XtCNW8/qrAZpIh5S6EuFSN9/hGnzE1iasovTIosbpHVtowZpIl5T6EtAFRU53lq5lUc/XkthkeOeS2OYMDxKDdJEqgiFvgTMxl2HiJ2XwMpNezmjS0seuaIPEc3DvC5LREpQ6Eu5FRQW8dK/N/HkZ+uoU6sGj43ry1W+DmqhIFIFKfSlXJLTDzJ57moStx/kwpg2PDCmN20aq0GaSFWl0JcyyS0o5B9fpPL8sg00DavNc9cN4KLebXV0L1LFKfTllK3aUtwgLTXzEFcMaM/dl8TQTA3SRKoFhb6ctMO5BTy+OIXXvtlMuyb1ee2mQZzdvbXXZYnIKVDoy0n5av0ups5LIG3fEW4Y1pHJo3rQsK5+fESqG/2rleM6kJ3Pgx8m869VaXRq2YDZtw5jcHRzr8sSkTJS6MsxfZK4g7sXJLL3cB7/c3Znbj+vqxqkiVRzCn35hcysHGYsTOKjhB3EhDfm1RsH0bt9E6/LEpEAUOjL/+ecY94P27l/UTJH8gu5c2R3Jo3oRO2aapAmEiwU+gJA2r5s7pqfyPJ1uxjYsRmPjutLl9YNvS5LRAJMoR/iiooc//ftFh79ZC0A913ei+uHdqSGGqSJBCWFfgjbsOsQU+bEE7dlH2d2bcnDY9UgTSTYKfRDUH5hEbOWb+Tpz9dTv3ZNHr+qH+MGtFcLBZEQUK7QN7OmwEtAb8ABNwMpwHtAFLAZuNo5t8+//lRgIlAI3O6c+7Q8ry+nLnH7AabMjScp/SAX92nLjMt70bqRGqSJhIryHuk/DXzinLvSzOoAYcBdwOfOuZlmFgvEAlPMLAYYD/QC2gFLzKybc66wnDXIScjJL+Tvn6/nn8s30iysDi/8egCjeod7XZaIVLIyh76ZNQZGADcCOOfygDwzGw2c7V/tdWAZMAUYDbzrnMsFNplZKjAYWFHWGuTkfL95L1PmxLNx92GuGtiB6ZfE0CSsttdliYgHynOk3wnYBbxqZv2AVcAfgTbOuQwA51yGmf3ckas98G2J7dP8Y79gZpOASQCRkZHlKDG0Hcot4LFP1vLGii20b1qfN24ezIhurbwuS0Q8VJ7QrwUMAP7gnPvOzJ6m+FTOsZR2ldCVtqJzbhYwC8Dn85W6jhzfl+t2cde8BNIPHOHG4VHcObI7DdQgTSTklScF0oA059x3/sdzKA79nWYW7j/KDwcyS6wfUWL7DkB6OV5fSrE/O4/7FyUz74ftdG7VgDm/HcbAjmqQJiLFyhz6zrkdZrbNzLo751KA84Bk/20CMNP/dYF/k4XA22b2BMUXcrsCK8tTvPy3jxIyuGdBIvuz8/n9OV34/bld1CBNRP5Lef/e/wPwlv+dOxuBm4AawGwzmwhsBa4CcM4lmdlsin8pFAC36Z07gZF5MIe7FyTyadJOerdvzOs3D6ZXOzVIE5FfMueq9ilzn8/n4uLivC6jSnLO8a9VaTy4KJmcgiLuOL8bt5wZTS01SBMJeWa2yjnnO3pcV/aqqW17s5k6L4F/p+5mcFRzZo7rQ6dWapAmIsen0K9mCoscb6zYzGOfpFDD4IExvblucKQapInISVHoVyOpmVlMnhPPD1v3c3b3Vjw0tg/tm9b3uiwRqUYU+tVAfmERLyzbwDNfpBJWtyZPXtOPMf3VIE1ETp1Cv4pLSDvAnXNWs3ZHFpf0Dee+y3vRsmFdr8sSkWpKoV9F5eQX8uSSdby4fCMtG9bln9cPZGSvtl6XJSLVnEK/Cvpu4x5i5yWwafdhrvFFcNclPWlSXw3SRKT8FPpVSFZOPo9+spY3v91KRPP6vPWbIZzepaXXZYlIEFHoVxFL12YybX4CGQdzmHhGNP97YTfC6mj3iEhgKVU8tvdwHg8sSmb+j9vp2rohc383nAGRzbwuS0SClELfI845FsVnMGNhEgeO5HP7eV257ZzO1K2lBmkiUnEU+h7YeTCHafMTWbJmJ307NOHN3wyhZ3hjr8sSkRCg0K9Ezjne+34bD320hryCIu66uAc3n64GaSJSeRT6lWTrnmxi58XzzYY9DIluzqPj+hLVsoHXZYlIiFHoV7DCIserX2/i8cUp1KpRg4fH9mH8oAg1SBMRTyj0K1DKjiymzI3np237ObdHax4a25vwJmqQJiLeUehXgLyCIp5blsqzS1NpVK82T4/vz+X92qlBmoh4TqEfYKu37WfynHhSdmZxeb923HtZDC3UIE1EqgiFfoAcySvkic9SePnfm2jdqB4v3eDj/Jg2XpclIvJfFPoBsGLDHmLnxbNlTza/GhJJ7EU9aFxPDdJEpOpR6JfDwZx8HvloLe+s3ErHFmG8fcsQhndWgzQRqboU+mW0JHkn095PYFdWLpNGdOKO87tRv45aKIhI1abQP0V7DuVy3wfJLFydTvc2jfjn9T76RzT1uiwRkZOi0D9JzjkWrk5nxsIkDuUWcMf53fjd2Z2pU0stFESk+lDon4SMA0eYPj+Rz9dm0j+iKY9d2ZdubRp5XZaIyClT6B9HUZHjne+38shHaykoKmL6JT256fRoaqqFgohUUwr9Y9i8+zCx8+L5duNehnduwcwr+hLZIszrskREykWhf5SCwiJe+XoTf1u8jjo1azDzij5cMyhCLRREJCgo9EtYk3GQKXPjiU87wPk92/DgmN60bVLP67JERAJGoQ/kFhTy7NINPLc0lSb1a/PMtadxad9wHd2LSNApd+ibWU0gDtjunLvUzJoD7wFRwGbgaufcPv+6U4GJQCFwu3Pu0/K+fnn9sHUfU+bEsz7zEGNPa8/dl8bQvEEdr8sSEakQgXiT+R+BNSUexwKfO+e6Ap/7H2NmMcB4oBcwCnjO/wvDE9l5BTywKJlxz3/DodwCXr1xEE9e01+BLyJBrVyhb2YdgEuAl0oMjwZe999/HRhTYvxd51yuc24TkAoMLs/rl9XXqbsZ+dRyXv73Jq4bEsniO0ZwTo/WXpQiIlKpynt65ylgMlDyk0ptnHMZAM65DDP7OU3bA9+WWC/NP/YLZjYJmAQQGRlZzhL/48CRfB7+cA3vxW0jumUD3ps0lCGdWgTs+UVEqroyh76ZXQpkOudWmdnZJ7NJKWOutBWdc7OAWQA+n6/UdU7V4qQdTH8/kd2Hcrn1rOIGafVqq0GaiISW8hzpnw5cbmYXA/WAxmb2JrDTzML9R/nhQKZ//TQgosT2HYD0crz+SdmVlcuMD5L4MD6DHm0b8dIEH307NK3olxURqZLKfE7fOTfVOdfBORdF8QXaL5xzvwYWAhP8q00AFvjvLwTGm1ldM4sGugIry1z5ietj/o9pXPDkl3yWtJO/XNiND/5whgJfREJaRbxPfyYw28wmAluBqwCcc0lmNhtIBgqA25xzhRXw+uQXFjHpjTiWpuxiQGRxg7QurdUgTUQkIKHvnFsGLPPf3wOcd4z1HgIeCsRrHk/tmjXo1KohI7q14oZhUWqQJiLiF7SfyL370hivSxARqXL0P4CIiIQQhb6ISAhR6IuIhBCFvohICFHoi4iEEIW+iEgIUeiLiIQQhb6ISAgx5wLSxLLCmNkuYEsZN28J7A5gOVWd5hvcNN/gVRFz7eica3X0YJUP/fIwszjnnM/rOiqL5hvcNN/gVZlz1ekdEZEQotAXEQkhwR76s7wuoJJpvsFN8w1elTbXoD6nLyIi/y3Yj/RFRKQEhb6ISAgJytA3s1FmlmJmqWYW63U9FcHMNptZgpn9ZGZx/rHmZvaZma33f23mdZ1lZWavmFmmmSWWGDvm/Mxsqn9/p5jZSG+qLrtjzHeGmW337+OfzOziEsuq+3wjzGypma0xsyQz+6N/PCj38XHmW/n72DkXVDegJrAB6ATUAVYDMV7XVQHz3Ay0PGrsMSDWfz8WeNTrOssxvxHAACDxRPMDYvz7uS4Q7d//Nb2eQwDmOwP4SynrBsN8w4EB/vuNgHX+eQXlPj7OfCt9Hwfjkf5gINU5t9E5lwe8C4z2uKbKMhp43X//dWCMd6WUj3NuObD3qOFjzW808K5zLtc5twlIpfjnoNo4xnyPJRjmm+Gc+8F/PwtYA7QnSPfxceZ7LBU232AM/fbAthKP0zj+N7e6csBiM1tlZpP8Y22ccxlQ/EMGtPasuopxrPkF8z7/vZnF+0///HyqI6jma2ZRwGnAd4TAPj5qvlDJ+zgYQ99KGQvG96We7pwbAFwE3GZmI7wuyEPBus+fBzoD/YEM4G/+8aCZr5k1BOYCf3LOHTzeqqWMVbs5lzLfSt/HwRj6aUBEiccdgHSPaqkwzrl0/9dMYD7Ff/rtNLNwAP/XTO8qrBDHml9Q7nPn3E7nXKFzrgh4kf/8eR8U8zWz2hQH4FvOuXn+4aDdx6XN14t9HIyh/z3Q1cyizawOMB5Y6HFNAWVmDcys0c/3gQuBRIrnOcG/2gRggTcVVphjzW8hMN7M6ppZNNAVWOlBfQH1c/j5jaV4H0MQzNfMDHgZWOOce6LEoqDcx8earyf72Our2hV0pfxiiq+ObwCmeV1PBcyvE8VX9lcDST/PEWgBfA6s939t7nWt5ZjjOxT/uZtP8VHPxOPND5jm398pwEVe1x+g+f4fkADE+0MgPIjmewbFpyvigZ/8t4uDdR8fZ76Vvo/VhkFEJIQE4+kdERE5BoW+iEgIUeiLiIQQhb6ISAhR6IuIhBCFvohICFHoi4iEkP8HdEwxvwAh8XoAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "y = 4 x + 375\n", + "a = 4\n", + "b = 375\n", + "test y_max: (2935 ~= 3000) ?\n", + "test y_min: (375 ~= 375) ?\n" + ] + } + ], + "source": [ + "# 3000 -> 16s\n", + "# 0 -> 2s\n", + "# x from 0 to 255\n", + "\n", + "pwm_min = 0\n", + "pwm_max = PWM_D_MAX\n", + "\n", + "t_max = int(16)\n", + "t_min = int(2)\n", + "cycles_max = int(3000)\n", + "cycles_min = int(t_min * cycles_max / t_max)\n", + "\n", + "y_min = cycles_min\n", + "y_max = cycles_max\n", + "x_min = pwm_min\n", + "x_max = pwm_max\n", + "\n", + "# cenario 1: quando x == x_min -> y = y_min\n", + "# y_min = a * x_min + b\n", + "# cenĂ¡rio 2: quando x == x_max -> y = y_max\n", + "# y_max = a * x_max + b\n", + "b = int(y_min)\n", + "a = int((y_max - y_min) / x_max)\n", + "\n", + "y = a*x +b\n", + "\n", + "plt.plot(x, y); plt.show()\n", + "\n", + "print(f\"y = {a} x + {b}\")\n", + "print(f\"a = {a}\")\n", + "print(f\"b = {b}\")\n", + "print(f\"test y_max: ({a*x_max + b} ~= {y_max}) ?\")\n", + "print(f\"test y_min: ({a*x_min + b} ~= {y_min}) ?\")" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "e7370f93d1d0cde622a1f8e1c04877d8463912d04d973331ad4851f04de6915a" + }, + "kernelspec": { + "display_name": "Python 3.10.2 64-bit", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From fce167d83f828cc9287655fcdd566309b5484e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ant=C3=B4nio=20Cardoso?= Date: Thu, 10 Mar 2022 00:32:18 -0300 Subject: [PATCH 11/11] fixup! Make the motor waiting time proportinal to last duty cycle value. --- firmware/src/machine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/src/machine.c b/firmware/src/machine.c index 556bca6..c894e93 100644 --- a/firmware/src/machine.c +++ b/firmware/src/machine.c @@ -165,7 +165,7 @@ inline void set_state_initializing(void) inline void set_state_contactor(void) { usart_send_string("SET STATE CONTACTOR\n"); - pwm_last_value = OCR1A; + pwm_last_value = control.D; set_pwm_off(); state_contactor = STATE_CONTACTOR_WAITING_MOTOR; state_machine = STATE_CONTACTOR;