Выключение вентилятора по таймеру
- Войдите на сайт для отправки комментариев
Всем привет, нужна ваша помощь. есть вентилятор напольный, у него 3 режима скорости, работает через ИК пульт. При включении любого режима два предыдущих всегда выключены, тоже самое при переключении на любой из 3-х режимов - предыдущие сразу же выключаются, что бы не было одновременно включено 2 режима. Решил сделать фиксированный таймер отключения на каждый из трёх режимов на - 20 / 40 / 60 минут (для отладки тестирую таймер на 10 секундах). только не могу понять как правильно организовать логику по таймеру: при нажатии кнопки - включить режим 1 на 20 минут, по истечению таймера отключить режим. Так же сделать по нажатию 2 кнопки - включить режим 1 на 40 минут, по истечению таймера отключить режим......
Код на таймере для отключения:
// ..................................... код... unsigned long millis_old[1]; //массив для хранения последних данных о времени срабатывания таймера.Количество элементов соответствует количеству таймеров boolean my_timer(unsigned long time, byte nomer) //функция таймер, time-время задержки, nomer-номер таймера { unsigned long current_millis; //текущее значение миллисекунды current_millis = millis(); if (current_millis - millis_old[nomer] > time) //если время срабатывания таймера наступило { millis_old[nomer] = current_millis; //перезаписываем время последнего срабатывания таймера return true; //возвращаем true } else return false; //возвращаем false } // ..................................... код... void loop { if (my_timer(10000,0))//если таймер №0, отсчитал 10 секунд { //выполняем наши действия... } }
Весь код:
#include <IRremote.h> // Библиотека для ИК приёмника #define REJ1 2 // режим 1 #define REJ2 3 // режим 2 #define REJ3 4 // режим 3 #define GREAN 5 // Зелёный #define BLUE 6 // Синий #define RED 7 // Красный byte RECV_PIN = 11; // вход ИК приемника IRrecv irrecv(RECV_PIN); decode_results results; // переменные переключения режимов, при нажатии кнопок они принимают значения +1 byte a=0; // Для режима 1 byte b=0; // Для режима 2 byte c=0; // Для режима 3 byte d=0; // Для выключения всех режимов byte e=0; // Таймер 20 мин для режима 1 //Далее идёт код для таймера... unsigned long millis_old[1]; //массив для хранения последних данных о времени срабатывания таймера.Количество элементов соответствует количеству таймеров boolean my_timer(unsigned long time, byte nomer) //функция таймер, time-время задержки, nomer-номер таймера { unsigned long current_millis; //текущее значение миллисекунды current_millis = millis(); if (current_millis - millis_old[nomer] > time) //если время срабатывания таймера наступило { millis_old[nomer] = current_millis; //перезаписываем время последнего срабатывания таймера return true; //возвращаем true } else return false; //возвращаем false } void setup(){ irrecv.enableIRIn(); // включить приемник // назначаем все необходимые pin'ы как ВЫХОДЫ pinMode(REJ1, OUTPUT); // режим 1 ВЫХОД pinMode(REJ2, OUTPUT); // режим 2 ВЫХОД pinMode(REJ3, OUTPUT); // режим 3 ВЫХОД pinMode(GREAN, OUTPUT); // Зелёный цвет к режиму 1 pinMode(BLUE, OUTPUT); // Синий цвет к режиму 2 pinMode(RED, OUTPUT); // Красный свет к Режиму 3 // При включении Arduino на всех пинах LOW. // ВНИМАНИЕ!!! ИНВЕРСИЯ питания для ЭЛЕКТРОМАГНИТНЫХ Реле!!! (HIGH - выключено реле, LOW - включено). digitalWrite(REJ1, HIGH); // режим 1 Off digitalWrite(REJ2, HIGH); // режим 2 Off digitalWrite(REJ3, HIGH); // режим 3 Off digitalWrite(GREAN, LOW); // Зелёный цвет Off digitalWrite(BLUE, LOW); // Синий цвет Off digitalWrite(RED, LOW); // Красный цвет Off } void loop() { if (irrecv.decode(&results)) { delay(150); // задержка перед выполнением определения кнопок, чтобы избежать быстрое двойное нажатие // обработка нажитя клавиши, здесь переменная принимает значение +1 // FF6897 - это код кнопок с ИК пульта, их нужно заменить на свои! if (results.value == 0xFF6897) {a=a+1; b=0; c=0;} // режим 1 on | режимы 2 и 3 off if (results.value == 0xFF9867) {b=b+1; a=0; c=0;} // режим 2 on | режимы 1 и 3 off if (results.value == 0xFFB04F) {c=c+1; a=0; b=0;} // режим 3 on | режимы 1 и 2 off if (results.value == 0xFF02FD) {d=d+1; a=0; b=0; c=0;} // Выключить всё! if (results.value == 0xFF30CF) {e=e+1; a=0; b=0; c=0;} // Таймер для режима 1 on | Все остальные режимы off // начинаем включать светодиоды на пинах if (a==1){ // Если "a" равер 1, то... //выключаем все остальные режимы и светодиоды digitalWrite(REJ2, HIGH); // режим 2 Off digitalWrite(BLUE, LOW); // Синий цвет Off digitalWrite(REJ3, HIGH); // режим 3 Off digitalWrite(RED, LOW); // Красный цвет Off // включаем 1 режим digitalWrite(REJ1, LOW); // режим 1 On digitalWrite(GREAN, HIGH); // Зелёный цвет On } else { // Иначе... // выключаем 1 режим digitalWrite(REJ1, HIGH); // режим 1 Off digitalWrite(GREAN, LOW); // Зелёный цвет Off a=0; //возвращаем переменную "a" в исходное состояние } if (b==1){ // Если "b" равер 1, то... //выключаем все остальные режимы и светодиоды digitalWrite(REJ1, HIGH); // режим 1 Off digitalWrite(GREAN, LOW); // Зелёный цвет Off digitalWrite(REJ3, HIGH); // режим 3 Off digitalWrite(RED, LOW); // Красный цвет Off // включаем 2 режим digitalWrite(REJ2, LOW); // режим 2 On digitalWrite(BLUE, HIGH); // Синий цвет On } else { // Иначе... // выключаем 2 режим digitalWrite(REJ2, HIGH); // режим 2 Off digitalWrite(BLUE, LOW); // Синий цвет Off b=0; //возвращаем переменную "b" в исходное состояние } if (c==1){ // Если "c" равер 1, то... //выключаем все остальные режимы и светодиоды digitalWrite(REJ1, HIGH); // режим 1 Off digitalWrite(GREAN, LOW); // Зелёный цвет Off digitalWrite(REJ2, HIGH); // режим 2 Off digitalWrite(BLUE, LOW); // Синий цвет Off // включаем 3 режим digitalWrite(REJ3, LOW); // режим 3 On digitalWrite(RED, HIGH); // Красный цвет On } else { // Иначе... // выключаем 3 режим digitalWrite(REJ3, HIGH); // режим 3 Off digitalWrite(RED, LOW); // Красный цвет Off c=0; //возвращаем переменную "c" в исходное состояние } if (d==1){ // Если "d" равер 1, то... // выключаем все реле digitalWrite(REJ1, HIGH); // режим 1 Off digitalWrite(REJ2, HIGH); // режим 2 Off digitalWrite(REJ3, HIGH); // режим 3 Off // выключаем все светодиоды digitalWrite(GREAN, LOW); // Зелёный цвет Off digitalWrite(BLUE, LOW); // Синий цвет Off digitalWrite(RED, LOW); // Красный цвет Off d=0; //возвращаем переменную "d" в исходное состояние } // Выключения по таймеру: if (e==1){ // Если "e" равер 1, то... //выключаем все остальные режимы и светодиоды digitalWrite(REJ2, HIGH); // режим 2 Off digitalWrite(BLUE, LOW); // Синий цвет Off digitalWrite(REJ3, HIGH); // режим 3 Off digitalWrite(RED, LOW); // Красный цвет Off // включаем 1 режим по Таймеру на 20 мин. digitalWrite(REJ1, LOW); // режим 1 On digitalWrite(GREAN, HIGH); // Зелёный цвет On if (my_timer(10000, 0)) { //иначе, если включен режим "E" и таймер №0, отсчитал 10 секунд (ДЛЯ ОТЛАДКИ!) // выключаем 1 режим по Таймеру digitalWrite(REJ1, HIGH); // режим 1 Off digitalWrite(GREAN, LOW); // Зелёный цвет Off e=0; //возвращаем переменную "e" по Таймеру в исходное состояние } } { delay(50); //пауза между повторами } irrecv.resume(); } }
Три- "таймера" вызываются следующим образом
Три- "таймера" вызываются следующим образом
Это понятно с таймерами, сложность вызвало для меня организация этой части кода:
Хочу сделать так, что бы при поступлении сигнала нажатия кнопки с пульта, вызывалась переменная "e", выключала все предыдущие режимы, если какой либо из них был включён, включала режим 1 на 20 мин. и отключалась по истечению времени.
Попробуйте этот код. Не проверял на железе но должен работать так как Вы просили. Не "е" не писал, добавите сами. 1й режим отключается через 1сек, 2й-2сек, 3й-3сек, ну а Вы поставите сколько надо.
Почему Вы не проверили мой код??? Я прогнал его на стимуляторе - полностью работае как Вы писали, вместо этого Вы вернулись к своему не рабочему коду и удивляетесь. Если он Вам так дорог то проверте хотябы правильность растановки скобок
Код, который Вы скинули, с ним не включался не один режим. Тем более первые 3 режима нужны были для работы в обычнов режиме вкл/выкл.
У меня нет пульта и приемника, вместо них я поставил автомотическую смену режима каждые 5 сек вы можете поставить для проверки другое время. Вот код которым я проверял, внем нет только дистанционки а так он идентичный тому что я скинул. Попробуйте - он работает на всех режимах
Понял почему на практике не работает код ни мой, ни Ваш. Проблема в Таймерах библиотеки <IRremote.h> и Таймера в коде скетча. Инструкции есть как таймер сменить в библиотеке <IRremote.h>, но это не помогает.
Если закомментировать irrecv.resume(); то таймер в скетче работает, но включается только 1 раз, и больше на кнопки пульта не реагирует, при не закомментрованном irrecv.resume(); режимы работают, но таймер в скетче не срабатывает на отключение.
Начните с простого, по нажатии кнопки загите 1н из диодов, 2я кнопка 2й-диод и т. д. После того как убедитесь в работоспособности дистанционки приступайте к режимам и таймеру
разобрался, нужно было поднять irrecv.resume(); вверх перед началом проверок if. И всё заработало, как должно, спасибо за помощь!!!!
Похожий проект на предыдущий... вентилятор на 3 режима (кнопки 1,2,3), общая кнопка выключения всех режимов (off), и 3 таймера (для примера 5с, 10с, 15с) (кнопки 4,5,6) на ИК ПДУ , каждый режим может работать как отдельно, так и по таймеру (одному их трех). Внимание вопрос!!! Допустим запустили на 1 режиме 3 таймер и не дожидаясь пока он закончится, захотели выключить вентилятор. Помогите добавить обработку в существующий код, чтобы задача выполнилась со сбросом всех параметров и отключением как таймера так и режима
в такой код
никак не добавить обработку сброса.
Это яркий пример того, как не надо использовать миллис.
Конструкция
полностью аналогична строчке delay(per2) - то есть это тупой блокирующий код
Переписывайте код на миллис правильно. Делеи на строчках 5 и 7 тоже нужно убрать.
Но внутри кода
есть мигание светодиодом и оно работает параллельно таймеру, почему нельзя внутрь этого кода вписать сброс?
хреновый у тебя код. перепиши.
есть мигание светодиодом и оно работает параллельно таймеру, почему нельзя внутрь этого кода вписать сброс?
потому что код команды сброса получается за пределами цикла с миллис
Ну я потому и обратился сюда на форум...Если бы знал что переписывать , не обращался бы за помощью...
Ну я потому и обратился сюда на форум...Если бы знал что переписывать , не обращался бы за помощью...
Я ж тебе говорю! Код переписуй!
Но внутри кода
есть мигание светодиодом и оно работает параллельно таймеру, почему нельзя внутрь этого кода вписать сброс?
какому таймеру оно "параллельно" работает? Тому что на цикле while? Где вы тут параллельность увидали? Этот "таймер" только миганием светодиода и занимается, вписать в него ничего другого невозможно.
Да даже если б и вписали - у вас таких таймеров три. В каждый будете отдельный сброс вписывать? :)
Ну я потому и обратился сюда на форум...Если бы знал что переписывать , не обращался бы за помощью...
переписывать весь ваш код за вас будут только в разделе "ищу исполнителя"
Если хотите сами - начните с примера "блинк без делей", разберитесь, как на самом деле надо использовать миллис
Все понятно, так бы и сказали что не знаете...
Все понятно, так бы и сказали что не знаете...
ок, так и говорю - не знаю. Легче стало?
Ну походите-поклянчите, мож кто и подаст.
Но внутри кода
есть мигание светодиодом и оно работает параллельно таймеру, почему нельзя внутрь этого кода вписать сброс?
какому таймеру оно "параллельно" работает? Тому что на цикле while? Где вы тут параллельность увидали? Этот "таймер" только миганием светодиода и занимается, вписать в него ничего другого невозможно.
Да даже если б и вписали - у вас таких таймеров три. В каждый будете отдельный сброс вписывать? :)
Этот таймер реально работает, через 10с он выключает все режимы, отключает вентилятор, параллельно работает и мигание светодиодом на 13 ноге... каждую секунду.. да таймеров 3 , на кадом из них по условию нажатия кнопки выключения , чтобы таймер сбрасывался..
да таймеров 3 , на кадом из них по условию нажатия кнопки выключения , чтобы таймер сбрасывался..
ну раз вы сами знаете - так пробуйте. Код с тройным дублированием? - ерунда... А что кнопки будут срабатывать с пятого раза - это мелочи...
Подскажите какой командой выйти из цикла по условию, разве это нельзя сделать?
Подскажите какой командой выйти из цикла по условию, разве это нельзя сделать?
break
Пробывал эту команду, не прокатывает
Пробывал эту команду, не прокатывает
другой нет.
все с ней прокатывает, просто уметь надо.
Все понятно, так бы и сказали что не знаете...
Точно! Шарлатаны!! А еще борютЬся за высокое звание... Плюсанул!
Пробывал эту команду, не прокатывает
другой нет.
все с ней прокатывает, просто уметь надо.
break безусловный. А ТСу надо по условию :) А самому прикрутить условие не сообразит как. Так что - шарлатаны! :)
break безусловный. А ТСу надо по условию :) А самому прикрутить условие не сообразит как. Так что - шарлатаны! :)
я думаю он пытается внутри цикла код отключения проверить... вот и не срабатывает
Да именно внутри цикла пытаюсь, трак мне и надо внутри цикла...за циклом у меня срабатывает.
Да именно внутри цикла пытаюсь, трак мне и надо внутри цикла...за циклом у меня срабатывает.
а вы задумайтесь, откуда внутри цикла возьмется этот код?
Если сильно хочется - засунь в циклы чтение кнопки, и если нажата - break. Только это конечно же «через задницу ногой ухо чесать», но как-то работать будет.
Через прерывание, я так понимаю, не получится из delay выйти.
http://arduino.ru/forum/programmirovanie/vzaimodeistvie-preryvanii-s-del...
Если сильно хочется - засунь в циклы чтение кнопки, и если нажата - break. Только это конечно же «через задницу ногой ухо чесать», но как-то работать будет.
да ну, подсказывать не интересно. Он бы через 5 минут сам дошел.
Только нормально работать все равно не будет, пока все делеи из цикла не уберет.
Через прерывание, я так понимаю, не получится из delay выйти.
ну тоже вариант, конечно :) вариант лечения кривой программы :)
Так и пробывал именно так, в цикл опрашиваю кнопку и если это она, то выход брейком , но не выходит))
Покажи код.
Если сильно хочется - засунь в циклы чтение кнопки, и если нажата - break. Только это конечно же «через задницу ногой ухо чесать», но как-то работать будет.
да ну, подсказывать не интересно. Он бы через 5 минут сам дошел.
Только нормально работать все равно не будет, пока все делеи из цикла не уберет.
делеи убрал, все убрал, кроме цикла, внутри цикла условие задаю если код кнопки if (kod == -484956645) break; не работает
Покажи код.
Покажи код.
и где тут опрос кнопки? ну и тупость...
Как переменная kod узнает, что на ИК-приемник пришла новая команда?
Del.
Надоело.
И почему ты решил, что не работает? Этот кусок кода где? В loop’е? А loop() это что?
BOOM, ну вы-то не тупите вместе с ТС. Это не работает и не должно
Покажи код.
и где тут опрос кнопки? ну и тупость...
Как переменная kod узнает, что на ИК-приемник пришла новая команда?
так же как и в самом верху, я нажимаю на кнопку с этим кодом, код кнопки получает ИК и это значение сравнивается с нашим, если это оно значит условие выполняется..
так же как и в самом верху, я нажимаю на кнопку с этим кодом, код кнопки получает ИК и это значение сравнивается с нашим, если это оно значит условие выполняется..
вы правда такой тупой или прикидываетесь?
Думаете, когда на ИК приемник приходит команда - переменная kod обновляется сама?
Посмотрите внимательно в начало кода - вы этот код читаете и присваиваете переменной явно. И потом он работает.
А в этом цикле вы ничего не читаете и не присваиваете. И оно не работает. Логично?
Вьюноша, ты дэбил? Как ты думаешь, что делает строчка
049
kod = (unsigned
long
)fnc_ir_rx_decode();
в начале твоего loop()?
Вьюноша, ты дэбил?
судя по всему, код от первой до последней строчки списал в инете
а по ресету выходить из цикла быстро и надежно!
гильотина как средство против мигрени?
Вьюноша, ты дэбил? Как ты думаешь, что делает строчка
049
kod = (unsigned
long
)fnc_ir_rx_decode();
в начале твоего loop()?
зачем оскорблять то сразу???