Reading virtual pins

Hi, i need to read the status of a blynk switch from the hardware side. There are many topics about reading virtual pins, but they are different from my question. Normally, If the user CHANGES the switch’s state from the app, it is possible to read the updated value from the hardware side with BLYNK_WRITE function. But i need to read the switch value inside my sketch on a specific row for some functions. (not just after user changes switch’s state. User changes it sometime before, hardware reads the value when needed) In this situation, app doesn’t push (BLYNK_WRITE) or pull (BLYNK_READ) any data from hardware when switch’s state is changed. (only blynk server knows the updated state) On the contrary, hardware requests data from server when needed in the sketch. Below is a detailed scenario:

i have an iot lighting setup in my home. There are 10 light devices. On blynk app I created 11 devices. Additional one is used as a virtual device for some functions I use. There is a switch linked to this virtual device on V3. If the switch’s state is OFF, all the iot lights cannot be controlled with hardware onoff button by the user. if state is ON, user can control lights with hardware button. (comm between devices is possible with bridge) Think it as a virtual master switch that disables relay-on-off functions when pressed on hardware button of the lights. Here is a simplified example sketch:

... 
void loop{
   blynk.run();
   if (digitalRead(hardwareButton) == LOW) { //buttonpressed
       if (bridge.virtualRead(V3) == HIGH) {
           digitalWrite(relayPin, !digitalRead(relayPin));
       }
       while(digitalRead(hardwareButton) == LOW) {
            yield() ;
       } 
   } 
}

This sketch does the job I want. But unfortunatelly there is not such function as blynk.virtualRead. What are your recommends? How can I read virtualswitch’s value? Am I missing something, or should I change my control procedure? Thanks in advance.

The simple way is to use BLYNK_WRITE(Vx) and store the result in a GLOBAL variable. You can then reference its current value anywhere within your sketch.

When your hardware device boots-up it won’t know what the current switch values are in the app (technically, they are stored on the server, but you see and set them in the app). The way around that is to use the Blynk.syncVirtual(Vx) command on startup, or on Blynk reconnection) which forces the BLYNK_WRITE(Vx) callback to fire, updating your global variable(s).

Also, you can’t have all this code in your void loop if you want Blynk to operate successfully. You either need to poll your physical switches on a regular basis, or use interrupts.

Pete.

2 Likes

Thanks Pete for your answer. I tried to use a global variable. But sync on device startup was a problem. I tried to change virtual switch’s state to LOW on connection. But if one of the devices goes offline, and then online, state changes and it effects all of the devices.

But your recommend about Blynk.syncVirtual(Vx) may be a good idea. I havent known that function. Blynk.syncVirtual(V3) function tells the server to send V3’s present state to hardware… Did I get it right? If I use this function just before if statements and update the global variable everytime user presses the hardware button, that does the job I want. But there may be some lags I guess… Or I can sync the state and update the variable, for example every 5 min.

You are right about the loop. There much more codes in the loop in my real sketch. But I am careful about not using delays or such functions takes long time. There is no problem for now, but not healthy I know. I faces some problems with interrupts on some esp-01 modul, so I postponed to use interrupts for now, but I plan to use after solving my issue on interrupts…

Yes, as I said, it caused the BLYNK_WRITE(V3) callback function to execute.

Please don’t take this approach, its totally unnecessary and very messy.
You can add the BLYNK_CONNECTED() callback function to your sketch. Every time your hardware connects to the Blynk sever then this function is called. If you add your Blynk.syncVirtual(V3) in there then you will always have the latest value of the V3 widget stored in your variable.

You should spend some time reading the documentation, it will save you time in the long run:
https://docs.blynk.cc/

This may be causing you problems that you are unaware of. You should clean-up your void loop now, otherwise you’ll be wasting time dealing with unpredictability and confusing results as you add more functionality to your code.

Pete.

1 Like

Thank you for your recommends, I will try to do them as soon as possible. Also about sync… My devices connects to the server and doesn’t get offline sometimes maybe 2 days or 3 days… So if I sync them just when I connect to the server (inside blynk.connected function) I cannot get the latest state I think. What do you think about timers? I guess it is not messy as much as sync everytime the user press the button…

The BLYNK_WRITE(V3) function will be called every time the value of that button changes in the app. This means that you automatically have the latest value within your global variable, unless it changes when your device is offline. In that case the Blynk.syncVirtual(V3) command inside the BLYNK_CONNECTED() function will take care of things. You don’t need to do anything else, Blynk does it for you.

My devices stay online for months at a time, but they always know the state of the buttons within the app.

Pete.

1 Like

Your point is right, thanks… Also I forgot to mention, I need to sync the virtual pin over bridge as in my example. When I call Blynk.syncVirtual(V3) It will sync V3 pin of that real device. But I need the virtual device sends its V3 pin state to the real device which requests virtual switch state linked to the virtual device. I guess the function is not used as bridge.syncVirtual(V3)…

I don’t really use Bridge on my devices, so I’m not an expert on its use, but what you’ve described makes no sense to me.

Maybe a diagram of what you’re trying to achieve would help?

Pete.