Files
lib_rgb/lib_rgb/api/rgb_effect.h
Vergil Wong afeac23054 重构了部分API,移除了例程中的bin
- 将配置部分移入头文件
- 修正部分类型问题
- 修正部分API
2023-11-23 21:15:12 +08:00

209 lines
8.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef RGB_EFFECT_H
#define RGB_EFFECT_H
#include <stdint.h>
#include <stddef.h>
#include "rgb_driver.h"
#include "volume_level.h"
#include "misc_utils.h"
// RGB灯的数量
#ifndef NUM_RGBS
#define NUM_RGBS (12)
#endif
// RGB灯组的数量不应超过NUM_RGBS
#ifndef NUM_RGB_GROUPS
#define NUM_RGB_GROUPS (2)
#endif
// 控制RGB亮度的最大值不超过255
#ifndef RGB_MAX
#define RGB_MAX (20)
#endif
// TODO:优化为编译时检查?
// 开关饱和检查,该检查会引入性能损失,在需要高刷新率时关闭它
#ifndef HSV_VALID_CHECK
#define HSV_VALID_CHECK (1)
#endif
// 控制HUE的最大值不超过360°
#ifndef HSV_HUE_MAX
#define HSV_HUE_MAX (360)
#endif
// 控制饱和度的最大值不超过100
#ifndef HSV_SATURATION_MAX
#define HSV_SATURATION_MAX (100)
#endif
// 控制VALUE不超过100
#ifndef HSV_VALUE_MAX
#define HSV_VALUE_MAX (100)
#endif
// 微秒定义每次颜色更新的延迟在cycleRGB下
// (1000/RGB_MAX)代表每个B/R/G值的爬升/缓降时间约为1000ms
#ifndef DELAY_TIME_RGB
#define DELAY_TIME_RGB (1000 / RGB_MAX)
#endif
/**
* 定义渐变方向的枚举类型。
*
* 该枚举用于指定颜色渐变过程中亮度的变化方向用于控制RGB颜色空间的遍历
* 实现颜色的平滑过渡,如呼吸灯效果。
*/
typedef enum
{
INCREMENTING, ///< 亮度递增:用于指示颜色亮度逐渐增加的渐变方向。
DECREMENTING ///< 亮度递减:用于指示颜色亮度逐渐减少的渐变方向。
} GradientDirection;
/** 遍历RGB颜色空间以实现呼吸灯效果。
*
* 此函数通过逐步调整RGB值来模拟呼吸灯效果根据提供的方向增加或减少颜色亮度。
* 它更新颜色值并将新颜色值通过RGB条输出。
*
* \param buf 指向存储RGB值的缓冲区的指针。
* \param color 当前颜色值。
* \param direction 指向当前渐变方向的指针,可以是递增或递减。
* \return 更新后的颜色值。
*/
uint32_t cycleRGB(uint32_t color, GradientDirection *direction);
/**
* 通过HSV颜色空间循环改变色调Hue以实现颜色渐变效果。
*
* 此函数负责在HSV颜色模型中改变色调值从而在不改变饱和度Saturation和亮度Value的情况下
* 遍历不同的颜色。色调值会在0到359之间循环每次调用函数色调值增加1当达到359后重置为0。
* 函数输出当前色调值并将新的RGB值存储在提供的缓冲区中。
*
* \param buf 指向存储RGB值的缓冲区的指针。此缓冲区将被更新为对应的RGB值。
* \param hue 指向当前色调值的指针。色调值在0到359之间变化。
*
* \return 根据当前色调值、饱和度和亮度计算出的RGB颜色值。
*/
uint32_t cycleHSV(uint32_t *hue);
/**
* 将HSV颜色空间转换为RGB颜色空间。
*
* 此函数接受HSV色相、饱和度、亮度颜色空间的值并将其转换为RGB红、绿、蓝颜色空间的值。
* 转换过程中可能会执行有效性检查取决于HSV_VALID_CHECK预处理器变量
*
* 实现步骤:
* 1. **规范化色调值:**
* $ H' = \frac{H}{360} $
*
* 2. **计算色度(Chroma)**
* $ C = S \times V $
*
* 3. **计算X值**
* $ X = C \times (1 - |(H' \times 6) \mod 2 - 1|) $
*
* 4. **计算中间RGB值**
* 根据H'的值,我们有:
* - 如果 $( 0 \leq H' < 1 )$$ R1 = C, G1 = X, B1 = 0 $
* - 如果 $( 1 \leq H' < 2 )$$ R1 = X, G1 = C, B1 = 0 $
* - 如果 $( 2 \leq H' < 3 )$$ R1 = 0, G1 = C, B1 = X $
* - 如果 $( 3 \leq H' < 4 )$$ R1 = 0, G1 = X, B1 = C $
* - 如果 $( 4 \leq H' < 5 )$$ R1 = X, G1 = 0, B1 = C $
* - 如果 $( 5 \leq H' < 6 )$$ R1 = C, G1 = 0, B1 = X $
*
* 5. **计算最终RGB值**
* $ R' = (R1 + (V - C)) \times 255 $
* $ G' = (G1 + (V - C)) \times 255 $
* $ B' = (B1 + (V - C)) \times 255 $
*
* 6. **限制最终值范围:**
* $ R'' = \min(\max(R', 0), 255) $
* $ G'' = \min(\max(G', 0), 255) $
* $ B'' = \min(\max(B', 0), 255) $
*
* \param hue 指向色相值的指针色相值的范围通常是0-360。
* \param sat 指向饱和度值的指针饱和度值的范围通常是0-100。
* \param value 指向亮度值的指针亮度值的范围通常是0-100。
*
* \return 转换后的RGB值其中G占最高8位R占中间8位B占最低8位。
*/
uint32_t HSV_to_RGB(uint32_t *hue, uint32_t *sat, uint32_t *value);
/**
* 将单一颜色填充到整个RGB条中并控制显示颜色的时间长度。
*
* 此函数遍历RGB条的每个颜色单元将它们统一设置为提供的颜色值。设置完成后
* 通过调用输出函数将这些颜色输出到RGB条上。之后函数会调用延迟函数以保持
* 当前颜色一段时间,从而控制颜色显示的持续时间,这可以用于创建闪烁效果。
*
* \param buf 指向存储RGB值的缓冲区的指针每个元素代表RGB条中一个颜色单元的颜色值。
* \param color 要填充的统一颜色值。
*/
void fill_gradient(uint32_t *buf, size_t num_filled_rgb, uint32_t color);
/**
* 在tile[1]上启动一个永久循环该循环会持续更新RGB灯条的颜色。
* 它初始化一个颜色值然后在一个无限循环中不断地调用fill_gradient和cycleRGB函数
* 以实现RGB灯条颜色的渐变效果。颜色的变化方向会根据GradientDirection变量进行调整。
*/
void cycleRGB_driver();
/**
* 驱动HSV颜色空间中的颜色循环以实现连续的颜色渐变效果。
*
* 此函数初始化颜色值并进入一个无限循环不断地计算新的颜色值并更新LED阵列。
* 使用并发执行关键字 'par' 来实现循环内部的并行处理。这个函数假定运行环境支持并行关键字 'par'。
*
* 在此循环中,它首先使用当前颜色填充一个预定义大小的缓冲区,然后调用 `cycleHSV` 函数
* 来更新当前色相值并获取新的颜色。最后它打印出当前的GRB颜色值。
*
* 注意:此函数设计为在嵌入式系统或具有并行处理能力的系统上运行。
* 它包含一个无限循环,应确保有适当的机制来安全地退出或中断执行。
*/
void cycleHSV_driver();
/**
* 将多种颜色分组填充到RGB条中并控制显示颜色的时间长度。
*
* 此函数将RGB条分为若干组每组填充指定的颜色。每组可以填充不同数量的RGB单元
* 数量由num_filled_rgb数组指定。填充完所有组指定的颜色后剩余的RGB单元将被熄灭。
* 如果组号为奇数,则该组的颜色顺序将被翻转。所有颜色设置完成后,通过调用输出函数
* 将这些颜色输出到RGB条上。最后函数调用延迟函数以保持当前颜色一段时间。
*
* \param buf 指向存储RGB值的缓冲区的指针每个元素代表RGB条中一个颜色单元的颜色值。
* \param colors 指向存储每组颜色值的数组的指针,每个元素代表一个组的颜色值。
* \param num_filled_rgb 指向存储每组已填充RGB单元数量的数组的指针每个元素代表一个组已填充的RGB单元数量。
*/
void fill_gradient_with_groups(uint32_t *buf, uint32_t *colors, size_t *num_filled_rgb);
/**
* 测试音量响应&HSV色彩循环
*
* 此函数不断地循环通过HSV色彩空间并根据音量水平来更新RGB条的颜色。
* 每个颜色组都会根据音量水平的随机值来更新其亮度。当前色相值从红色开始,
* 并在每次循环中更新以通过HSV色彩空间进行循环。每次循环后将当前颜色
* 应用到RGB条的相应组中。此函数旨在并发执行以模拟实时音乐响应的灯光效果。
*
* 注意:此函数包含无限循环,仅用于测试目的。
* 注意使用了par关键词来并发执行代码块这依赖于特定的硬件或并发模型。
*/
void test_cycleHSV_with_vol_level();
/**
* 用于测试HSV溢出
*/
void test_HSV_to_RGB();
/**
* 测试 fill_gradient_with_groups 函数。
*
* 此测试函数创建一个缓冲区,并定义两种颜色和每组的填充数量,然后调用
* fill_gradient_with_groups 函数来填充缓冲区。之后,它会验证缓冲区中的颜色
* 是否符合预期每组的前N个LED应该是指定的颜色剩余的LED应该是关闭的黑色
* 如果所有LED的颜色都正确测试通过否则输出错误信息并标记测试失败。
*/
void test_fill_gradient_with_groups();
#endif // RGB_EFFECT_H