Virtual pins not working

int ldrPin = A0; // Pin connected to the LDR
int switchPin = V0; // Virtual pin for the switch in the Blynk app


int ledStatus = LOW;  // Initial LED status (LOW = OFF)
int ldrValue = 0;    // Variable to store LDR value
int overrideStatus = 0;  // Initial override status (0 = OFF)

BLYNK_READ(V1) {  // This function sends the current status of the LED to the Blynk app
  Blynk.virtualWrite(V1, ledStatus);  // Send the LED status to virtual pin V1
}

BLYNK_WRITE(switchPin) {  // This function is called whenever the switch widget in the Blynk app changes value
  overrideStatus = param.asInt();  // Get the value from the Blynk app (0 or 1)
}

void setup() {
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass, "blynk.cloud", 80);

  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, ledStatus);  // Set the initial LED status
}

void loop() {
  Blynk.run();

  // Read LDR value
  ldrValue = analogRead(ldrPin);

  if (overrideStatus == 0) {
    // If override is OFF, control LED with LDR
    int brightness = map(ldrValue, 1023, 0, 0, 255);
    analogWrite(ledPin, brightness);
  } else {
    // If override is ON, control LED with switch
    digitalWrite(ledPin, overrideStatus);
  }

  delay(100);  // Delay for stability
}

hi the above is a code i am running to control an LED with an LDR but it has a virtual pin V0 overwrite it to function manually and also V1 to check the current status of the LED. the LDR part is working but the virtual pins all don’t work. Please assist am i missing something

@Ge-raldo_Eichab Please edit your post, using the pencil icon at the bottom, and add triple backticks at the beginning and end of your code so that it displays correctly.
Triple backticks look like this:
```

Copy and paste these if you can’t find the correct symbol on your keyboard.

corrected thanks

It helps if you post your entire sketch, with sensitive dara replaced with the word “REDACTED”.

You can’t have a cluttered void loop and use delays with Blynk, so you should read this…

You’re using BLYNK_READ() but that method isn’t supported with Blynk IoT.
I could never figure-out a sensible use for this method when it existed in Blynk Legacy, so I was glad when it was deleted in IoT.

It’s not clear what you’re trying to achieve with this LED widget, so it’s difficult to suggest a different approach with this part of your sketch.

Pete.

#define BLYNK_TEMPLATE_ID ""
#define BLYNK_TEMPLATE_NAME ""
#define BLYNK_AUTH_TOKEN ""


// Blynk - Version: Latest 
#include <Blynk.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>


char auth[] = "";  // Replace with your Blynk authentication token

char ssid[] = "";  // Replace with your WiFi SSID
char pass[] = "";  // Replace with your WiFi password

int ledPin = 2;  // Pin connected to the LED
int ldrPin = A0; // Pin connected to the LDR
int switchPin = V0; // Virtual pin for the switch in the Blynk app


int ledStatus = LOW;  // Initial LED status (LOW = OFF)
int ldrValue = 0;    // Variable to store LDR value
int overrideStatus = 0;  // Initial override status (0 = OFF)

BLYNK_READ(V1) {  // This function sends the current status of the LED to the Blynk app
  Blynk.virtualWrite(V1, ledStatus);  // Send the LED status to virtual pin V1
}

BLYNK_WRITE(switchPin) {  // This function is called whenever the switch widget in the Blynk app changes value
  overrideStatus = param.asInt();  // Get the value from the Blynk app (0 or 1)
}

void setup() {
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass, "blynk.cloud", 80);

  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, ledStatus);  // Set the initial LED status
}

void loop() {
  Blynk.run();

  // Read LDR value
  ldrValue = analogRead(ldrPin);

  if (overrideStatus == 0) {
    // If override is OFF, control LED with LDR
    int brightness = map(ldrValue, 1023, 0, 0, 255);
    analogWrite(ledPin, brightness);
  } else {
    // If override is ON, control LED with switch
    digitalWrite(ledPin, overrideStatus);
  }

  delay(100);  // Delay for stability
}

So what i am trying to do is the LED is the output. on Normal operation the LED is controlled by the LDR’s output. in addition to that I want to use the virtual switch (V0) to overwrite the status of of the LED at any given moment. with V1 it should display the current status of the LED.

You have a physical LED attached to pin GPIO2 on your board. You may have added an LED widget to your dashboard, but you aren’t doing any Blynk.virtualWrite(VPin, value) commands to enable the LED widget to mimic the physical LED (except in the BLYNK_READ function which does nothing in Blynk IoT.
Your Blynk.virtualWrite() commands needs to immediately follow your digitalWrite() commands.

However, it’s essential that you read the “keep your void loop clean” article that I linked to, and sort-out your void loop before adding-in these Blynk.virtualWrite() commands.

Pete.

#define BLYNK_TEMPLATE_ID ""
#define BLYNK_TEMPLATE_NAME ""
#define BLYNK_AUTH_TOKEN ""


// Blynk - Version: Latest 
#include <Blynk.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>


char auth[] = "";  // Replace with your Blynk authentication token
char ssid[] = "";  // Replace with your WiFi SSID
char pass[] = "";  // Replace with your WiFi password

int LDR_Val = 0;     /*Variable to store photoresistor value*/
int sensor =A0;  /*Analogue pin for photoresistor*/
int ledPin = 2;  // Pin connected to the LED
int ledStatus = LOW;  // Initial LED status (LOW = OFF)
int overrideStatus = 0;  // Initial override status (0 = OFF)


BlynkTimer timer; // Announcing the timer

BLYNK_WRITE(V0) {  // This function is called whenever the V0 widget in the Blynk app changes value
  ledStatus = param.asInt();  // Get the value from the Blynk app (0 or 1)
  overrideStatus = param.asInt();
  digitalWrite(ledPin, ledStatus);  // Set the LED accordingly
  Blynk.virtualWrite(V1, ledStatus);  // Send the LED status to virtual pin V1
}

void setup() {
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(1000L, sensorDataSend); //timer will run every sec 
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, ledStatus);  // Set the initial LED status
}

void sensorDataSend(){
  LDR_Val = analogRead(sensor);   /*Analog read LDR value*/

    if(overrideStatus == 0 && LDR_Val > 850) {       /*If light intensity is HIGH*/
        digitalWrite(ledPin,LOW); /*LED Remains OFF*/
        Blynk.virtualWrite(V1, LOW);  // Send the LED status to virtual pin V1
    }
    else if(overrideStatus == 1 && LDR_Val < 850) {       /*If light intensity is HIGH*/
        digitalWrite(ledPin,LOW); /*LED Remains OFF*/
        Blynk.virtualWrite(V1, LOW);  // Send the LED status to virtual pin V1
    }
    else {
     /*Else if Light intensity is LOW LED will Remain ON*/
        digitalWrite(ledPin,HIGH);  /* LED Turn ON LDR value is less than 100*/
        Blynk.virtualWrite(V1, HIGH);  // Send the LED status to virtual pin V1
    }
}

void loop() {
  Blynk.run();
  timer.run();        // run timer every second
}

Thanks I changed the code to the above code thanks for the assistance. Both the overwrite switch and LED status check LED wedge are working. The final stage will be add and code the timing wedge. Any advice or direction you can point me in?

I have no idea what a timing wedge is.

Pete.

Its a wedge that for some reason is not available on the web dashboard but is available on the mobile dashboard. It allows you to insert a time Input / Time Schedule from the blynk platform.

Do you mean Widget?

Pete.

oh yes apologies yes widget

Okay.
You’ll see that there are far more widgets available in the app compared to the desktop dashboard.

Using the Time Input widget can be tricky, although it depends what you want to achieve and whether you are using the days selector, time zones etc.

Have you looked at an Automation to achieve this?

Pete.

No what do you mean by automation.

Pete.

Hi I have tried the Automations but i am not getting what i need. this made me revert back to coding but i am stuck again. the timer widget code works correct on its own but once i combine it with the LDR and over write virtual code it gives issues. it does start when its supposes to start but it switches off immediately this is due to the first if statement and i cant seem to work around it. the code is bellow please assist.

#define BLYNK_TEMPLATE_ID ""
#define BLYNK_TEMPLATE_NAME ""
#define BLYNK_AUTH_TOKEN ""


// Blynk - Version: Latest 
#include <Blynk.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

char auth[] ="xx";  // Replace with your Blynk authentication token
char ssid[] = "888";  // Replace with your WiFi SSID
char pass[] = "888";  // Replace with your WiFi password

// create an instance of the NTPClient class named timeClient using the ntpUDP object
WiFiUDP ntpUDP;
const long utcOffsetInSeconds = 7200; //UTC: +2 in seconds (windhoek time)
NTPClient timeClient(ntpUDP, "africa.pool.ntp.org", utcOffsetInSeconds);// set the NTP server to "africa.pool.ntp.org"

int LDR_Val = 0;     /*Variable to store photoresistor value*/
int sensor =A0;  /*Analogue pin for photoresistor*/
int ledPin = 2;  // Pin connected to the LED
int ledStatus = LOW;  // Initial LED status (LOW = OFF)
int overrideStatus = 0;  // Initial override status (0 = OFF)
int startTime1;
int endTime1;



BlynkTimer timer; // Announcing the timer


BLYNK_WRITE(V0) {  // This function is called whenever the V0 widget in the Blynk app changes value
  ledStatus = param.asInt();  // Get the value from the Blynk app (0 or 1)
  overrideStatus = param.asInt();
  digitalWrite(ledPin, ledStatus);  // Set the LED accordingly
  Blynk.virtualWrite(V1, ledStatus);  // Send the LED status to virtual pin V1
}

BLYNK_WRITE(V2){
  startTime1 = param[0].asInt();
  endTime1 = param[1].asInt();
  if(startTime1 == 0 && endTime1 == 0)
  {
    startTime1 = 999999;
    endTime1 = 999999;
  }
  Serial.println(startTime1);
  Serial.println(endTime1);
}

void setup() {
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(1000L, sensorDataSend); //timer will run every sec 
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, ledStatus);  // Set the initial LED status
  timeClient.begin();
}

void sensorDataSend() {
  LDR_Val = analogRead(sensor);

timeClient.update();
  int HH = timeClient.getHours();
  int MM = timeClient.getMinutes();
  int SS = timeClient.getSeconds();
  int server_time = 3600 * HH + 60 * MM + SS;

  if (overrideStatus == 0 && LDR_Val > 850) {
    digitalWrite(ledPin, LOW);
    Blynk.virtualWrite(V1, LOW);
    Serial.println("Condition 1 met. LED OFF");
  } else if (overrideStatus == 1 && LDR_Val < 850) {
    digitalWrite(ledPin, LOW);
    Blynk.virtualWrite(V1, LOW);
    Serial.println("Condition 2 met. LED OFF");
  } else {
    digitalWrite(ledPin, HIGH);
    Blynk.virtualWrite(V1, HIGH);
    Serial.println("No condition met. LED ON");
  }

  if (startTime1 == server_time && overrideStatus == 0 && LDR_Val > 850) {
    digitalWrite(ledPin, HIGH);
    Blynk.virtualWrite(V1, HIGH);
    Serial.println("Start Time Condition met. LED ON");
  }

  if (endTime1 == server_time) {
    digitalWrite(ledPin, LOW);
    Blynk.virtualWrite(V1, LOW);
    Serial.println("End Time Condition met. LED OFF");
  }
}

void loop() {
  Blynk.run();
  timer.run();        // run timer every second
  
}```

I’m surprised about that, but I suspect that it’s due to the way that you’ve written your code rather than the limitations of the automations.

I think you need to explain in detail the behaviour you’re looking for

What is the purpose of the override switch? What behaviour do you expect when you activate this switch, and when (if ever) is this override status meant to be cleared?

What is the purpose of the timer and LDR sensor? What behaviour are you expecting from these, and how are they meant to work together or against each other?

Is there any reason why you aren’t updating your device date/time from the NTP server and using this? calling the NTP server every second to obtain the current time isn’t a great idea.

Pete.

Okay so i am building/ coding a prototype smart street lighting system using a arduino nano 33 iot. The light has 3 modes of operation.

  1. It works Automatically based on the output of the LDR. switching on where low ambient light and off during high ambient light situations. The status of the light should be updated to Blynk app (using as a database).
  2. You must be able to overwrite the current status of the light from the virtual switch via Blynk. this can be used in cases where the LDR mode fails etc.
  3. Timer mode. This mode allows you to switch the light on and off based on the timer widget irrespective of the LDR status.

Okay, well that’s not how you’ve written your code.

I’d re-write your sensorDataSend() function to have a much better structure - first testing if override mode is enabled and taking the appropriate action if it is.

Then testing if the timer is active and taking the appropriate action.

Finally, if none of the above then taking the LDR reading and doing the appropriate thing.

You’ll need to use return commands to stop one set of tests overwriting the previous ones.

You’ve conveniently ignored my questions about whether you want the manual override to persist indefinably, and why you are constantly getting the time from the NPT server, and you’ll need to address those issues.

Pete.

Thanks for the prompt response. Apologies for the two questions i missed. yes the overwrite button will stay persist indefinably until switch off manual. I am very new to the timer widget and the example i saw / followed was using the NPT server to get the time and also to check the endtimer1 == server time as to stop the timer mode as the timer mode is on start/stop.

When you re-structuring the sensorData() function are you referring to the use of goto() functions?

You’’d be better using the Blynk RTC functionality instead of NTP, but whichever approach you use you should update the MCU time to match that time, then only re-synchronise the MCU with the time source on an infrequent basis.
You may also want to add a physical RTC device with battery backup if you want the device to work autonomously if WiFi or the Blynk server goes down.

No, No, No!! There is no good reason to use goto() in this sketch, and it’s something I would recommend avoiding at all costs.

I was taking about return! Like this…

Void do_some_tests
{
   if(override_on)
  {
    Do some stuff…
    return;
  }

   if(timer_on)
  {
    Do some stuff…
    return;
  }

  // you only get here if neither of the above if statement are true…
  Do some LDR stuff…

}

Pete.