Random fade animation & coulour change

Hi,

I am new to programming and I would really appreciate some help.
I'm a costume designer and I made a dress with optic fiber.

I have an Arduino Gemma chip with 4 Neopixels working, however I would like a different animation. The show is next week so I am very close to the deadline.

I would like the 4 LEDs to fade separate and random from each other and randomly change colour between 4 different set colours. It should kinda create a sparkle/twinkle effect in the dress.

Could someone help me please?

Colours:

RGB
100, 200, 255 Blue
255, 250, 170 Yellow
255, 170, 255 Pink
255, 255, 255 White

The idea but it needs to be a bit slower:

Thank you!

Twan

I'm not familiar with the neopixel library or the gemma.

Would it be any use to you to have some code that worked by calling a function named "setNeopixelColor(int n, int r, int g, int b)", and it's up to you to write that function so as to get the colours out to the neopixels?

To put it another way - you have an existing animation. Do you have code for that? It might be reasonably easy to hack it up to do what you want, even without having the hardware.

Hi,

Thanks for your reply.

I've got this on there at the moment:

void rgbFadeInAndOut(uint8_t red, uint8_t green, uint8_t blue, uint8_t wait) {
for(uint8_t b = 180; b <255; b++) {
for(uint8_t i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, red * b/255, green * b/255, blue * b/255);
}
strip.show();
delay(wait);
};
for(uint8_t b=255; b > 179; b--) {
for(uint8_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, red * b/255, green * b/255, blue * b/255);
}
strip.show();
delay(wait);
};
};

I changed the colour to a pink colour. But it just fades in and out simultaneous right now and stays the same colour.

I know this is a bit of code to set up the fav colours:

#include <Adafruit_NeoPixel.h>

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_RGB Pixels are wired for RGB bitstream
// NEO_GRB Pixels are wired for GRB bitstream
// NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels)
// NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(6, 6, NEO_GRB + NEO_KHZ800);
Adafruit_LSM303 lsm;

// Here is where you can put in your favorite colors that will appear!
// just add new {nnn, nnn, nnn}, lines. They will be picked out randomly
// R G B
uint8_t myFavoriteColors[][3] = {{200, 0, 200}, // purple
{200, 0, 0}, // red
{200, 200, 200}, // white
};
// don't edit the line below
#define FAVCOLORS sizeof(myFavoriteColors) / 3

And this is to call a colour I think but I really don't know enough about it:

void flashRandom(int wait, uint8_t howmany) {

for(uint16_t i=0; i<howmany; i++) {
// pick a random favorite color!
int c = random(FAVCOLORS);
int red = myFavoriteColors

[0];
    int green = myFavoriteColors[c][1];
    int blue = myFavoriteColors[c][2]; 
 
    // get a random pixel from the list
    int j = random(strip.numPixels());
    //Serial.print("Lighting up "); Serial.println(j); 
    
    // now we will 'fade' it in 5 steps
    for (int x=0; x < 5; x++) {
      int r = red * (x+1); r /= 5;
      int g = green * (x+1); g /= 5;
      int b = blue * (x+1); b /= 5;
      
      strip.setPixelColor(j, strip.Color(r, g, b));
      strip.show();
      delay(wait);
    }
    // & fade out in 5 steps
    for (int x=5; x >= 0; x--) {
      int r = red * x; r /= 5;
      int g = green * x; g /= 5;
      int b = blue * x; b /= 5;
      
      strip.setPixelColor(j, strip.Color(r, g, b));
      strip.show();
      delay(wait);
    }
  }
  // LEDs will be off when done (they are faded to 0)
}

Thanks

Ok, man. I have done up a bit of a thing, FWIW. Haven't tested it or anything, but it does compile.

You will need to insert into this sketch your setup() for the neopixels, and you will want to replace the calls to my dummy function setPixelColor with calls to the actual strip.setPixelColor .

Source code is also on github at PaulMurrayCbr/arduino_topic_363073 .

If it works, Karma me! Or Karma me anyway, just for the example code :slight_smile: .

// we want to randomly select from these colours

const int COLOURS[][3] = {
{100, 200, 255}, //Blue
{255, 250, 170}, //Yellow
{255, 170, 255}, //Pink
{255, 255, 255} //White
};

const int NCOLOURS = sizeof(COLOURS) / sizeof(*COLOURS);

// this structure holds the state of the given pixel

struct PixelState {
  // is the pixel currently on
  boolean on;
  // time at which the pixel was turned on or off
  unsigned long timeMarkMs;
  // amount of time for which the pixel should remain off
  unsigned long offTimeMs;
  // selected colout if the pixel is on
  int selectedColour;
  // most recent max brightness. We keep this to stop us
  // sending colour changes to the pixels if it is unnecessary
  // this is important, because neopixels use a timing-based protocol
  int mostRecentBrightness;
};

// we have 4 pixels

const int NPIXELS = 4;
struct PixelState pixel[NPIXELS];

// I want the pixels to sparkle, so I will use a triangle wave, 
// which is to say that they will come on at full brightness and them fade

const unsigned long FADE_TIME_MS = 3000; // three seconds

// the pixels should come on at a random time, To simulate this, 
// the pixel will be off for a random amount of time. 

const int MIN_OFF_TIME_MS = 100;
const int MAX_OFF_TIME_MS = 250;

void setup() {
  for(int i = 0; i<NPIXELS;i++) {
    pixel[i].on = false;
    pixel[i].timeMarkMs = millis();
    pixel[i].offTimeMs = 0;
  }
}

// this is a dummy function. I put it here just to check that the code compiles.
// Replace calls to this function with your
// strip.setPixelColor function
void setPixelColor(int strip, int r, int g, int b) {
}

void loop() {
  for(int i = 0; i< NPIXELS; i++) {
    if(pixel[i].on) {
      // pixel is on
      
      if(millis() - pixel[i].timeMarkMs >= FADE_TIME_MS) {
        // time to turn the pixel off
        setPixelColor(i,0,0,0);
        pixel[i].timeMarkMs = millis();
        pixel[i].offTimeMs = random(MIN_OFF_TIME_MS, MAX_OFF_TIME_MS);
        pixel[i].mostRecentBrightness = 0;
        pixel[i].on = false;
      }
      else {
        // calculate the new brightness as flaoting point
        // this is the bit that you change if you want the fade pattern to change
        float brightness = 1 - (millis() - pixel[i].timeMarkMs)/((float)FADE_TIME_MS);
        
        // ok. do we actually need to change the pixel colour?
        int mostRecentBrightness = 255 * brightness;
        if(mostRecentBrightness != pixel[i].mostRecentBrightness) {
          // yes we do
          pixel[i].mostRecentBrightness = mostRecentBrightness;
          setPixelColor(i,
             (int)(COLOURS[pixel[i].selectedColour][0] * brightness),
             (int)(COLOURS[pixel[i].selectedColour][1] * brightness),
             (int)(COLOURS[pixel[i].selectedColour][2] * brightness)
          );
        }
      }
    }
    else {
      // pixel is off. do we need to turn it on?
      
      if(millis()-pixel[i].timeMarkMs > pixel[i].offTimeMs) {
        pixel[i].on = true;
        pixel[i].mostRecentBrightness = 0; // this will force an update next loop
        pixel[i].selectedColour = random(NCOLOURS);
      }
    }
  }
}

Thank you! I will test it when I get home :slight_smile:
I wish I could test it here at work so I can just work on finishing costumes at home :frowning:

I was playing around with code on a sim and it didn't give any errors, but I doubt it actually works LOL

I will let you know and thank you from the bottom of my heart. This whole costume making took 20 years off my life! :open_mouth:

twananas:
Thank you! I will test it when I get home :slight_smile:

Points to note:

The LEDs will all start when the board is powered up, and will gradually move out of sync and random. Fixing it so that they start out of sync and random from the get-go is pretty easy.

You can alter the timings by fiddling with the constants.
FADE_TIME_MS
MIN_OFF_TIME_MS
MAX_OFF_TIME_MS

Maybe it would look better if they were on for a short time compared to the off time. If you want a different pattern for the brightness - ramping up to full brighness instaead of comming on suddenly or something, that's doable too. One thing that might be very worthwhile is taking the square of the brightness like so:

  float brightness = 1 - (millis() - pixel[i].timeMarkMs)/((float)FADE_TIME_MS);
  brightness =  brightness * brightness;

Taking the square effectively does a gamma correction of 2.

Oh, and altering the colours is just a matter of fiddling with the initializer of the COLOURS array. If you add more blocks, the code will just pick them up.

I'll switch the whole thing on a few minutes before she goes on stage, so it should be fine I guess. Otherwise I will try what you suggested :slight_smile:

I tried replacing the strip.setpixelcolor and then an error comes up?

(sketch file) Blink.ino:66:6: error: variable has incomplete type 'void'
void strip.setPixelColor(int strip, int r, int g, int b) {
^
(sketch file) Blink.ino:66:11: error: expected ';' after top level declarator
void strip.setPixelColor(int strip, int r, int g, int b) {
^
;
2 errors generated.

So I tried this. I probably have to change more than I know. As this has no errors but it's not working:

#include <Adafruit_NeoPixel.h>

#define PIN 1

// Parameter 1 = number of pixels in strip
// Parameter 2 = 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)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(4, PIN, NEO_GRB + NEO_KHZ800);

// we want to randomly select from these colours

const int COLOURS[][3] = {
  {100, 200, 255}, //Blue
  {255, 250, 170}, //Yellow
  {255, 170, 255}, //Pink
  {255, 255, 255} //White
};

const int NCOLOURS = sizeof(COLOURS) / sizeof(*COLOURS);

// this structure holds the state of the given pixel

struct PixelState {
  // is the pixel currently on
  boolean on;
  // time at which the pixel was turned on or off
  unsigned long timeMarkMs;
  // amount of time for which the pixel should remain off
  unsigned long offTimeMs;
  // selected colout if the pixel is on
  int selectedColour;
  // most recent max brightness. We keep this to stop us
  // sending colour changes to the pixels if it is unnecessary
  // this is important, because neopixels use a timing-based protocol
  int mostRecentBrightness;
};

// we have 4 pixels

const int NPIXELS = 4;
struct PixelState pixel[NPIXELS];

// I want the pixels to sparkle, so I will use a triangle wave,
// which is to say that they will come on at full brightness and them fade

const unsigned long FADE_TIME_MS = 3000; // three seconds

// the pixels should come on at a random time, To simulate this,
// the pixel will be off for a random amount of time.

const int MIN_OFF_TIME_MS = 100;
const int MAX_OFF_TIME_MS = 250;

void setup() {
  for (int i = 0; i < NPIXELS; i++) {
    pixel[i].on = false;
    pixel[i].timeMarkMs = millis();
    pixel[i].offTimeMs = 0;

  }
}

// this is a dummy function. I put it here just to check that the code compiles.
// Replace calls to this function with your
// strip.setPixelColor function
void colorWipe(int strip, int r, int g, int b) {
}

void loop() {
  for (int i = 0; i < NPIXELS; i++) {
    if (pixel[i].on) {
      // pixel is on

      if (millis() - pixel[i].timeMarkMs >= FADE_TIME_MS) {
        // time to turn the pixel off
        strip.setPixelColor(i, 0, 0, 0);
        pixel[i].timeMarkMs = millis();
        pixel[i].offTimeMs = random(MIN_OFF_TIME_MS, MAX_OFF_TIME_MS);
        pixel[i].mostRecentBrightness = 0;
        pixel[i].on = false;
      }
      else {
        // calculate the new brightness as flaoting point
        // this is the bit that you change if you want the fade pattern to change
        float brightness = 1 - (millis() - pixel[i].timeMarkMs) / ((float)FADE_TIME_MS);

        // ok. do we actually need to change the pixel colour?
        int mostRecentBrightness = 255 * brightness;
        if (mostRecentBrightness != pixel[i].mostRecentBrightness) {
          // yes we do
          pixel[i].mostRecentBrightness = mostRecentBrightness;
          strip.setPixelColor(i,
                        (int)(COLOURS[pixel[i].selectedColour][0] * brightness),
                        (int)(COLOURS[pixel[i].selectedColour][1] * brightness),
                        (int)(COLOURS[pixel[i].selectedColour][2] * brightness)
                       );
        }
      }
    }
    else {
      // pixel is off. do we need to turn it on?

      if (millis() - pixel[i].timeMarkMs > pixel[i].offTimeMs) {
        pixel[i].on = true;
        pixel[i].mostRecentBrightness = 0; // this will force an update next loop
        pixel[i].selectedColour = random(NCOLOURS);
      }
    }
  }
}

Sorry I just don't know enough to work it out :frowning:

twananas:
Sorry I just don't know enough to work it out :frowning:

I'll have a look when I get home. Unfortunately, my windowbox has fallen down, and I'm playing Guild Ball for the first time tonight. So much to do!

The first thing I do will be to get some serial output from the sketch. I'll temporarily comment out the call to strip.setPixel (because I don't have the hardware), put in Serial.begin, and do a print in the spot where it tries to set the pixel.

If I get a whole bunch of pixel setting output scrolling past, then I'll be asking you for an entire sketch that actually does set the pixels (even though it might not be setting them in the pattern you want). I'll be looking at that "wait" parameter. How important is it?

If I don't get a whole bunch of pixel setting output scrolling past, then I'll be fixing my code :slight_smile: .

Gaaah! Found the error.

After this line

        pixel[i].selectedColour = random(NCOLOURS);

We need a

        pixel[i].timeMarkMs = millis();

Try this:

#include <Adafruit_NeoPixel.h>

#define PIN 1

// Parameter 1 = number of pixels in strip
// Parameter 2 = 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)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(4, PIN, NEO_GRB + NEO_KHZ800);

// we want to randomly select from these colours

const int COLOURS[][3] = {
  {100, 200, 255}, //Blue
  {255, 250, 170}, //Yellow
  {255, 170, 255}, //Pink
  {255, 255, 255} //White
};

const int NCOLOURS = sizeof(COLOURS) / sizeof(*COLOURS);

// this structure holds the state of the given pixel

struct PixelState {
  // is the pixel currently on
  boolean on;
  // time at which the pixel was turned on or off
  unsigned long timeMarkMs;
  // amount of time for which the pixel should remain off
  unsigned long offTimeMs;
  // selected colout if the pixel is on
  int selectedColour;
  // most recent max brightness. We keep this to stop us
  // sending colour changes to the pixels if it is unnecessary
  // this is important, because neopixels use a timing-based protocol
  int mostRecentBrightness;
};

// we have 4 pixels

const int NPIXELS = 4;
struct PixelState pixel[NPIXELS];

// I want the pixels to sparkle, so I will use a triangle wave,
// which is to say that they will come on at full brightness and them fade

const int FADE_TIME_MS = 3000; 

// the pixels should come on at a random time, To simulate this,
// the pixel will be off for a random amount of time.

const int MIN_OFF_TIME_MS = 500;
const int MAX_OFF_TIME_MS = 1500;

void setup() {
  for (int i = 0; i < NPIXELS; i++) {
    pixel[i].on = false;
    pixel[i].timeMarkMs = millis();
    pixel[i].offTimeMs = 0;
  }
}

void loop() {
  for (int i = 0; i < NPIXELS; i++) {
    if (pixel[i].on) {
      // pixel is on

      if (millis() - pixel[i].timeMarkMs >= FADE_TIME_MS) {
        // time to turn the pixel off
        strip.setPixelColor(i, 0, 0, 0);
        pixel[i].timeMarkMs = millis();
        pixel[i].offTimeMs = random(MIN_OFF_TIME_MS, MAX_OFF_TIME_MS);
        Serial.print("off time");
        Serial.print( pixel[i].offTimeMs);
        Serial.println();
        pixel[i].mostRecentBrightness = 0;
        pixel[i].on = false;
      }
      else {
        // calculate the new brightness as flaoting point
        // this is the bit that you change if you want the fade pattern to change
        float brightness = 1 - (millis() - pixel[i].timeMarkMs) / ((float)FADE_TIME_MS);
        brightness = brightness * brightness; //gamma correction

        // ok. do we actually need to change the pixel colour?
        int mostRecentBrightness = 255 * brightness;
        if (mostRecentBrightness != pixel[i].mostRecentBrightness) {
          // yes we do
          pixel[i].mostRecentBrightness = mostRecentBrightness;
          strip.setPixelColor(i,
                        (int)(COLOURS[pixel[i].selectedColour][0] * brightness),
                        (int)(COLOURS[pixel[i].selectedColour][1] * brightness),
                        (int)(COLOURS[pixel[i].selectedColour][2] * brightness)
                       );
        }
      }
    }
    else {
      // pixel is off. do we need to turn it on?

      if (millis() - pixel[i].timeMarkMs > pixel[i].offTimeMs) {
        pixel[i].on = true;
        pixel[i].mostRecentBrightness = 0; // this will force an update next loop
        pixel[i].selectedColour = random(NCOLOURS);
        pixel[i].timeMarkMs = millis();
        strip.setPixelColor(i,
                      COLOURS[pixel[i].selectedColour][0],
                      COLOURS[pixel[i].selectedColour][1],
                      COLOURS[pixel[i].selectedColour][2]
                     );
      }
    }
  }
}

LOL Thanks! I was just about to post what I think it should be including from the things you told me. I have looked at other codes and it seems to work on codebender.cc but that was the same yesterday and in Arduino it didn't work. But I shall see when I get home again :smiley:

#include <Adafruit_NeoPixel.h>

#define PIN 1

// Parameter 1 = number of pixels in strip
// Parameter 2 = 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)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(4, PIN, NEO_GRB + NEO_KHZ800);

// we want to randomly select from these colours

const int COLOURS[][3] = {
  {100, 200, 255}, //Blue
  {255, 250, 170}, //Yellow
  {255, 170, 255}, //Pink
  {255, 255, 255} //White
};

const int NCOLOURS = sizeof(COLOURS) / sizeof(*COLOURS);

// this structure holds the state of the given pixel

struct PixelState {
  // is the pixel currently on
  boolean on;
  // time at which the pixel was turned on or off
  unsigned long timeMarkMs;
  // amount of time for which the pixel should remain off
  unsigned long offTimeMs;
  // selected colout if the pixel is on
  int selectedColour;
  // most recent max brightness. We keep this to stop us
  // sending colour changes to the pixels if it is unnecessary
  // this is important, because neopixels use a timing-based protocol
  int mostRecentBrightness;
};

// we have 4 pixels

const int NPIXELS = 4;
struct PixelState pixel[NPIXELS];

// I want the pixels to sparkle, so I will use a triangle wave,
// which is to say that they will come on at full brightness and them fade

const unsigned long FADE_TIME_MS = 3000; // three seconds

// the pixels should come on at a random time, To simulate this,
// the pixel will be off for a random amount of time.

const int MIN_OFF_TIME_MS = 100;
const int MAX_OFF_TIME_MS = 250;

void setup() {
  for (int i = 0; i < NPIXELS; i++) {
    pixel[i].on = false;
    pixel[i].timeMarkMs = millis();
    pixel[i].offTimeMs = 0;
  strip.begin();                   // Allocate NeoPixel buffer
  strip.clear();                   // Make sure strip is clear
  strip.show();  
  }
}

// this is a dummy function. I put it here just to check that the code compiles.
// Replace calls to this function with your
// strip.setPixelColor function
void colorWipe(int strip, int r, int g, int b) {
}

void loop() {
  for (int i = 0; i < NPIXELS; i++) {
    if (pixel[i].on) {
      // pixel is on

      if (millis() - pixel[i].timeMarkMs >= FADE_TIME_MS) {
        // time to turn the pixel off
        strip.setPixelColor(i, 0, 0, 0);
        pixel[i].timeMarkMs = millis();
        pixel[i].offTimeMs = random(MIN_OFF_TIME_MS, MAX_OFF_TIME_MS);
        pixel[i].mostRecentBrightness = 0;
        pixel[i].on = false;
      }
      else {
        // calculate the new brightness as flaoting point
        // this is the bit that you change if you want the fade pattern to change
        float brightness = 1 - (millis() - pixel[i].timeMarkMs) / ((float)FADE_TIME_MS);
  
   //Serial.print("Lighting up "); Serial.println(j); 
   
        // ok. do we actually need to change the pixel colour?
        int mostRecentBrightness = 255 * brightness;
        if (mostRecentBrightness != pixel[i].mostRecentBrightness) {
          // yes we do
          pixel[i].mostRecentBrightness = mostRecentBrightness;
          strip.setPixelColor(i,
                        (int)(COLOURS[pixel[i].selectedColour][0] * brightness),
                        (int)(COLOURS[pixel[i].selectedColour][1] * brightness),
                        (int)(COLOURS[pixel[i].selectedColour][2] * brightness)
                       );
      strip.show();
      }
      }
    }
    else {
      // pixel is off. do we need to turn it on?

      if (millis() - pixel[i].timeMarkMs > pixel[i].offTimeMs) {
        pixel[i].on = true;
        pixel[i].mostRecentBrightness = 0; // this will force an update next loop
        pixel[i].selectedColour = random(NCOLOURS);
        pixel[i].timeMarkMs = millis();
        
      strip.show();


      }
    }
  }
}

Oh great it works now! Thank you so much!!!
The only thing I would like is for them not to switch off completely but stay at 50 brightness minimum. I couldn't find out how that works.

This is what it does right now. It fades out but then comes back on right away too

Well, to alter the timing, fiddle with the values

const int MIN_OFF_TIME_MS = 100;
const int MAX_OFF_TIME_MS = 250;
const int FADE_TIME_MS = 3000;

They are in milliseconds. Try it with

const int MIN_OFF_TIME_MS = 500;
const int MAX_OFF_TIME_MS = 2000;
const int FADE_TIME_MS = 250;

To have a minimum brightness, easiest way is to express it as an amount between 0 and 1 rather than as a number between 0 and 255.

const float MIN_BRIGHTNESS = 50.0/255.0;

Change this

strip.setPixelColor(i, 0, 0, 0);

To this

strip.setPixelColor(i, 
  (int)(255*MIN_BRIGHTNESS),
  (int)(255*MIN_BRIGHTNESS),
  (int)(255*MIN_BRIGHTNESS));

And after this line

float brightness = 1 - (millis() - pixel[i].timeMarkMs) / ((float)FADE_TIME_MS);

add

brighness = MIN_BRIGHTNESS + brightness / (1-MIN_BRIGHTNESS);

If you would prefer that the LEDs get brighter and dimmer rather than come on suddenly and then fade, after this line

float brightness = 1 - (millis() - pixel[i].timeMarkMs) / ((float)FADE_TIME_MS);

add

brightness = Math.sin(brightness * Math.PI);

to alter the contour.

Even though included the math.h I get this error:

Fairy_fabulous.ino: In function 'void loop()':
Fairy_fabulous:99: error: 'Math' was not declared in this scope
In file included from /Users/Twan/Documents/Arduino/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.h:23:0,
from Fairy_fabulous.ino:2:
/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:47:12: error: expected unqualified-id before numeric constant
#define PI 3.1415926535897932384626433832795
^
Fairy_fabulous.ino:99:49: note: in expansion of macro 'PI'
'Math' was not declared in this scope

#include <Adafruit_NeoPixel.h>
#include <math.h>

#define PIN 1

// Parameter 1 = number of pixels in strip
// Parameter 2 = 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)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(4, PIN, NEO_GRB + NEO_KHZ800);

// we want to randomly select from these colours

const int COLOURS[][3] = {
  {100, 200, 255}, //Blue
  {255, 250, 170}, //Yellow
  {255, 170, 255}, //Pink
  {255, 255, 255} //White
};

const int NCOLOURS = sizeof(COLOURS) / sizeof(*COLOURS);

// this structure holds the state of the given pixel

struct PixelState {
  // is the pixel currently on
  boolean on;
  // time at which the pixel was turned on or off
  unsigned long timeMarkMs;
  // amount of time for which the pixel should remain off
  unsigned long offTimeMs;
  // selected colout if the pixel is on
  int selectedColour;
  // most recent max brightness. We keep this to stop us
  // sending colour changes to the pixels if it is unnecessary
  // this is important, because neopixels use a timing-based protocol
  int mostRecentBrightness;
};

// we have 4 pixels

const int NPIXELS = 4;
struct PixelState pixel[NPIXELS];

// I want the pixels to sparkle, so I will use a triangle wave,
// which is to say that they will come on at full brightness and them fade

const unsigned long FADE_TIME_MS = 2000; // three seconds

// the pixels should come on at a random time, To simulate this,
// the pixel will be off for a random amount of time.

const int MIN_OFF_TIME_MS = 500;
const int MAX_OFF_TIME_MS = 250;
const float MIN_BRIGHTNESS = 50.0/255.0;

void setup() {
  for (int i = 0; i < NPIXELS; i++) {
    pixel[i].on = false;
    pixel[i].timeMarkMs = millis();
    pixel[i].offTimeMs = 0;
  strip.begin();                   // Allocate NeoPixel buffer
  strip.clear();                   // Make sure strip is clear
  strip.show();  
  }
}

// this is a dummy function. I put it here just to check that the code compiles.
// Replace calls to this function with your
// strip.setPixelColor function
void colorWipe(int strip, int r, int g, int b) {
}

void loop() {
  for (int i = 0; i < NPIXELS; i++) {
    if (pixel[i].on) {
      // pixel is on

      if (millis() - pixel[i].timeMarkMs >= FADE_TIME_MS) {
        // time to turn the pixel off
        strip.setPixelColor(i, 
  (int)(255*MIN_BRIGHTNESS),
  (int)(255*MIN_BRIGHTNESS),
  (int)(255*MIN_BRIGHTNESS));
        pixel[i].timeMarkMs = millis();
        pixel[i].offTimeMs = random(MIN_OFF_TIME_MS, MAX_OFF_TIME_MS);
        pixel[i].mostRecentBrightness = 0;
        pixel[i].on = false;
        strip.show();
      }
      else {
        // calculate the new brightness as flaoting point
        // this is the bit that you change if you want the fade pattern to change
        float brightness = 1 - (millis() - pixel[i].timeMarkMs) / ((float)FADE_TIME_MS);
        brightness = Math.sin(brightness * Math.PI);
  
   //Serial.print("Lighting up "); Serial.println(j); 
   
        // ok. do we actually need to change the pixel colour?
        int mostRecentBrightness = 255 * brightness;
        if (mostRecentBrightness != pixel[i].mostRecentBrightness) {
          // yes we do
          pixel[i].mostRecentBrightness = mostRecentBrightness;
          strip.setPixelColor(i,
                        (int)(COLOURS[pixel[i].selectedColour][0] * brightness),
                        (int)(COLOURS[pixel[i].selectedColour][1] * brightness),
                        (int)(COLOURS[pixel[i].selectedColour][2] * brightness)
                       );
      strip.show();
      }
      }
    }
    else {
      // pixel is off. do we need to turn it on?

      if (millis() - pixel[i].timeMarkMs > pixel[i].offTimeMs) {
        pixel[i].on = true;
        pixel[i].mostRecentBrightness = 0; // this will force an update next loop
        pixel[i].selectedColour = random(NCOLOURS);
        pixel[i].timeMarkMs = millis();
        
      strip.show();


      }
    }
  }
}

twananas:
Even though included the math.h I get this error:

Mate, there's a line between "I honestly can't do this" and "I'm not prepared to make any effort". I'm ok about the algorithm, the problem of making lights change with independent timing, I get that that's hard, but correctly calling the "take the sine of a number" function (I wrote the code at work) is a slightly different kettle of fish. We haven't agreed on any money, so I am going to leave it to you to work out how to call sin(). Or you can just leave the code as it was and go with the "on full and fade".

I am sorry you think I don't try to get it to work myself.

With every error I am trying to find out what it is via Google at work. I think I have spend about 10 hours on it this week. Sorry I just don't know nothing about this. At home I have to spend all my time sewing the costumes. When I bought the stuff I needed, I thought it would by fairly easy to find out how this all works but I was wrong and that's why I was asking for help.

Thank you for you help anyway, I appreciate that.

twananas:
I am sorry you think I don't try to get it to work myself.

Apologies from me, too - I had a bad Friday night, and let's leave it at that.

Turns out, you don't need Math.h. the sin function and PI are already defined without including anything.

brightness = sin(brightness * PI);

The code I gave to turn the pixel off (but leave it at minimum brighness)

        strip.setPixelColor(i,
  (int)(255*MIN_BRIGHTNESS),
  (int)(255*MIN_BRIGHTNESS),
  (int)(255*MIN_BRIGHTNESS));

Will always make the pixel colour dim white between colours. One way to go would just be to comment out this setpixel altogether - this will mean that it stays at whatever brighness and colour it was when the other branch of the if() finished, which should be a dim version of one of your colours.

Don't worry. I understand.

I still don't get it working the way I want it and I think I just messed up the chip as well. It's not going into program mode anymore. :frowning:

I'll buy a new one and just use what it is.

Thanks again for all your help!

New chip and working system.

Thanks for all the help again. I hope it well show up well on stage. It's very hard to get it captured on a picture even in the dark. You can see it much better in person. I will use a larger battery to make sure it will last all day.

Light system
Result, nearly finished costume