Задержка включения выхода

Здравствуйте. Подскажите куда копать или найти наглядный пример что бы разобраться.
Проектируемое устройство должно выдавать два одинаковых управляющих сигнала, значение 0 или 1. Управление с кнопки ИК-пульта, либо с кнопки без фиксации. Оба варианта управления равнозначны и по сути просто меняют переменную состояния.
Собрал макетку, залил скетч, всё работает. Но теперь нужно добавить задержку при включении для одного из выходов: Поступил сигнал - Выход1=1 - Задержка 5 сек. - Выход2=1. Поступил следующий сигнал - Выход1=0 и Выход2=0. Если в процессе отсчёта задержки поступил сигнал, то Выход1=0, а Выход2 так и не успев перейти в 1 должен остаться в 0.

//Библиотеки
#include "IRremote.h"             //Подключаем библиотеку ИК управления версия 2.2.3 (не выше)

//Входы и выходы
IRrecv irrecv(2);                 // Указываем вывод, к которому подключен ИК-приемник
#define switchPin 3               // Указываем вывод, к которому подключена кнопка
#define START_1 7                 // Указываем вывод, к которому подключен светодиод кнопки
#define START_2 6                 // Указываем вывод, к которому подключен светодиод пульта

/*Переменные*/
boolean buttonWasUp = true;       // Объявляем переменную состояния ВЫХОДОВ с указыванием их начального состояния (правда/1)
boolean ledState = false;         // Объявляем переменную состояния ВХОДОВ с указыванием их начального состояния (фальш/0)
decode_results results;           // То что принял приёмник, является значением "results" и записывается в переменную
//unsigned long delayTime;          // Объявляем переменную времени

void setup() {
irrecv.enableIRIn();              // Запускаем приемник ИК сигнала
pinMode(switchPin, INPUT_PULLUP); // Вход "switchPin" это кнопка (контакт 3) (после тестирования убрать _PULLUP)
pinMode(START_1, OUTPUT);         // Выход 7
pinMode(START_2, OUTPUT);         // Выход 6
}

void loop()
{

/*Действия с кнопкой*/
{
  boolean buttonIsUp = digitalRead(switchPin);                     // Считываем состояние кнопки
   if (buttonWasUp && !buttonIsUp) {                               // Если есть разница между состояниями, то:
    delay(100);                                                    // Ждём
    buttonIsUp = digitalRead(switchPin);                           // Считываем сигнал снова
     if (!buttonIsUp) {                                            // Если она всё ещё нажата, то это клик
     ledState = !ledState;                                         // Переворачиваем сигнал
     digitalWrite(START_1, ledState);                              // Обновляем состояние выхода 
     digitalWrite(START_2, ledState);                              // Обновляем состояние выхода 2
    }
  }
  buttonWasUp = buttonIsUp;                                        // Запоминаем последнее состояние
}
/*Действия с ИК приёмником*/
{
   if (irrecv.decode( &results )) {                                // Получение данных с ИК приемника и записываем их в ОЗУ
    if (results.value == 0xFF0FF0)                                 // Если они соответветствует коду пульта то:
      {
      ledState = !ledState;                                        // Переворачиваем сигнал
     digitalWrite(START_1, ledState);                              // Обновляем состояние выхода 1
     digitalWrite(START_2, ledState);                              // Обновляем состояние выхода 2
     }
     irrecv.resume();                                              // Ожидаем следующий сигнал с ИК приемника
   }
 }
}
1 лайк

Спасибо за относительно ясное обьяснение (на фоне других спрашивающих).

Теперь обьясните, в чем у вас проблемы. Обычно если человек четко понимает, что ему нужно и может это внятно объяснить - изобразить это в коде уже не проблема для него.

1 лайк

В тот момент когда переменная ledState меняет значение на true, выход START_1 должен обновиться сразу и принимать значение true, а выход START_2 должен выждать задержку в 5000 мсек. и только тогда принять значение true. Но если же в процессе отсчёта времени переменная ledState снова стала false, то и выходы START_1 и START_2 должны принять значение false.
Пробовал играться с delay, но ничего толкового не получается, функция либо тормозит, либо … ну либо я не разобрался до конца )))

Это в строке номер какой? (намек, что нужно бы код вставить правильно: три одинарные кавычки, которые расположены на букве “ё”)

1 лайк

delay() просто останавливает выполнение программы, поэтому программа в это время ни на что не реагирует

1 лайк

Тут на форуме миллион тем про millis() и delay()-прошерстите обязательно найдется ответ

1 лайк

Прошу прощения, не найду эти верхние апострофы. Уже пробовал редактировать. Постараюсь сейчас найти и отредактировать

На делее это невозможно написать в принципе. Используйте миллис.
Когда переменная ledState стала true, вы меняете состояние выхода START_1 и запускаете таймер на миллис с задержкой 5 сек. Если таймер истек - меняете выход START_2.
Если в процессе переменная ledState снова изменилась - сбрасываем таймер и выключаем выходы… и все!

1 лайк

Чуть выше

Код писали сами? Зачем области видимости разграничили? Управление выходами дублируются.

Спасибо

Ну как сам… брал примеры, дорабатывал, экспериментировал, выводил к нужному варианту

Строки 33 и 45

Вот этот код в луп эквивалентен вашему, проверьте:

//Библиотеки
#include “IRremote.h” //Подключаем библиотеку ИК управления версия 2.2.3 (не выше)

//Входы и выходы
IRrecv irrecv(2); // Указываем вывод, к которому подключен ИК-приемник
#define switchPin 3 // Указываем вывод, к которому подключена кнопка
#define START_1 7 // Указываем вывод, к которому подключен светодиод кнопки
#define START_2 6 // Указываем вывод, к которому подключен светодиод пульта

/* Переменные */
boolean buttonWasUp = true; // Объявляем переменную состояния ВЫХОДОВ с указыванием их начального состояния (правда/1)
boolean ledState = false; // Объявляем переменную состояния ВХОДОВ с указыванием их начального состояния (фальш/0)
decode_results results; // То что принял приёмник, является значением “results” и записывается в переменную
//unsigned long delayTime; // Объявляем переменную времени

void setup() {
  irrecv.enableIRIn(); // Запускаем приемник ИК сигнала
  pinMode(switchPin, INPUT_PULLUP); // Вход “switchPin” это кнопка (контакт 3) (после тестирования убрать _PULLUP)
  pinMode(START_1, OUTPUT); // Выход 7
  pinMode(START_2, OUTPUT); // Выход 6
}

void loop() {
  /* Действия с кнопкой */
  boolean buttonIsUp = digitalRead(switchPin); // Считываем состояние кнопки
  if (buttonWasUp && !buttonIsUp) { // Если есть разница между состояниями, то:
    delay(100); // Ждём
    buttonIsUp = digitalRead(switchPin); // Считываем сигнал снова
    if (!buttonIsUp) { // Если она всё ещё нажата, то это клик
      ledState = !ledState; // Переворачиваем сигнал
    }
  }
  buttonWasUp = buttonIsUp; // Запоминаем последнее состояние
  /* Действия с ИК приёмником */
  if (irrecv.decode( &results )) { // Получение данных с ИК приемника и записываем их в ОЗУ
    if (results.value == 0xFF0FF0) { // Если они соответветствует коду пульта то:
      ledState = !ledState; // Переворачиваем сигнал
    }
    irrecv.resume(); // Ожидаем следующий сигнал с ИК приемника
  }
  digitalWrite(START_1, ledState); // Обновляем состояние выхода 1
  digitalWrite(START_2, ledState); // Обновляем состояние выхода 2
}

Скажите честно, эти кавычки-“защита от дурака”? Я в свое время не мало постарался что бы их победить (возможно даже немножко поумнел :wink: в процессе), просто в нашем комфортном мире ожидаешь мановения волшебной палочки а тут такое ; (

Дык есть же и “палочка” нормально работает и для “в строке”, и для “блок кода”
image

2 лайка

Честно сказать не дошёл до объединения ))) Но так код выглядит меньше и это плюс

Я не автор, поначалу тоже искал эти апострофы )) А вообще это markdown-форматирование

1 лайк

О как! А ну-ка, ошибочка - нет, работает! Ура! Буду знать! Спасибо!

Конечно.
Теперь нужно убрать delay(), и завести переменную-счетчик, для отсчета времени задержки включения START_2. Подробнее тут:

1 лайк