Neopixel - Make some LEDS solid and others blink

Hello,

Total newbie when it comes to C++ and Arduino programing. I have been able to adapt this code to work on a NodeMCU ESP8266, but I would like to make some improvements upon it, and that's where my skills really die. The first code snippet is an abbreviated version of the full code so that you can have an idea of what is going on(if you want), but I really want to focus on snippet 2 and 3.

// LED variables
const int LEDPin = D7;
const int LEDCount = 172;
//Adafruit_NeoPixel strip(LEDCount, LEDPin, NEO_GRB + NEO_KHZ800);

// Wifi and Server Variables
char ssid[] = "";        // your network SSID (name)
char pass[] = "";    // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;     // the Wifi radio's status
char url[] = "";
WiFiClient client;
bool printWebData = false;

//Four Hour Interval between calls to API
const unsigned long postingInterval = 1000000;

// Used to tell whether to check API again
unsigned long lastConnectionTime = 0;

// initialize LED strip and some commonly used colors
Adafruit_NeoPixel strip(LEDCount, LEDPin, NEO_GRB + NEO_KHZ800);
uint32_t red = strip.Color(127, 0, 0);
uint32_t green = strip.Color(0, 127, 0);
uint32_t blue = strip.Color(0, 0, 128);
uint32_t orange = strip.Color(255, 165, 0);
uint32_t yellow = strip.Color(255, 255, 0);

//variables for parsing the API response and handling which LEDs to light up
boolean foundStart = false;
unsigned int dataCount = 0;
unsigned int pixelNum = 0;

void setup() {

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(125); // Set BRIGHTNESS to about 1/5 (max = 255)

  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  //connect to wifi network
  wifiConnect();

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();

}

void loop() {
  if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status

    // if there are incoming bytes available
    // from the server, read them and print them:
    int len = client.available();
    
    if (len > 0) {
      unsigned char buffer[len];
      if (len > 80) len = 80;
      client.read(buffer, len);
      if (printWebData) {
        Serial.write(buffer, len);
      }
      
      // if headers are still being read
      int i = 0;
      if (!foundStart) {
        for (i; i < len; i++) {
          if (buffer[i] == 2) {
            Serial.println("FOUND WHERE START OF MESSAGE IS");
            foundStart = true;
            i++;
            break;
          }
        }
      }
  
      //once past headers, read the useful data
      if (foundStart) {
        for (int j = i; j < len; j++) {
          Serial.print("j: ");
          Serial.println(j);
          Serial.print("buffer[j]: ");
          Serial.println((char)buffer[j]);
          yield();
          Serial.print("pixelNum: ");
          Serial.println(pixelNum);
          Serial.print("dataCount: ");
          Serial.println(dataCount);
          if (buffer[j] == 48) {
            Serial.println("closed trail");
            // data point for a lift
            if (dataCount == 87 || dataCount == 88 || dataCount == 89 || dataCount == 90 || dataCount == 91 || dataCount == 92 || dataCount == 93) {
              Serial.println("found a lift");
              colorLift(red);
            }
            else {
              strip.setPixelColor(pixelNum, red);
              pixelNum++;
            }
          }
          // trail is open
          else if (buffer[j] == 49) {
            Serial.println("open trail");
            // data point for a lift
            if (dataCount == 87 || dataCount == 88 || dataCount == 89 || dataCount == 90 || dataCount == 91 || dataCount == 92 || dataCount == 93) {
              Serial.println("found a lift");
              colorLift(green);
            }
            else {
              strip.setPixelColor(pixelNum, green);
              pixelNum++;
            }
          }
          else if (buffer[j] == 50) {
            Serial.println("groomed trail");
            // data point for a lift
            if (dataCount == 87 || dataCount == 88 || dataCount == 89 || dataCount == 90 || dataCount == 91 || dataCount == 92 || dataCount == 93) {
              Serial.println("found a lift");
              colorLift(blue);
            }
            else {
              strip.setPixelColor(pixelNum, blue);
              pixelNum++;
            }
          }
          else if (buffer[j] == 52) {
            Serial.println("closed lift");
            // data point for a lift
            if (dataCount == 87 || dataCount == 88 || dataCount == 89 || dataCount == 90 || dataCount == 91 || dataCount == 92 || dataCount == 93) {
              Serial.println("found a lift");
              colorLift(red);
            }
            else {
              strip.setPixelColor(pixelNum, red);
              pixelNum++;
            }
          }
          else if (buffer[j] == 53) {
            Serial.println("open lift");
            // data point for a lift
            if (dataCount == 87 || dataCount == 88 || dataCount == 89 || dataCount == 90 || dataCount == 91 || dataCount == 92 || dataCount == 93) {
              Serial.println("found a lift");
              colorLift(green);
            }
            else {
              strip.setPixelColor(pixelNum, green);
              pixelNum++;
            }
          }
          dataCount++;
          strip.show();
        }
      }
    }

    if (millis() - lastConnectionTime > postingInterval || lastConnectionTime == 0) {
      //reset the variables needed for parsing a response
      foundStart = false;
      pixelNum = 0;
      dataCount = 0;
      if (serverConnect()) {
        strip.clear();
      }
      else {
        Serial.println("Server could not be reached");
      }
    }
  }
  else {
    Serial.print("You were disconnected from the network");
    wifiConnect();
    printCurrentNet();
    printWifiData();
  }
}

void colorLift(uint32_t color) {
  switch (dataCount) {
    case 89:
      Serial.println("89th data point");
      for (pixelNum; pixelNum < 91; pixelNum++) {
        strip.setPixelColor(pixelNum, color);
      }
      break;
    case 90:
      Serial.println("90th data point");
      for (pixelNum; pixelNum < 93; pixelNum++) {
        strip.setPixelColor(pixelNum, color);
      }
      break;
  }
  Serial.print("pixelNum after lift: ");
  Serial.println(pixelNum);
}

Ideally I would love for this section within the code to have a chasing effect for however many cells are defined. In order to avoid have to rewrite the entire strip each time, I was hoping there was a way to just run these specific cells on some sort of a loop.

    case 90:
      Serial.println("90th data point");
      for (pixelNum; pixelNum < 93; pixelNum++) {
        strip.setPixelColor(pixelNum, color);
      }
      break;

Similar to the above one, I would like this section to have the strip.setPixelColor(pixelNum, blue) blink blue rather than just be statically on

          else if (buffer[j] == 50) {
            Serial.println("groomed trail");
            // data point for a lift
            if (dataCount == 87 || dataCount == 88 || dataCount == 89 || dataCount == 90 || dataCount == 91 || dataCount == 92 || dataCount == 93) {
              Serial.println("found a lift");
              colorLift(blue);
            }
            else {
              strip.setPixelColor(pixelNum, blue);
              pixelNum++;
            }
          }

Any assistance with this would be greatly appreciated!

Thanks

In order to avoid have to rewrite the entire strip each time,

You have to send the whole strip at one time. If you only want certain LEDs to change then only set the colours you want to change. If you don’t change a colour with the set colour call then it will be the same as it was list time. Unless you have a call to set all the LEDs. I can’t see one in the code you posted but that is why we ask for the whole code.

Often the error is in the code you don’t post.

Ideally I would love for this section within the code to have a chasing effect for however many cells are defined. In order to avoid have to rewrite the entire strip each time, I was hoping there was a way to just run these specific cells on some sort of a loop.

Could you restate the problem and desired outcome?

Similar to the above one, I would like this section to have the strip.setPixelColor(pixelNum, blue) blink blue rather than just be statically on

One time around turn the leds on, the next time turn them off.

Before connecting to WiFi it is best to use the wiFi.Disconnect() which does 2 things, if connected. Disconnect. AND most importantly, resets the WiFi stack to default values. With corruption of the WiFi stack being one of the most common reasons for WiFi connect issues.

this is not as accurate

 if ((WiFi.status() == WL_CONNECTED))

as this

if ( (wifiClient.connected()) && (WiFi.status() == WL_CONNECTED) )

Grumpy_Mike:
You have to send the whole strip at one time. If you only want certain LEDs to change then only set the colours you want to change. If you don’t change a colour with the set colour call then it will be the same as it was list time. Unless you have a call to set all the LEDs. I can’t see one in the code you posted but that is why we ask for the whole code.

Often the error is in the code you don’t post.

Sorry, I should have clarified. My code works perfectly as is right now, every pixel lights up a solid color depending on the buffer[j] output code . I am just looking to tweak it to alter the pattern. So for instance, if buffer[j] == 50, I want those pixels to blink blue, rather than just be statically blue.

    case 90:[color=#222222][/color]

Serial.println("90th data point");
     for (pixelNum; pixelNum < 93; pixelNum++) {
       strip.setPixelColor(pixelNum, color);
     }
     break;

Similarly, for case 90, I want those specific LEDs identified, in this case only a few pixels, to perform a chase sequence like this https://www.yoctopuce.com/FR/interactive/gif/wave.gif
I hope that helps clarify what I am looking to accomplish.
TIA

Idahowalker:
Before connecting to WiFi it is best to use the wiFi.Disconnect() which does 2 things, if connected. Disconnect. AND most importantly, resets the WiFi stack to default values. With corruption of the WiFi stack being one of the most common reasons for WiFi connect issues.

this is not as accurate

 if ((WiFi.status() == WL_CONNECTED))

as this

if ( (wifiClient.connected()) && (WiFi.status() == WL_CONNECTED) )

Appreciate it . I will look to incorporate that. The reasoning makes sense.

I am seriously concerned about your code:

    int len = client.available();
   
    if (len > 0) {
      unsigned char buffer[len];
      if (len > 80) len = 80;
      client.read(buffer, len);

This would imply re-allocating a buffer on each pass through the loop when data is available. I cannot imagine that actually working, so just what happens if you run that is a mystery - to me at least. :astonished:

To use a buffer array, you set it up before "setup()". Since you want it to be 80 characters, that is fine, set it up at 80 characters. Read only a maximum of 80 characters into it and use "len" to define your manipulation of it, but do not try to dynamically allocate a buffer.

When you initialise a "strip", you are allocating a buffer of the number of pixels times the number of colours per pixel. In RAM, which is why how many pixels you can control is limited by the RAM available. strip.show() writes that buffer in one fell swoop to the NeoPixel string. Do not be confused by the description of "addressable" LEDs; they are not addressable, they are merely a long shift register.

So to blink one or more LEDs it is actually quite simple, you must at each timing interval determined by milllis(), set each pixel in the array to the colour required for that step (which may be black to turn just that pixel off)

   strip.setPixelColor(pixelNum, red);

and once you have defined the set of pixels to change, you execute the strip.show() to set all the pixels according to what is in the buffer array. They will continue to show this pattern until the next strip.show().

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.