NEOPIXEL RINGS - COLOR CODING

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
spencerdwight
 
Posts: 1
Joined: Thu Aug 20, 2015 10:27 pm

NEOPIXEL RINGS - COLOR CODING

Post by spencerdwight »

Hello Adafruit friends,

This is my first time posting to the forum. Over the last couple of months I've become increasingly interested in LED art. I was introduced to Adafruit through a friend who built a pair of NeoPixel LED Goggles and let me wear them at a dance party. After that experience, I purchased the kit and built my own pair. It was my first time soldering small components on a board and my first experience with the Arduino IDE. As a meticulous maker, my first attempt at the project went well, and I was very excited to see the goggles light up after uploading the NeoPixel library (provided):

Code: Select all

// Low power NeoPixel goggles example.  Makes a nice blinky display
// with just a few LEDs on at any time.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc.
 #include <avr/power.h>
#endif

#define PIN 0

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(32, PIN);

uint8_t  mode   = 0, // Current animation effect
         offset = 0; // Position of spinny eyes
uint32_t color  = 0xFF0000; // Start red
uint32_t prevTime;

void setup() {
#ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc.
  if(F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  pixels.begin();
  pixels.setBrightness(85); // 1/3 brightness
  prevTime = millis();
}

void loop() {
  uint8_t  i;
  uint32_t t;

  switch(mode) {

   case 0: // Random sparks - just one LED on at a time!
    i = random(32);
    pixels.setPixelColor(i, color);
    pixels.show();
    delay(10);
    pixels.setPixelColor(i, 0);
    break;
 
   case 1: // Spinny wheels (8 LEDs on at a time)
    for(i=0; i<16; i++) {
      uint32_t c = 0;
      if(((offset + i) & 7) < 2) c = color; // 4 pixels on...
      pixels.setPixelColor(   i, c); // First eye
      pixels.setPixelColor(31-i, c); // Second eye (flipped)
    }
    pixels.show();
    offset++;
    delay(50);
    break;
  }

  t = millis();
  if((t - prevTime) > 8000) {      // Every 8 seconds...
    mode++;                        // Next mode
    if(mode > 1) {                 // End of modes?
      mode = 0;                    // Start modes over
      color >>= 8;                 // Next color R->G->B
      if(!color) color = 0xFF0000; // Reset to red
    }
    for(i=0; i<32; i++) pixels.setPixelColor(i, );
    prevTime = t;
  }
}
Now I would love to modify this code to customize the colors and p a t t e r n s of the LED rings.

Here are some of the modifications I'm interested in:
1. change the color cycle of "random sparks" (case 0) and "spinny wheels" (case 1) from standard RGB to a yellow-orange-purple cycle
2. change the time interval between case 0 and case 1 to 30 seconds
3. increase the LED brightness to 2/3 the power of the current LED brightness
4. change the rotation of the second NeoPixel ring (counter clockwise) to match the rotation of the first ring (clockwise movement on both)

*Please note: I have a beginners understanding of programming, however I am confident in my ability to piece this puzzle together.
*Second note: I have researched the adafruit forums and backtracked through NeoPixel tutorials but found nothing directly helpful
*Resources utilized: Adafruit NeoPixel Überguide, RainbowCycle - Adafruit Learning System, Multi-tasking the Arduino (Part 3)

Any advice is appreciated, I'm very excited and grateful for this learning experience!

User avatar
sergneri
 
Posts: 37
Joined: Mon Jan 20, 2014 9:00 pm

Re: NEOPIXEL RINGS - COLOR CODING

Post by sergneri »

A simple "breakthrough" for me was being able to split the LEDs into chunks and work inside out and outside in using random colors. I'm very much new to C++ and the IDE but playing can result in some fun effects. Keep hammering on it, you'll get it.

Code: Select all


void split() {
  int a = (strip.numPixels() / 2);
  int r = random(0, 255);
  int b = random(0, 255);
  int g = random(0, 255);

for (int i = (strip.numPixels() / 2); i > -1; i--) {
    strip.setBrightness(70);
    strip.setPixelColor(i, r, b, g);
    strip.show();
    strip.setPixelColor(a, r, b, g);
    strip.show();
    delay(10);
    a = a + 1;
  }
}
void unsplit() {
  int a = (strip.numPixels());
  int r = random(0, 255);
  int b = random(0, 255);
  int g = random(0, 255);
  for (int i = 0; i < (strip.numPixels() / 2); i++) {
    strip.setBrightness(70);
    strip.setPixelColor(i, r, b, g);
    strip.show();
    strip.setPixelColor(a, r, b, g);
    strip.show();
    delay(10);
    a = a - 1;
  }
}

User avatar
wayout440
 
Posts: 5
Joined: Thu Nov 19, 2015 4:31 pm

Re: NEOPIXEL RINGS - COLOR CODING

Post by wayout440 »

I'm in the same boat, I know next to nothing. I would like to add two colors to the spinny wheels: orange and yellow.
I'm stuck here: color >>= 8
How does this command give me the three primary colors red, blue and green, and how do I modify that to make 5 colors of my choosing?

User avatar
michaelmeissner
 
Posts: 1830
Joined: Wed Aug 29, 2012 12:40 am

Re: NEOPIXEL RINGS - COLOR CODING

Post by michaelmeissner »

Neopixel colors are encoded as a 24-bit integer, which each of red, green, and blue taking up 8 bits.

So, if you have red, green, and blue components (each one is 0 to 255), you would make the composite value by:

Code: Select all

    uin32_t value = (red * 65536UL) + (green * 256UL) + blue;
Internally, to multiply by powers of 2 (65536 is 2^16, 256 is 2^8), you would just shift the bits left. The compiler would optimize the above to be:

Code: Select all

    value = (((uint32_t)red) << 16) + (((uint32_t)green) << 8) + blue;
Now, to decode a composite value, you do it the reverse way:

Code: Select all

    uint8_t red = (value / 65536UL) % 256UL;
    uint8_t green = (value / 256UL) % 256UL;
    uint8_t blue = value % 256UL;
which again can be done with shifting:

Code: Select all

    uint8_t red = (value >> 16) & 255UL;
    uint8_t green = (value >> 8) & 255UL;
    uint8_t blue = value & 255UL;
Note, I used UL as a suffix on constants to make sure that arithmetic was performed in 32-bits (on AVR platforms, the default is to do integer arithmetic in 16-bits, but you need 32-bits to encode red/green/blue).

User avatar
wayout440
 
Posts: 5
Joined: Thu Nov 19, 2015 4:31 pm

Re: NEOPIXEL RINGS - COLOR CODING

Post by wayout440 »

Thanks for taking the time to reply. I somewhat understand what is going there, still not sure how to get the shift to go through 5 different colors of my choosing, it almost seems as though I would have to write an entire subroutine to do what I wand, since the three primary colors are easily represented by the values of the three pixels, but adding two non-primary colors orange and yellow is going to require blending values of multiple pixels.

User avatar
michaelmeissner
 
Posts: 1830
Joined: Wed Aug 29, 2012 12:40 am

Re: NEOPIXEL RINGS - COLOR CODING

Post by michaelmeissner »

The way I would solve this would be to have an array of uint32_t's that has the colors that you want to do, and iterate through the array.

Right now, it is using the fact that it only goes through the 3 primary colors, and it does so by setting the c to red, and then shifting it right 8 bits so the next iteration, it is green, and then blue. When the value becomes 0, it starts the process over again.

So, you would need to have an array of the 5 colors, say:

Code: Select all

const int num_colors = 5;
const static uint32_t colors[num_colors] = {
  0xff0000,    // red
  0x00ff00,    // green
  0x0000ff,    // blue
  0x3f3f00,    // red + green
  0x003f3f     // green + blue
};

uint32_t color;
int color_index = 0;

// ...
void setup () {
  // ...
  color = colors[color_index];
}

void loop () {
  // ...
  t = millis();
  if((t - prevTime) > 8000) {      // Every 8 seconds...
    mode++;                        // Next mode
    if(mode > 1) {                 // End of modes?
      mode = 0;                    // Start modes over
      color_index = ((color_index + 1) % num_colors);    // go to next color in table
      color = colors[color_index];
    }

User avatar
wayout440
 
Posts: 5
Joined: Thu Nov 19, 2015 4:31 pm

Re: NEOPIXEL RINGS - COLOR CODING

Post by wayout440 »

That explains it perfectly. The bit shifting technique is a shorter method of coding for lighting the 3 pixels individually,
Thank you!

Locked
Please be positive and constructive with your questions and comments.

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”