Устранить зацикливание

Sumatra
Offline
Зарегистрирован: 19.02.2015

Здравствуйте! Мне необходимо включать и выключать 2 нагрузки:  F и Z с ИК-пульта последовательно, с задержкой полсекунды, а затем выключать -тоже последовательно:

команда А. Макетирую на Arduino Uno, использую библиотеку IRremote. Команды В и С выполняются без замечаний, а вместо команды А запускается бесконечный цикл, выйти из которого можно командами В и С. Видимо неправильно использую delay. Прошу указать на ошибку или подсказать, как сделать иначе.Уровень в программировании начальный, основы читал.

 

Sumatra
Offline
Зарегистрирован: 19.02.2015

Прошу прощения - код не вставился, пока не могу с этим разобраться. Отправил код повторно:

#include <IRremote.h>
int RECV_PIN = 2;
int RELAY_PIN_F = 10;
int RELAY_PIN_Z = 11;
 
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup() {
delay (1000);
pinMode(RELAY_PIN_F, OUTPUT);
pinMode(RELAY_PIN_Z, OUTPUT);
 
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}
void loop() {
  if (irrecv.decode(&results)) {
  Serial.println(results.value);
  irrecv.resume(); // Receive the next value
  }
 
if (results.value == A){
digitalWrite (RELAY_PIN_F, HIGH);
delay (500);
digitalWrite (RELAY_PIN_Z, HIGH);
delay (100);
digitalWrite (RELAY_PIN_Z,LOW);
delay (100);
digitalWrite (RELAY_PIN_F,LOW);
}
 
if (results.value == B){
digitalWrite (RELAY_PIN_F,HIGH);
delay (500);
digitalWrite (RELAY_PIN_Z, HIGH);
}
 
if (results.value == C){
digitalWrite (RELAY_PIN_Z,LOW);
delay (100);
digitalWrite (RELAY_PIN_F,LOW);
}
delay (100);
}

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Не знаю как работает IRremote но results надо очищать иначе, циклится не только по А но и по всему остальному, просто там незаметно. Или проще выполнять действия только когда decode срабатывает.

Sumatra
Offline
Зарегистрирован: 19.02.2015

Уважаемый Penni! Если циклится , но незаметно, то меня устроит. Мне бы практический совет - в какую сторону двигаться ? Мне нужно по команде А включить F, пауза, включить Z , пауза , выключить Z, пауза, выключить F. И ждать следующей команды.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Я ж написал надо results.value = 0 сделать после выполнения команд A B C

Это может не получиться, я не знаю как там клас написан, можно ли просто так значение задавать.

Либо, опять же как писал выше, выполнять все действия тоьлко когда decode отрабатывает. Для этого надо перенести кусок кода внутрь {} которые к decode относятся.

Sumatra
Offline
Зарегистрирован: 19.02.2015

Добавил results.value =0; в выполнение команды А (   после выполнения команд А,В,С - не компилируется). И - все команды заработали. Как я понял вопрос однократного кратковременного включения нагрузок имеет общий характер. Как люди решают эту задачу? Т.е. нужно остановить цикл после снятия команды - правильно? Большое   спасибо за совет!

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Если вставить строку перед последним delay(100) должно компилироваться и работать.

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

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Можно без очистки, в этом случае перенести обратную фигурную скобку из строки 4 функции loop в строку сразу после delay(100);

Логика простая, если код не пришел, зачем сравнивать несуществующие данные? (риторический).

UPD: Да, поскольку выполняете irrecv.resume, после этого следующим кодом может испортиться irrecv.value, что может доставить некоторые плавающие проблемы. Потому, как вариант, перед resume скопируйте irrecv.value в локальную переменную с которой и работайте (сравнивайте).

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну я два раза предлагал так сделать, топикстартер хочет идти по другому пути похоже.