Sorry if something similar has been answered before...
I am working on a garden timer project that runs on a ESP8266 based NodeMCU and is integrated with Blynk.
I have a waterNow function that activates when I press a button on the Blynk app, it sets pin D5 to HIGH and waits 3 seconds with a delay function, the problem is that with delay the code just halts all other functions until the delay is complete.
After doing some research I found out that the millis function could be used to have a time delay and have the program still run, but I can't get it to work.
How do use the millis function to add a delay?
Any help is appreciated.
Code:-
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include "DHT.h"
#include "LiquidCrystal_PCF8574.h"
#define BLYNK_PRINT Serial
#define DHT_PIN_DATA 12
// LCD definations
#define LCD_ADDRESS 0x27
#define LCD_ROWS 2
#define LCD_COLUMNS 16
#define SCROLL_DELAY 150
#define BACKLIGHT 25
#define DHTTYPE DHT22
char auth[] = "ymri204FL9_xZhf6WIRHtQ1qEWOt9zBy";
char ssid[] = "Aihertgtel-Hotspotgfdf-82DB";
char pass[] = "";
int autoSch;
int waterNow;
int morTime;
int afterTime;
int eveTime;
int schTime;
int x;
DHT dht(DHT_PIN_DATA, DHTTYPE);
LiquidCrystal_PCF8574 lcdI2C;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "in.pool.ntp.org", 19800, 600000);
// This function will be called every time Slider Widget
// in Blynk app writes values to the Virtual Pin 1
BLYNK_CONNECTED() {
Blynk.syncAll();
}
BLYNK_WRITE(V0)
{
autoSch = param.asInt(); // assigning incoming value from pin V1 to a variable
}
BLYNK_WRITE(V1)
{
morTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}
BLYNK_WRITE(V2)
{
afterTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}
BLYNK_WRITE(V3)
{
eveTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}
BLYNK_WRITE(V10)
{
waterNow = param.asInt(); // assigning incoming value from pin V1 to a variable
}
BLYNK_WRITE(V4)
{
schTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}
void time_run() {
Blynk.virtualWrite(V11, int(timeClient.getHours()));
Blynk.virtualWrite(V12, int(timeClient.getMinutes()));
Blynk.virtualWrite(V13, float(dht.readTempC()));
Blynk.virtualWrite(V14, float(dht.readHumidity()));
Serial.println(dht.readTempC());
}
void auto_run1() {
if (morTime == 1 && String(timeClient.getFormattedTime()) > "06:00:00" && String(timeClient.getFormattedTime()) < "06:20:00") {
digitalWrite(14, HIGH);
Blynk.virtualWrite(V5, 255);
Blynk.syncAll();
}
else if (afterTime == 1 && String(timeClient.getFormattedTime()) > "12:00:00" && String(timeClient.getFormattedTime()) < "12:20:00") {
digitalWrite(14, HIGH);
Blynk.virtualWrite(V5, 255);
Blynk.syncAll();
}
else if (eveTime == 1 && String(timeClient.getFormattedTime()) > "15:47:00" && String(timeClient.getFormattedTime()) < "13:48:00") {
// digitalWrite(14, HIGH);
for (x; x > 10; x++){
digitalWrite(14, HIGH);
delay(1000);
}
Blynk.virtualWrite(V5, 255);
Blynk.syncAll();
}
else {
digitalWrite(14, LOW);
Blynk.virtualWrite(V5, 0);
Blynk.syncAll();
}
}
void sch_run2() {
if (schTime == 1) {
digitalWrite(14, HIGH);
Blynk.virtualWrite(V5, 255);
Blynk.syncAll();
} else {
digitalWrite(14, LOW);
Blynk.virtualWrite(V5, 0);
}
}
void waterNowrun() {
if (waterNow == 1) {
digitalWrite(14, HIGH);
Blynk.virtualWrite(V5, 255);
lcdI2C.selectLine(2);
lcdI2C.print("Watering Now ");
delay(3000); // I want to remove this for millis
Blynk.virtualWrite(V10, 0);
Blynk.syncAll();
} else {
digitalWrite(14, LOW);
Blynk.virtualWrite(V5, 0);
}
}
void lcd() {
delay(300);
lcdI2C.clear();
timeClient.update();
lcdI2C.print(timeClient.getFormattedTime());
if (autoSch == 0) {
lcdI2C.setCursor(9, 0);
lcdI2C.print("Auto");
} else {
lcdI2C.print(" Sch");
}
if (digitalRead(14) == 1) {
lcdI2C.selectLine(2);
lcdI2C.print("Watering Now");
}
else
{
if (int(timeClient.getHours()) < 6 && morTime == 1 && autoSch == 0) {
Blynk.syncAll();
lcdI2C.selectLine(2);
lcdI2C.print("Auto Wtr at: 6");
} else if (int(timeClient.getHours()) < 12 && afterTime == 1 && autoSch == 0) {
Blynk.syncAll();
lcdI2C.selectLine(2);
lcdI2C.print("Auto Wtr at: 12");
} else if (int(timeClient.getHours()) < 18 && eveTime == 1 && autoSch == 0) {
Blynk.syncAll();
lcdI2C.selectLine(2);
lcdI2C.print("Auto Wtr at: 18");
} else if (int(timeClient.getHours()) >= 18 && morTime == 1 && autoSch == 0) {
Blynk.syncAll();
lcdI2C.selectLine(2);
lcdI2C.print("Auto Wtr at: 6");
} else {
Serial.println(timeClient.getHours());
}
}
}
void loop()
{
Blynk.run();
time_run();
lcd();
timeClient.update();
if (waterNow == 1) {
waterNowrun();
}
if (autoSch == 0) {
auto_run1();
} else {
sch_run2();
}
}
void setup()
{
dht.begin();
lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, BACKLIGHT);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
pinMode(14, OUTPUT);
digitalWrite(14, LOW);
pinMode(16, INPUT_PULLDOWN_16);
Serial.begin(9600);
//WiFi.begin(ssid, password);
Blynk.begin(auth, ssid, pass);
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
Serial.print ( "." );
}
timeClient.begin();
}
millis()
for non-blocking time delays and event scheduling.WaterNow
function you have to store the millis() value to a variable when you start watering and then compare that value regularly with the current time to find out when the required amount has elapsed.