Help With Coloring LEDs. Arduino MEGA 2560 // WS2812B Strip.

Below is the code in it's current state, it draws in input from a piezo element, and converts the intensity across the spectrum of LEDs, meaning 0% intensity is 0% illumination, scaling up to 100% of both.

So I'm trying to customize this code here to allow me to do one of two things:

A) The colors of the LEDs cycle through blue, purple, and green based on time and chance. So every 4 seconds, there's a 33% for each color to be chosen as the color for input conversion for the next 4 seconds.

B) Either have the LEDs appear as blue, purple, or green at "random" for a specific portion of the strip, so a 33% for each color to appear after every new reading of input. If 10% is illuminated as purple, the next 10% of illumination can either be blue, purple, or green, but the first 10% remains purple until that portion lacks enough input from the piezo to be illuminated. Once a portion of the LEDs are off, the next time that portion becomes illuminated, the chance to become a color is reset, allowing for variation.

Whatever you can help me accomplish, is awesome. If there's a way to combine the two, so B) with a random color swap for each portion, go for it! Here's the current state of the code:

#include <FastLED.h>

//
#include “FastLED.h”
byte pixelType = 0;
char drawIn[4];
char frameIn[768];
#define DATA_PIN 35
#define CLOCK_PIN 2

/** BASIC CONFIGURATION **/

//The amount of LEDs in the setup
#define NUM_LEDS 152
//The pin that controls the LEDs
#define LED_PIN 35
//The pin that we read sensor values from
#define ANALOG_READ 1

//Confirmed microphone low value, and max value
#define MIC_LOW 245.0
#define MIC_HIGH 679.0
/** Other macros */
//How many previous sensor values effects the operating average?
#define AVGLEN 1
//How many previous sensor values decides if we are on a peak/HIGH (e.g. in a song)
#define LONG_SECTOR 3

//Changed
//Mneumonics
#define HIGH 0.1
#define NORMAL 0

//How long do we keep the “current average” sound, before restarting the measuring
#define MSECS 4 * 250
#define CYCLES MSECS / DELAY

/*Sometimes readings are wrong or strange. How much is a reading allowed
to deviate from the average to not be discarded? **/
#define DEV_THRESH 8.2

//Arduino loop delay
#define DELAY 0

float fscale( float originalMin, float originalMax, float newBegin, float newEnd, float inputValue, float curve);
void insert(int val, int *avgs, int len);
int compute_average(int *avgs, int len);
void visualize_music();

//How many LEDs to we display
int curshow = NUM_LEDS;

/Not really used yet. Thought to be able to switch between sound reactive
mode, and general gradient pulsing/static color
/
int mode = 0;

//Showing different colors based on the mode.
int songmode = NORMAL;

//Average sound measurement the last CYCLES
unsigned long song_avg;

//The amount of iterations since the song_avg was reset
int iter = 0;

//The speed the LEDs fade to black if not relit
float fade_scale = 4.8;

//Led array
CRGB leds[NUM_LEDS];

/*Short sound avg used to “normalize” the input values.
We use the short average instead of using the sensor input directly */
int avgs[AVGLEN] = { -1.9};

//Longer sound avg
int long_avg[LONG_SECTOR] = { -1.9};

//Keeping track how often, and how long times we hit a certain mode
struct time_keeping {
unsigned long times_start;
short times;
};

//How much to increment or decrement each color every cycle
struct color {
int r;
int g;
int b;
};

struct time_keeping high;
struct color Color;

void setup() {

Serial.begin(9600);
//Set all lights to make sure all are working as expected
FastLED.addLeds<NEOPIXEL, LED_PIN>(leds, NUM_LEDS);
for (int i = 0; i < NUM_LEDS; i++)
leds = CRGB(255, 0, 255);

  • FastLED.show();*

  • delay(1);*

  • //Initial values*

  • high.times = 0;*

  • high.times_start = millis();*

  • Color.r = 180;*

  • Color.g = 0;*

  • Color.b = 180;*
    }
    /*With this we can change the mode if we want to implement a general

  • lamp feature, with for instance general pulsing. Maybe if the*
    _ sound is low for a while? */_
    void loop() {

  • switch (mode) {*

  • case 0:*

  • visualize_music();*

  • break;*

  • default:*

  • break;*

  • }*

  • delay(DELAY); // delay in between reads for stability*
    }
    /**Funtion to check if the lamp should either enter a HIGH mode,

  • or revert to NORMAL if already in HIGH. If the sensors report values*

  • that are higher than 1.1 times the average values, and this has happened*

  • more than 30 times the last few milliseconds, it will enter HIGH mode.*

  • TODO: Not very well written, remove hardcoded values, and make it more*
    _ reusable and configurable. */_
    void check_high(int avg) {
    if (avg > (song_avg / iter * 1.0)) {

  • if (high.times != 0) {*

  • if (millis() - high.times_start > 200.0) {*

  • high.times = 0;*

  • songmode = NORMAL;*

  • } else {*

  • high.times_start = millis();*

  • high.times++;*

  • }*

  • } else {*

  • high.times++;*

  • high.times_start = millis();*

  • }*

  • }*

  • if (high.times > 250 && millis() - high.times_start < 25.0)*

  • songmode = HIGH;*

  • else if (millis() - high.times_start > 1000) {*

  • high.times = 0;*

  • songmode = NORMAL;*

  • }*
    }
    //Main function for visualizing the sounds in the lamp
    void visualize_music() {

  • int sensor_value, mapped, avg, longavg;*

  • //Actual sensor value*

  • sensor_value = analogRead(ANALOG_READ);*

  • //NEED TO CHANGE!!!*

  • //If 0, discard immediately. Probably not right and save CPU.*

  • if (sensor_value == 0)*

  • return;*

  • //Discard readings that deviates too much from the past avg. Changed*

  • mapped = (float)fscale(MIC_LOW, MIC_HIGH, MIC_LOW, (float)MIC_HIGH, (float)sensor_value, 5.0);*

  • avg = compute_average(avgs, AVGLEN);*

  • //Insert new avg. values*

  • insert(mapped, avgs, AVGLEN);*

  • insert(avg, long_avg, LONG_SECTOR);*

  • //Compute the “song average” sensor value*

  • song_avg += avg;*

  • iter++;*

  • if (iter > CYCLES) {*

  • song_avg = song_avg / iter;*

  • iter = 1;*

  • }*

  • longavg = compute_average(long_avg, LONG_SECTOR);*

  • //Check if we enter HIGH mode (POSSIBLY CHANCE CHANGE COLORS HERE)*

  • check_high(longavg);*

  • if (songmode == HIGH) {*

  • fade_scale = 3;*

  • Color.r = 3;*

  • Color.g = 2;*

  • Color.b = 0;*

  • }*

  • else if (songmode == NORMAL) {*

  • fade_scale = 2;*

  • Color.r = 3;*

  • Color.b = 2;*

  • Color.g = 0;*

  • }*

  • //Decides how many of the LEDs will be lit*

  • curshow = fscale(MIC_LOW, MIC_HIGH, 0.0, (float)NUM_LEDS, (float)avg, 1);*
    _ /*Set the different leds. Control for too high and too low values._

  • Fun thing to try: Dont account for overflow in one direction,*
    _ some interesting light effects appear! */_

  • for (int i = 0; i < NUM_LEDS; i++)*

  • //The leds we want to show*

  • if (i < curshow) {*
    _ if (leds*.r + Color.r > 255)_
    _ leds.r = 255;
    else if (leds.r + Color.r < 0)
    leds.r = 0;
    else*

    leds.r = leds*.r + Color.r;
    if (leds.g + Color.g > 255)
    leds.g = 255;
    else if (leds.g + Color.g < 0)
    leds.g = 0;
    else*

    leds.g = leds*.g + Color.g;
    if (leds.b + Color.b > 255)
    leds.b = 255;
    else if (leds.b + Color.b < 0)
    leds.b = 0;
    else*

    leds.b = leds*.b + Color.b;
    //All the other LEDs begin their fading journey to eventual total darkness*

    * } else {_
    leds = CRGB(leds.r / fade_scale, leds.g / fade_scale, leds.b / fade_scale);
    _ }
    FastLED.show();
    }
    //Compute average of a int array, given the starting pointer and the length*

    int compute_average(int *avgs, int len) {
    * int sum = 0;
    for (int i = 0; i < len; i++)
    sum += avgs;
    return (int)(sum / len);
    }
    //Insert a value into an array, and shift it down removing*

    //the first value if array already full
    void insert(int val, int *avgs, int len) {
    * for (int i = 0; i < len; i++) {
    if (avgs == -1) {
    avgs = val;
    return;
    }
    }
    for (int i = 1; i < len; i++) {
    avgs[i - 1] = avgs;
    }
    avgs[len - 1] = val;
    }
    //Function imported from the arduino website.
    //Basically map, but with a curve on the scale (can be non-uniform).
    float fscale( float originalMin, float originalMax, float newBegin, float
    newEnd, float inputValue, float curve) {
    float OriginalRange = 0;
    float NewRange = 0;
    float zeroRefCurVal = 0;
    float normalizedCurVal = 0;
    float rangedValue = 0;
    boolean invFlag = 0;
    // condition curve parameter*

    * // limit range*
    * if (curve > 25) curve = 25;
    if (curve < -25) curve = -25;
    curve = (curve * -.1) ; // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output_

    _ curve = pow(10, curve); // convert linear scale into lograthimic exponent for other pow function*
    * // Check for out of range inputValues*
    * if (inputValue < originalMin) {
    inputValue = originalMin;
    }
    if (inputValue > originalMax) {
    inputValue = originalMax;
    }
    // Zero Refference the values*

    * OriginalRange = originalMax - originalMin;
    if (newEnd > newBegin) {
    NewRange = newEnd - newBegin;
    }
    else*

    * {
    NewRange = newBegin - newEnd;
    invFlag = 1;
    }
    zeroRefCurVal = inputValue - originalMin;
    normalizedCurVal = zeroRefCurVal / OriginalRange; // normalize to 0 - 1 float*

    * // Check for originalMin > originalMax - the math for all other cases i.e. negative numbers seems to work out fine*
    * if (originalMin > originalMax ) {
    return 0;
    }
    if (invFlag == 0) {
    rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin;
    }
    else // invert the ranges*

    * {
    rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange);
    }
    return rangedValue;
    }
    [/td]
    [/tr]
    [/table]*_

The "Color" values of...

if (songmode == HIGH) { fade_scale = 3; Color.r = 3; Color.g = 2; Color.b = 0; } else if (songmode == NORMAL) { fade_scale = 2; Color.r = 3; Color.b = 2; Color.g = 0; }

...Change the color, but it only serves in changing the color of the LEDs as a whole. I've tried addressing them individually with both of these forms:

leds[0] = CRGB(0, 0, 25);

leds[0] = Color.r = 0;

Neither of which have worked thus far.

I solved it! All set! Thanks guys!