neopixel strip colors from serial input

morning all.
i have an arduino leonardo taking serial input and setting a ws2812 strip color base on the serial input but am getting funky results

program follows

// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library
#include <Adafruit_NeoPixel.h>

// Which pin on the Arduino is connected to the NeoPixels?
#define PIN            4

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS      195
int ctem = 0;
int ro = 0;
int go = 0;
boolean newData = false;

const byte numChars = 32; 
char tempChars[numChars];   
char receivedChars[numChars];
// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


void setup() {
  pixels.begin(); // This initializes the NeoPixel library.
  pixels.show();
// loop through each pixel setting startup color
   for (int p = 0; p < NUMPIXELS; p++) {
 pixels.setPixelColor(p, pixels.Color(0,255,0)); // full bright green color.
}

}

void loop() {




    recvWithStartEndMarkers();
    if (newData == true) {
        strcpy(tempChars, receivedChars);
            // this temporary copy is necessary to protect the original data
            //   because strtok() used in parseData() replaces the commas with \0
        parseData();
        mapcolor(ctem);// map new color to the temp
        updatecolor(); // set new color of strip
        newData = false;
        
}
//loop from 3 to 155 and back setting strip brightness as we go
for (int i=3; i<155; i++) { pixels.setBrightness(i); pixels.show(); delay(5); }

for (int i=155; i>3; i--) { pixels.setBrightness(i); pixels.show(); delay(5); }







 
       // updatecolor();// fallback? incase no new data?

        
      Serial.println(ctem);
       Serial.println(ro);
       Serial.println(go);

}







void updatecolor() {      // update strip color with temperature
 
   for (int p = 0; p < NUMPIXELS; p++) {
 pixels.setPixelColor(p, pixels.Color(ro,go,0)); // full bright green color.
}
pixels.show();
}

void mapcolor(int temp) {      // map temp to color value
    ro = map(temp,35,85,50,255);
    go = map(temp,35,85,255,50);

}




void parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempChars,"|");      // get the first part - the string
    ctem = atoi(strtokIndx);     // convert this part to an integer

}


void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

which seems make the pixels full green when ctem is 0-59
all lights simply go dark when ctem == 60
and then full red for anything from 61 and up

with the serial output as a form of debugging
these are the numbers i get
first number is ctem
second number is ro
and third is go

59
148
157

59
148
157

59
148
157

59
148
157

60
152
153

60
152
153

60
152
153

61
156
149

61
156
149

am i misusing the neopixel library?
from that output it seems that i should be getting the right color gradient… but on the strip i seem to be getting green until it hits 60 then it turns off and turns all red for 61 and higher?

try changingpixels.setPixelColor(p, pixels.Color(ro,go,0)); to simplypixels.setPixelColor(p, ro, go, 0);

so i moved it into a function and updated with your suggestion, dont know how or why i did it like that haha

but same behaviour…
code as it sits now

// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library
#include <Adafruit_NeoPixel.h>


#define PIN            4                           // Which pin on the Arduino is connected to the NeoPixels?


#define NUMPIXELS      195                        // How many NeoPixels are attached to the Arduino?
int ctem = 0;
int ro = 0;
int go = 0;
boolean newData = false;
const byte numChars = 32; 
char tempChars[numChars];   
char receivedChars[numChars];


                                                  // When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
                                                  // Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
                                                 // example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


void setup() {
  pixels.begin();                                 // This initializes the NeoPixel library.
  pixels.show();  
  for (int p = 0; p < NUMPIXELS; p++) {
      pixels.setPixelColor(p, 0, 255, 0);       // full bright green color.
  }
}


void loop() {
  checkdata();// check for new input

                                                //loop from 3 to 155 and back setting strip brightness as we go
  for (int i=3; i<155; i++) { pixels.setBrightness(i); pixels.show(); delay(5); }
  for (int i=155; i>3; i--) { pixels.setBrightness(i); pixels.show(); delay(5); }

                                                //debugging
  Serial.println(ctem);
  Serial.println(ro);
  Serial.println(go);
            }

void checkdata(){
  recvWithStartEndMarkers();
  if (newData == true) {
    strcpy(tempChars, receivedChars);
                                                // this temporary copy is necessary to protect the original data
                                                //   because strtok() used in parseData() replaces the commas with \0
    parseData();
    mapcolor(ctem);                             // map new color to the temp
    updatecolor();                              // set new color of strip
    newData = false;
    }
    //not needed   updatecolor();               // fallback? incase no new data?
}


void updatecolor() {                           // update strip color with temperature
  for (int p = 0; p < NUMPIXELS; p++) {
    pixels.setPixelColor(p, ro, go, 0);       // full bright green color.
  }
  pixels.show();
}


void mapcolor(int temp) {                     // map temp to color value
    ro = map(temp,35,85,50,255);
    go = map(temp,35,85,255,50);
}


void parseData() {                            // split the data into its parts
  char * strtokIndx;                          // this is used by strtok() as an index
  strtokIndx = strtok(tempChars,"|");         // get the first part - the string
  ctem = atoi(strtokIndx);                    // convert this part to an integer
}


void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0';        // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }
        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

ok . so i have the color changing with the temp…
i think the combination of setpixel.color and setpixel.brightness was causing the issue
so i have the color scaling with the temperature exactly how i want it with a cutoff to just drive all red
but how can i animate this into a breathing effect?

// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library
#include <Adafruit_NeoPixel.h>


#define PIN            4                           // Which pin on the Arduino is connected to the NeoPixels?


#define NUMPIXELS      195                        // How many NeoPixels are attached to the Arduino?
int ctem = 0;
int ro = 0;
int go = 0;
boolean newData = false;
const byte numChars = 32; 
char tempChars[numChars];   
char receivedChars[numChars];


                                                  // When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
                                                  // Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
                                                 // example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


void setup() {
  pixels.begin();                                 // This initializes the NeoPixel library.
  pixels.show();  
  for (int p = 0; p < NUMPIXELS; p++) {
      pixels.setPixelColor(p, 0, 255, 0);       // full bright green color.
  }
}


void loop() {
  checkdata();// check for new input
//   
if (ctem > 80){
  ro = 255;
  go = 0;
  
}
  for (int i=3; i<155; i++) {   for (int p = 0; p < NUMPIXELS; p++) {pixels.setPixelColor(p, ro,go,0); } pixels.show(); delay(5); }
  for (int i=155; i>3; i--) {   for (int p = 0; p < NUMPIXELS; p++) {pixels.setPixelColor(p, ro,go,0); }pixels.show(); delay(5); }



//loop from 3 to 155 and back setting strip brightness as we go
//  for (int i=3; i<155; i++) { pixels.setBrightness(i); pixels.show(); delay(5); }
//  for (int i=155; i>3; i--) { pixels.setBrightness(i); pixels.show(); delay(5); }

                                                //debugging
  Serial.println(ctem);
  Serial.println(ro);
  Serial.println(go);
            }

void checkdata(){
  recvWithStartEndMarkers();
  if (newData == true) {
    strcpy(tempChars, receivedChars);
                                                // this temporary copy is necessary to protect the original data
                                                //   because strtok() used in parseData() replaces the commas with \0
    parseData();
    mapcolor(ctem);                             // map new color to the temp
  //  updatecolor();                              // set new color of strip
    newData = false;
    }
    //not needed   updatecolor();               // fallback? incase no new data?
}


//void updatecolor() {                           // update strip color with temperature
 // for (int p = 0; p < NUMPIXELS; p++) {
//pixels.setPixelColor(p, ro, go, 0);       // full bright green color.
 // }
//pixels.show();
//}


void mapcolor(int temp) {                     // map temp to color value
    ro = map(temp,15,80,0,255);
    go = map(temp,15,80,255,0);
    
}


void parseData() {                            // split the data into its parts
  char * strtokIndx;                          // this is used by strtok() as an index
  strtokIndx = strtok(tempChars,"|");         // get the first part - the string
  ctem = atoi(strtokIndx);                    // convert this part to an integer
}


void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0';        // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }
        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

this gives original behaviour of green at low, off in the middle, and red after 65 or so

for (int p = 0; p < NUMPIXELS; p++) {pixels.setPixelColor(p, ro,go,0); }
pixels.show();

//loop from 3 to 155 and back setting strip brightness as we go
  for (int i=3; i<155; i++) { pixels.setBrightness(i); pixels.show(); delay(5); }
  for (int i=155; i>3; i--) { pixels.setBrightness(i); pixels.show(); delay(5); }

this gives me the color going with temperature perfectly… i just need to figure how to animate it

  for (int i=3; i<155; i++) {   for (int p = 0; p < NUMPIXELS; p++) {pixels.setPixelColor(p, ro,go,0); } pixels.show(); delay(5); }
  for (int i=155; i>3; i--) {   for (int p = 0; p < NUMPIXELS; p++) {pixels.setPixelColor(p, ro,go,0); }pixels.show(); delay(5); }

i was thinking something like

  for (int i=3; i<ro; i++) {   for (int p = 0; p < NUMPIXELS; p++) {pixels.setPixelColor(p, ro,go,0); } pixels.show(); delay(5); }

  for (int i=155; i>3; i--) {   for (int p = 0; p < NUMPIXELS; p++) {pixels.setPixelColor(p, ro,go,0); }pixels.show(); delay(5); }

so that it would “breathe” from 0 to the max brightness for each channel but i cant figure how to do the loop to count ro going up and setting the first value of each pixel as it goes whilst simultaneously doing the same in reverse for the second parameter

nevermind :slight_smile: got back to it fresh and found a solution
my head hurts but i think im getting better :slight_smile:

see youtube for for final result

// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library
#include <Adafruit_NeoPixel.h>


#define PIN            4                           // Which pin on the Arduino is connected to the NeoPixels?


#define NUMPIXELS      195                        // How many NeoPixels are attached to the Arduino?
int ctem = 0;
int ro = 0;
int go = 0;
int green = 0;
boolean newData = false;
const byte numChars = 32; 
char tempChars[numChars];   
char receivedChars[numChars];


                                                  // When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
                                                  // Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
                                                 // example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


void setup() {
  pixels.begin();                                 // This initializes the NeoPixel library.
  pixels.show();  
  for (int p = 0; p < NUMPIXELS; p++) {
      pixels.setPixelColor(p, 0, 255, 0);       // full bright green color.
  }
}


void loop() {
  checkdata();// check for new input
//   
if (ctem > 80){
  ro = 255;
  go = 1;
  
}
  for (int i=0; i<ro; i++) {
    for (int p = 0; p < NUMPIXELS; p++) {
    //    go = map(temp,15,80,255,0);
      green = map(i, 0, ro,0, go);
      pixels.setPixelColor(p, i,green,0); 
      }
      pixels.show(); delay(0); 
  
  //Serial.println("brighter");
 // Serial.println(ctem);
//Serial.println(i);
 // Serial.println(green);
      }
 
 
  for (int i=ro; i>0; i--) { 
   for (int p = 0; p < NUMPIXELS; p++) {

    green = map(i, 0, ro,0, go);
    pixels.setPixelColor(p, i,green,0);
    }
    pixels.show(); delay(0);

  //Serial.println("dimmer");  
 // Serial.println(ctem);
//  Serial.println(i);
 // Serial.println(green);
    }

  

// for (int p = 0; p < NUMPIXELS; p++) {pixels.setPixelColor(p, ro,go,0); }
// pixels.show();

//loop from 3 to 155 and back setting strip brightness as we go
//  for (int i=3; i<155; i++) { pixels.setBrightness(i); pixels.show(); delay(5); }
//  for (int i=155; i>3; i--) { pixels.setBrightness(i); pixels.show(); delay(5); }

                                                //debugging
 // Serial.println(ctem);
 // Serial.println(ro);
// Serial.println(go);
            }

void checkdata(){
  recvWithStartEndMarkers();
  if (newData == true) {
    strcpy(tempChars, receivedChars);
                                                // this temporary copy is necessary to protect the original data
                                                //   because strtok() used in parseData() replaces the commas with \0
    parseData();
    mapcolor(ctem);                             // map new color to the temp
  //  updatecolor();                              // set new color of strip
    newData = false;
    }
    //not needed   updatecolor();               // fallback? incase no new data?
}


//void updatecolor() {                           // update strip color with temperature
 // for (int p = 0; p < NUMPIXELS; p++) {
//pixels.setPixelColor(p, ro, go, 0);       // full bright green color.
 // }
//pixels.show();
//}


void mapcolor(int temp) {                     // map temp to color value
    ro = map(temp,15,80,0,255);
    go = map(temp,15,80,255,0);
    
}


void parseData() {                            // split the data into its parts
  char * strtokIndx;                          // this is used by strtok() as an index
  strtokIndx = strtok(tempChars,"|");         // get the first part - the string
  ctem = atoi(strtokIndx);                    // convert this part to an integer
}


void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0';        // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }
        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}