Время выполнения сценария IF

Yanki
Offline
Зарегистрирован: 28.04.2016

Добрый день, заранее извиниюсь за возможно глупый вопрос. Я только начал изучать програмирование arduino, немогу разобраться с одной проблемой. К примеру, суть программы при нажатии кнопки на пульте выполняется сценарий, но надо чтоб он выполнялся допустим 30 сек, подскажите пожалуйста как это можно сделать? не могу никак найти.

#include <IRremote.h>

int RECV_PIN = 2;
int LED = 13;
IRrecv irrecv(RECV_PIN);
decode_results results;
int IN1 = 8;
int IN2 = 7;


void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); 
  pinMode(LED, OUTPUT);
  pinMode (IN2, OUTPUT);
  pinMode (IN1, OUTPUT);
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value);
    if (results.value == 2246090081) 
    {
      digitalWrite (IN2, HIGH);
      digitalWrite (IN1, LOW); 
    }

    if (results.value == 3419589885) 
    {
      digitalWrite (IN2, LOW);
      digitalWrite (IN1, HIGH); 
    }
    irrecv.resume(); 
  }
}

 

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

класс титановый велосипед для delay без delay().

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Запоминайте время начала выполнения сценария и проверяйте, прошло ли нужное время с этого момента.

Yanki
Offline
Зарегистрирован: 28.04.2016

Не совсем понимаю как это сделать, у Вас нет примера какого-нибудь?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Время в миллисекундах возвращает функция millis() из типовой коробки Ардуино. В этом же разделе описаны и иные функции времени.

"Запоминание" есть результат присваивания значения в переменную "запоминателя". Исполняется оператором присваивания.

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

То есть, к моменту проверки уже надо иметь переменную "время начала" с присвоенным значением времени в некоторый момент исполнения раньше (там, где "начало"); получить текущее время (вызвав millis() ещё раз) и иметь "интервал" .. в вашем варианте = 30сек = 30000миллисекунд. И воспользоваться оператором IF.

Собственно и всё. Дополнительно, настоятельно советую перечитать и остальные разделы того же самого оглавления. :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Yanki пишет:

надо чтоб он выполнялся допустим 30 сек

Что Вы под этим понимаете?

Чтобы в течение 30с ничего другого контроллер не делал? 

Или чтобы в течение 30с контроллер не реагировал на возможные последующие нажатия кнопок?

Или чтобы он начал какое-то дело, и выполнял его 30с, а через 30с, если не успел закончить, просто бросал это занятие? 

Yanki
Offline
Зарегистрирован: 28.04.2016

ЕвгенийП пишет:

Yanki пишет:

надо чтоб он выполнялся допустим 30 сек

Или чтобы он начал какое-то дело, и выполнял его 30с, а через 30с, если не успел закончить, просто бросал это занятие? 

Да, что-то вроде того, переменная IN1 это мотор, при получении команды с пульта, он должен крутить 30 сек и остановится, вот это не понимаю как сделать

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Я правильно понимаю, что в строках 25-26 он у Вас включается в одну сторону, а в строках 31-32 - включается в другую? И после этого вертится вечно, не останавливаясь. И всё, что Вам нужно, это его остановить через определённое время? Так?

А что делать, если в течение этих 30 сек. поступила ещё какая-нибудь команда с пульта? Игнорировать? Или как-то исполнять?

Yanki
Offline
Зарегистрирован: 28.04.2016

Да, все верно, так и есть..наверное это очень банально, но до меня не доходит как это сделать

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, Вам Архат всё правильно написал, только не нужно бояться это делать. Вот смотрите, здесь Ваш loop() в который я добавил несколько строк так, как Вам писал Архат - сравните его текст с этим. (один из 100500 способов сделать это - не самый лучший, но простой и нагладный):

void loop() {
	static unsigned long engineStartMoment = 0;	//	Момент запуска двигателя
	static const unsigned long engineWrokingPeriod = 30000;	// Продолжительность работы двигателя в миллисекундах
	
  if (irrecv.decode(&results)) {
    Serial.println(results.value);
    if (results.value == 2246090081) 
    {
      digitalWrite (IN2, HIGH);
      digitalWrite (IN1, LOW); 
      engineStartMoment = millis();	// запоминаем момент старта
    }

    if (results.value == 3419589885) 
    {
      digitalWrite (IN2, LOW);
      digitalWrite (IN1, HIGH); 
      engineStartMoment = millis();	// запоминаем момент старта
    }
    irrecv.resume(); 

    //
    //	Здесь, если двигатель работает, проверяем не пора ли выключить
    //	и, если пора, то выключаем нафиг
    //
    if (engineStartMoment) {	//	если работает
    	if (millis() - engineStartMoment >= engineWrokingPeriod) { // если пора выключать
	      digitalWrite (IN2, LOW);
	      digitalWrite (IN1, LOW); 
	      engineStartMoment = 0;	// признак того, что двигатель не работает
    	}
    }
  }
}

 

Yanki
Offline
Зарегистрирован: 28.04.2016

Спасибо, сейчас нет возможности попробовать, вечером буду разбираться

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

разбирайтесь

Yanki
Offline
Зарегистрирован: 28.04.2016

Добрый день, прошу прощения ,что так затянул с этим делом. Но к сожалению у меня никак не получается, делал по Вашему примеру, все равно он не выключается через 30 сек. Что я сделал не так подскажите пожалуйста?  С логикой millis вроде разобрался, все понятно и вроде все верно, но не работает как надо.

#include <IRremote.h>

int RECV_PIN = 2;
int LED = 13;
IRrecv irrecv(RECV_PIN);
decode_results results;
int IN1 = 8;
int IN2 = 7;


void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); 
  pinMode(LED, OUTPUT);
  pinMode (IN2, OUTPUT);
  pinMode (IN1, OUTPUT);
}


void loop() {
	static unsigned long engineStartMoment = 0;	//	Момент запуска двигателя
	static const unsigned long engineWrokingPeriod = 5000;	// Продолжительность работы двигателя в миллисекундах
	
  if (irrecv.decode(&results)) {
    Serial.println(results.value);
    if (results.value == 2246090081) 
    {
      digitalWrite (IN2, HIGH);
      digitalWrite (IN1, LOW); 
      engineStartMoment = millis();	// запоминаем момент старта
    }

    if (results.value == 3419589885) 
    {
      digitalWrite (IN2, LOW);
      digitalWrite (IN1, HIGH); 
      engineStartMoment = millis();	// запоминаем момент старта
    }
    irrecv.resume(); 

    //
    //	Здесь, если двигатель работает, проверяем не пора ли выключить
    //	и, если пора, то выключаем нафиг
    //
    if (engineStartMoment) {	//	если работает
    	if (millis() - engineStartMoment >= engineWrokingPeriod) { // если пора выключать
	      digitalWrite (IN2, LOW);
	      digitalWrite (IN1, LOW); 
	      engineStartMoment = 0;	// признак того, что двигатель не работает
    	}
    }
  }
}

 

madtosh
Offline
Зарегистрирован: 11.04.2016

Сделайте переменную engineStartMoment глобальной(т.е. строку 22 переместите в строку 09), а то она у Вас обнуляется каждый раз в начале loop и условие проверки работы двигателя  и его отключения не проходят.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

madtosh пишет:

Сделайте переменную engineStartMoment глобальной(т.е. строку 22 переместите в строку 09), а то она у Вас обнуляется каждый раз в начале loop и условие проверки работы двигателя  и его отключения не проходят.

static не обнуляется.........

madtosh
Offline
Зарегистрирован: 11.04.2016

Не обнулялось бы, если бы просто было - static unsigned long engineStartMoment;

А по-скольку ...=0; - то обнуляется

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Вы не правы. 
Не обнуляется.
Проверьте:

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

void loop() {
  static int my_static = 0;
  Serial.println ( my_static );
  delay ( 1000 );
  my_static ++ ;
}

 

James
Offline
Зарегистрирован: 26.02.2016

наоборот объявление static и не дает ей обнулятся, если бы было int тогда да

madtosh
Offline
Зарегистрирован: 11.04.2016

Да, был не прав, так не обнуляется. Пихал в другой код, с паралельным выводом.