Blynk and neopixel fade

Which part the hue slider?

The HSV function is expecting a 16 bit value for hue. So You’d need to update the slider settings in blynk app to output values from 0-65535. Then you read the value just like you do in your BLYNK_WRITE function with “uint16_t hue = parma.asInt();”. Except I’d declare hue as a global variable so you can use it outside the BLYNK_WRITE function. Declare a rgbcolor variable globally as well like this…

uint32_t rgbcolor = 0;

Then inside the BLYNK_WRITE function you would do he following:

1.) Get the new hue from slider:
hue = parma.asInt();

2.) set the strip to the new color;
rgbcolor = strip.ColorHSV(hue, saturation, value);
strip.fill(rgbcolor);

Note: You can use 255 for full saturation for now or create another slider from 0-255 for that. Less saturation washes the color out with more white. Zero saturation is white.

When doing the fading you just need to go from “value” = 0 (off) to “value” = 255 (full brightness) with the same 2 lines as item 2 above. This should be done in your main loop.

Oh and your “value” variable should be declared globally as well.

Thank you so much for all the help so far
But in that case I would use 3 sliders?
One for each color?
And how would I do this being that all leds are controlled by the same D4 pin?

Give me a little time and I can send you some tested code to show you what I’m talking about. It’s one slider for color. Hue is a single value representing all 3 values of (red,green,blue). So it would only be one slider for color. Maybe another for saturation depending on what you’re doing.

Try this code. You will have to make a single slider for Hue that uses Virtual pin V2 (or change it to whatever virtual pin you want) in your App. Edit the output of the slider to go from 0 to 65535 in the blynk app. You will also need to input you auth, ssid, and pass into the code.

One thing you will notice is that the dimming and brightening will not seem linear. That’s due to the way or eyes see light. There is a way to correct for this but it takes more code.

I also changed how your fade function is called so that it’s not blocking Blynk.run() from being called. It uses a timestamp and the millis() function to see if it’s time to adjust the brightness. Hopefully that all makes sense. The “TIMESTEP” is how often the brightness is adjusted. It’s similar to your delay.

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

#include <Adafruit_NeoPixel.h>
#include <SPI.h>

const char* ssid = "";
const char* pass = "";

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

#define PIN 4
#define NUMPIXELS 7
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


#define TIMESTEP 25
uint16_t hue = 0;
uint32_t rgbcolor = 0;
uint8_t saturation = 255;
uint8_t value = 255;
boolean step_number = 1;
unsigned long TIMESTAMP = 0;


BLYNK_WRITE(V2)
{
  hue = param.asInt();
  rgbcolor = pixels.ColorHSV(hue,saturation,value);
  pixels.fill(rgbcolor);
  pixels.show();
}

void setup()
{
  // Debug console
  //Serial.begin(9600);

  //Configure blynk with authentification token
  Blynk.begin(auth, ssid, pass);

  pixels.begin();
  pixels.setBrightness(255);  //may not be needed
  pixels.show(); //may not be needed
  
  TIMESTAMP = millis();
}

void loop()
{
  //Do this every so many milliseconds defined by TIMESTEP
  if((millis() - TIMESTAMP) > TIMESTEP) {
    TIMESTAMP = millis();
    FadeInOut();
  }
  Blynk.run();
}

void FadeInOut() {
  if (step_number == 0) { //increase brighness (fadein)
    value++;
    if (value == 255) { //value hit full brightness so next time decrease brightness
      step_number = 1;
    }
  }
  else if (step_number == 1) { //decrease brighness (fadeout)
    value--;
    if (value == 0) { //value hit zero brightness so next time increase brightness
      step_number = 0;
    }
  }
  rgbcolor = pixels.ColorHSV(hue,saturation,value);
  pixels.fill(rgbcolor);
  pixels.show();
}
1 Like

The transition was much better and smoother.
That’s what I wanted

Thank you so much.

But if I want to make a button to turn off the LED like I would?

You could have another BLYNK_WRITE tied to a button widget in the blynk app. The button should be setup in switch mode with a value of 0 to 1. Then you could control the master brightness.

BLYNK_WRITE(V3)
{ 
  //cycle effect variable
  if (param.asInt()) {
    pixels.setBrightness(255);
  }
  else {
    pixels.setBrightness(0);
  }
}

Give this a try as well.

This code changes the fading to a log scale which looks more natural to our eyes. You can adjust FADETIME to however many milliseconds you want the effect to take to do one complete cycle. TIMESTEP still controls how often a brightness adjustment is made. The code calculates the number of intervals it will take to go from full brightness to off based on these 2 values. The variable i is incremented from zero to the max number of calculated intervals each TIMESTEP.

Adjusting TIMESTEP to a smaller number (within reason) should make the effect look smoother.

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

#include <Adafruit_NeoPixel.h>
#include <SPI.h>

const char* ssid = "";
const char* password = "";

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

#define PIN 4
#define NUMPIXELS 7
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

#define TIMESTEP 20
#define FADETIME 5000 //time for 1 complete fade cycle from full bright to off and back to full bright in milliseconds
uint16_t hue = 0;
uint32_t rgbcolor = 0;
uint8_t saturation = 255;
uint8_t value = 255;
boolean step_number = 1;
unsigned long TIMESTAMP = 0;
unsigned int intervals = 0;
int i = 0;
float r;

BLYNK_WRITE(V2)
{
  hue = param.asInt();
  rgbcolor = pixels.ColorHSV(hue,saturation,value);
  pixels.fill(rgbcolor);
  pixels.show();
}

void setup()
{
  // Debug console
  //Serial.begin(9600);

  //Configure blynk with authentification token
  Blynk.begin(auth, ssid, pass);

  pixels.begin();
  pixels.setBrightness(255);
  pixels.show();
  calculate_r();
  i=intervals;
  
  TIMESTAMP = millis();
}

void loop()
{
  //Do this every so many milliseconds defined by TIMESTEP
  if((millis() - TIMESTAMP) > TIMESTEP) {
    TIMESTAMP = millis();
    FadeInOut();
  }
  Blynk.run();
}

void FadeInOut() {
  if (step_number == 0) { //increase brighness (fadein)
    i++;
    if (i == intervals) { //value hit full brightness so next time decrease brightness
      step_number = 1; 
    }
  }
  else if (step_number == 1) { //decrease brighness (fadeout)
    i--;
    if (i == 0) { //value hit zero brightness so next time increase brightness
      step_number = 0;
    }
  }
  value = pow (2, (i / r)) - 1;
  rgbcolor = pixels.ColorHSV(hue,saturation,value);
  pixels.fill(rgbcolor);
  pixels.show();
}

void calculate_r() {
   
  intervals = FADETIME/2/TIMESTEP;

  //Calculate r based on max brightness
  r = (intervals * log10(2))/(log10(255 + 1));
}

The transition got a lot better.

But now as I have only the slider, I would like to know if there is any way to show blynk the chosen color and if so, what should I add in the app?

There is a way you can tell the blynk slider to change colors on the fly like this:
Blynk.setProperty(V2,”color”,RGBcolor).

Blynk is expecting a hex value string for RGBcolor. So you would have to convert the HSV back to RGB values first. I think the neopixel library has a function for going from HSV to RGB but I’m not sure what the output format is from that function. I always use the FastLED library.

I’m make this code, But at some points on the slider the HEX turns black but on the LED the color is right. What can it be?

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Adafruit_NeoPixel.h>
#include <SPI.h>

#define PIN D4
#define NUMPIXELS 7
#define BLYNK_PRINT Serial
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

char auth[] = "------";
const char* ssid = "----";
const char* pass = "----";

#define TIMESTEP 25
uint16_t hue = 0;
uint32_t rgbcolor = 0;
uint8_t saturation = 255;
uint8_t value = 255;
boolean step_number = 1;
unsigned long TIMESTAMP = 0;

void setup()
{
//Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  pixels.begin();
  pixels.setBrightness(255);  //may not be needed
  pixels.show(); //may not be needed
  
  TIMESTAMP = millis(); 
  Blynk.virtualWrite(V2, 1);
}


BLYNK_WRITE(V1)
{
  hue = param.asInt();
  rgbcolor = pixels.ColorHSV(hue,saturation,value);
  pixels.fill(rgbcolor);
  pixels.show();
  RGBprocess();
}

BLYNK_WRITE(V2)
{
   //cycle effect variable
  if (param.asInt()) {
    pixels.setBrightness(255);
  }
  else {
    pixels.setBrightness(0);
  }
}

void loop()
{
   if((millis() - TIMESTAMP) > TIMESTEP) {
    TIMESTAMP = millis();
    FadeInOut();
  }
Blynk.run();

}
void FadeInOut() {
  if (step_number == 0) { //increase brighness (fadein)
    value++;
    if (value == 255) { //value hit full brightness so next time decrease brightness
      step_number = 1;
    }
  }
  else if (step_number == 1) { //decrease brighness (fadeout)
    value--;
    if (value == 0) { //value hit zero brightness so next time increase brightness
      step_number = 0;
    }
  }
  rgbcolor = pixels.ColorHSV(hue,saturation,value);
  pixels.fill(rgbcolor);
  pixels.show();
}

void RGBprocess()  // Do all the pin value to HEX conversion, and display it to app widgets
{
  String strRGB = String(rgbcolor, HEX);  // Convert rgbcolor to HEX.
  String HEXstring = String("#" + strRGB);  
  Blynk.run();
  HEXstring.toUpperCase();  // Change HEX value to all upper case for ease of visuals.
  Blynk.setProperty(V8, "color", HEXstring);  // Change background colour of HEX Data Label.
  Blynk.virtualWrite(V8, HEXstring);  // Display HEX data.
  Blynk.setProperty(V9, "color", HEXstring);  // Send formatted HEX colour to vRGB.
  Blynk.virtualWrite(V9, 255);  // Activate vRGB.
}

Well done. You are very close :slight_smile: There are just a couple issues with your code.

1.) rgbcolor is not reliable for use with the slider color because the program is continuously changing the brightness. What you want is the color at full brightness. So I suggest you use a new variable in your RGBprocess function to get the color based on the current Hue, full saturation, and full brightness:

uint32_t slider_color = pixels.ColorHSV(hue,255,255);

2.) “String(rgbcolor, HEX)” drops leading zeros. This is a problem. I suggest using the following instead. The sprintf command is told to keep all 6 digits of the hex value with the “%06” even if they are zeros.

char HEXstring[8];
sprintf(HEXstring,"#%06X", slider_color);

You also don’t need the “HEXstring.toUpperCase();” line

Thank You!!

My Project is Done!!

1 Like