Как использовать миллис вместо задержки?

Извините, если на что-то подобное уже отвечали раньше...

Я работаю над проектом garden timer, который работает на NodeMCU на базе ESP8266 и интегрирован с Blynk.

У меня есть функция waterNow, которая активируется, когда я нажимаю кнопку в приложении Blynk, она устанавливает pin D5 на ВЫСОКИЙ и ждет 3 секунды с функцией задержки, проблема в том, что с задержкой код просто останавливает все остальные функции до тех пор, пока задержка не будет завершена.

Проведя некоторые исследования, я обнаружил, что функция millis может быть использована для временной задержки и запуска программы, но я не могу заставить ее работать.

Как использовать функцию millis для добавления задержки?

Любая помощь будет оценена по достоинству.

Код:-

#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();
}

, 👍1

Обсуждение

Этот вопрос возникает регулярно. Посмотрите на пример “Blink without delay”, включенный в Arduino IDE, чтобы увидеть, как вы можете использовать millis() для неблокирующих временных задержек и планирования событий., @StarCat

Я уже смотрел на это, ничего не могу разобрать... но попробую еще раз, @Coder9390

Короткая подсказка: Вы должны следить за своим состоянием. Поэтому в функции "WaterNow" вы должны сохранить значение millis() в переменную, когда вы начинаете поливать, а затем регулярно сравнивать это значение с текущим временем, чтобы узнать, когда истекло требуемое количество., @PMF

Это ответ на ваш вопрос? Как использовать millis() в моем коде вместо delay()?, @sa_leinad

Это ответ на ваш вопрос? [Можно ли заменить эту задержку на millis()? (И проблема с другим циклом миллис)](https://arduinoprosto.ru/q/22204/19409), @sa_leinad

Попробуйте выполнить этот поиск: https://arduino.stackexchange.com/search?q=%5Bmillis%5D+задержка, @sa_leinad


1 ответ


Лучший ответ:

2

Я предполагаю, что после того, как вы начнете поливать, вы хотите установить V10 на 0 через 3 секунды.

Во-первых, вам нужно будет установить waterNow в 0 после того, как вы начнете watring. В противном случае waterNowrun() будет продолжать выполняться.

Во - вторых, вам нужно следить за состоянием "полива", чтобы вы знали, что должны начать отслеживать время.

В-третьих, сохраните время начала полива, чтобы вы могли сравнить его с текущим временем, чтобы увидеть, прошли ли ваши "3 секунды".

Вот простой пример:

// Глобальные переменные
const long int MAX_TIME_THRESHOLD_MS = 3000;
bool WateringStarted = false;
long int WateringStartTime = 0;

... ... ...

void waterNowrun() 
{
  if (waterNow == 1) 
  {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    lcdI2C.selectLine(2);
    lcdI2C.print("Watering Now     ");
    
    waterNow = 0;
    WateringStarted = true;
    WateringStartTime = millis();

  } 
  else   // <------ Why do you even have else! You only call waterNowrun() when waterNow == 1
  {                   
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
  }
}

... ... ...

void loop()
{
  ... ... ...
  
  if(WateringStarted && (millis() - WateringStartTime) > MAX_TIME_THRESHOLD_MS)
  {
    WateringStarted = false;
    Blynk.virtualWrite(V10, 0);
    Blynk.syncAll();
  }

  ... ... ...

}

Я не запускал этот код, и у меня нет вашей установки, чтобы проверить его. Но это должно дать вам некоторое представление. Кроме того, проверьте комментарии к вашему вопросу для получения дополнительной информации о millis().

,

Настройка выполняется после цикла , @Coder9390

Ха-ха! Я имел в виду вашу фактическую настройку оборудования, приложение Blynk и т. Д., @Fahad

О, хорошо..... Я решил эту проблему, @Coder9390