Нужна помощь: Кнопка, тайминг, реле

SC-LERA
Offline
Зарегистрирован: 11.08.2014

Здравствуйте!

Помогите мне пожалуйста со скетчем, с апаратной я знаком.

Алгоритм такой:

Ардуинка при включении слушает кнопку на пине №X, и при нажатии, включает реле на пине №Y на 6 секунд 19 милисекунд в это время ардуинка на кнопку не реагирует (то-есть таймер на 6 секунд 19 милисекунд не перезапускает), а по истечению этого времени, не реагирует еще 10 секунд 53 милисекунды и сново уходит в ожидание команды с кнопки.

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Нужно использовать функцию millis() , две константы#define RELAY_ON 6019 и #define RELAY_OFF 10053. Еще должна быть некоторая переменная offset, которая будет точкой отсчета для сравнения с millis(). также нужна переменная флаг для того чтобы нажатие на кнопку не вызывали никаких действий.

в цикле loop пишем: если кнопка нажата и флаг не установлен то установить флаг, задать точку отсчета, включить реле. Еще один оператор сравнеия - если флаг установлне и millis() - offset больше или равно константе RELAY_ON то выключить реле. Еще один оператор сравнения - если флаг установлен и millis() - offset больше или равно сумме констант RELAY_ON и RELAY_OFF то снять флаг.

1bool isWork; //флаг
2long offset; //точка отсчета
3 
4isWork = True; //Установим флаг
5offset = millis(); //зададим точку отсчета

 

Leshiy
Offline
Зарегистрирован: 19.07.2014

Если проект расти не будет, то вполне сойдёт и delay(). Чтобы не реагировать на кнопку после запуска таймера, можно ввести переменную-флаг, состояние которой будет указывать на состояние кнопки, была нажата, или нет. 

1SANTER1
1SANTER1 аватар
Offline
Зарегистрирован: 07.03.2015
Подскажите пожалуйста как решить задачу: Нажимаем кнопку и держим неизвестно сколько, (это будет не кнопка, а датчик,но пока кнопка)
Как только кнопка нажата, включается реле и работает 5 секунд, потом выключается и больше не включается до следующего нажатия на кнопку. Перерыл весь интернет нечего не нашёл, delay не подходит. Как решить незнаю :(  
01#define button 2    // кнопка
02#define relay  1    // реле
03void setup(){
04    pinMode(button,INPUT_PULLUP);    // кнопка на вход  вкл.подтягивающий резистор.
05    pinMode(relay,OUTPUT);           // реле на выход
06}
07void loop()
08{
09  if (!digitalRead(button))           // нажали кнопку
10    digitalWrite(relay,HIGH);         // включили реле
11   
12}

 

Kolchugin
Offline
Зарегистрирован: 15.12.2013

Попробуйте вот так (реле на пин 13):

 

1SANTER1
1SANTER1 аватар
Offline
Зарегистрирован: 07.03.2015

Kolchugin пишет:

Попробуйте вот так (реле на пин 13):

 

Спасибо. Вроде работает.

Но почему для такой простой функции нужен такой огромный код ?

Подругому не как ?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

1SANTER1, ваш случай удобно реализовать используя внешнее прерывание (вывод под кнопку не изменять). Кнопка  нажата - ничего. Кнопка -отжата, и счёт 5 секунд пошёл, я правильно понял?

01#define button 2    // кнопка
02#define relay  13    // реле
03volatile bool flag=0;
04volatile unsigned long prevmillis;
05 
06void setup(){
07pinMode(button,INPUT_PULLUP);    // кнопка на вход  вкл.подтягивающий резистор.
08pinMode(relay,OUTPUT);           // реле на выход
09attachInterrupt(0, my_func, RISING); //прерывание на возрастание лог. уровня
10}
11 
12void loop() {
13 
14if (flag==1) { // если кнопку отжали
15  digitalWrite(relay,HIGH); //включаем что-то
16        if ( millis()-prevmillis >=5000){   //если счёт 5 секунд вышел, то
17        digitalWrite(relay,LOW);   //отключаем что-то
18         flag=0; //сбрасываем флаг работы
19              }
20       }
21}
22 
23void my_func() { //отжали
24flag=1; //ставим флаг что работа идёт..
25prevmillis= millis(); //запомним время
26}

 

1SANTER1
1SANTER1 аватар
Offline
Зарегистрирован: 07.03.2015

dimax пишет:

1SANTER1, ваш случай удобно реализовать используя внешнее прерывание (вывод под кнопку не изменять). Кнопка  нажата - ничего. Кнопка -отжата, и счёт 5 секунд пошёл, я правильно понял?

01#define button 2    // кнопка
02#define relay  13    // реле
03volatile bool flag=0;
04volatile unsigned long prevmillis;
05 
06void setup(){
07pinMode(button,INPUT_PULLUP);    // кнопка на вход  вкл.подтягивающий резистор.
08pinMode(relay,OUTPUT);           // реле на выход
09attachInterrupt(0, my_func, RISING); //прерывание на возрастание лог. уровня
10}
11 
12void loop() {
13 
14if (flag==1) { // если кнопку отжали
15  digitalWrite(relay,HIGH); //включаем что-то
16        if ( millis()-prevmillis >=5000){   //если счёт 5 секунд вышел, то
17        digitalWrite(relay,LOW);   //отключаем что-то
18         flag=0; //сбрасываем флаг работы
19              }
20       }
21}
22 
23void my_func() { //отжали
24flag=1; //ставим флаг что работа идёт..
25prevmillis= millis(); //запомним время
26}

 

Несовсем так. Нажимается кнопка и с ней включается реле, через 5 секунд реле должно выключится деже если кнопка остается нажатой.

Kolchugin
Offline
Зарегистрирован: 15.12.2013

1SANTER1 пишет:

Спасибо. Вроде работает.

Но почему для такой простой функции нужен такой огромный код ?

Подругому не как ?

В каком смысле большой? Если по количеству строк, ну так выкинте из него защиту от дребезга. Будет немного меньше.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

1SANTER1, ну тогда по идее только слово RISING поменять на FALLING

1SANTER1
1SANTER1 аватар
Offline
Зарегистрирован: 07.03.2015

dimax пишет:

1SANTER1, ну тогда по идее только слово RISING поменять на FALLING

Ага :) Огромное вам спасибо.

X-Dron
Offline
Зарегистрирован: 24.01.2015

Топикстартера нет, а про решение второй части вопроса никто не написал.

SC-LERA пишет:

а по истечению этого времени, не реагирует еще 10 секунд 53 милисекунды и сново уходит в ожидание команды с кнопки.

Kolchugin
Offline
Зарегистрирован: 15.12.2013

X-Dron пишет:
Топикстартера нет, а про решение второй части вопроса никто не написал.
SC-LERA пишет:
а по истечению этого времени, не реагирует еще 10 секунд 53 милисекунды и сново уходит в ожидание команды с кнопки.

Так скетч из 4 сообщения вам не подходит? Поменяйте тайминги и всё. По топикстартеру:

 

X-Dron
Offline
Зарегистрирован: 24.01.2015

У меня получилось так

01#include <Timer_P.h>
02#define RELAY_PIN 13
03#define KEY_PIN 2
04 
05Timer_P RelayOn, RelayBlock;
06long Pulse_ms = 6019, Block_ms = 10063;
07bool  RelayOnQO_Old = false;
08 
09void setup(){
10  pinMode(KEY_PIN, INPUT_PULLUP);
11  pinMode(RELAY_PIN, OUTPUT);
12}
13 
14void loop(){
15  RelayOn.TimerV(!digitalRead(KEY_PIN) && !RelayOn.Q0(), RelayBlock.Q0(), 1, Pulse_ms);
16  RelayBlock.TimerV(!RelayOn.Q0() && RelayOnQO_Old, 0, 1, Block_ms);
17  digitalWrite (RELAY_PIN, RelayOn.Q0());
18  RelayOnQO_Old = RelayOn.Q0();
19}

Библиотека Timer_P.h здесь

https://github.com/X-Dron/X-Dron_lib/archive/master.zip

Это для схемы со стягивающим резистором (INPUT_PULLUP и !digitalRead(KEY_PIN)