Задержка в функции

Вопрос немного праздный. При необходимости временной задержки при выполении функции пользуюсь такой конструкцией:


bool funct_del_flag=false;

void setup() {
    
}

void funct()
{ static unsigned long d_time;
  if (!funct_del_flag)
  {
  ...//инструкции до задержки
  d_time=millis();
  funct_del_flag=true;
  }
  else
  {
   ...//инструкции до задержки
   if((millis()-d_time)>=30)
   {
   funct_del_flag=false;
   ...//инструкции после задержки   
    }
  }
}
void loop() {
  ...
    if(funct_del_flag) funct();
  ...
  
}

То есть ставлю при первом вызове функции глобальный флаг задержки из функции также во внутринней перпменной присваиваю миллис(), и флаг задержки он активный эта функция дергается из LOOPа пока задержка не сработает далее функция выполняетчто нужно флаг устанвливается в ноль и все.

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

1 лайк

внутри функции объявить статическую переменную флага (вместо глобальной переменной) и по истечении времени делать нужный функционал и сбросить флаг, а в общем - вполне рабочее решение.

В его случае “не проканает”, он в лупе этот флаг юзает (зачем-то).

сообщение не может быть пустым

в loop запускать funct() без условия, как раз будет выполняться две части функции, до задержки и после.

Интересная тема. А если return использовать?
К сожалению, не проверял, если что, проверю позже

bool funct_del_flag = false;
static unsigned long d_time = 0;
 
void setup() {

}

void funct()
{
  //...инструкции до задержки
  if (funct_del_flag) {
    
    if ((millis() - d_time) >= 30) {
      d_time = millis();
      funct_del_flag = false;
    }
    else {
      return;
    }
  }
  //...инструкции после задержки
}


void loop() {
  //  ...
  funct();
  //  ...

}

  1. Не нужно внешних глобальных переменных - заменить их на внутренние статические.
  2. Функция-диспетчер должна быть не void, а bool.
  3. Ну и действия по диспетчеризации можно включать в состав функции, которой нужна задержка. Но это уже по вкусу - зависит от того, сколько подобных функций нужно в текущем проекте (а то и во всех своих проектах - вопрос повторного использования кода никто не отменял).

Примечание: кстати, не очевидно, что булев флаг - это оптимальное решение. Он может принимать, скажем, 3 значения: при первом использовании (до задержки), после задержки, после того, как действие, требующее задержки, уже осуществлено.

Да я то это понимаю, зачем так ТС делает не ясно, может этот флаг на что ещё влияет?

Как мк стал заниматься понял, что памяти может не хватать. Отсюда у меня вопрос, наверное. Все равно bool один байт занимает, проще тогда его с умом использовать (там где это уместно), например, не два значения, а 3…254… Я к тому, что не совсем понимаю зачем в мк нужен такой тип (bool).

А при чем здесь вообще МК?
Тип нужен для использования в алгоритмах. Если в МК используются алгоритмы, соответственно, нужен и тип.

Да понятно, я тут наверное больше сам с собой говорил )))

Канпилятор может обратить внимание на факт возврата из boolean-функции числа 3, к примеру.
Или не даст сделать boolean & 5, настаивая на &&.
Вобщем, дополнительная защита от дурака.

Просто надо не быть дураком и вместо bool использовать uint8_t )))

Я никогда не позиционировал себя как знатока С/С++, но мне кажется, здесь это не сработает. С/С++ - языки со слабой типизацией, в частности, bool рассматривается как разновидность int. Именно с этим связано, например, различие в записи между битовыми и логическими операциями: тип операции не может быть однозначно установлен по типам используемых в ней данных.

Смысл?

И вообще: я бы с аккуратностью использовал эпитеты в отношении тех, кто использует в своем коде bool. (((

Да, недоделал.)) Нужна ещё одна проверка. Но это не лучше, чем у Alexey_Rem , просто как вариант. Избавиться от глобального флага не удалось. Надо будет ещё позаниматься.

Не совсем понял, зачем в 1-ом посте второй раз пишем инструкции до задержки (стр.17).

Ещё ,как вариант, делить функцию с задержкой на две функции и вызывать их по таймеру из loop().

bool funct_del_flag = false;
unsigned long d_time = 0;

void setup() {
  Serial.begin(9600);
  delay(300);
}

void funct()
{
  if (!funct_del_flag) {
    Serial.println("ON");
    //...инструкции до задержки
    funct_del_flag = true;
  }
  if (funct_del_flag) {

    if ((millis() - d_time) >= 1000) {
      d_time = millis();
      funct_del_flag = false;
      Serial.println("OFF");
      //...инструкции после задержки
    }
    else {
      return;
    }
  }

}


void loop() {
  //  ...
  funct();
  //  ...
}

P.S. Ну я и тупорез))!!! Глянул на свежую голову - в таком варианте и return не нужен)))

bool funct_del_flag = false;
unsigned long d_time = 0;

void setup() {
  Serial.begin(9600);
  delay(300);
}

void funct()
{
  if (!funct_del_flag) {
    Serial.println("ON");
    //...инструкции до задержки
    funct_del_flag = true;
  }
  if (funct_del_flag) {

    if ((millis() - d_time) >= 1000) {
      d_time = millis();
      funct_del_flag = false;
      Serial.println("OFF");
      //...инструкции после задержки
    }
  }
}

void loop() {
  //  ...
  funct();
  //  ...
}

И что это даст недураку?

Евгений Петрович, вы вырвали из контекста фразу.

А “в контексте” ничего кроме этой фразы и не было.

Вот с этого начинать надо, так то, если хотите воздух по сотрясать…