Virtual pins on nodemcu doesn't work

I am trying to test the Blynk led fading example on a nodemcu. The script with my authcode and password uploads and the serial monitor shows that I am connected. to the Blynk cloud. I am using the led widget on V4. The led in my Blynk app fades and the serial monitor shows the corresponding fading values corresponding to the state of the led in my app, so I know I am communicating from nodemcu to the cloud. However, if I put an LED between ground and pin D4, nothing happens. It might be of note that in the timer statement “.timer.setInterval(300L,fadeLedWidget”, the time interval 300L is not blue but is just the normal text color. I am using Blynk version 0.6.1 on an Arduino running version 1.8.9 on a fresh install. I am able to set digital pins with no problem. Also I have tried to use the Arduino to nodemcu pin equivalences to no effect. I have spent a lot of time trying various scripts to no avail. Please help…

to operate a real LED you need to manipulate the value of a real pin, not a virtual pin.
Try a pin such as D4

1 Like

There is no connection between virtual pins (which are effectively just software communication channels) and physical pins.

If you want the code to fade a physical LED connected to pin D4 (GPIO2) then you’d need to modify the code to declare the pinMode of GPIO4 as an OUTPUT then do an analogueWrite to that pin at the same time as the virtualWrite that is going to the virtual pin V4.
Note that virtual LEDs use the range 0-255 whereas NodeMCU physical pins use the range 0-1023, so writing 255 to a digital pin will achieve quarter brightness only.

Pete.

1 Like

Hi Pete,
As I wrote in response to your solution, I got led fading to work. Afterwards, I added a new button on V7 to the Blynk app and wrote the value to the nodemcu using Blynk_Write to turn the fading function on or off. The Blynk_Write code is as follows:

BLYNK_WRITE (V7)
{
   Serial.println (" ENTERING BLYNK_WRITE");
   int pinValue = 0;
   pinValue = param.asInt(); // assigning incoming value from pin V7 to a variable
   if  (pinValue == 1)
   {
    Serial.print ("pin value on V7 = ");
    Serial.println(pinValue);
    fadeLedWidget();
   }else
    {  Serial.print ("pin value on V7 = ");
       Serial.println(pinValue);
        // DON'T RUN fadeLedWidget
    }
}

The fading function (essentially from the example) is:

WidgetLED led1(V4);
void fadeLedWidget() // is controlled by V7
{
   Serial.println (" ENTERING fadeLedWidget");
  Serial.println (" ENTERING fadeLedWidget");
  static int value = 0;
  static int delta = 30;
  value += delta;
  if (value > 255 || value < 0)
 {
   delta = -delta;
 } else
  {
    // Serial.print("LED on V4: ");
    // Serial.println(value);
   led1.setValue(value);
   analogWrite(D4, value*4);
  }
}

By looking at the output on the serial monitor, the fadeLedWidget is evoked repeatedly – irrespective of whether the value of V7 is 0 or 1 (i.e. the LED on D4 goes through the fade sequence repeatedly). What did I do wrong or what didn’t I do to make the LED on D4 fade or not fade depending on the Value on V7?

A more general issue is that I don’t understand the the structural flow of a “program” in Blynk. Is there a document that discusses the programming structure of Blynk?

I appreciate you help! Regards, Gary

.

I’ve fixed your code formatting so that it displays correctly.
In future please add triple backticks at the beginning and end of each block of code.
Triple backticks look like this:
```

How is the button on V7 configured in the app (push or switch)?
As there’s no loop in the fadeLedWidget() function, it should only increment/decrement the LED brightness one step per operation of the button widget.

As each operation of a button widget in push mode will produce an on/off pair of values, so this may be why you’re seeing the results that you are.

Pete.

The Blynk.run() command runs some fairly complex processing in the background, but you don’t need to worry too much about that.

The thing that isn’t obvious at first is the way that BLYNK_WRITE(Vpin) functions work.
The name is a bit confusing, it’s the server that’s writing data into your program. It’s also not clear that these are in effect callback functions. They area triggered automatically (by the stuff that Blynk.run() does in the background) whenever the value associated with a virtual pin changes on the server as a result of something done in the app.
If you change the value of that virtual pin from your code (using virtualWrite(Vpin) then the corresponding BLYNK_WRITE(Vpin) callback is NOT triggered, as it could lead to endless loops being created.

When the MCU powers up and connects to Blynk, the BLYNK_WRITE(Vpin) callbacks are not triggered automatically, you have to use a Blynk.syncVirtual(vPin) command to trigger the server to push the value for that virtual pin, triggering the corresponding BLYNK_WRITE(Vpin) callback event.

Pete.

Hi Pete,
I still have major issues. I am trying to use a switch on V7 to make a LED on V4 fade. The BLYNK_WRITE(V7) function is never evoked. The serial monitor output is shown below the code. Secondly the fadeLedWidget() function is called repeatedly - with or without the BLYNK_WRITE (V7) code. My code and serial output are below:

// LED is on V4 
// virtual switch on V7 switches LED on and off
// V7 is set to switch mode
// when switch is off, LED on V4 should be off
//when switch is on LED on V4 should fade
// one increment for each time fadeLedWidget() is executed

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SPI.h>
BlynkTimer timer;
char auth[] = "auth";
char ssid[] = "ssid";
char pass[] = "pass";

BLYNK_WRITE (V7) 
{
  // Blynk.syncVirtual(Blynk.syncVirtual(V7));
   Serial.println (" ENTERING BLYNK_WRITE"); 
   int pinValue = 0;
   pinValue = param.asInt(); // assigning incoming value from pin V7 to a variable
   if  (pinValue == 1)
   { 
    Serial.print ("pin value on V7 = ");
    Serial.println(pinValue);
    fadeLedWidget();
   }else
    {  Serial.print ("pin value on V7 = ");
       Serial.println(pinValue);
       // DON'T RUN fadeLedWidget
    }
}

WidgetLED led1(V4);
    // V4 LED Widget fades one increment for every time
    // fadeLedWidget runs
void fadeLedWidget()
{
  Serial.println("ENTERING fadeLedWidget");
  static int value = 0;
  static int delta = 30;
  value += delta;
  if (value > 255 || value < 0) {
    delta = -delta;
  } else 
   {
    led1.setValue(value);
    analogWrite(D4, value*4);
    Serial.print("LED level on V4: ");
    Serial.println(value);
    Serial.println("LEAVING fadeLedWidget");
   }
}

void setup()
{
  Serial.begin (9600);
  Serial.println (" IN SETUP");
  Blynk.begin(auth, ssid, pass);
  pinMode(D4, OUTPUT); // the ACTUAL LED (Led1) is on D4
  timer.setInterval(300L,fadeLedWidget);
  Serial.println (" ENTERING LOOP"); 
}

void loop() 
{ 
  Blynk.run();
  timer.run();
}

and the beginning of the serial output


    ___  __          __
   / _ )/ /_ _____  / /__
  / _  / / // / _ \/  '_/
 /____/_/\_, /_//_/_/\_\
        /___/ v0.6.1 on NodeMCU

[633] Connecting to blynk-cloud.com:80
[902] Ready (ping: 85ms).
 ENTERING LOOP
ENTERING fadeLedWidget
LED level on V4: 30
LEAVING fadeLedWidget
ENTERING fadeLedWidget
LED level on V4: 60
LEAVING fadeLedWidget
ENTERING fadeLedWidget
LED level on V4: 90
LEAVING fadeLedWidget
ENTERING fadeLedWidget
LED level on V4: 120

Switch V7 has no effect on the output since the BLYNK_WRITE seems never to be evoked Please also check the timer.setInterval(300L,fadeLedWidget) in Setup. The “300L” does not change color indicating a value. Also the Serial.println(“in setup”) is never printed to the serial monitor. My issues are probably simple and stupid but I just can’t explain the behavior…

Much Thanks, Gary

Yes, that’s because you have a timer calling that function every 0.3 seconds…

Pete.

I now understand the issue. The fadeLedWidget() function is called at the interval set in timer.setInterval (###L, fadeLedWidget() continuously.I was trying to use another pin to “evoke” the function at my command (or not to “evoke” the function) using a BLINK_WRITE loop. Apparently, this causes an issue with BLINK_WRITE and the timer function and can’t be done. If I try to “call” another function that doesn’t depend on the timer, it works perfectly.

If you read the documentation for simpletimer (Blynk timer is basically the same, without the bugs, but with a few additions) then you’ll see how to enable/disable timers during the code, or define a timer that will run x times then stop.

Pete.