WS2812灯珠(四)---实现全彩呼吸灯效果

WS2812灯珠实现呼吸灯效果主要涉及到呼吸函数及颜色模型两部分的内容。清楚了这两点结合之前的灯珠驱动程序,便可以实现任意颜色的呼吸变换效果了。

呼吸函数

具体的呼吸函数细节这里就不介绍了,感兴趣的可以自行搜索。这里下面的呼吸灯曲线表是从呼吸函数中取得离散点,最大值为256(rgb的分别值最大为255),总共300个亮度等级,若每个亮度下亮10ms则整个过程持续3S,符合人实际呼吸的情况。

/* 呼吸灯曲线表 */
const uint16_t index_wave[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 
                               4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 
                               13, 13, 14, 14, 15, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 30, 31, 32, 33, 
                               34, 36, 37, 38, 40, 41, 43, 45, 46, 48, 50, 52, 54, 56, 58, 60, 62, 65, 67, 70, 72, 75, 78, 81, 84, 87, 90, 
                               94, 97, 101, 105, 109, 113, 117, 122, 126, 131, 136, 141, 146, 152, 158, 164, 170, 176, 183, 190, 197, 205, 
                               213, 221, 229, 238, 247, 256, 256, 247, 238, 229, 221, 213, 205, 197, 190, 183, 176, 170, 164, 158, 152, 146, 
                               141, 136, 131, 126, 122, 117, 113, 109, 105, 101, 97, 94, 90, 87, 84, 81, 78, 75, 72, 70, 67, 65, 62, 60, 58, 
                               56, 54, 52, 50, 48, 46, 45, 43, 41, 40, 38, 37, 36, 34, 33, 32, 31, 30, 28, 27, 26, 25, 25, 24, 23, 22, 21, 20, 
                               20, 19, 18, 18, 17, 16, 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 
                               6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
                               2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};

RGB与HSV转换

如果过采用rgb的方式实现呼吸变换,变换过程中需要同时改变RGB三个值,很难保证颜色不会改变。因此我们需要一种更好的表示颜色的模型HSV,H:色调、S:饱和度、V:亮度。只要H和S不变就能够保证颜色不改变。但因为WS2812是属于RGB控制的,因此我们需要两者之间互相转化的公式,先由RGB设定我们要实现呼吸变换的颜色,然后将该颜色的RGB值转为HSV的值,通过定时改变V的值来改变亮度。改变后再将HSV的值转换成RGB的值赋值给灯珠显示。

static float min(float a, float b, float c)
{
  float m;
  
  m = a < b ? a : b;
  return (m < c ? m : c); 
}

static float max(float a, float b, float c)
{
  float m;
  
  m = a > b ? a : b;
  return (m > c ? m : c); 
}
  
void rgb2hsv(uint8_t r, uint8_t g, uint8_t b, float *h, float *s, float *v)
{
  float red, green ,blue;
  float cmax, cmin, delta;
  
  red = (float)r / 255;
  green = (float)g / 255;
  blue = (float)b / 255;
  
  cmax = max(red, green, blue);
  cmin = min(red, green, blue);
  delta = cmax - cmin;

  /* H */
  if(delta == 0)
  {
    *h = 0;
  }
  else
  {
    if(cmax == red)
    {
      if(green >= blue)
      {
        *h = 60 * ((green - blue) / delta);
      }
      else
      {
        *h = 60 * ((green - blue) / delta) + 360;
      }
    }
    else if(cmax == green)
    {
      *h = 60 * ((blue - red) / delta + 2);
    }
    else if(cmax == blue) 
    {
      *h = 60 * ((red - green) / delta + 4);
    }
  }
  
  /* S */
  if(cmax == 0)
  {
    *s = 0;
  }
  else
  {
    *s = delta / cmax;
  }
  
  /* V */
  *v = cmax;
}
  
void hsv2rgb(float h, float s, float v, uint8_t *r, uint8_t *g, uint8_t *b)
{
    int hi = ((int)h / 60) % 6;
    float f = h * 1.0 / 60 - hi;
    float p = v * (1 - s);
    float q = v * (1 - f * s);
    float t = v * (1- (1 - f) * s);
    switch (hi){
        case 0:
            *r = 255 * v;
            *g = 255 * t;
            *b = 255 * p;
            break;
        case 1:
            *r = 255 * q;
            *g = 255 * v;
            *b = 255 * p;
            break;
        case 2:
            *r = 255 * p;
            *g = 255 * v;
            *b = 255 * t;
            break;
        case 3:
            *r = 255 * p;
            *g = 255 * q;
            *b = 255 * v;
            break;
        case 4:
            *r = 255 * t;
            *g = 255 * p;
            *b = 255 * v;
            break;
        case 5:
            *r = 255 * v;
            *g = 255 * p;
            *b = 255 * q;
            break;
    }
}
  • 36
    点赞
  • 234
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
### 回答1: 要实现控制ws2812灯珠实现流星效果,我们可以使用Arduino来编写代码和控制。下面是一个简单的实现流程: 首先,我们需要连接ws2812灯珠到Arduino板上。将VCC引脚连接到Arduino的5V引脚,GND引脚连接到Arduino的GND引脚,将DI引脚连接到Arduino的数字引脚,例如D2。 接下来,在Arduino IDE中编写程序。首先,我们需要包含“Adafruit_NeoPixel”库,这是一个用于控制ws2812灯珠的库。 然后,我们需要定义灯珠的数量和引脚。使用“Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, PIN, NEO_GRB + NEO_KHZ800);”来初始化灯珠。 接下来,我们需要在“setup”函数中设置引脚模式和数量。使用“strip.begin();”来初始化灯珠。 然后,在“loop”函数中编写流星效果的代码。我们可以使用for循环控制灯珠的数量,并在每个迭代中通过“strip.setPixelColor(i, strip.Color(255, 255, 255));”来设置灯珠的颜色。然后,我们可以使用“strip.show();”来将颜色应用到灯珠上。 在每个迭代之间,我们可以使用“strip.setPixelColor(i, strip.Color(0, 0, 0));”来将灯珠颜色设置为黑色,以模拟流星移动的效果。可以通过增加延迟来调整流星移动的速度。 最后,我们可以在Arduino上上传代码,灯珠就会展示流星效果了。 需要注意的是,这只是一个简单的流星效果实现方法。如果想要更复杂的效果,可以在代码中做更多的调整和改进。 ### 回答2: 要实现流星效果,可以通过Arduino控制WS2812灯珠实现。首先,我们需要将WS2812灯珠与Arduino连接起来。通过连接DI(Digital Input)引脚和5V、GND引脚,将WS2812灯珠与Arduino连接在一起。 接下来,我们需要通过编写代码来实现流星效果。首先,在Arduino中安装FastLED库,该库可以帮助我们更方便地对WS2812灯珠进行控制。 然后,我们需要定义一些变量来控制流星的行为,比如流星的起始位置、流星的速度、流星的长度等。在Arduino的setup函数中,我们可以初始化这些变量,同时设置WS2812灯珠的数量和引脚。 在Arduino的loop函数中,我们可以使用FastLED库提供的函数来控制WS2812灯珠的亮度和颜色。通过循环遍历每个灯珠,我们可以逐渐改变流星的位置和亮度,从而实现流星效果。我们可以通过改变流星的起始位置和速度来控制流星的移动方向和速度。 为了实现流星的效果,我们还可以使用一些特殊的算法,比如渐变亮度、尾巴效果等。通过增加尾巴效果,可以让流星在移动过程中留下一道模糊的尾巴,增加流星的真实感。 最后,通过将Arduino连接到电源,我们可以看到WS2812灯珠闪烁起来,模拟出流星落下的效果。通过调整代码中的参数,我们还可以改变流星的颜色、长度和速度,实现不同的流星效果。 总之,通过使用Arduino控制WS2812灯珠,并结合合适的代码和算法,我们可以轻松实现流星效果。这种效果可以应用于各种场景,比如舞台表演、节日布置等。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值