From 651e3b02d13ad97d6b44a16766aeb56a9a72e0db Mon Sep 17 00:00:00 2001 From: Anton Mukhin Date: Thu, 18 Jan 2024 15:26:13 +0300 Subject: [PATCH] Smooth LED lights level change --- Core/Inc/board_logic.h | 12 ++++---- Core/Src/board_logic.c | 66 +++++++++++++++++++++++++++-------------- Core/Src/main.c | 8 +---- Core/Src/modbus_logic.c | 11 ++----- 4 files changed, 54 insertions(+), 43 deletions(-) diff --git a/Core/Inc/board_logic.h b/Core/Inc/board_logic.h index 1bff2a2..8f6e2d4 100644 --- a/Core/Inc/board_logic.h +++ b/Core/Inc/board_logic.h @@ -9,18 +9,20 @@ #define MODBUS_FIRMWARE_VERSION ( /*major*/ 11 + /*minor*/ 0 * 0x100) #define MODBUS_BOARD_TYPE (8) //Relay Module board ID -#define REL_MAIN_BIT (1u<<0) -#define REL_AUX_BIT (1u<<1) +#define REL_MAIN_BIT (1u<<0) +#define REL_AUX_BIT (1u<<1) -#define MOTOR_MIN 0 -#define MOTOR_MAX 255 +#define PWM_DUTY_MIN 0 +#define PWM_DUTY_MAX 255 +#define PWM_LIGHTS_STEP 20 // Time step in ms between LED light PWM changes +#define LIGHTS_TIME 1000 // Time in ms to spend for smooth lights level change void estop_reset(void); void board_init(void); +uint16_t clamp_duty(uint16_t duty); void set_pwm(uint8_t unit, uint16_t duty); void loop_iterate(); -void timer1_ovf_isr(void); void update_service_indication(void); #endif diff --git a/Core/Src/board_logic.c b/Core/Src/board_logic.c index 839b5f9..3219457 100644 --- a/Core/Src/board_logic.c +++ b/Core/Src/board_logic.c @@ -17,7 +17,6 @@ extern TIM_HandleTypeDef htim3; extern TIM_HandleTypeDef htim14; static const char board_description[BOARD_DESC_LEN] = "RS485_Relay V2R1"; extern uint16_t tranfer_errors_count; -extern uint16_t last_rx_time; #define REL_MAIN_ON HAL_GPIO_WritePin(RL_MAIN_GPIO_Port, RL_MAIN_Pin, GPIO_PIN_SET) #define REL_MAIN_OFF HAL_GPIO_WritePin(RL_MAIN_GPIO_Port, RL_MAIN_Pin, GPIO_PIN_RESET) @@ -36,6 +35,8 @@ uint16_t status = 0; uint16_t motor1_pwm = 0; uint16_t motor2_pwm = 0; uint16_t lights_pwm = 0; +uint16_t lights_pwm_target = 0; +int16_t lights_pwm_delta = 0; uint16_t led_time_act = 0; void estop_reset(void) { @@ -52,6 +53,13 @@ void board_init(void) { HAL_TIM_Base_Start_IT(&htim1); } + +uint16_t clamp_duty(uint16_t duty) { + if (duty > PWM_DUTY_MAX) return PWM_DUTY_MAX; + if (duty < PWM_DUTY_MIN) return PWM_DUTY_MIN; + return duty; +} + void set_pwm(uint8_t unit, uint16_t duty) { uint32_t channel; TIM_HandleTypeDef* tim; @@ -73,8 +81,7 @@ void set_pwm(uint8_t unit, uint16_t duty) { return; } - if (duty > MOTOR_MAX) duty = MOTOR_MAX; - if (duty < MOTOR_MIN) duty = MOTOR_MIN; + duty = clamp_duty(duty); if (duty == 0) HAL_TIM_PWM_Stop(tim, channel); else { @@ -114,22 +121,6 @@ void loop_iterate() HAL_Delay(1); } -// Timer1 overflow interrupt service routine -void timer1_ovf_isr(void) //1 ms -{ - static uint32_t count_1sec=0; - if(last_rx_time<0xFFFF)last_rx_time++; - - update_service_indication(); - - if(++count_1sec==1000) - { - count_1sec = 0; - //led_time_g += 10; - } - -} - void update_service_indication(void) { if (led_time_act) { @@ -208,8 +199,14 @@ uint8_t write_register(uint16_t address, uint16_t value) set_pwm(2, motor2_pwm); break; case 0x2004: - lights_pwm = value; - set_pwm(3, lights_pwm); + lights_pwm_target = clamp_duty(value); + if (lights_pwm_target != lights_pwm) { + lights_pwm_delta = (lights_pwm_target - lights_pwm) / LIGHTS_TIME / PWM_LIGHTS_STEP; + if (lights_pwm_delta == 0) { + if (lights_pwm_target - lights_pwm > 0) lights_pwm_delta = 1; + else lights_pwm_delta = -1; + } + } break; case 0x2020: if (value == 1) { @@ -230,10 +227,35 @@ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) status = status | 0b010; } if(GPIO_Pin == LIGHTS_SW_Pin) { - status |= 0b100; // Set "lights switch pressed" status bit + // Set "lights switch pressed" status bit + status |= 0b100; } if(GPIO_Pin == WATER_Pin) { // Set or reset "water" status bit status |= HAL_GPIO_ReadPin(WATER_GPIO_Port, WATER_Pin); } } + +// Timers overflow interrupt +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { + // check if the interrupt comes from TIM1 + if(htim->Instance == TIM1) { + static uint32_t count_ms = 0; + + update_service_indication(); + + // Check if we should change lights pwm for smooth transition + if (lights_pwm != lights_pwm_target) { + // Change pwm only every 20ms (PWM_LIGHTS_STEP) + if(++count_ms == PWM_LIGHTS_STEP) { + count_ms = 0; + + lights_pwm += lights_pwm_delta; + // Set lights pwm to target if the difference is less than the delta + if (abs(lights_pwm_target - lights_pwm) < abs(lights_pwm_delta)) + lights_pwm = lights_pwm_target; + set_pwm(3, lights_pwm); + } + } + } +} diff --git a/Core/Src/main.c b/Core/Src/main.c index c1e7f22..eeee9cc 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -428,13 +428,7 @@ static void MX_GPIO_Init(void) } /* USER CODE BEGIN 4 */ -void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) -{ - if(htim->Instance == TIM1) //check if the interrupt comes from TIM1 - { - timer1_ovf_isr(); - } -} + /* USER CODE END 4 */ /** diff --git a/Core/Src/modbus_logic.c b/Core/Src/modbus_logic.c index ef52a60..2f273f3 100644 --- a/Core/Src/modbus_logic.c +++ b/Core/Src/modbus_logic.c @@ -15,7 +15,7 @@ uint8_t recv_buffer[BUFFERS_SIZE]; uint8_t send_buffer[BUFFERS_SIZE]; uint16_t bytes_to_send = 0; -uint16_t last_rx_time = 0xFFFF; +//uint16_t last_rx_time = 0xFFFF; enum recv_state cmd_receiving = RECV_IDLE; enum send_state cmd_sending = SEND_IDLE; uint16_t tranfer_errors_count; @@ -79,14 +79,7 @@ void modbus_loop_iterate() { if (cmd_receiving == RECV_ERROR) { - // poor man's way to synchronize packets - //if(last_rx_time>=BUS_IDLE_TIME) - //{ - cmd_receiving = RECV_IDLE; - //TXEN_485 = 1; - //delay_us(10); - //TXEN_485 = 0; - //} + cmd_receiving = RECV_IDLE; } if (cmd_receiving == RECV_IDLE) {