增加模式切换柔和过渡
This commit is contained in:
@@ -21,6 +21,7 @@ uint8_t direction = 1; //
|
||||
|
||||
uint8_t choose_mode_falsg=0; //模式值
|
||||
uint8_t choose_mode_bh=0; //模式变化
|
||||
static uint8_t mode_entry_initialized;
|
||||
|
||||
uint16_t Color_table_static[3][2]={
|
||||
{100,0}, // warm light
|
||||
@@ -113,31 +114,32 @@ void set_mode(){
|
||||
break;
|
||||
case 6:
|
||||
//暖光跳变
|
||||
W_PWM=Color_table[0][0];
|
||||
C_PWM=Color_table[0][1];
|
||||
W_PWM=0;
|
||||
C_PWM=0;
|
||||
driveMode=1;//切换为暖光的底层输出
|
||||
direction=1;//呼吸方向恢复默认值
|
||||
direction=0;//呼吸方向恢复默认值
|
||||
Mode=mode2;
|
||||
break;
|
||||
case 7:
|
||||
//中性光跳变
|
||||
W_PWM=Color_table[1][0];
|
||||
C_PWM=Color_table[1][1];
|
||||
W_PWM=0;
|
||||
C_PWM=0;
|
||||
driveMode=0;//切换为中性光的底层输出
|
||||
direction=0;
|
||||
Mode=mode2;
|
||||
break;
|
||||
case 8:
|
||||
//冷光跳变
|
||||
W_PWM=Color_table[2][0];
|
||||
C_PWM=Color_table[2][1];
|
||||
W_PWM=0;
|
||||
C_PWM=0;
|
||||
driveMode=2;//切换为中性光的底层输出
|
||||
direction=1;//呼吸方向恢复默认值
|
||||
direction=0;//呼吸方向恢复默认值
|
||||
Mode=mode2;
|
||||
break;
|
||||
case 9:
|
||||
//暖光中性光冷交替跳变,先从暖光跳变
|
||||
W_PWM=Color_table[0][0];
|
||||
C_PWM=Color_table[0][1];
|
||||
W_PWM=0;
|
||||
C_PWM=0;
|
||||
driveMode=1;//切换为暖光的底层输出
|
||||
direction=1;//呼吸方向恢复默认值
|
||||
Mode=mode2;
|
||||
@@ -147,6 +149,15 @@ void set_mode(){
|
||||
Mode=mode0;
|
||||
break;
|
||||
}
|
||||
if(mode_entry_initialized)
|
||||
{
|
||||
Light_Transition_BeginModeChange();
|
||||
startTimer(&timer1,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
mode_entry_initialized=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Mode0(){ //常量
|
||||
@@ -353,6 +364,7 @@ pfunc modefunctin[] = { //ģʽ
|
||||
Mode3,
|
||||
};
|
||||
void choice_mode(){
|
||||
if(Light_Transition_ModeActive) return;
|
||||
if (!timer1.active && timer1.count == 0){
|
||||
if(Mode==mode0){
|
||||
startTimer(&timer1,1);
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
#include "light_transition.h"
|
||||
|
||||
volatile uint8_t Light_Transition_FadeActive;
|
||||
volatile uint8_t Light_Transition_ModeActive;
|
||||
volatile uint32_t Light_Transition_W_Output_Q12;
|
||||
volatile uint32_t Light_Transition_C_Output_Q12;
|
||||
|
||||
#define BRIGHTNESS_SMOOTH_SHIFT 4U
|
||||
#define OUTPUT_SMOOTH_SHIFT 4U
|
||||
#define MODE_TRANSITION_TICKS 40U
|
||||
#define LIGHT_OUTPUT_SCALE 1000U
|
||||
#define BREATH_MIN_OUTPUT (LIGHT_OUTPUT_SCALE / 100U)
|
||||
#define DUAL_MIN_STABLE_CHANNEL_OUTPUT 102U
|
||||
@@ -81,6 +83,9 @@ static uint16_t power_fade_progress_q12;
|
||||
static uint16_t power_fade_remainder;
|
||||
static uint8_t power_fade_direction;
|
||||
static uint8_t transition_sync_pending;
|
||||
static uint16_t mode_transition_start_w;
|
||||
static uint16_t mode_transition_start_c;
|
||||
static uint8_t mode_transition_tick;
|
||||
|
||||
static uint16_t brightness_scale_for_level(uint8_t level)
|
||||
{
|
||||
@@ -142,6 +147,35 @@ static uint16_t approach_target(uint16_t current, uint16_t target)
|
||||
return current - step;
|
||||
}
|
||||
|
||||
static uint16_t interpolate_mode_output(uint16_t start, uint16_t target,
|
||||
uint8_t tick)
|
||||
{
|
||||
uint32_t delta;
|
||||
|
||||
if(tick >= MODE_TRANSITION_TICKS) return target;
|
||||
if(target >= start)
|
||||
{
|
||||
delta = (uint32_t)(target - start) * tick;
|
||||
return (uint16_t)(start +
|
||||
((delta + (MODE_TRANSITION_TICKS / 2U)) /
|
||||
MODE_TRANSITION_TICKS));
|
||||
}
|
||||
|
||||
delta = (uint32_t)(start - target) * tick;
|
||||
return (uint16_t)(start -
|
||||
((delta + (MODE_TRANSITION_TICKS / 2U)) /
|
||||
MODE_TRANSITION_TICKS));
|
||||
}
|
||||
|
||||
static uint16_t effect_gamma_output(uint16_t level)
|
||||
{
|
||||
if(level == 0U) return 0U;
|
||||
if(level > 100U) level = 100U;
|
||||
return (uint16_t)(
|
||||
((uint32_t)brightness_gamma_q12[level - 1U] *
|
||||
LIGHT_OUTPUT_SCALE + 2048U) >> 12);
|
||||
}
|
||||
|
||||
static uint16_t power_fade_scale(uint16_t progress_q12)
|
||||
{
|
||||
uint32_t position;
|
||||
@@ -220,6 +254,14 @@ void Light_Transition_SyncBrightness(uint8_t level)
|
||||
transition_sync_pending = 1U;
|
||||
}
|
||||
|
||||
void Light_Transition_BeginModeChange(void)
|
||||
{
|
||||
mode_transition_start_w = W_PWM_duty;
|
||||
mode_transition_start_c = C_PWM_duty;
|
||||
mode_transition_tick = 0U;
|
||||
Light_Transition_ModeActive = 1U;
|
||||
}
|
||||
|
||||
void Light_Transition_Task(void)
|
||||
{
|
||||
uint8_t powered_on = deviceStatus != POWEROFF;
|
||||
@@ -236,6 +278,9 @@ void Light_Transition_Task(void)
|
||||
uint32_t scaled_c_q12;
|
||||
uint8_t power_transitioning;
|
||||
|
||||
if(!powered_on)
|
||||
Light_Transition_ModeActive = 0U;
|
||||
|
||||
/*
|
||||
* Keep APP brightness tracking while off. Power fading is a separate
|
||||
* envelope, so on/off duration does not change with the saved brightness.
|
||||
@@ -251,12 +296,24 @@ void Light_Transition_Task(void)
|
||||
powered_on ? (power_fade_progress_q12 < POWER_FADE_Q12_MAX)
|
||||
: (power_fade_progress_q12 != 0U);
|
||||
|
||||
if(Mode == mode1)
|
||||
{
|
||||
target_w = (uint16_t)(
|
||||
((uint32_t)effect_gamma_output(W_PWM) *
|
||||
brightness_scale + 2048U) >> 12);
|
||||
target_c = (uint16_t)(
|
||||
((uint32_t)effect_gamma_output(C_PWM) *
|
||||
brightness_scale + 2048U) >> 12);
|
||||
}
|
||||
else
|
||||
{
|
||||
target_w =
|
||||
(uint16_t)(((uint32_t)W_PWM * brightness_scale *
|
||||
(LIGHT_OUTPUT_SCALE / 100U) + 2048U) >> 12);
|
||||
target_c =
|
||||
(uint16_t)(((uint32_t)C_PWM * brightness_scale *
|
||||
(LIGHT_OUTPUT_SCALE / 100U) + 2048U) >> 12);
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep the weaker mixed-light direction at the measured stable threshold.
|
||||
@@ -307,7 +364,19 @@ void Light_Transition_Task(void)
|
||||
target_c = BREATH_MIN_OUTPUT;
|
||||
}
|
||||
|
||||
if((Mode == mode2 && powered_on) || power_transitioning ||
|
||||
if(Light_Transition_ModeActive && powered_on && !power_transitioning)
|
||||
{
|
||||
mode_transition_tick++;
|
||||
W_PWM_duty =
|
||||
interpolate_mode_output(mode_transition_start_w, target_w,
|
||||
mode_transition_tick);
|
||||
C_PWM_duty =
|
||||
interpolate_mode_output(mode_transition_start_c, target_c,
|
||||
mode_transition_tick);
|
||||
if(mode_transition_tick >= MODE_TRANSITION_TICKS)
|
||||
Light_Transition_ModeActive = 0U;
|
||||
}
|
||||
else if((Mode == mode2 && powered_on) || power_transitioning ||
|
||||
transition_sync_pending)
|
||||
{
|
||||
W_PWM_duty = target_w;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
extern volatile uint8_t Light_Transition_FadeActive;
|
||||
extern volatile uint8_t Light_Transition_ModeActive;
|
||||
extern volatile uint32_t Light_Transition_W_Output_Q12;
|
||||
extern volatile uint32_t Light_Transition_C_Output_Q12;
|
||||
|
||||
@@ -12,5 +13,6 @@ extern volatile uint32_t Light_Transition_C_Output_Q12;
|
||||
|
||||
void Light_Transition_Task(void);
|
||||
void Light_Transition_SyncBrightness(uint8_t level);
|
||||
void Light_Transition_BeginModeChange(void);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user