Water Valve Project: Adding Blynk control to previously written code

I’ll start by stating I’m completely new at using Blynk, Arduino & ESP32. However, I’ve embarked on a project that will allow me to open and close a water main remotely for a beach condo. Some background on the project. I currently operate the valve via a 2 channel wifi relay set to interlock mode and the ewelink app. Works OK to open or close, but, it does not provide feedback on the status (open/closed/midway) of the valve. For this project I will be using a 120vAc to 24vDC power supply for the valve, a 5vdc DPDT relay to switch polarity and ESP32 to control it. The valve has 5 wires, 2 to open and close the valve and three to Illuminate LEDs when the valve has fully opened or has fully closed. The project I found does not use physical LEDs to display the status, but I may want to use them on site as a visual representation of the status.

I did some digging and found someone who wrote the code for this exact valve for an irrigation project. A full description and the code is available on github by searching ‘Ballvalve’ or here if the link is allowed. I’ve also attached schematic of the connections. I can cut and paste the code to the forum if needed.

I can upload this code and run it, but would not want to use the Arduino IDE to always operate it. My question is, can I incorporate Blynk to this existing code in order to add mobile connectivity and control to this project ? Do I create the blynk interface and just add it to the existing code? If so, could someone point to some tutorials on how that’s done. Or do I have to start from scratch and write new code just because I’m using Blynk (If so this will take much longer as I would need to learn how to rewrite this code for blynk)

In Blynk, I would essentially have a single button for on (open) and off (closed) (this toggle would need to reverse the polarity) with a second ‘display’ of some sort that shows the valve did OPEN, did CLOSE or is MIDWAY (did not open or close after a set period of time based on Jordan’s code)

Would also like some opinions on the addition of physical LEDs. In the attached schematic, The valve’s black wire is connected directly to the AC24V ground, which I don’t have as I will go from 120v AC to 24vdc and the schematic does not use LEDS for display.

The manufacturer has:

  • One leg of each LED connected directly to ‘+’ side of a 24vDC power supply
  • The second leg of each LEDs connected directly to the Red or Green valve wires (which in
    this project go to directly to ESPs 17 pin [Grn] and 18 pin [Red])
  • The valves Black wire connecting directly to ‘-‘ side of 24vDC Power supply
  • The valve operation works by switching the polarity to the yellow and blue wires, which will open or close it

Do I need any resistors to add the LEDs, or can I just connect directly to the board (17 & 18) and ‘-‘ side of the 24vDC power supply as stated above?

Thanks for reading and any help that is provided !

Not really. The code in the link is a demo that seems to move the valve from one location to another then waits 45 seconds, then moves it back.
The wait process, and the sampling delays on the opening process, which seem to be for calibration) use blocking delay() commands. These aren’t compatible with Blynk.

The example is simply a calibration and demo sketch, not a working solution that can then be 'Blynkified".

You need to understand the process of getting commands from the Blynk app into the sketch and using them to perform the actions you need.
I’d suggest that you use virtual pins on the widgets that you choose for this. You may find this tutorial useful:

Looking at that example sketch, I’d start from scratch.

Maybe LED widgets to mimic those physical one you are thinking about using?

Well, first of all, I don’t understand the schematic. It’s colour coding is somewhat bizarre, as is it’s use of what I assume are grounplane symbols.
Secondly, I don’t understand your comment comment about you not having the “black wire”.

There is no GND with an AC supply, unless you’re referring to the mains GND, which should be at the same potential as the mains Neutral.
The way to control physical LEDs is to connect them to GPIO pins on your ESP32. Depending on your LEDs, you will probably need a resistor to drop the 3.3v to a voltage which is acceptable to the LEDs, and to limit the current. There are plenty of online calculators for this, simply input the parameters of your chosen LEDs (and remember that different coloured LEDs tend to have different parameters, so different resistor values may be required for each LED.

Pete.

Hi Pete, thanks for the quick response, I will look at your virtual pin link and review. I may have linked the demo previously, so here is the .ccp file (new link). I was under the impression that his files in the link contained everything required to operate the valve via the Arduino software, but, maybe I’m mistaken, if so, I’ll see what I come up with after reading your link.

I’ll try and clarify the black wire question & schematic. The ‘schematic’ is a screen grab from the youtube video he created to show his project. Bottom Left is the valve and its 5 wires (Blue, Yellow, Green, Red, Black) Bottom center is the DPDT Switch, top center ac to dc converter and top right ESP32. He has the valve’s black wire (which is used as the common for the LEDs when using manual switches) connected to ‘ground’ …its drawn as if the 24vAC output had a ground, but maybe he really meant the ground at the outlet? Since he has no LEDs, that may be OK.

The valve’s yellow and blue wires go to the DPDT switch as it’s outputs (COM1, COM2)
The valve’s red and green wires go to the ESP32 (pin 17 & 18) so it can read the valves position (I guess if red is powered its closed and if green is powered it’s open, at least that’s how the LED illuminate in a manual setup … in between neither light would be on). The ‘+’ and ‘-’ coming from the converter to the DPDT switch (NO1,NO2) is the valves power source. Its seems that when a signal is sent from pin 16 via the blue wire to the DPDT input, the switch reverses the polarity of COM1/COM2 thereby opening or closing the valve. There are also jumpers between NC2 and NO1 as well as NC1 and NO2 for the polarity reversal. Finally the ESP32 powers the DPDT switch via 5vDC connections.

So, if I understand your LED ‘control’ reference, I could connect the valves red and green wires to say pins 17 and 18 which will let the ESP32 know the valves position, but a different set of pins on the ESP32 would physically illuminate the LEDs if the open/closed conditions were met ?

Thanks again Pete
Jack

The files are a library, which consist of a .h and .cpp file, that provide functions which can be called from the code.
The example .ino file uses this library to demonstrate some of the available functionality.

That wasn’t really what I was suggesting. I meant to use different GPIOs to control the LEDs and turn them on/off in the code at the appropriate points.

Pete.

Hi Pete, I’ve set up Blynk to open and close my valve (Yay!) using only the ESP 32 Wifi example sketch and updating my credentials, then adding a on/off button in blynk.

I’ve been thinking about the valve position ‘confirmation’. Since the valve simply acts as a switch completing a connection between the black wire and either the red or green wires (depending on valves position) I figured I’d run a lead off the ESP32’s 3.3v pin, connect it to the valves black wire, then connect the valves green wire to GPIO pin 17 (Open) and red to GPIO pin 18 (closed) on the ESP32. I figured if pin 17 gets 3.3 volts, the valve is open and if pin18 has 3.3 volts it’s closed.

In blynk, I could not get the ‘LED’ under display to work, so I tried ‘Value Displays’ instead. I created 2 and set them to GPIO 17 or 18. It kind of works… when pin 17 gets voltage the value display for ‘Open’ shows ‘High’ but the closed value display (for pin #18) alternates between high and low, same goes if 18 gets voltage (closed) then it displays ‘High’ and the other (open) value display alternates between high and low … not sure why.

Here’s where I need some help, I’d really like to get the on screen 'LED’s (red and green) in Blynk to work. This way they would be next to my on/off button with each one only illuminating when the valve is either fully open or fully closed , assuming my 3.3v connections above are reasonable and I won’t blow up the ESP32 :slight_smile: Not sure how to get this to work (blynk settings or sketches) I figure, once I get this working, I’ll play around with adding physical LEDs at a later time. Any help on getting this to work properly is greatly appreciated !!

Thanks, Jack

I’m finding it difficult to follow your wiring description, especially as the initial diagram was so dodgy. I’d suggest you start by producing a better diagram of what you actually have set-up.

You also need to post the code you’re using, correctly formatted with triple backticks of course.

It would also be helpful if you distinguished between physical and widget LED and switches in your descriptions, as it’s currently very different to know which of these you are referring to.

I’m guessing that you’ve connected this button widget to a digital pin in the app? If so then this really isn’t the best approach. My advice is to always attach widgets to virtual pins.

Pete.

FIRSTLY - Have figured out the basic sample widget led sketch?

IF SO - add the necessary led1.on(); directly after the code that writes the pin high the valve and on after the code that writes the other pin high.

Hi Dave,
Still learning all this stuff so please forgive my lack of skills …

I found some sample sketches to turn on virtual LEDs, so I tried to copy what I found and had some success & I’ll attach the code I’m working with that kind of works.

The virtual button to turn relay on and off work fine. In the sketch below, I probably have stuff written incorrectly & in the wrong spot … and can only seem to get one virtual LED written in the code at a time. For the one I do have, the virtual LED does go on when the valve has ‘closed’. When it opens though, the virtual LED blinks … not sure why. I’m also not sure where (or how) to write in the second virtual LED for an open valve (3.3v to gpio17) most things I’ve tried have not worked. Basically I ran a lead off of the 3.3v pin on the esp32, it goes to a switch within the valve and will either send the 3.3v to pin 17 (when valve is open) or pin 18 (when valve is closed) and no power in between… this is the source I’m trying to use to turn the virtual LEDs on and off. FYI I’m using gpio16 to trigger my relay for on and off. I also tried Pete’s example for using a virtual pin on the button to turn the relay on and off , but got an error “exit status 1 - Error compiling for board ESP32 Dev Module” seems like it may be a library issue, so I went back to connecting the button with the digital pin for now …

Thanks again for everyone’s help

/*************************************************************
  Download latest Blynk library here:
    https://github.com/blynkkk/blynk-library/releases/latest

  Blynk is a platform with iOS and Android apps to control
  Arduino, Raspberry Pi and the likes over the Internet.
  You can easily build graphic interfaces for all your
  projects by simply dragging and dropping widgets.

    Downloads, docs, tutorials: http://www.blynk.cc
    Sketch generator:           http://examples.blynk.cc
    Blynk community:            http://community.blynk.cc
    Follow us:                  http://www.fb.com/blynkapp
                                http://twitter.com/blynk_app

  Blynk library is licensed under MIT license
  This example code is in public domain.

 *************************************************************
  This example runs directly on ESP32 chip.

  Note: This requires ESP32 support package:
    https://github.com/espressif/arduino-esp32

  Please be sure to select the right ESP32 module
  in the Tools -> Board menu!

  Change WiFi ssid, pass, and Blynk auth token to run :)
  Feel free to apply it to any other example. It's simple!
 *************************************************************/

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial


#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

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

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "****";
char pass[] = "****";

WidgetLED led1(V1); // VIRTUAL led 1 closed

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

  Blynk.begin(auth, ssid, pass);
  
  while (Blynk.connect() == false) {
    // Wait until connected
  }

 pinMode(18, INPUT); // gpio 18 closed status LED
}
void loop()
{
  Blynk.run();
  //----------------------virtual led--------------
  byte inp = digitalRead(18);
   
  if (inp == HIGH)
  {
   led1.on();
  }
   else
   led1.off();
}

@Blink_tynker 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 character on your keyboard.

Pete.

OK let me fix that

You should read this:
http://help.blynk.cc/getting-started-library-auth-token-code-examples/blynk-basics/keep-your-void-loop-clean

Believe me, virtual pins are the way to go.
I’d suggest that you should forget your current code and post details of the code and error message that you previously had.

Pete.

You need to clean your void loop first off. You are writing to your virtual led hundreds or thousands of times a second with this code. Search “clean void loop” on this forum. Also for a second virtual Led you would declare it

WidgetLED led1(V1);
WidgetLED redLED(V2);

Or whatever strikes your fancy.

I think I’m starting to see whats up, thanks Pete and Dave… I will do some more reading and testing. One question, I assume I write a second if then statement for the second LED, do,they get written together meaning one line after the next or totally seperate?

Personally, I never bother with the LED object like this…

WidgetLED led1(V1);

I simply do a Blynk.virtualWrite to the relevant pin. Just remember that LED widgets are capable of being dimmed, and have 255 levels of brightness, so to turn an LED widget on at full brightness you would do:

Blynk.virtualWrite(V1,255);

It depends if your logic is to switch both LED widgets at the same time (one on and the other off, or both on/off together). If it is, then one LED is really redundant, but if not then you’d want to handle them separately.

As I’ve said before, I still don’t really have an overview of where you are at currently and what the overall goal is.

Pete.

Thanks Pete. I’ll have to draw up a diagram when I’m at the computer again, Short story, if I can get blynk to open and close my valve via the relay and display virtual LEDs when its open or closed I’d be happy. Later, I can try to do some upgrades like adding physical LEDs to illuminate along with the virtual ones. I might also add a manual momentary Dpdt switch as a second option to open and close the valve manually and add Alexa control as a third option. Of the valves 5 wires, yellow and blue (when connected to 24vDC) will open and close the valve depending on the polarity.

The other three (Black, Red and green) are a part of a switch inside the valve. Black will either connect to green once the valve reaches its full open position or black to red when it reaches its full closed position.

That’s why I connected the board’s 3.3v pin to the valve’s black wire, the valves red wire to pin (18) and green wire pin (17) on the esp32. I figured if either one of these pins gets 3.3v, it confirms the valve has reached it’s full open or closed position. The internal switch does not make this connection until it does.

Normally when using a manual switch and physical LED’s, black would connect directly to the ‘+’ side of the LED power supply and then red or green would connect to one leg of the red or green LED. The other leg of the LEDs would go directly to ‘-’ side of the LEDs power supply. Each only illuminating when the switch connects the black wire to either the green or red wire and competing the circuit to the LEDs. Hopefully that makes sense.

Okay, that explanation would have been useful before :grinning:

So, the way to go is to connect the black wire to either GND, and the green and red wires to GPIO pins. You can then poll these GPIOs to see if they are LOW (circuit to GND completed).
The GPIOs will need to have pinMode declarations in void setup, and these should use the INPUT_PULLUP modifier to ensure that they are HIGH by default and don’t float at an intermediate voltage.

You can poll the GPIOs with a timer that calls a function which reads the values of the GPIOs. The timer frequency will depend on how quickly you need to know that the circuit is made, but somewhere around 100ms will probably be okay.

Pete.

OK, so its sounds like I don’t have to connect the 3.3v pin thru the switch to the GPIOs as connecting GND thru the switch to the GPIOs will still be able to read they are connected or disconnected from the GND pin ? Just curious, any particular reason using ground vs the 3.3v connection ? 100 ms should be fine, The valve takes like 6 seconds or so to open or close as it is … so that’s lightning fast

Correct.
The advantage of doing it this way is that you can use INPUT_PULLUP, as the NodeMCU doesn’t have an INPUT_PULLDOWN modifier, so you’d need to use physical 10k pulldown resistors.

Pete.

Hi Guys, I got the valve to open/close using virtual pins, so now I’m onto the virtual LED widget. I’ve added code I’ve come up with here, but, getting an error during verification…
“exit status 1 - expected unqualified-id before ‘{’ token”
on top of that, I can’t be sure what I wrote will even work … was not sure how to poll via the timer function Pete mentioned


#define relay 16
#define openPositionGPIO 17
#define closedPositionGPIO 18
#define vRelayBtn V1
#define v_openLED V2
#define v_closedLED V3

{
  if (openPositionGPIO == HIGH) {
    Blynk.virtualWrite(v_openLED,255);
  } if (closedPositionGPIO == HIGH);
    Blynk.virtualWrite(v_closedLED,255);
  } else {
    Blynk.virtualWrite(v_openLED,0);
    Blynk.virtualWrite(v_closedLED,0);
  }
}

void setup()
{
  // Debug console
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  {
    pinMode(relay,OUTPUT);
    pinMode(openPositionGPIO,INPUT_PULLUP);
    pinMode(closedPositionGPIO,INPUT_PULLUP);
  }
}
BLYNK_WRITE(vRelayBtn){
    if (param.asInt()){       
        digitalWrite(relay, HIGH);
    } else {
        digitalWrite(relay, LOW);
    }
}
void loop()
{
  Blynk.run();
}

This is the piece of code that your compiler is complaining about, and there are quite a few things wrong with it.
I’m assuming that it is meant to be a function, and in that case it needs to be given a name, so that the compiler recognises it as a function, and it can be called from within the rest of your code. As it’s meant to control you LEDs, lets call it control_LEDs, like this…

void control_LEDs()
{
  // your code in here...
}

Your piece of function code has a mis-matched number of opening and closing curly brackets, which the compiler won’t like.
In addition, one of your 'ifstatements isn't written correctly as it has a semicolon after theifcomparison, and no curly brackets around the action to be taken if theif` statement evaluates as true.

Also, to find the current state of a GPIO, it’s necessary to do a digitalRead on the pin, so this:

won’t do what you are wanting it to.

I’m also not sure that the logic of your if / else statements will actually do what you are expecting.

It’s much easier to see at a glance what your code is meant to be doing if you are sensible about where you position your opening and closing curly brackets, and uses indents appropriately.

In addition to this, you also have some curly brackets scattered around your void setup which shouldn’t be there.

This is what I think your code should look like, with the addition of a timer to call your new control_LEDs function every 100ms…

#define relay 16
#define openPositionGPIO 17
#define closedPositionGPIO 18
#define vRelayBtn V1
#define v_openLED V2
#define v_closedLED V3

BlynkTimer timer;

void control_LEDs()
{
  if (digitalRead(openPositionGPIO) == HIGH)
  {
    Blynk.virtualWrite(v_openLED,255);
  }
  else
  {
    Blynk.virtualWrite(v_openLED,0);    
  }


  if (digitalRead(closedPositionGPIO) == HIGH)
  {
    Blynk.virtualWrite(v_closedLED,255);
  }
  else
  {
    Blynk.virtualWrite(v_closedLED,0);
  }
}


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

  pinMode(relay,OUTPUT);
  pinMode(openPositionGPIO,INPUT_PULLUP);
  pinMode(closedPositionGPIO,INPUT_PULLUP);

  timer.setInterval(100,control_LEDs);

  Blynk.begin(auth, ssid, pass);
}


BLYNK_WRITE(vRelayBtn)
{
  if (param.asInt())
  {       
    digitalWrite(relay, HIGH);
  }
  else
  {
    digitalWrite(relay, LOW);
  }
}


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

If you’re having trouble sleeping and fancy a little light bedtime reading, then this will tell you all you ever wanted to know (and much, much more) about timers…

Pete.