Dual Neopixel Control

Hoping this is a quick one. I have two Neo rings setup (a 24 ring and a 16 ring) and I'm trying to do separate colors with a slight fade effect on each of them on execution. When I do I keep getting the same colors even when I change the values differently in the HSV.

void playAnimation2() {
int position = 0;
unsigned long timer = millis();

timer = millis();
position = 0;
while (millis() - timer < 5000) {

for (int i = 0; i < CNT; i++)    
  strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 200, 70));
for (int i = CNT; i < CNT + CNT1; i++)   
  strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 100, 70));
strip.show();
strip.show();                      
position++;                        
position %= (CNT + CNT1);                
delay(50);                       

for (int x = 0; x < 10; x++) { //fading
for (int i = 0; i < CNT; i++)
strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 200, 70 - x));
for (int i = CNT; i < CNT + CNT1; i++) //Execute for total number of leds
strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 200, 70 - x));
strip.show();
position++;
position %= (CNT + CNT1);
delay(50);

}
for (int i = 0; i < CNT + CNT1; i++)
strip.setPixelColor(i, strip.Color( 0, 0, 0)); //Set pixel color off
strip.show();

}

Can anyone help? Thanks in advance!

Please post a complete sketch that compiles and runs. I am too lazy to complete your code.

We can then try it for ourselves and help…

a7

Thanks for the help

#include "Arduino.h"
#include <Adafruit_NeoPixel.h>

#define Button 3
#define PIN 6
#define CNT 24
#define CNT1 16
#define MAXHUE 256*6

Adafruit_NeoPixel strip = Adafruit_NeoPixel(CNT + CNT1, PIN, NEO_GRB + NEO_KHZ800);

int c = 0 , p = 0;
unsigned long timer;

void setup() {
pinMode(Button , INPUT);

strip.begin();
strip.show();
}

void loop() {
if (digitalRead(Button) == HIGH && p == 0) {
p = 1;
switch (c) {
case 0:
timer = millis();
playAnimation1();
delay(500);
c = 1;
break;
case 1:
playAnimation1();
c = 0;
break;

}

}
else if (digitalRead(Button) == LOW && p == 1) {
p = 0;
}

}

//-------------------------------------------------------------------------------------------------------------------------------

void playAnimation1() {
int position = 0;
unsigned long timer = millis();

timer = millis();
position = 0;
while (millis() - timer < 5000) {

for (int i = 0; i < CNT; i++)   
  strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 20, 70));
for (int i = CNT; i < CNT + CNT1; i++)   
  strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 20, 70));
strip.show();
strip.show();                     
position++;                        
position %= (CNT + CNT1);                
delay(50);                        

for (int x = 0; x < 10; x++) { //fading
for (int i = 0; i < CNT; i++)
strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 200, 70 - x));
for (int i = CNT; i < CNT + CNT1; i++)
strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 200, 70 - x));
strip.show();
position++;
position %= (CNT + CNT1);
delay(50);
}
for (int i = 0; i < CNT + CNT1; i++)
strip.setPixelColor(i, strip.Color( 0, 0, 0));
strip.show();
}
}

//-------------------------------------------------------------------------------------------------------------------------------

uint32_t getPixelColorHsv(
uint16_t n, uint16_t h, uint8_t s, uint8_t v) {
uint8_t r, g, b;

if (!s) {

r = g = b = v;

} else {
uint8_t sextant = h >> 8;
if (sextant > 5)
sextant = 5;

g = v;    // Top level

uint16_t ww;       
ww = v * (uint8_t)(~s);
ww += 1;           
ww += ww >> 8;      
b = ww >> 8;

uint8_t h_fraction = h & 0xff; 
uint32_t d;     

if (!(sextant & 1)) {
  // r = ...slope_up...
  // --> r = (v * ((255 << 8) - s * (256 - h)) + error_corr1 + error_corr2) / 65536
  d = v * (uint32_t)(0xff00 - (uint16_t)(s * (256 - h_fraction)));
  d += d >> 8;  // Error correction
  d += v;       // Error correction
  r = d >> 16;
} else {
  // r = ...slope_down...
  // --> r = (v * ((255 << 8) - s * h) + error_corr1 + error_corr2) / 65536
  d = v * (uint32_t)(0xff00 - (uint16_t)(s * h_fraction));
  d += d >> 8;  // Error correction
  d += v;       // Error correction
  r = d >> 16;
}
if (!(sextant & 6)) {
  if (!(sextant & 1)) {
    uint8_t tmp = r;
    r = g;
    g = tmp;
  }
} else {
  if (sextant & 1) {
    uint8_t tmp = r;
    r = g;
    g = tmp;
  }
}
if (sextant & 4) {
  uint8_t tmp = g;
  g = b;
  b = tmp;
}
if (sextant & 2) {
  uint8_t tmp = r;
  r = b;
  b = tmp;
}

}
return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
}

Could you post your code using code tags by selecting the code in the IDE, right-click and select "Copy for forum" (preferred) or as an attachment. The formatting that the new forum does makes it very hard to read.

#include "Arduino.h"                        
#include <Adafruit_NeoPixel.h>              

#define Button 3                          
#define PIN 6                             
#define CNT 24                              
#define CNT1 16                             
#define MAXHUE 256*6                        


Adafruit_NeoPixel strip = Adafruit_NeoPixel(CNT + CNT1, PIN, NEO_GRB + NEO_KHZ800); 

int c = 0 , p = 0;                          
unsigned long timer;                       

void setup() {
  pinMode(Button , INPUT);           


  strip.begin();                           
  strip.show();                            
}

void loop() {
  if (digitalRead(Button) == HIGH && p == 0) { 
    p = 1;                          
    switch (c) {                    
      case 0:                          
        timer = millis();             
        playAnimation1();
        delay(500);
        c = 1;                        
        break;
      case 1:                          
        playAnimation1();             
        c = 0;                         
        break;

    }
  }
  else if (digitalRead(Button) == LOW && p == 1) {  
    p = 0;
  }

}


//-------------------------------------------------------------------------------------------------------------------------------



void playAnimation1() {
  int position = 0;                           
  unsigned long timer = millis();     


  timer = millis();      
  position = 0;
  while (millis() - timer < 5000) {    
  
    
    for (int i = 0; i < CNT; i++)   
      strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 200, 70));
    for (int i = CNT; i < CNT + CNT1; i++)   
      strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 200, 70));
    strip.show();
    strip.show();                     
    position++;                        
    position %= (CNT + CNT1);                
    delay(50);                        
 
  for (int x = 0; x < 100; x++) {               //fading
    for (int i = 0; i < CNT; i++)    
      strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 200, 70 - x));
    for (int i = CNT; i < CNT + CNT1; i++)   
      strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 200, 70 - x));
    strip.show();
    position++;                      
    position %= (CNT + CNT1);
    delay(50); 
  }
    for (int i = 0; i < CNT + CNT1; i++)      
    strip.setPixelColor(i, strip.Color(  0,   0, 0));  
  strip.show();                        
}
}


//-------------------------------------------------------------------------------------------------------------------------------

uint32_t getPixelColorHsv(
  uint16_t n, uint16_t h, uint8_t s, uint8_t v) {
  uint8_t r, g, b;

  if (!s) {
   
    r = g = b = v;
  } else {
    uint8_t sextant = h >> 8;
    if (sextant > 5)
      sextant = 5;  

    g = v;    // Top level

    uint16_t ww;       
    ww = v * (uint8_t)(~s);
    ww += 1;           
    ww += ww >> 8;      
    b = ww >> 8;

    uint8_t h_fraction = h & 0xff; 
    uint32_t d;     

    if (!(sextant & 1)) {
      // r = ...slope_up...
      // --> r = (v * ((255 << 8) - s * (256 - h)) + error_corr1 + error_corr2) / 65536
      d = v * (uint32_t)(0xff00 - (uint16_t)(s * (256 - h_fraction)));
      d += d >> 8;  // Error correction
      d += v;       // Error correction
      r = d >> 16;
    } else {
      // r = ...slope_down...
      // --> r = (v * ((255 << 8) - s * h) + error_corr1 + error_corr2) / 65536
      d = v * (uint32_t)(0xff00 - (uint16_t)(s * h_fraction));
      d += d >> 8;  // Error correction
      d += v;       // Error correction
      r = d >> 16;
    }
    if (!(sextant & 6)) {
      if (!(sextant & 1)) {
        uint8_t tmp = r;
        r = g;
        g = tmp;
      }
    } else {
      if (sextant & 1) {
        uint8_t tmp = r;
        r = g;
        g = tmp;
      }
    }
    if (sextant & 4) {
      uint8_t tmp = g;
      g = b;
      b = tmp;
    }
    if (sextant & 2) {
      uint8_t tmp = r;
      r = b;
      b = tmp;
    }
  }
  return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
}

Ah great, this is actually usable.
Now i see how this sketch is setup, you didn't start from scratch really did you ?

    strip.show();
    strip.show();   

Anyway normally i would not daisy chain 2 rings when you want to have different animations (or colors on each) it is more straight forward to just connect them to a pin each, but let's see how far we get like this.

    for (int i = 0; i < CNT; i++)   
      strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 200, 70));
    for (int i = CNT; i < CNT + CNT1; i++)   
      strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 200, 70));

now i think that if you want to separate them properly then i think (?)

for (int i = 0; i < CNT; i++)   
      strip.setPixelColor((i + position) % (CNT), getPixelColorHsv(i, i * (MAXHUE / CNT), 200, 70));
    for (int i = 0; i < CNT1; i++)   
      strip.setPixelColor(((i + position) % CNT1) + CNT, getPixelColorHsv(i, i * (MAXHUE / CNT1), 200, 70));

it should be more like this
I am not really sure about the accumulator though.

    position++;                      
    position %= (CNT + CNT1);

TBH i never do much delay based animation, particularly because controlling 2 part (or layers) becomes rather difficult (even more so when you want to do it at different speeds.
But try this.

All exactly true @Deva_Rishi, it is amazing how much easier it is to read formatted code.

I usually use one pin and do backflips to manage subsets if indeed they are doing something that my main pattern cannot accommodate.

But I always pick slogging with the code. At the very least one should be able to get this kinda thing cooking with some tricks as you have employed. Similar patterns arise in other circumstances where the equivalent of hauling out another pin is not an available solution.

Naturally you will use delay() differently (or not at all) in the future.

a7

Wow..

Can you explain "in human" what the end result of the effect should be? How would you explain this to your inattentive boss for example?

All I got was you have two rings.. Are they doing different things?

-jim lee

Yeah i got that too, they were meant to do something similar but different i think.

Me too usually, but i never use anything delay() based, mine are all millis() & modulo (of the pattern length)
Mind you since i use pattern layers on the same strip, a situation with 2 daisy-chained strips (or rings) of a different size never occur, but that doesn't mean it can not be done.

I can get it to two different colors, but I can't get the fade effect that I had previously, it's more chasing. Even when I change the delay.

  timer = millis();     
  position = 0;
  while (millis() - timer < 1000) {    
    for (int i = 0; i < CNT; i++)    
      strip.setPixelColor((i + position) % CNT, getPixelColorHsv(i, 0, 255, strip.gamma8(i * (255 / CNT))));
    for (int i = CNT; i < CNT + CNT1; i++)   
      strip.setPixelColor(CNT+(i + position) % CNT1, getPixelColorHsv(i, 1000, 255, strip.gamma8(CNT+i * (255 / CNT1))));
    strip.show();
    strip.show();                     
    position++;                       
    position %= (CNT + CNT1);   
    delay(50);                        
  }

When playing the animation I want to have two steady colors for example blue and orange but have movement.

When I change the delay on the most recent code I replied with the pixels move as opposed to staying steady which is what I'm looking to accomplish.

In short...

The original code I posted has the movements I want with a rainbowish color.

The most recent code I replied with has the solid colors without the movement.

I'm trying to get those movements from the rainbow with the solid colors.

Ah look fiddling around with someone else's code is going to be fiddling by trial and error for me (which i don't like to do)
i think the 'position' variable is supposed to provide you with some movement

strip.gamma8(CNT+i * (255 / CNT1))));

pretty sure the CNT+i needs to be within braces

strip.gamma8((CNT+i) * (255 / CNT1))));

but as i stated before i can only remove your obvious mistakes. like

strip.show();
strip.show();   

there is no need to call show() twice in a row.
Just from looking at your sketch, i deduct, you've taken an example and doubled that. (or combined it into itself..)
Now do you know how it works and what variables do what ?

Yeah that's where I'm kinda confused as to where something is wrong.

Changing the delay lower goes to speeds the ring super fast and slowing it down slows the ring circling which is expected.

I just don’t know what I need to do to keep all leds on at the same time.

With the 2 loops you set every led on the ring, but you set them, with the result of getPixelColorHSV()
I never use this builtin function of the neopixel library, but i am pretty sure the first argument is the pixel that is taken as the starting point, in the 2nd iteration of it, this should probably be 'i + CNT' not just 'i' (hmm missed that the 1st time...)

strip.setPixelColor(CNT+(i + position) % CNT1, getPixelColorHsv(i + CNT, 1000, 255, strip.gamma8(CNT+i * (255 / CNT1))));

any idea what the other arguments to that function are ?
and to gamma8() ? what does that function do.
The mathematics are universal, but these functions return values and take arguments, to figure out what is going on we need to know what the arguments are and how the return value is created (optional) and what it represents.

Not sure. All I can say is I have it working the way I want it here just without the colors:

  timer = millis();      
  position = 0;
  while (millis() - timer < 1000) {   
    for (int i = 0; i < CNT; i++)    
      strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 255, 10));
    for (int i = CNT; i < CNT + CNT1; i++)   
      strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 50, 10));
    strip.show();
    strip.show();                     
    position++;                      
    position %= (CNT + CNT1);                 
    delay(90);                        

But not working here with the colors only the movement:

  timer = millis();     
  position = 0;
  while (millis() - timer < 1000) {    
    for (int i = 0; i < CNT; i++)   
      strip.setPixelColor((i + position) % CNT, getPixelColorHsv(i, 0, 255, strip.gamma8(i * (255 / CNT))));
    for (int i = CNT; i < CNT + CNT1; i++) 
      strip.setPixelColor(CNT+(i + position) % CNT1, getPixelColorHsv(i, 1000, 255, strip.gamma8(CNT+i * (255 / CNT1))));
    strip.show();
    strip.show();                      
    position++;                        
    position %= (CNT + CNT1);                
    delay(50);                        
  }

And with all the comparisons I'm doing I still can't match it.

In your first code, you don't actually separate the rings, the roll over into each other.

(i + position) % (CNT + CNT1)

unless we know what the functions do we are just guessing.
We should probably look in either the library documentation or the library itself.
Maybe comments in the examples will give us more of a clue...

Does this help?

void playAnimation2() {
  int position = 0;                           //Setting start position to 0
  unsigned long timer = millis();      //Intialize timer

  timer = millis();      //Intialize timer
  position = 0;
  while (millis() - timer < 10000) {    //Execute the rainbow animation rotation for 5 seconds
    for (int i = 0; i < CNT; i++)    //Execute for total number of leds
      strip.setPixelColor((i + position) % CNT, getPixelColorHsv(i, 200, 255, strip.gamma8(i * (200 / CNT))));
    for (int i = CNT; i < CNT + CNT1; i++)   //Execute for total number of leds
      strip.setPixelColor(CNT+(i + position) % CNT1, getPixelColorHsv(i + CNT, 3000, 255, strip.gamma8(CNT+i * (255 / CNT1)));
    strip.show();                      //Set the led stripe color
    position++;                        //Increment position
    position %= (CNT + CNT1);                 //Max value of position is less than total pixel in our case 0-23
    delay(1000);                         //Wait for 50milli seconds
  }

  timer = millis();      //Intialize timer
  position = 0;
  while (millis() - timer < 1000) {    //Execute the rainbow animation rotation for 5 seconds
    for (int i = 0; i < CNT; i++)    //Execute for total number of leds
      strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 255, 10));
    for (int i = CNT; i < CNT + CNT1; i++)   //Execute for total number of leds
      strip.setPixelColor((i + position) % (CNT + CNT1), getPixelColorHsv(i, i * (MAXHUE / (CNT + CNT1)), 50, 10));
    strip.show();
    strip.show();                      //Set the led stripe color
    position++;                        //Increment position
    position %= (CNT + CNT1);                 //Max value of position is less than total pixel in our case 0-23
    delay(90);                         //Wait for 50milli seconds
  }

  for (int x = 0; x < 5; x++) {               //Rainbow fading
    for (int i = 0; i < CNT; i++)    //Execute for total number of leds
      strip.setPixelColor((i + position) % CNT, getPixelColorHsv(i, 0, 255, strip.gamma8(i * (255 / CNT))));
    for (int i = CNT; i < CNT + CNT1; i++)   //Execute for total number of leds
      strip.setPixelColor(CNT+(i + position) % CNT1, getPixelColorHsv(i, 1000, 255, strip.gamma8(CNT+i * (255 / CNT1))));
    strip.show();
    strip.show();
    position++;                        //Increment position
    position %= (CNT + CNT1);
    delay(100);
  }

@flashinglights226

I think, not sure, but I think your biggest issue is that you have not really explained what you want the lights to do. You keep waving broken code around, but really, the important bit is. What do you actually want? Stop trying to think like a coder, think like a.. Designer and tell us about the lights.

-jim lee

I want the lights to move while all remaining fully lit. Different colors for both rings.

Back and forth? Around and around? Up and down? Vibrating?

-jim lee