Smooth LED lights level change

This commit is contained in:
Anton Mukhin
2024-01-18 15:26:13 +03:00
parent 108f165ca2
commit 651e3b02d1
4 changed files with 54 additions and 43 deletions

View File

@@ -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

View File

@@ -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);
}
}
}
}

View File

@@ -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 */
/**

View File

@@ -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)
{