My first Blynk and FastLED project

this is my first Blynk project and im not sure if the following code will actually work, as i’m at work for the next week and wont be able to actually run this on hardware to test.

It compiles on arduino IDE but i ask if any of you folks can take a look and see if there is a reason this wouldnt work

Its a single NodeMCU, and 4 LED strip, each with its own data pin, and only 3 states right now. solid fill, 2 color blending, or off.

see code below and let me know if it’ll work as far as you can tell, or if there is any optimization i could be doing. I still fairly new at c++/arduino /Blynk in general

Thanks Folks!

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <FastLED.h>

#define NUM_LEDS 40  //40 LEDS PER STRIP
#define NUM_STRIPS 4 //PC=1, UNDERDESK=2, UNDERDESK2=3, TV=4
#define FASTLED_ESP8266_NODEMCU_PIN_ORDER

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "XXX";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "XXX";
char pass[] = "XXX";

CRGB leds[NUM_STRIPS][NUM_LEDS];

uint8_t gBrightness = 128; //half brightness while testing
int activeStrip = 0; //0 = all, 1 = pc, 2 = underdesk1, 3 = underdesk2, 4 = tv
int stripColor1[NUM_STRIPS][3];//volatile primary color 0 = pc, 1 = underdesk1, 2 = underdesk2, 3 = tv
int stripColor2[NUM_STRIPS][3]; //secondary color for color blend mode
int stripColorSaved1[NUM_STRIPS][3]; //stored primary color
int stripOn[NUM_STRIPS]; //is strip on
int stripState[NUM_STRIPS]; //solidfill or blending
int blendDir = 0; //from primary to secondary or reversed
int fadeTime = 1000; //effect speed

// Helper function that blends one uint8_t toward another by a given amount
void nblendU8TowardU8( uint8_t& cur, const uint8_t target, uint8_t amount)
{
  if( cur == target) return;
  
  if( cur < target ) {
    uint8_t delta = target - cur;
    delta = scale8_video( delta, amount);
    cur += delta;
  } else {
    uint8_t delta = cur - target;
    delta = scale8_video( delta, amount);
    cur -= delta;
  }
}

// Blend one CRGB color toward another CRGB color by a given amount.
// Blending is linear, and done in the RGB color space.
// This function modifies 'cur' in place.
void fadeTowardColor( CRGB& cur, const CRGB& target, uint8_t amount)
{
  nblendU8TowardU8( cur.red,   target.red,   amount);
  nblendU8TowardU8( cur.green, target.green, amount);
  nblendU8TowardU8( cur.blue,  target.blue,  amount);
}

void led_state()
{  
  for(int i=0; i<NUM_STRIPS; i++){
    if(stripState[i] == 0){
      fill_solid(leds[i], NUM_LEDS, CRGB(stripColor1[i][0],stripColor1[i][1],stripColor1[i][2]));
    }
    if (stripState[i] == 1){
      if (leds[i][0] == CRGB(stripColor1[i][0],stripColor1[i][1],stripColor1[i][2])){
        blendDir = 0;
      }
      if (leds[i][0] == CRGB(stripColor2[i][0],stripColor2[i][1],stripColor2[i][2])){
        blendDir = 1;
      }
      if (blendDir == 0){
        for(int x = 0; x , NUM_LEDS; x++){
          fadeTowardColor( leds[i][x], CRGB(stripColor2[i][0],stripColor2[i][1],stripColor2[i][2]), 5);       
        }
      } else {
        for(int x = 0; x < NUM_LEDS; x++){
          fadeTowardColor( leds[i][x],CRGB(stripColor1[i][0],stripColor1[i][1],stripColor1[i][2]), 5);
        }
      }
      FastLED.delay(fadeTime);
    }
  }
}

void setup(){
  Blynk.begin(auth, ssid, pass, IPAddress(0,0,0,0), 8080);
  delay(1000);
  FastLED.addLeds<WS2812,1,GRB>(leds[0], NUM_LEDS);   //D1
  FastLED.addLeds<WS2812,2,GRB>(leds[1], NUM_LEDS);  //D2
  FastLED.addLeds<WS2812,5,GRB>(leds[2], NUM_LEDS); //D5
  FastLED.addLeds<WS2812,6,GRB>(leds[3], NUM_LEDS); //D6
}

void loop(){
  Blynk.run();
  led_state();
  FastLED.setBrightness(gBrightness);
  FastLED.show();
}

BLYNK_CONNECTED(){
  Blynk.syncAll();
}

 //active strip menu widget
BLYNK_WRITE(V1) {
  activeStrip = (param.asInt()-1);
}

//solid or blend
BLYNK_WRITE(V2) {
  stripState[activeStrip] = (param.asInt()-1);
}

//on-off switch widget
BLYNK_WRITE(V3) { 
  stripOn[activeStrip] = param.asInt();
  if (param.asInt() == 0){ //turn off
    memcpy(stripColorSaved1,stripColor1,sizeof(stripColor1)); //save old colors
    if (activeStrip == 0){ // set all to black
      for(int i = 0; i < NUM_STRIPS; i++){
        stripColor1[i][0] = CRGB::Black;
        stripColor1[i][1] = CRGB::Black;
        stripColor1[i][2] = CRGB::Black;
      }
    } else { //set active to black
      stripColor1[activeStrip][0] = CRGB::Black;
      stripColor1[activeStrip][1] = CRGB::Black;
      stripColor1[activeStrip][2] = CRGB::Black;
    }
  } else { //if off, turn back to old color
    if (activeStrip == 0){
      memcpy(stripColor1,stripColorSaved1,sizeof(stripColor1));
    } else {
      stripColor1[activeStrip][0] = stripColorSaved1[activeStrip][0];
      stripColor1[activeStrip][1] = stripColorSaved1[activeStrip][1];
      stripColor1[activeStrip][2] = stripColorSaved1[activeStrip][2];
    }
  }
}

//zeRGBa widget primary color
BLYNK_WRITE(V4) {
  if(stripOn[activeStrip]){ 
    if(activeStrip == 0){
      for(int i = 0; i < NUM_STRIPS; i++){
      stripColor1[i][0] = param[0].asInt();
      stripColor1[i][1] = param[1].asInt();
      stripColor1[i][2] = param[2].asInt();
      }
    }else{
      stripColor1[activeStrip][0] = param[0].asInt();
      stripColor1[activeStrip][1] = param[1].asInt();
      stripColor1[activeStrip][2] = param[2].asInt();
    }
  }
}
//zeRGBa widget secondary color
BLYNK_WRITE(V5) {
  if(stripOn[activeStrip]){ 
    if(activeStrip == 0){
      for(int i = 0; i < NUM_STRIPS; i++){
        stripColor2[i][0] = param[0].asInt();
        stripColor2[i][1] = param[1].asInt();
        stripColor2[i][2] = param[2].asInt();
      }
    }else{
      stripColor2[activeStrip][0] = param[0].asInt();
      stripColor2[activeStrip][1] = param[1].asInt();
      stripColor2[activeStrip][2] = param[2].asInt();
    }
  }
}

//fade speed
BLYNK_WRITE(V6) {
  fadeTime = param.asInt();
}

//fade speed
BLYNK_WRITE(V7) {
  gBrightness = param.asInt();
}

It looks like your led_state function will take some time to execute and you’re calling it every time your void loop executes, along with some other stuff.
That’s not very conducive to Blynk functioning well.

Pete.

1 Like

i could probably trim it down in complexity if i have all strips share the same fill type. Unless theres a simpler way to wite the code so it executes faster or with less iteration