BLYNK
HOME       📲 GETTING STARTED       📗 DOCS       ❓HELP CENTER       👉 SKETCH BUILDER

Button Widget turn on solenoid for a set time


#1

HI Guys,

Big Picture - I have a project running where I press a button widget and it turns on a solenoid that allows water to flow to water my plants. I want to have it turn off after 5 minutes.

I want to use mills() (and have done so in the past) but am really struggling with this seemingly simple process.

As a test setup I am using a simple Arduino Uno with an LED and Button (I press the button and the LAD should turn on for 3 seconds). I can do this easily with delay() - but have spent four hours trying to replicate with millis() - I am clearly missing something very, very basic - HELP! Please!:weary::weary::weary:

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin
int buttonState = 0;         // variable for reading the pushbutton status
unsigned long currentMillis;
long previousMillis = 0;
long interval = 3000;        // wait before turn off led


void setup() 
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
}

void loop() 
{
  buttonState = digitalRead(buttonPin);
  Serial.println(buttonState);
    
  if(buttonState == HIGH)       // pressed button
  {     
    digitalWrite(ledPin, HIGH); // turn on led
    delay(3000);
    //unsigned long currentMillis = millis();           // wait 3 secs
      //if(currentMillis - previousMillis > interval)
      //{
      //previousMillis = currentMillis;
        digitalWrite(ledPin, LOW);                    // then turn off led   
      //}
  }  
}

Once I get this working with millis() I’ll implement it into my existing Blynk watering project.

cul

billd

PS. Yes, I know this is not a strictly Blynk issue, but I get far more useful, helpful and meaningful response in this community than other other I’m apart of . . .and the delay()/millis() issue is core to keeping Blynk projects working well. Thnx


#2

Actually the BlynkTimer (which does use millis) is the best way for Blynk. Avoid delay() as it actually stops ALL processing for the set time.

Use a timeout timer, set for whatever time you need. I use them all the “time” :wink: for blinking things, timed relays, etc.

Probably becasue we regulate it to only Blynk related issues as much as possible :stuck_out_tongue_winking_eye: hint


#3

Thnx mate, this is really doing my head in! I know its simple, and I should be able to get it, but have been going round in circles for hours!

help much appreciated!

cul
billd


#4

Same thing with a timeout timer (using the Lambda shortcut)

if(buttonState == HIGH)  // pressed button
  {     
    digitalWrite(ledPin, HIGH);   // turn on led
  // Timed Lambda Function
  timer.setTimeout(3000L, []() {  // Run following command(s) after set time.
    digitalWrite(ledPin, LOW);   // then turn off led 
  });  // END Lambda Function
}

And long form use (non-Lambda)…

if(buttonState == HIGH) // pressed button
{ 
    digitalWrite(ledPin, HIGH);   // turn on led
    timer.setTimeout(3000L, TurnOffLED) {  // Run function after set time.
}


void TurnOffLED() 
{
    digitalWrite(ledPin, LOW);   // then turn off led 
}

5 minutes will be 300000L

Remember to add in all the BlynkTimer (or SimpleTimer library if not using Blynk) setup and timer.run() in the void loop()


#5

Or 3e5, which ever floats your boat :stuck_out_tongue:
Yes I am still alive! ^.^


#6

Don’t want to float a boat . . . just want to water my chilli plants . . .:stuck_out_tongue_winking_eye::hot_pepper::hot_pepper::hot_pepper::droplet::droplet::droplet:


#7

Thnx for the examples, I can make this work perfectly with a physical button (I press the button, LED turns on for 5 seconds then goes off) - but not with a button widget.

Sketch start as planned, button widget is OFF, LED is OFF, nothing is printed on Serial Monitor (SM). I press the widget button, LED lights ON and SM prints as expected . . .after 5 seconds LED stays ON (should go OFF); and SM shows the sketch switching in and out of TurnOnWater() and TurnOffWater() in sequence.

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

char auth[] = "nnn";
char ssid[] = "nnn";
char pass[] = "nnn";
BlynkTimer timer;                                      // define Blynk timere to determine when to check sensors
const int ledPin =  2;
int pinValue = 0;
long interval = 5000;                                  // stop watering after interval

BLYNK_WRITE(V5) {
  digitalWrite(ledPin, param.asInt());                // Sets ledPin HIGH or LOW depending on state of Button Widget.
}

void TurnOnWater(){
  pinValue = 0;
  Serial.print("TurnOnWater(); ");
  Serial.println(pinValue);
  timer.setTimeout(interval, TurnOffWater);         // Run TurnOffLWater() after set time.
}

void TurnOffWater(){
  pinValue = 0;
  Blynk.virtualWrite(V5, 0);  // set buttom LOW
  Serial.print("TurnOffWater(); ");
  Serial.println(pinValue);
}

void setup(){
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  Blynk.virtualWrite(V5, 0);  // set button LOW on startup
  pinMode(2, OUTPUT);         // test led
}

void loop(){
  Blynk.run();
  timer.run();
  pinValue = digitalRead(ledPin);
  if (pinValue == 1)                         // if button pressed
    {
      TurnOnWater();
    }
}

*Note the delays are just there to slow down the SM output.

I want to use the Button Widget as a SWITCH (not button), so that when I press it the LED turns ON, the widget stays on showing me that it is active, then after a set time it goes OFF.

What is wrong with my code please? As I said this works perfectly with a physical buttn, but not with the Blynk Button Widget in switch mode.

thnx
billd


#8

OK, as usually happens immediately after I posted I got it working . . . (I find articulating the problem in detail on this forum helps me see the logical errors . . . sometimes :stuck_out_tongue_winking_eye:

My working code is included as a reference for others if needed.

Basically I needed to explicitly set the state of ledPIN (digitalWrite(ledPin, HIGH); ) in each function. then I had to do another digital read in each function (pinValue = digitalRead(ledPin);) otherwise the value of ledPin was unknown.

Working now, thnx again for the examples and thnx for listening

cul
billd

/*************************************************************
  Wemos D1 + Blynk button widget + led on wemos to test the auto time of function
  Button V5 to trigger led
  Timer to auto off
  
*************************************************************/

#define BLYNK_PRINT Serial
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <ArduinoOTA.h>                                // OTA

char auth[] = "nnn";
char ssid[] = "nnn";
char pass[] = "nnn";
//BlynkTimer timer;                                      // define Blynk timere to determine when to check sensors
SimpleTimer timer;
const int ledPin = 2;
int testOTA = 391234;                                  // int that i can change to prove OTA it appears in a labeled value widget
int pinValue = 0;
long interval = 5000;                                  // stop watering after interval



BLYNK_WRITE(V5) 
{
  digitalWrite(ledPin, param.asInt());                // Sets ledPin HIGH or LOW depending on state of Button Widget.
}

void TurnOnWater()
{
  digitalWrite(ledPin, HIGH);
  Serial.print("TurnOnWater(); ");
  pinValue = digitalRead(ledPin);
  Serial.println(pinValue);
  timer.setTimeout(interval, TurnOffWater);         // Run TurnOffLWater() after set time.
}

void TurnOffWater()
{
  digitalWrite(ledPin, LOW);
  Blynk.virtualWrite(V5, LOW);                        // set button LOW
  Serial.print("TurnOffWater(); ");
  pinValue = digitalRead(ledPin);
  Serial.println(pinValue);
}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  IPAddress strWiFiIp = WiFi.localIP();               // gets local IP address
  Serial.println("");
  Serial.print("Local IP Address: ");
  Serial.println(strWiFiIp);                          // prints to serial monitor
  Blynk.virtualWrite(V2, testOTA);                    // OTA test
  Blynk.virtualWrite(V4, WiFi.localIP().toString());  // local IP address
  Blynk.virtualWrite(V5, LOW);  // set buttom LOW on startup
  pinMode(2, OUTPUT); 
    
  ArduinoOTA.begin();                                 // OTA last line of setup()
}

void loop()
{
  ArduinoOTA.handle();                                // OTA first line of loop()
  Blynk.run();
  timer.run();
  pinValue = digitalRead(ledPin);
  
  if (pinValue == 1)                            // if button pressed
    {
      TurnOnWater();
    }
}