2014-10-06 125 views
1

对于我的Arduino项目,我有一个Neopixel RGB Strip和72个LED。Arduino功能将RGB从一种颜色褪色到下一个

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

我想要做的是能够选择一种颜色,然后选择另一种颜色,并使第一种颜色淡入到下一种颜色等等(很像LIFX灯泡在使用iPhone应用程序时的行为)。

这是我的时刻:

我记录所有变量的输出,给你这是怎么回事的指示。我并不是100%确定自己要出错的地方,还是有更简单的方法来做我以后的事情(我愿意接受建议)。

该函数采用一个称为command参数,它是由逗号分隔的字符串:

例如255, 0, 0(RED)或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 

回答

2

我觉得你的代码是没有那么糟糕,你只需要延迟。因为你的for循环太快会让你注意到衰落。

project I'm working on,这里是一个c++/pseudocode示例使led之间的颜色渐变为rgb。

它可以被修改,很容易地处理你的图书馆。 Serial.print()用于调试目的,一旦工作就可以删除。请注意,在每个循环迭代结束时,waitMS()。您也可以使用Arduino delay()函数替换它。

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); 
} 

希望这有助于:)

编辑:

这里是链接的ColorLed代码:

+1

@gotnull我刚刚更新了我的答案与文档:) – ladislas 2014-10-14 15:33:31

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等,然后更新您的targetcolours。另一件事是,这个代码被调整为褪色,因为如果信誉< =目标红色。我原本使用!=但有时ccolour会射过ctarget并继续前进。我需要弄清楚如何设定更好的容差。我正在尝试避免使用延迟,以便稍后在没有延迟的情况下接收外部输入时更容易。

无论如何,从不同的方法看同样的问题是很好的,这是另一回事。祝你好运!

相关问题