Краще перемикання кольорів RGB

Я намагався досягти способу підключитися до 16 мільйонів кольорів, які RGB надає цій світлодіодній смузі. Я подумав про використання LEDS.setBrightness (); , але не був успішним у своїх спробах. Я прочитав документацію про вицвітання кольору , але не зміг написати це моєму Arduino Leonardo. Ось мій код нижче, який цикли через початкову веселку 0-255. Мені було цікаво, як отримати більше 0-255, якщо не всі кольори.

#include 

#define LED_COUNT 60
#define LED_OUT       13
#define BUTTON_IN     10
#define ANALOG_INPUT  A9
#define EXTRA_PIN_A    7
#define EXTRA_PIN_B   11

struct CRGB leds[LED_COUNT];
int wait_time = 5;

void setup() {
  Serial.begin(57600);
  LEDS.addLeds(leds, LED_COUNT);
  LEDS.show();
}

void loop() {
  //start from red
  for(int colorStep=0; colorStep <= 255; colorStep++) {
    int r = 255;
    int g = 0;
    int b = colorStep;
   //Now loop though each of the LEDs and set each one to the current color
    for(int x = 0; x < LED_COUNT; x++) {
      leds[x] = CRGB(r,g,b);
    }
   //Display the colors we just set on the actual LEDs
    delay(wait_time);
    LEDS.show();
  }

  //into blue
  for(int colorStep=255; colorStep >= 0; colorStep--) {
    int r = colorStep;
    int g = 0;
    int b = 255;
   //Now loop though each of the LEDs and set each one to the current color
    for(int x = 0; x < LED_COUNT; x++) {
      leds[x] = CRGB(r,g,b);
    }
   //Display the colors we just set on the actual LEDs
    delay(wait_time);
    LEDS.show();
  }
  //start from blue
  for(int colorStep=0; colorStep <= 255; colorStep++) {
    int r = 0;
    int g = colorStep;
    int b = 255;
   //Now loop though each of the LEDs and set each one to the current color
    for(int x = 0; x < LED_COUNT; x++) {
      leds[x] = CRGB(r,g,b);
    }
   //Display the colors we just set on the actual LEDs
    delay(wait_time);
    LEDS.show();
  }
  //into green
  for(int colorStep=255; colorStep >= 0; colorStep--) {
    int r = 0;
    int g = 255;
    int b = colorStep;
   //Now loop though each of the LEDs and set each one to the current color
    for(int x = 0; x < LED_COUNT; x++) {
      leds[x] = CRGB(r,g,b);
    }
   //Display the colors we just set on the actual LEDs
    delay(wait_time);
    LEDS.show();
  }
  //start from green
  for(int colorStep=0; colorStep <= 255; colorStep++) {
    int r = colorStep;
    int g = 255;
    int b = 0;
   //Now loop though each of the LEDs and set each one to the current color
    for(int x = 0; x < LED_COUNT; x++) {
      leds[x] = CRGB(r,g,b);
    }
   //Display the colors we just set on the actual LEDs
    delay(wait_time);
    LEDS.show();
  }
  //into yellow
  for(int colorStep=255; colorStep >= 0; colorStep--) {
    int r = 255;
    int g = colorStep;
    int b = 0;
   //Now loop though each of the LEDs and set each one to the current color
    for(int x = 0; x < LED_COUNT; x++) {
      leds[x] = CRGB(r,g,b);
    }
   //Display the colors we just set on the actual LEDs
    delay(wait_time);
    LEDS.show();
  }
} //end main loop
2
але 0-255 рівнів RGB є всіма кольорами, що ви намагаєтеся зробити?
додано Автор Alastair, джерело
Ах, я бачу; потім просто вкладіть петлі ...
додано Автор Alastair, джерело
це правильно, але якщо ви будете стежити за моїми петлями, ви побачите, що я роблю тільки комбінації 0 <255 і 0> 255 для rgb. I.E. 0, 0, 255//синій або 255, 0, 0//червоний, тому я і сказав початкову веселку. немає комбінацій, скажімо, 128, 64, 250.
додано Автор Oddacon, джерело
спробував, що як w/@ 6v6gt відповідь. На жаль, він не працює через світлодіоди належним чином. Схоже, існує проблема з ітерацією з першим вкладеним циклом (не передбачений код) саме так, як клас FastLED обробляє вкладеність?
додано Автор Oddacon, джерело

6 Відповіді

Я думаю, варто зауважити, що три 255 значень колірного простору RGB - це лише один із способів кодування 255 ^ 3 (16 581 375) кольорів. До них відносяться також кожний рівень яскравості.

Якщо ви намагаєтеся отримати ефект веселки, ви можете мати більше успіху або легше використовувати колірний простір HSL або HSV.

HSV використовує Hue, Saturation і Value замість RGB. FastLED оптимізував реалізацію HSV для використання адреси 0-255 для Hue (замість 360), підтримуючи швидкість анімації, що працює на мікроконтролерах:

https://github.com/FastLED/FastLED/wiki/FastLED-HSV- Кольори

2
додано
Повторне використання fastled дійсно дуже хороший варіант! Ви подолаєте винайдення колеса, і маєте більш ефективне колесо;
додано Автор dotnetengineer, джерело

Я включив простий ескіз, який буде цикл одного RGB світлодіодних з використанням техніки синуса зникають

// Cycle a single RGB led using the sine fade technique
// For common cathode led

const uint8_t lights[360]={
  0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 15, 17, 18, 20, 22, 24, 26, 28, 30, 32, 35, 37, 39,
 42, 44, 47, 49, 52, 55, 58, 60, 63, 66, 69, 72, 75, 78, 81, 85, 88, 91, 94, 97, 101, 104, 107, 111, 114, 117, 121, 124, 127, 131, 134, 137,
141, 144, 147, 150, 154, 157, 160, 163, 167, 170, 173, 176, 179, 182, 185, 188, 191, 194, 197, 200, 202, 205, 208, 210, 213, 215, 217, 220, 222, 224, 226, 229,
231, 232, 234, 236, 238, 239, 241, 242, 244, 245, 246, 248, 249, 250, 251, 251, 252, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255, 254, 254, 253, 253,
252, 251, 251, 250, 249, 248, 246, 245, 244, 242, 241, 239, 238, 236, 234, 232, 231, 229, 226, 224, 222, 220, 217, 215, 213, 210, 208, 205, 202, 200, 197, 194,
191, 188, 185, 182, 179, 176, 173, 170, 167, 163, 160, 157, 154, 150, 147, 144, 141, 137, 134, 131, 127, 124, 121, 117, 114, 111, 107, 104, 101, 97, 94, 91,
 88, 85, 81, 78, 75, 72, 69, 66, 63, 60, 58, 55, 52, 49, 47, 44, 42, 39, 37, 35, 32, 30, 28, 26, 24, 22, 20, 18, 17, 15, 13, 12,
 11, 9, 8, 7, 6, 5, 4, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

const byte redpin = 3;  
const byte greenpin = 5;  
const byte bluepin = 6;  
int loopdelay = 5000;//ms  
int displaylength = 50;//ms  

boolean showiterations = false;  

//_______________________________  
void setup() {  
      Serial.begin(9600);  
}

void loop() {  
for (int k=0; k<360; k++)  
{  
    if (showiterations) {  
    Serial.print(k);  
    Serial.print(F(","));  
    }
analogWrite(redpin, lights[(k+120)%360]);  
analogWrite(greenpin, lights[k]);  
analogWrite(bluepin, lights[(k+240)%360]);  
delay(displaylength);  
}
if (showiterations) {  
Serial.println("  ");  
}
delay(loopdelay);  
}

Цей нарис походить від публікації Instructables під назвою "Як зробити правильні кольори веселки та випадкових кольорів за допомогою кольорової моделі RGB", http://www.instructables.com/id/How-to-Make-Proper-Rainbow-and-Random-Colors-With-/
Крім того, він надає інформацію та обґрунтування різних методів велосипедних кольорів.


Якщо ви намагаєтеся похитнути кольори вздовж смуги, створюючи ефект веселки, у мене є ще один ескіз [від Adafruit, я вважаю], що зробить це. Я використовував його ефективно з різними конфігураціями кільця Neopixel. Ескіз демонструє ряд різних методів. В даний час я прокоментував виклики всіх, крім театруChaseRainbow, але ви можете вивчити їх усі.

#include 
// following atatement should be wrapped with an ifdef for __AVR__, but this facility botches it up.
// As it is, formatting for the sketch is not quite right, and I do not have a solution for that.
  #include 

const  byte PIN = 7;

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
// Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800)`
Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, 6, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

void setup() {
 //This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
 //End of trinket special code


  strip.begin();
   colorWipe(strip.Color(0, 0, 0), 50);//blank
  strip.show();//Initialize all pixels to 'off'
}

void loop() {
 //Some example procedures showing how to display to the pixels:
//  colorWipe(strip.Color(255, 0, 0), 50);//Red
//  colorWipe(strip.Color(0, 255, 0), 50);//Green
//  colorWipe(strip.Color(0, 0, 255), 50);//Blue
//colorWipe(strip.Color(0, 0, 0, 255), 50);//White RGBW
 //Send a theater pixel chase in...
//  theaterChase(strip.Color(127, 127, 127), 50);//White
//  theaterChase(strip.Color(127, 0, 0), 50);//Red
//  theaterChase(strip.Color(0, 0, 127), 50);//Blue

//  rainbow(20);
//  delay(50000);
//  colorWipe(strip.Color(0, 0, 0), 50);//blank
//  rainbowCycle(10);
//  delay(5000);
//    colorWipe(strip.Color(0, 0, 0), 50);//blank
//   delay(5000);
  theaterChaseRainbow(50);
//  delay(5000);
//    colorWipe(strip.Color(0, 0, 0), 50);//blank
//   delay(5000);
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<256; j++) {
    for(i=0; i<256*5; j++) {//5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256/strip.numPixels()) + j) & 255));     
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {    //cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
1
додано
Незважаючи на те, що ваша відповідь на 100% правильна, вона також може стати на 100% марною, якщо посилання буде переміщено, змінено, об'єднано в інше, або головний сайт просто зникне ... :( Тому, будь ласка, відредагуйте свою відповідь і скопіюйте відповідні кроки з посилання у відповідь, гарантуючи таким чином відповідь на 100% життя цього сайту! ;) Ви завжди можете залишити посилання внизу вашої відповіді як джерело матеріалу ...
додано Автор user67244, джерело
Здається добре, спасибі!
додано Автор user67244, джерело
@Avamander, пропозиція прийнята, PLS переоцінити.
додано Автор Richard, джерело

Вам слід розглянути можливість його блокування :)

loop(){
   //if(millis() > previous+100){//uncomment this part to only do a step of the rainbow effect every 100ms
   rainbowEffect();
   //previous = millis();
   //}

   //you can do other stuff, like check a buttons' state here.
   //using the same structure as above, you can choose to give it a higher or lower priority.
}

unsigned char r,g,b;
void rainbowEffect(){
   if(r>254){
      r=0;
      g++;
   }
   if(g>254){
      g=0;
      b++;
   }
   if(b>254){
      b=0;
   }
   r++;
   ledStrip.set(r,g,b);
}
0
додано

Я думаю, @Mazaryk був правильний, HSV це шлях для цього. 16+ мільйонів кольорів RGB включають яскравість, і деякі з них просто не відображатимуться на смузі, тому я знайшов спосіб, принаймні, краще зникати:

int thissat = 255;           //- LOOPS DELAY VAR
int idex = 0;                //-LED INDEX
int ihue = 0;                //-hue (0-255)

void rainbow_fade() {
    ihue++;
    if (ihue > 255) {ihue = 0;}
    for(int idex = 0 ; idex < LED_COUNT; idex++ ) {
      leds[idex] = CHSV(ihue, thissat, 255);
    }
    LEDS.show();    
    delay(wait_time);
}
0
додано

Ви можете скористатися тим, що колір rgb може бути представлений у довжині без знака. І використовуйте лічильник. Але терпіння цикл через 16 міо кольори з 1ms при ітерації потрібно деякий час :-). (близько 4-5 годин: 16581375/(1000 [мс] * 60 [м] * 60 [год]) = 4,6)

void loopThrougAllColors(){
 //The trick here is to use a unsigned long value as the color representation. 
 //Each byte represent a color (except the first)
 //         none, R  G  B
 //         0x00 00 00 00                     
 //Note: static means it is a global variable - but only seen in thisfunction.                                            
  static unsigned long ledColor = 0;        
  static int ledIndex = 0;

  ledColor++;
  ledColor &= 0x00FFFFFF; /* Overflow preventing (instead of if sentence checking the boundaries). */           

  leds[0] = ledColor;

  FastLED.show();
  FastLED.delay(1);
  //delay(10);
} 
0
додано

Якщо ви хочете відобразити кожен з приблизно 16 мільйонів можливих кольорів, вам доведеться вкласти свої петлі, як у цьому прикладі:

x = 1 ; //only for testing
for ( int redx = 0 ; redx <= 255 ; redx ++ ) {
    for ( int greenx = 0 ; greenx <= 255 ; greenx ++ ) {
        for ( int bluex = 0 ; bluex <= 255 ; bluex ++ ) {
             leds[ x ] = CRGB(redx,greenx,bluex);
             delay(wait_time); 
             LEDS.show(); 
        }
    }
}
0
додано
Альтернативою може бути використання HSB або HSV замість RGB, таким чином можна збільшити відтінок з часом, щоб отримати ефект веселки.
додано Автор dotnetengineer, джерело
IT KPI C/С++ новым годом
IT KPI C/С++ новым годом
747 учасників

Чат обсуждения С/С++. - Вопросы "напишите за меня лабу" - это оффтоп. - Оффтоп, флуд, оскорбления и вбросы здесь не приняты. - За нарушение - предупреждение или mute на неделю. - За спам и рекламу - ban. Все чаты IT KPI: https://t.me/itkpi/1147