1. Project function outline
Because the for loop was originally used to traverse and then execute the code in sequence, but due to the existence of the watchdog, dead delays such as delay_ms cannot be used. So now I plan to use the timer callback function to control the state of the state machine.
2. State machine
effect
When the system needs to perform a certain task, different operations can be selected based on the status of the state machine, for example:
- Control system status : For example, the controller chooses to perform different operations based on the status of the state machine, thereby controlling the status of the entire system, such as turning on and off lights, controlling motors, etc.
- System scheduling : For example, the operating system chooses to execute different tasks according to the status of the state machine, thereby realizing system scheduling.
- System event processing : For example, the network communication system selects different data processing methods according to the status of the state machine, such as processing received data, sending data, etc.
- System error handling : For example, when an error occurs in the system, different error handling methods can be selected according to the status of the state machine, such as restarting the system, outputting error information , etc.
In short, the state machine can help us decompose the complexity of the system into multiple simple states, and choose to perform different operations according to different states, thereby better realizing the design and development of the system.
Main process
-
Define states and events
First, you need to define all possible states of the system, usually represented by enumeration types. At the same time, you need to define all events that may occur, such as input data, timer arrival, etc.
-
Initialize state machine
When the program starts, the state machine needs to be initialized to a specific state.
-
Define state transitions and actions
Use statements such as switch-case if-else function pointers to define state transitions and actions. When an event occurs, the current state is determined, corresponding actions are performed based on different events, and the state is converted to the next state.
-
event handling
When an event occurs, the event is passed to the state machine as a parameter and the state transition and action functions are called.
-
Loop execution
A state machine usually runs as a separate task and waits for events to occur in an infinite loop.
3. Thoughts related to the implementation process
To be honest, I tried the idea of suddenly using flags.
// 定义全局指针变量
u8 *global_bt_receive_buffer_gradually;
u32 global_length_gradually;
volatile u8 time_flag_gradually = 0;
void handleColor_arrayChange_gradually(u8 *bt_receive_buffer, u32 length)
{
printf("通过数组控制灯颜色状态\n");
static int j = 0;
static int i = 5;
u8 STEPS = 30;
static u8 i_balance = 3;
// 获取初始亮度i-
u8 initial_red_value = bt_receive_buffer[i];
u8 initial_green_value = bt_receive_buffer[i+1];
u8 initial_blue_value = bt_receive_buffer[i+2];
for (; (i < (length - 5)) && (time_flag_gradually == 0);)
{
u8 target_red_value = bt_receive_buffer[i + 3];
u8 target_green_value = bt_receive_buffer[i + 4];
u8 target_blue_value = bt_receive_buffer[i + 5];
printf("i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------%d\n", i);
printf("target_red_value------------------target_red_value---------------target_red_value%d\n", target_red_value);
printf("target_red_value------------------target_red_value---------------target_red_value%d\n", target_green_value);
printf("target_red_value------------------target_red_value---------------target_red_value%d\n", target_blue_value);
// 计算每个颜色通道的增量
int red_increment = (target_red_value - initial_red_value) / STEPS;
int green_increment = (target_green_value - initial_green_value) / STEPS;
int blue_increment = (target_blue_value - initial_blue_value) / STEPS;
// 逐步更新颜色值,使其渐变到目标值
for (; (j < STEPS) && (time_flag_gradually == 0); j++)
{
u8 current_red_value = initial_red_value + (red_increment * j);
u8 current_green_value = initial_green_value + (green_increment * j);
u8 current_blue_value = initial_blue_value + (blue_increment * j);
handleColorChange(current_red_value, current_green_value, current_blue_value);
// delay_2ms(24); // 延时一段时间,控制灯的变化速度
printf("initial_red_value----initial_red_value----initial_red_value----initial_red_value----initial_red_value----%d\n", initial_red_value);
printf("initial_green_value-----initial_green_value-------initial_green_value-------initial_green_value-------%d\n", initial_green_value);
printf("initial_blue_valueinitial_blue_valueinitial_blue_valueinitial_blue_valueinitial_blue_valueinitial_b%d\n", initial_blue_value);
printf("红色值每一次增量------红色值每一次增量--------红色值每一次增量--------红色值每一次增量-------红色值每一次增量%d\n", red_increment);
printf("绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------%d\n", green_increment);
printf("蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------%d\n", blue_increment);
time_flag_gradually = 1;
printf("jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj===================%d\n", j);
}
if (j >= STEPS)
{
j = 0;
i = i + 3;
}
printf("第一组 RGB 值已经渐变到第二组一样\n");
// 更新初始亮度为目标亮度,以便下一组渐变
initial_red_value = target_red_value;
initial_green_value = target_green_value;
initial_blue_value = target_blue_value;
}
if (i >= (length - 5))
{
i = 5;
}
global_bt_receive_buffer_gradually = bt_receive_buffer;
global_length_gradually = length;
}
u32 timeout_msec_gradually = 5; // 设置定时时间为10毫秒
void timeout_callback_gradually(void *priv)
{
// 每10ms
static u8 i = 5;
// printf("回调函数渐变\n");
printf("回调函数渐变%d\n", time_flag_gradually);
// printf("time_flag_gradually != 0time_flag_gradually != 0time_flag_gradually != 0time_flag_gradually != 0time_flag_gradually != 0\n");
i = i + 5;
if (i == 50)
{
time_flag_gradually = 0;
i = 0;
}
handleColor_arrayChange_gradually(global_bt_receive_buffer_gradually, global_length_gradually);
}
In fact, the array shift in the first for loop is transferred to the small for loop. Only when the color gradient has been fully realized in the small for loop, i++ is allowed to implement the shift. But there is a problem. After the color gradient is completed, it will suddenly change from the last color to the first color. This should be due to the reassignment during initialization of the setting code, resulting in a missing section of color change.
- Extract the desired color data as an array. Each time the color gradient is completed, the last three digits of the array are assigned to the first three digits, and so on, and the function is re-executed.
- The second type is hard-coded, and each time an extra section of code is executed from the last color gradient to the first color.
I'm wondering if there is a more concise method, or if a circular array would display this kind of loop better.
Post a picture of the current code
u16 timer_id_color_change_suddenly = 0;
u16 timer_id_color_change_gradually = 0;
void *private_data = NULL; // 设置私有参数为NULL
u32 timeout_msec = 10; // 设置定时时间为10毫秒
u8 priority = 1; // 设置优先级为1
void timeout_callback(void *priv)
{
static u16 i = 0;
printf("回调函数跳变\n");
i = i + 10;
if (i == 1000)
{
printf("ifififiifiifififiififififi\n");
time_flag_suddenly = 1;
i = 0;
}
handleColor_arrayChange_suddenly(global_bt_receive_buffer, global_length, global_color_mode_record, global_color1);
}
// 定义全局指针变量
u8 *global_bt_receive_buffer_gradually;
u32 global_length_gradually;
volatile u8 time_flag_gradually = 0;
void handleColor_arrayChange_gradually(u8 *bt_receive_buffer, u32 length)
{
printf("通过数组控制灯颜色状态\n");
static int j = 0;
static int i = 5;
u8 STEPS = 30;
static u8 i_balance = 3;
static flag = 1;
// 获取初始亮度i-
u8 initial_red_value = bt_receive_buffer[i];
u8 initial_green_value = bt_receive_buffer[i + 1];
u8 initial_blue_value = bt_receive_buffer[i + 2];
for (; (i < (length - 5)) && (time_flag_gradually == 0);)
{
u8 target_red_value = bt_receive_buffer[i + 3];
u8 target_green_value = bt_receive_buffer[i + 4];
u8 target_blue_value = bt_receive_buffer[i + 5];
printf("i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------%d\n", i);
printf("target_red_value------------------target_red_value---------------target_red_value%d\n", target_red_value);
printf("target_red_value------------------target_red_value---------------target_red_value%d\n", target_green_value);
printf("target_red_value------------------target_red_value---------------target_red_value%d\n", target_blue_value);
// 计算每个颜色通道的增量
int red_increment = (target_red_value - initial_red_value) / STEPS;
int green_increment = (target_green_value - initial_green_value) / STEPS;
int blue_increment = (target_blue_value - initial_blue_value) / STEPS;
// 逐步更新颜色值,使其渐变到目标值
for (; (j < STEPS) && (time_flag_gradually == 0); j++)
{
u8 current_red_value = initial_red_value + (red_increment * j);
u8 current_green_value = initial_green_value + (green_increment * j);
u8 current_blue_value = initial_blue_value + (blue_increment * j);
handleColorChange(current_red_value, current_green_value, current_blue_value);
// delay_2ms(24); // 延时一段时间,控制灯的变化速度
printf("initial_red_value----initial_red_value----initial_red_value----initial_red_value----initial_red_value----%d\n", initial_red_value);
printf("initial_green_value-----initial_green_value-------initial_green_value-------initial_green_value-------%d\n", initial_green_value);
printf("initial_blue_valueinitial_blue_valueinitial_blue_valueinitial_blue_valueinitial_blue_valueinitial_b%d\n", initial_blue_value);
printf("红色值每一次增量------红色值每一次增量--------红色值每一次增量--------红色值每一次增量-------红色值每一次增量%d\n", red_increment);
printf("绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------%d\n", green_increment);
printf("蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------%d\n", blue_increment);
time_flag_gradually = 1;
printf("jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj===================%d\n", j);
}
if (j >= STEPS)
{
j = 0;
i = i + 3;
}
printf("第一组 RGB 值已经渐变到第二组一样\n");
// 更新初始亮度为目标亮度,以便下一组渐变
initial_red_value = target_red_value;
initial_green_value = target_green_value;
initial_blue_value = target_blue_value;
}
if (i >= (length - 5))
{
i=5;
}
global_bt_receive_buffer_gradually = bt_receive_buffer;
global_length_gradually = length;
}