1

对于我的 Arduino 项目,我有一个带有 72 个 LED 的Neopixel RGB 灯带。

我可以成功更改任何 LED 的颜色(目前我只是将第一个设置为 0 用于测试目的)所以我知道我的接线在这里不是问题,这是我的编码。

我想做的是能够选择一种颜色,然后选择另一种颜色,并让第一种颜色褪色到下一种颜色,依此类推(很像使用 iPhone 应用程序时 LIFX 灯泡的行为)。

这就是我目前所拥有的:

我正在记录所有变量的输出,以便您了解正在发生的事情。我不能 100% 确定我哪里出错了,或者是否有更简单的方法来做我想做的事情(我愿意接受建议)。

该函数接受一个名为 的参数command,它是一个用逗号分隔的字符串:

例如255, 0, 0(红色)或0, 255, 0(绿色)。

/*******************************************************************************
 * Function Name  : tinkerSetColour
 * Description    : Sets the strip with the appropriate colour
 * Input          : Pin and value
 * Output         : None.
 * Return         : 1 on success and a negative number on failure
 *******************************************************************************/
int Rstart = 0, Gstart = 0, Bstart = 0;
int Rnew = 0, Gnew = 0, Bnew = 0;

int tinkerSetColour(String command)
{
    sprintf(rgbString, "Rstart %i, Gstart %i, Bstart %i", Rstart, Gstart, Bstart);
    Spark.publish("rgb", rgbString);

    sprintf(rgbString, "Rnew %i, Gnew %i, Bnew %i", Rnew, Gnew, Bnew);
    Spark.publish("rgb", rgbString);

    // Clear strip.
    strip.show();

    int commaIndex = command.indexOf(',');
    int secondCommaIndex = command.indexOf(',', commaIndex+1);
    int lastCommaIndex = command.lastIndexOf(',');

    int red = command.substring(0, commaIndex).toInt();
    int grn = command.substring(commaIndex+1, secondCommaIndex).toInt();
    int blu = command.substring(lastCommaIndex+1).toInt();

    int Rend = red, Gend = grn, Bend = blu;

    sprintf(rgbString, "Rend %i, Gend %i, Bend %i", Rend, Gend, Bend);
    Spark.publish("rgb", rgbString);

    // Larger values of 'n' will give a smoother/slower transition.
    int n = 200;
    for (int i = 0; i < n; i++)
    {
        Rnew = Rstart + (Rend - Rstart) * i / n;
        Gnew = Gstart + (Gend - Gstart) * i / n;
        Bnew = Bstart + (Bend - Bstart) * i / n;

        // Set pixel color here.
        strip.setPixelColor(0, strip.Color(Rnew, Gnew, Bnew));
    }

    sprintf(rgbString, "Rnew %i, Gnew %i, Bnew %i", Rnew, Gnew, Bnew);
    Spark.publish("rgb", rgbString);

    Rstart = red, Gstart = grn, Bstart = blu;

    sprintf(rgbString, "Rstart %i, Gstart %i, Bstart %i", Rstart, Gstart, Bstart);
    Spark.publish("rgb", rgbString);

    return 1;
}

问题是颜色之间没有褪色。

抱歉,如果其中任何一个令人困惑。如有必要,我可以提供更多信息。

这是选择RED开头的输出:

Rstart 0, Gstart 0, Bstart 0
Rnew 0, Gnew 0, Bnew 0
Rend 255, Gend 0, Bend 0
Rnew 253, Gnew 0, Bnew 0

这是之后直接选择GREEN的输出

Rstart 255, Gstart 0, Bstart 0
Rnew 253, Gnew 0, Bnew 0
Rend 0, Gend 255, Bend 0
Rnew 2, Gnew 253, Bnew 0

然后输出选择BLUE之后:

Rstart 0, Gstart 255, Bstart 0
Rnew 2, Gnew 253, Bnew 0
Rend 0, Gend 23, Bend 255
Rnew 0, Gnew 25, Bnew 253
4

2 回答 2

2

我认为您的代码还不错,您只需要延迟。因为你的for循环太快了,你不会注意到衰落。

我正在处理的一个项目中,这是一个c++/pseudocode将 LED 渐变为 rgb 颜色的示例。

它可以很容易地修改为与您的库一起使用。它们用于调试目的,Serial.print()一旦工作就可以删除。请注意,在每次循环迭代结束时,waitMS(). 您也可以将其替换为 Arduinodelay()功能。

void fade(uint16_t duration, Color startColor, Color endColor) {

    int16_t redDiff = endColor.getR() - startColor.getR();
    int16_t greenDiff = endColor.getG() - startColor.getG();
    int16_t blueDiff = endColor.getB() - startColor.getB();

    int16_t delay = 20;
    int16_t steps = duration / delay;

    int16_t redValue, greenValue, blueValue;

    for (int16_t i = 0 ; i < steps - 1 ; ++i) {
        redValue = (int16_t)startColor.getR() + (redDiff * i / steps);
        greenValue = (int16_t)startColor.getG() + (greenDiff * i / steps);
        blueValue = (int16_t)startColor.getB() + (blueDiff * i / steps);

        Serial.print(redValue);
        Serial.print("\t");
        Serial.print(greenValue);
        Serial.print("\t");
        Serial.print(blueValue);
        Serial.println("\t");

        led.shine(redValue, greenValue, blueValue);
        waitMs(delay);
    }

    led.shine(endColor);
}

希望这可以帮助 :)

编辑:

这是和的代码的Color链接Led

于 2014-10-06T07:19:10.870 回答
2

几天来我一直在解决同样的问题。我对 arduino 和编码还很陌生,所以我的代码可能有点简单,但现在这似乎可行。

我正在使用 FastLED 库。

#include "FastLED.h"

#define NUM_LEDS 15

#define DATA_PIN 6

CRGB leds[NUM_LEDS];

 int fade = 2; //minutes

   byte cred; //current red
   byte cgreen;
   byte cblue;
   byte targetred; //red after fade
   byte targetgreen;
   byte targetblue;
   byte oldred; //red before fade
   byte oldgreen;
   byte oldblue;
   byte deltared; //difference before and after fade
   byte deltagreen;
   byte deltablue;

unsigned long start;
unsigned long current;
unsigned long whole; 


void setup() { 
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  cred = 0; cblue = 0; cgreen = 0;
  oldred = 0; oldblue = 0; oldgreen = 0;
  update();
  start = millis();

}

void loop() {
  targetred = 20;
  targetgreen = 220;
  targetblue = 130;
  deltared = targetred - oldred; deltagreen = targetgreen - oldgreen; deltablue = targetblue - oldblue;
  whole = fade * 60000 + start; //fade time in milliseconds

  if (cred <= targetred && millis() <= whole){
  current = millis();
  cred = current * deltared / whole;
  cred = cred + oldred;}

if (cgreen <= targetgreen && millis() <= whole){
  current = millis();
  cgreen = current * deltagreen / whole;
  cgreen = cgreen + oldgreen;}

  if (cblue <= targetblue && millis() <= whole){
  current = millis();
  cblue = current * deltablue / whole;
  cblue = cblue + oldblue;}

  update();

}

void update(){
 for (int i = 0; i <= NUM_LEDS; i++){
  leds[i] = CRGB (cred, cgreen, cblue);
  FastLED.show();
  }};

这个版本之后实际上并不会褪色为另一种颜色,但您只需分配 oldred = cred 等,然后更新您的目标颜色。另一件事是,由于 if cred <= target red,这段代码被调整为淡出。我最初使用的是 != 但有时 ccolor 会射过 ctarget 并继续前进。我需要弄清楚如何设置更好的公差。我试图避免使用延迟,以便以后更容易接收外部输入而不会出现延迟。

无论如何,从不同的方法来看同一个问题是很好的,这是另一个。祝你褪色好运!

于 2014-11-18T08:04:05.177 回答