Помогите поменять delay на millis

pioli
Offline
Зарегистрирован: 14.04.2020

есть код

void loop()
{
//действие1;
delay(500);
//действие2;
delay(500);
//действие3;
delay(500);
//действие4;
delay(500);
}

Как delay заменить на millis? Нужно чтобы все 4 разных действия повторялись друг за другом. Вроде как должно быть просто, но я не догоняю.

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Примерно так

u32 tmr1, tmr2, tmr3, tmr4;

bool TimerOver(u32* timer, u32 interval)
{
  u32 m=millis();
  if(m-*timer<interval) return false;
  *timer=m;
  return true;
}

void loop()
{
  if(TimerOver(&tmr1, 100))  do1();
  if(TimerOver(&tmr2, 1000)) do2();
  if(TimerOver(&tmr3, 500))  do3();
  if(TimerOver(&tmr4, 1234)) do4();
}

pioli
Offline
Зарегистрирован: 14.04.2020

Не работает так как хотелось. Все действия пытаются одновременно выполняться.

WavGat
Offline
Зарегистрирован: 14.04.2020

delay(n) - делает задержку в n миллисекунд.

millis() - возвращает количество микросекунд.

Теперь подробнее про задачу: что нужно?

Может Вы попутали millis и delayMicroseconds ?

delayMicroseconds(n)- делает задержку в n микросекунд.

 

Duino A.R.
Offline
Зарегистрирован: 25.05.2015

pioli пишет:

Как delay заменить на millis? Нужно чтобы все 4 разных действия повторялись друг за другом. Вроде как должно быть просто, но я не догоняю.

Посмотрите тут http://alxarduino.blogspot.com/2013/09/BlinkAndPrintWithoutDelay.html  Возможно, подойдёт.

Я не очень понял задачу. Так как у Вас написан фрагмент кода, действия как раз и повторяются друг за другом с дистанцией в 500 мс. В чем смысл замены delay() на millis()?

 

pioli
Offline
Зарегистрирован: 14.04.2020

WavGat пишет:

Теперь подробнее про задачу: что нужно?

Может Вы попутали millis и delayMicroseconds ?

 


Нужно чтобы все 4 действия выполнялись строго друг за другом через пол секунды. Все действия разные. Delay прост и удобен и с ним всё работает. Но проблема в том что delay тормозит всю программу, а это не хорошо. И вообще использовать delay не комильфо. На каждом углу кричать что лучше использовать millis(). С millis() всё просто когда нужно повторять одно и тоже же действие. А у меня они разные. И каждое последующее действие должно выполняться после выполнения предыдущего. Не знаю как еще более подробно описать.

vk007
Offline
Зарегистрирован: 16.06.2015

pioli пишет:
И вообще использовать delay не комильфо. На каждом углу кричать что лучше использовать millis()

Ну да, ну да... "Все побежали, и я побежал" (с)

sadman41
Offline
Зарегистрирован: 19.10.2016

В блинке без делей счётчик от 1 до N и switch case.

pioli
Offline
Зарегистрирован: 14.04.2020

sadman41 пишет:
В блинке без делей счётчик от 1 до N и switch case.

Здесь что-то на эльфийском. Я не понимаю)

WavGat
Offline
Зарегистрирован: 14.04.2020
	void loop()
	{
	//действие1;

//	delay(500);
unsigned long current_time = millis();
while(millis()-current_time<500) {};

	//действие2;

//	delay(500);
current_time = millis();
while(millis()-current_time<500) {};

	//действие3;

//	delay(500);
current_time = millis();
while(millis()-current_time<500) {};

	//действие4;

//	delay(500);
current_time = millis();
while(millis()-current_time<500) {};

	}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Что тут понимать? Берете скетч "blink без delay", в условии наращиваете переменную и прогоняете через switch.

b707
Offline
Зарегистрирован: 26.05.2017

Вавгат, ваш код ничем не отличается от delay - так же блокирует программу

WavGat
Offline
Зарегистрирован: 14.04.2020

Так человеку это и нужно, судя из его описания. Ему просто звёзды запрещают пользоваться delay, нужен именно millis

Во всяком случае из постановки задачи я понял именно так.

 

А если нужно, чтобы от начала действия 1 до начала действия 2 было 0,5 сек. (если конечно само действие не длиться дольше), то кто вам мешает переставить одну строчку?

pioli
Offline
Зарегистрирован: 14.04.2020

WavGat пишет:
Так человеку это и нужно, судя из его описания. Ему просто звёзды запрещают пользоваться delay, нужен именно millis Во всяком случае из постановки задачи я понял именно так. А если нужно, чтобы от начала действия 1 до начала действия 2 было 0,5 сек. (если конечно само действие не длиться дольше), то кто вам мешает переставить одну строчку?

Да. Вы всё правильно поняли. Это то что нужно, как бы странно это кому ни казалось. Спасибо. Вопрос решен)

b707
Offline
Зарегистрирован: 26.05.2017

Ребята, что за чушь вы оба пишете? Вы понимаете, что ваш код блокирует контроллер?

bwn
Offline
Зарегистрирован: 25.08.2014

b707 пишет:
Ребята, что за чушь вы оба пишете? Вы понимаете, что ваш код блокирует контроллер?

Вера, она такая - слепая и беспощадная. Но делей был повержен.(((((

pioli
Offline
Зарегистрирован: 14.04.2020

b707 пишет:
Ребята, что за чушь вы оба пишете? Вы понимаете, что ваш код блокирует контроллер?

Есть вариант как это сделать не блокируя контроллер?

Kakmyc
Offline
Зарегистрирован: 15.01.2018
int operation_num=0;


if(millis()-timer>=500){
switch(operation_num){
case 0:
//Func 1
timer=millis();
operation_num++;
break;
case 1:
//Func 2
timer=millis();
operation_num++;
break;
case 2:
//Func 3
timer=millis();
operation_num++;
break;
case 3:
//Func 4
timer=millis();
operation_num++;
break;
}
if(operation_num>3)operation_num=0;

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Так поменьше писанины:

int operation_num=0;


if(millis()-timer>=500){

   switch(operation_num){
       case 0:
          //Func 1
          break;
       case 1:
          //Func 2
          break;
          ...
     }
     timer=millis();
     operation_num++;
     if(operation_num>3)operation_num=0;
}

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Так дальнейшее развитие событий в кривых руках , менее предсказуемо.
Я вот не представляю, что у него в Func'ах.
Но как убить работоспособность вашего варианта, вижу очень четко и ясно

WavGat
Offline
Зарегистрирован: 14.04.2020

Я извиняюсь, но чем Ваш вариант лучше моего? Тем, что в цикл добавлена ещё 1 переменная и два условия, а код стал более читабельным?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Тем что не блокирует код
Почитай про while, может дойдёт

WavGat
Offline
Зарегистрирован: 14.04.2020

b707 пишет:
Ребята, что за чушь вы оба пишете? Вы понимаете, что ваш код блокирует контроллер?

Из сформулированной задачи, поставленной автором темы, совсем не видно, что в этот промежуток времени микроконтроллеру нужно ещё что-то делать, кроме как ждать 500 мс. Вариантов решения конечно же много, можно и таймер подключить. НО для задачи "поменять delay на millis", для начинающего - это самое оно. А то, что человек только начинает вникать, понятно из текста вопроса и ответов данного человека. А Вы его высшей математикой сразу же пытаетесь загрузить.

sadman41
Offline
Зарегистрирован: 19.10.2016

Убить можно всё, что угодно. Вне зависимости от того, где ++ стоит ;)

И код этот не лучше и не хуже. Он просто другой. А так, как ТС объяснил требования на пальцах, то ему все равно, как оно будет работать. Поэтому и пошли упражнения.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Так в том и прикол, что примерно так через while и реализован delay() в ядре Ардуино.
Вы его не заменили на миллис, а тупо написали свой delay2().
Точно так же тормозящий программу

b707
Offline
Зарегистрирован: 26.05.2017

WavGat пишет:

Я извиняюсь, но чем Ваш вариант лучше моего?

вы реально не въезжаете, что ваш код - бредятина? Может не стоило тогда с советами вылезать?

Для проверки попробуйте написать через while мигание двумя светодиодами с некратными периодами

WavGat
Offline
Зарегистрирован: 14.04.2020

Я знаю про while и про то, что while (1) { действие } гораздо быстрее, чем void loop { действие }

Но каким боком это к вопросу автора? Хотите похвастаться знаниями, так прямо и скажите, что "так-то и так лучше, потому что...".

b707
Offline
Зарегистрирован: 26.05.2017

WavGat пишет:

для задачи "поменять delay на millis", для начинающего - это самое оно.

похоже, что вы сами от этого "начинающего" очень недалеко ушли. Еще раз повторюсь - "ваше решение" - не решение, а бредятина. Отказ от delay() делается ради написания неблокирующего кода. ваше решение ничего общего с этим не имеет.

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

WavGat
Offline
Зарегистрирован: 14.04.2020

У sadman41 и Kakmyc вообще только кусок программы, который в реальности если скопировать и тупо вставить в while или loop, будет выполнять только 1 функцию. А для того, чтобы выполнились остальные 3, нужно одну строчку перенести в секцию setup.

 

b707
Offline
Зарегистрирован: 26.05.2017

WavGat пишет:

У sadman41 и Kakmyc вообще только кусок программы, который в реальности если скопировать и тупо вставить в while или loop, будет выполнять только 1 функцию.

похоже что вы мало того, что сами писать не умеете - вы даже чужой код прочитать не в состоянии

Pyotr
Offline
Зарегистрирован: 12.03.2014

pioli пишет:

Как delay заменить на millis? Нужно чтобы все 4 разных действия повторялись друг за другом. Вроде как должно быть просто, но я не догоняю.

В песочницу заглядывали?

WavGat
Offline
Зарегистрирован: 14.04.2020

А я и не скрываю, что я далеко не профи, но я хоть какой-то вариант предложил. Думающий человек из моего варианта сможет сделать то, что нужно. А с Вашей стороны только критика сыпется и никаких дельных советов. У человека был ступор: он не понимал, как функцию, возвращающую время, использовать для создания задержки. Я наглядно показал это.

По поводу массивов - Может для Вас это будет новостью, но в некоторых языках допускаются многомерные массивы с не фиксированным количеством элементов.

pioli
Offline
Зарегистрирован: 14.04.2020

Спасибо всем кто отписался по данной теме. Не ожидал такого фидбека и даже спора по такому казалось бы простому вопросу). Способ через switch действительно более подходящий.

WavGat
Offline
Зарегистрирован: 14.04.2020

b707 пишет:

WavGat пишет:

У sadman41 и Kakmyc вообще только кусок программы, который в реальности если скопировать и тупо вставить в while или loop, будет выполнять только 1 функцию.

похоже что вы мало того, что сами писать не умеете - вы даже чужой код прочитать не в состоянии

Вы в этом уверены? Вставим к примеру в while:

while (1) {
  int num = 0;

  swith (num) {
  ...
  }
  num ++;
}

Что получим?

b707
Offline
Зарегистрирован: 26.05.2017

WavGat пишет:

А я и не скрываю, что я далеко не профи, но я хоть какой-то вариант предложил.

этот вариант не просто бесполезный - он категорически вредный. Если вы этого не понимаете - слушайте тех, кто понимает больше вас.

Еще раз - для саморазвития попробуйте написать на основе своего кода с while мигание двух диодов с периодами, например, 300 и 800 миллисекунд. Напишете - публично извинюсь

b707
Offline
Зарегистрирован: 26.05.2017

WavGat пишет:

Вы в этом уверены? Вставим к примеру в while: Что получим?

вы совсем идиот? Спросите еще, как этот код будет работать, если от МК отключить питание? :)))

Kakmyc
Offline
Зарегистрирован: 15.01.2018

WavGat пишет:

b707 пишет:

WavGat пишет:

У sadman41 и Kakmyc вообще только кусок программы, который в реальности если скопировать и тупо вставить в while или loop, будет выполнять только 1 функцию.

похоже что вы мало того, что сами писать не умеете - вы даже чужой код прочитать не в состоянии

Вы в этом уверены? Вставим к примеру в while:

while (1) {
  int num = 0;

  swith (num) {
  ...
  }
  num ++;
}

Что получим?

А если так ?

  int num=0;
while (1) {


  swith (num) {
  ...
  }
  num ++;

 

b707
Offline
Зарегистрирован: 26.05.2017

или так

while (1) {
 static  int num = 0;

  swith (num) {
  ...
  }
  num ++;
}

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Если так хочется запихать переменную внутрь цикла , и при этом нужно ее использовать не обнуляя в каждом проходе то тогда она и обьявляться будет по другому

 

while (1) {
 static int num = 0;

  swith (num) {
  ...
  }
  num ++;

 

WavGat
Offline
Зарегистрирован: 14.04.2020

b707 пишет:

или так

while (1) {
 static  int num = 0;

  swith (num) {
  ...
  }
  num ++;
}

 

 

Так будет работать

b707
Offline
Зарегистрирован: 26.05.2017

Похоже мы присутсвуем при рождении очередного Великого. Написать чушь смелости хватило, а признать что слошил - уже нет. Теперь будет доказывать, что ТС именно этого и хотел...

Kakmyc
Offline
Зарегистрирован: 15.01.2018

b707 пишет:

Похоже мы присутсвуем при рождении очередного Великого. Написать чушь смелости хватило, а признать что слошил - уже нет. Теперь будет доказывать, что ТС именно этого и хотел...

 

Кое кто из этих "великих", хоть в коде что то понимал, в отличие от этого неофита

WavGat
Offline
Зарегистрирован: 14.04.2020

pioli пишет:
WavGat пишет:

Теперь подробнее про задачу: что нужно?

Может Вы попутали millis и delayMicroseconds ?

 

Нужно чтобы все 4 действия выполнялись строго друг за другом через пол секунды. Все действия разные. Delay прост и удобен и с ним всё работает. Но проблема в том что delay тормозит всю программу, а это не хорошо. И вообще использовать delay не комильфо. На каждом углу кричать что лучше использовать millis(). С millis() всё просто когда нужно повторять одно и тоже же действие. А у меня они разные. И каждое последующее действие должно выполняться после выполнения предыдущего. Не знаю как еще более подробно описать.

Delay прост и удобен и с ним всё работает.

На каждом углу кричать что лучше использовать millis().

Фраза "Но проблема в том что delay тормозит всю программу, а это не хорошо. И вообще использовать delay не комильфо." скорее всего взята "из учебника". Я больше чем уверен, что человек Вам не объяснит, как именно этот delay тормозит его программу, так как она у него работает!!!

И я уже признал выше, что мой код не оптимальный. Но в данной задаче имеет право на жизнь, так как если не касаться вопроса while или loop, то он (код) эффективнее, чем вариант с switch, так как на 1 переменную и 2 условия меньше.

Больше не вижу смысла продолжать дискуссию по данному вопросу, так как некоторые начинают переходить на личности.

b707
Offline
Зарегистрирован: 26.05.2017

WavGat пишет:

И я уже признал выше, что мой код не оптимальный. Но в данной задаче имеет право на жизнь, так как если не касаться вопроса while или loop, то он эффективнее, чем вариант с switch, так как на 1 переменную и 2 условия меньше.

он не просто "не-оптимальный" - он бесполезный. А рассуждение об "эффективности" звучит примерно так - "давайте вместо лекарства будем пить простую воду - она конечно ничего не лечит, зато и побочки нет"

b707
Offline
Зарегистрирован: 26.05.2017

WavGat пишет:

Больше не вижу смысла продолжать дискуссию по данному вопросу, так как некоторые начинают переходить на личности.

хорошо б вы ее и не начинали вовсе. И в других темах тоже...

sadman41
Offline
Зарегистрирован: 19.10.2016

Интересно, по каким критериям 4 пустых цикла с условиями эффективней одного свича с предрасчитанными переходами? 

WavGat
Offline
Зарегистрирован: 14.04.2020

b707 пишет:

WavGat пишет:

А я и не скрываю, что я далеко не профи, но я хоть какой-то вариант предложил.

этот вариант не просто бесполезный - он категорически вредный. Если вы этого не понимаете - слушайте тех, кто понимает больше вас.

Еще раз - для саморазвития попробуйте написать на основе своего кода с while мигание двух диодов с периодами, например, 300 и 800 миллисекунд. Напишете - публично извинюсь

unsigned long old_time;
unsigned long new_time;
unsigned long delta_time;
bool led_on;

void setup {
  pinMode(13, OUTPUT);
  old_time = millis();
  led_on = false;
  
  while(1) {
    new_time = millis();
    if(new_time<old_time) {
       delta_time = 4294967295 - old_time + new_time; 
     } else {
       delta_time = new_time - old_time; 
    if(delta_time<300 && led_on) {
      led_on= false;
     digitalWrite(13,LOW);
    };
    if(delta_time>=300 && !led_on) {
      led_on= true;
     digitalWrite(13,HIGH);
    };
    if(delta_time>=1100) old_time = millis();

// Сюда можно дописать доп. задачи

  }
}

Сразу не увидел, дописываю свой вариант. Критикуйте.

WavGat
Offline
Зарегистрирован: 14.04.2020

Что-то я не внимательный сегодня (не выспался). На основе моего кода:

   while(1)
	    {
	unsigned long current_time = millis();
	    //действие1;

	//  delay(500);
	while(millis()-current_time<300) {};
	digitalWrite(13,LOW);

	current_time = millis();
	    //действие2;

	//  delay(500);
	while(millis()-current_time<800) {};
	digitalWrite(13,HIGH);

	current_time = millis();
	    //действие3;

	//  delay(500);
	while(millis()-current_time<300) {};
	digitalWrite(13,LOW);

	current_time = millis();
	    //действие4;

	//  delay(500);
	while(millis()-current_time<800) {};
	digitalWrite(13,HIGH);
	    }

 

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:

Вангую дополнительный миллис-срач.

+100 ^) Вавгат. будем обсуждать переполнение миллис? :))

Что касается вашего кода - и где в нем ваши циклы while для измерения времени? - незачет

WavGat
Offline
Зарегистрирован: 14.04.2020

Говорю же: не выспался. До 3-х ночи сидел читал про прерывания. В 8 утра встал.

b707
Offline
Зарегистрирован: 26.05.2017

WavGat пишет:

Что-то я не внимательный сегодня (не выспался). На основе моего кода:

   while(1)
	    {
	unsigned long current_time = millis();
	    //действие1;

	//  delay(500);
	while(millis()-current_time<300) {};
	digitalWrite(13,LOW);

	current_time = millis();
	    //действие2;

	//  delay(500);
	while(millis()-current_time<800) {};
	digitalWrite(13,HIGH);

	current_time = millis();
	    //действие3;

	//  delay(500);
	while(millis()-current_time<300) {};
	digitalWrite(13,LOW);

	current_time = millis();
	    //действие4;

	//  delay(500);
	while(millis()-current_time<800) {};
	digitalWrite(13,HIGH);
	    }

 

это код мигания одного светика с периодом 1100 мс, а не двух с периодами 300 и 800

поправка - это код мигания одного светика с периодом ON 800 и OFF 300мс

Но все равно незачет