孤独飞行 发表于 2022-2-24 10:16:25

请问8位机全彩RGB渐变,有好的算法吗?

如题,项目有个附属功能需要有个RGB灯做全彩渐变效果。开始用R G B三个PWM相位相差120度呼吸灯,自我感觉效果还可以,但是这样的效果同时只有两个颜色混色,没有三个颜色的时候,客户不满意。我想用可能要用HSV转RGB,可是8位机的算力不够。。请问大家有啥简单的办法么?谢谢~!

yyts 发表于 2022-2-24 10:24:44

给你个HSV转RGB的算法,你看看

void led_strip_hsv2rgb(uint32_t h, uint32_t s, uint32_t v, uint32_t *r, uint32_t *g, uint32_t *b)
{
    h %= 360; // h ->
    uint32_t rgb_max = v * 2.55f;
    uint32_t rgb_min = rgb_max * (100 - s) / 100.0f;

    uint32_t i = h / 60;
    uint32_t diff = h % 60;

    // RGB adjustment amount by hue
    uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60;

    switch (i) {
    case 0:
      *r = rgb_max;
      *g = rgb_min + rgb_adj;
      *b = rgb_min;
      break;
    case 1:
      *r = rgb_max - rgb_adj;
      *g = rgb_max;
      *b = rgb_min;
      break;
    case 2:
      *r = rgb_min;
      *g = rgb_max;
      *b = rgb_min + rgb_adj;
      break;
    case 3:
      *r = rgb_min;
      *g = rgb_max - rgb_adj;
      *b = rgb_max;
      break;
    case 4:
      *r = rgb_min + rgb_adj;
      *g = rgb_min;
      *b = rgb_max;
      break;
    default:
      *r = rgb_max;
      *g = rgb_min;
      *b = rgb_max - rgb_adj;
      break;
    }
}

aammoo 发表于 2022-2-24 10:44:57

是要用HSV,算力不够空间来凑啊,提前算好存下来

孤独飞行 发表于 2022-2-24 11:14:37

aammoo 发表于 2022-2-24 10:44
是要用HSV,算力不够空间来凑啊,提前算好存下来
(引用自3楼)

空间也不够{:sad:}

孤独飞行 发表于 2022-2-24 11:14:50

yyts 发表于 2022-2-24 10:24
给你个HSV转RGB的算法,你看看
(引用自2楼)

先谢谢~!

孤独飞行 发表于 2022-2-24 14:05:12

没仔细看HVS转RGB程序,抛开V ,S两项为固定值的情况下,没有浮点运算。问题解决,感谢大家。

ffbiao 发表于 2022-2-24 14:10:27

有没有视频看效果如何

AVR_USER 发表于 2022-2-24 14:59:03

楼主,给你一个思路:3个颜色可以混出来7种颜色,保存下来表格
R         G         B
255   0          0
0         255      0
0         0          255
255   255      0
255   0          255
0         255      255
255   255      255
通过设置RGB三个变量,当前变量值跟颜色表格的目标颜色对比,大的就自减1,小的就自加1,三个变量都等于目标颜色了,就取下一个目标颜色做对比,每对比一次,就将当前的RGB变量值输出给到PWM,这样就可以控制渐变了,通过设置对比的速度,可以控制渐变的快慢

孤独飞行 发表于 2022-2-24 16:33:10

#define rgb_max255
#define rgb_min   0
void led_strip_hsv2rgb(void)
{
        static unsigned char Speed=0;
        unsigned char i,diff;
        unsigned int rgb_adj;
        //=========
        if(Speed<5)
        {
                Speed++;
                return;
        }
        Speed=0;
    h++;
    if(h>360)h=0;
    i = h / 60;
    diff = h % 60;
        rgb_adj = 255* diff / 60;
    switch (i)
   {
    case 0:
      PwmR = rgb_max;
      PwmG = rgb_min + rgb_adj;
      PwmB = rgb_min;
      break;
    case 1:
      PwmR = rgb_max - rgb_adj;
      PwmG = rgb_max;
      PwmB = rgb_min;
      break;
    case 2:
      PwmR = rgb_min;
      PwmG = rgb_max;
      PwmB = rgb_min + rgb_adj;
      break;
    case 3:
      PwmR = rgb_min;
      PwmG = rgb_max - rgb_adj;
      PwmB = rgb_max;
      break;
    case 4:
      PwmR = rgb_min + rgb_adj;
      PwmG = rgb_min;
      PwmB = rgb_max;
      break;
    default:
      PwmR = rgb_max;
      PwmG = rgb_min;
      PwmB = rgb_max - rgb_adj;
      break;
    }
}
改成适应小资源的MCU使用,PwmR ,PwmG , PwmB 赋值到对应的PWM寄存器,10MS调用一次。Speed的最大值决定速度。

zzz123456 发表于 2022-2-28 14:26:32

记号,谢谢分享

wjb888 发表于 2022-2-28 18:46:14

谢谢,好方法

zyw19987 发表于 2023-6-16 09:17:42

孤独飞行 发表于 2022-2-24 16:33
#define rgb_max255
#define rgb_min   0
void led_strip_hsv2rgb(void)
(引用自9楼)

能否稍作你的思路解释?
最近看FOC无刷电机控制算法,把RGB看成相位相差120度,旋转角度相当于颜色配比选项,各自向量大小控制亮度。不知道这个启发能否实现。

zyw19987 发表于 2023-6-16 09:21:26

本帖最后由 zyw19987 于 2023-6-16 09:22 编辑

孤独飞行 发表于 2022-2-24 16:33
#define rgb_max255
#define rgb_min   0
void led_strip_hsv2rgb(void)
(引用自9楼)

似乎看明白了,你的i应该就是做所在象限的判断,然后对第三象限进行耦合计算。h相当于旋转角度。
果然,技术都是相通的。

waymcu 发表于 2023-6-17 00:49:40

学习了,谢了

ackyee 发表于 2023-6-17 08:54:19

本帖最后由 ackyee 于 2023-6-17 08:55 编辑

无非就是 +1   减1的问题这项目我做过你想的太复杂了   而且我用的星芒微来做的成本 几毛钱   几乎无法做复杂算法 ,我还加了个FFT{:sweat:}

我做的星空灯都量产卖国外了
页: [1]
查看完整版本: 请问8位机全彩RGB渐变,有好的算法吗?