Help with Blynk button to control RGB LED fading loop

Hi, I’m new to both the Arduino IDE and Blynk, so hoping for some help with my project.
Using a NodeMCU V3 ESP8266 12E and Blynk on Android.

I’m trying to make a small Blynk app to control an RGB LED, with multiple features:

  • The sliders and zeRGBa widgets are working to fix a specific colour.
  • The buttons on virtual pins work for individually turning red, green and blue on and off.
  • My problem is with the fourth button “V4 Fade Loop”. When I switch the button to “on” the LED’s starting fading in and out. But when I switch it to “off” the loop continues and I can’t seem to get out of this, where they should all switch off.
  • Additionally, I would like to use a text input in Blynk to set the delay time, to control the fading speed.

Any help would be appreciated as I’m very new to this and struggling to get my head around it.

The code so far:


#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = "xxx";
char ssid[] = "xxx";
char pass[] = "xxx";

int LEDR = D0; // Pin for red LED
int LEDG = D1; // Pin for green LED
int LEDB = D2; // Pin for blue LED

int redValue; // Value for fading red LED
int greenValue; // Value for fading green LED
int blueValue; // Value for fading blue LED

void setup()
{
  //Debug console
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
}

void loop()
{
  Blynk.run();
}
 
BLYNK_WRITE(V1) {
  int pinValue = param.asInt(); // Assigning incoming value from pin V1 to a variable
  Serial.print("Pin number: ");
  Serial.println(LEDR);
  Serial.println(pinValue);
  if (pinValue == 1) {
    digitalWrite(LEDR, HIGH); // Turn LED on.
  } else {
    digitalWrite(LEDR, LOW); // Turn LED off.
  }
}

BLYNK_WRITE(V2) {
  int pinValue = param.asInt(); // Assigning incoming value from pin V2 to a variable
  Serial.print("Pin number: ");
  Serial.println(LEDG);
  Serial.println(pinValue);
  if (pinValue == 1) {
    digitalWrite(LEDG, HIGH); // Turn LED on.
  } else {
    digitalWrite(LEDG, LOW); // Turn LED off.
  }
}

BLYNK_WRITE(V3) {
  int pinValue = param.asInt(); // Assigning incoming value from pin V3 to a variable
  Serial.print("Pin number: ");
  Serial.println(LEDB);
  Serial.println(pinValue);
  if (pinValue == 1) {
    digitalWrite(LEDB, HIGH); // Turn LED on.
  } else {
    digitalWrite(LEDB, LOW); // Turn LED off.
  }
}

BLYNK_WRITE(V4) {
  int pinValue = param.asInt(); // Assigning incoming value from pin V4 to a variable
  Serial.print("RGB LEDs: ");
  Serial.println(pinValue);
  while (pinValue == 1) {
    #define delayTime 5 // Fading time
    redValue = 255; // Starts loop with red LED on full brightness
    greenValue = 0;
    blueValue = 0;
    for(int i = 0; i < 255; i += 1) { // Fades out red bring in green full when i=255
      redValue -= 1;
      greenValue += 1;
      analogWrite(LEDR, redValue);
      analogWrite(LEDG, greenValue);
      Serial.print(redValue);
      Serial.print("\t");
      Serial.print(greenValue);
      Serial.print("\t");
      Serial.println(blueValue);
      delay(delayTime);
    }
    redValue = 0;
    greenValue = 255;
    blueValue = 0;
    for(int i = 0; i < 255; i += 1) { // Fades out green bring in blue full when i=255
      greenValue -= 1;
      blueValue += 1;
      analogWrite(LEDG, greenValue);
      analogWrite(LEDB, blueValue);
      Serial.print(redValue);
      Serial.print("\t");
      Serial.print(greenValue);
      Serial.print("\t");
      Serial.println(blueValue);
      delay(delayTime);
    }
    redValue = 0;
    greenValue = 0;
    blueValue = 255;
    for(int i = 0; i < 255; i += 1) { // Fades out blue bring in red full when i=255
      blueValue -= 1;
      redValue += 1;
      analogWrite(LEDB, blueValue);
      analogWrite(LEDR, redValue);
      Serial.print(redValue);
      Serial.print("\t");
      Serial.print(greenValue);
      Serial.print("\t");
      Serial.println(blueValue);
      delay(delayTime);
    }
  }
  if (pinValue == 0) {
    digitalWrite(LEDR, LOW); // Turn red LED off.
    digitalWrite(LEDG, LOW); // Turn green LED off.
    digitalWrite(LEDB, LOW); // Turn blue LED off.
  }
}

The problem is the while statement.

BLYNK_WRITE(vPin) is triggered once when the widget state changes. This means that it never changes part way through the execution of this code, so your…

test is ALWAYS true if the BLYNK_WRITE(V4) callback is triggered by a change in the widget from 0 to 1.
The code execution never breaks out of that while loop to get back to the void loop and ‘see’ another Blynk.run command, so the subsequent presses of the V4 widget are never processed.

Instead, use an if(pinValue = 1) test, with a corresponding else statement.

In fact, I’d go as far as saying that you should almost never use use while commands with Blynk unless you really know what you are doing.

The problem with that is that the text input allows both numbers and letters to be entered. You need to be careful to do some validation on the input string before using it.
The Numeric input widget is a far better choice.

Pete.

Hi Pete, thanks for your reply.
I did originally use if and else statements, but found the string of code just ran once, where the LEDs faded from red to green to blue to red, then just stopped. Strangely though, when used on an Arduino the same code works fine, so I’m thinking the use of a Blynk button handles this slightly differently?

I’ve already explained how BLYNK_WRITE(vPin) callback works.

If you want a loop to repeat indefinitely until a widget button changes state then you should do this in an independent loop, not part of a callback function.
But, you’ll need Blynk.run() commands in there too.

If you took a little time to search the forum you’d find lots of examples.

Pete.

Thanks for the info. I’ll have a look on the forum to find some similar examples to play with. Only two weeks into using an Arduino and trying to learn the language, so most of this completely baffles me!