Как запустить цикл на определенное время?

В настоящее время у меня есть цикл for, который повторяется 300 раз, а затем движется дальше.

Вместо этого я бы хотел, чтобы этот цикл выполнялся в течение определенного количества минут.

Вот текущий цикл для справки.

for(int i = 1; i<300; i++){
  if (kill() == true){ break; }

  strip.setPixelColor(1, strip.Color(random(100,255),random(100,255),random(100,255)));
  strip.show();

  tone(TONE, notes[random(0,3)]);
  delay(100);
}

Кроме того, у меня есть RTC, который используется где-то в приложении, поэтому реальное время доступно для использования, если это имеет смысл... хотя я хотел бы узнать, как сделать это без RTC. модуль для будущих проектов.

, 👍5


3 ответа


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

10

Вот пример, который будет работать в течение 5 минут. Обратите внимание, что выполнение цикла начнется в любое время до истечения лимита времени, в том числе за 1 мс; он не может отрезать что-то, происходящее на 5-минутной отметке, а это означает, что точность синхронизации будет ограничена длительностью кода в цикле.

Обновление: в моем первом предложении была ошибка, связанная с периодом пролонгации часов millis() в 50 с лишним дней. Этот более надежен:

uint32_t period = 5 * 60000L;       // 5 минут

for( uint32_t tStart = millis();  (millis()-tStart) < period;  ){
   doStuff();
   moreStuff();
}
,

Это основано на «5 минутах от запуска Arduino», верно?, @Shpigford

Нет, это основано на времени входа в петлю. Первое предложение цикла for вычисляет время окончания, а второе предложение сравнивает текущее время в начале каждого цикла с этим временем., @JRobert

Только что протестировано и прекрасно работает. Спасибо!, @Shpigford

К вашему обновлению, нужно ли где-то определять tQuit?, @Shpigford

Акч! Это то, что я получаю за кодирование на лету! tQuit больше не используется (баг был связан с tQuit). Это должно сказать «период». (исправлено). Спасибо за улов., @JRobert


2

Вы можете использовать переменную, которая увеличивается при каждом выполнении цикла, тогда вам нужно только изменить цикл с использования for на while.

Например:

   int incremented_variable = 0;
   int incremented_value = 100;
   int max_value = 1000;  

   while(incremented_variable < max_value){
   if (kill() == true){ break; }

   strip.setPixelColor(1, strip.Color(random(100,255),random(100,255),random(100,255)));
   strip.show();

   tone(TONE, notes[random(0,3)]);

   delay(100);
   incremented_variable = incremented_variable + incremented_value;
   }

EDIT: я только что прочитал ваше обновление по этому вопросу.

Затем вы можете использовать while с логическим флагом, который поможет вам завершить цикл, или, если хотите, вы можете отслеживать время, вызвав метод: millis(). р>

,

Но как это соотносится с реальным _time_? т.е. «Этот цикл выполняется уже 5 минут»., @Shpigford

@Shpigford, вы можете управлять временем, изменяя incremented_value, которое теперь установлено на 100, и max_value, которое установлено на 1000. В качестве совета запускайте скрипт только один раз, чтобы увидеть время, необходимое для выполнения только один раз чем вы устанавливаете эти значения соответственно., @rebatoma


3

В этом примере:

http://playground.arduino.cc/Code/ElapsedMillis

Вы можете попробовать что-то вроде:

#include <elapsedMillis.h>

elapsedMillis timeElapsed;
unsigned int interval = 60000; // одна минута в мс

while(timeElapsed < interval){
    //делаем что-то
}

В зависимости от того, насколько точным вы хотите быть, вы можете выбрать аналогичный метод с использованием RTC.

,

Хорошо, *"Эти специальные типы переменных автоматически увеличиваются по прошествии времени."*, @Arjan