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!
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
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()…
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.
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
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();
}
}