Обработка количества нажатий кнопки

andre13455
Offline
Зарегистрирован: 26.08.2016

Привет всем.

Хочу сделать своеобразный таймер.

Одна кнопка и одно реле.

При подаче питания нагрузка включена. При нажатии кнопки работает ещё 15 мин и отключается. Если нажать 2 раза - 30 мин, 3 - 45, 4 раза час - и так далее, максимально 24 часа.

Не соображу, как это описать в коде?

andre13455
Offline
Зарегистрирован: 26.08.2016

Нашёл подходящую библиотеку, http://roboforum.ru/forum86/topic15932.html

как теперь её применить?

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

И что, для 24 часов кнопку надо 96 раз жать? Может придумать другой алгоритм работы?

Pyotr
Offline
Зарегистрирован: 12.03.2014

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

И что, для 24 часов кнопку надо 96 раз жать? Может придумать другой алгоритм работы?

Я делал так: нажал кнопку - мигает светик раз в сек - удерживаем кнопку и считаем количество вспышек светика. Одна вспышка = 15 мин или там 10 мин. Набралось нужное количество вспышек - отпустил кнопку - число записал в EEPROM, чтоб при следующих включениях/перезагрузке не потерять значение.

andre13455
Offline
Зарегистрирован: 26.08.2016

Кстати, отличная идея. Кодом не поделитесь?)) Мне записывать в EEPROM ничего не надо, хочу сделать отключение вентиляции в ванной с задержкой
 

Pyotr
Offline
Зарегистрирован: 12.03.2014

Вам нужен таймер обратного отсчета, например CDT-1G в Леруа брал по 100 руб. Задержки 5, 10...45,50 мин.

Если всёже хочется самому сделать, то опишу словами, Вы попробуете написать скетч, а мы с коллегами подредактируем, если что.

andre13455
Offline
Зарегистрирован: 26.08.2016

Давайте попробую написать. Хочется сделать)

Pyotr
Offline
Зарегистрирован: 12.03.2014

Рассказывайте какая дуинка и какое реле, куда что подключено?

И пошагово алгоритм работы таймера. Чтобы Вы сами чётко представляли что хотите.

andre13455
Offline
Зарегистрирован: 26.08.2016

Вместо дуинки тензи 2, но это не принципиально совершенно, фактически одно и то же.

На цифровой вход вешаем кнопку

На цифровой выход 1 - светодиод+резистор, выход 2 - реле с али с опторазвязкой. Всё работает нормально, осталось придумать код.

Алгоритм Ваш лучше моего, поэтому возьмём его)) - При подаче напряжения по умолчанию реле включено, вентилятор крутится. Вентилятор включается отдельным выключателем из коридора, реле ставим в разрыв фазы. Далее нажал кнопку - мигает светик раз в сек - удерживаем кнопку и считаем количество вспышек светика. Одна вспышка = 15 мин. Набралось нужное количество вспышек - отпустил кнопку - и теперь контроллер ждёт заданное кол-во минут и затем отрубает реле. Всю схему планирую засунуть в корпус вентилятора. Контроллер запитывается с помошью б/п от сотового до реле, и после сработки реле остаётся запитан (выключатель в коридоре включен). Пришли мы домой. Чтобы теперь включить вентилятор, выключаем и включаем выключатель. Контроллер сбрасывается в исходное состояние, когда реле включено и вентилятор крутится. Если нам ничего не надо - включаем и выключаем вентилятор ыыключателем в коридоре, как обычно. Если нужно уйти, а в ванной высокая влажность (помылись только что) - нажимаем и удерживаем кнопку, вмонтированную в вентилятор, и считаем вспышки светика. От кнопки лучше вывести веревочку вниз, так будет удобнее, да и фабричные такие варианты есть.

Вот как-то так...

Pyotr
Offline
Зарегистрирован: 12.03.2014

Пробуйте скетч... Словами дольше объснять алгоритм.

#define BUT_PIN 3
#define LED_PIN 1
#define RELE_PIN 2
#define ONE_DELAY_MIN 15
byte numBlinkLed; //храним колич.вспышек led
unsigned long timeDelayMs;
void setup(){
  pinMode(BUT_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);
  pinMode(RELE_PIN, OUTPUT);//вкл.реле
  while(digitalRead(BUT_PIN)){}//если кнопка отпущена, стоп
  delay(20);
}

void loop(){
  while(!digitalRead(BUT_PIN)){//пока кнопка нажата
    delay(800);
    digitalWrite(LED_PIN, HIGH);
    numBlinkLed++;
    delay(200);
    digitalWrite(LED_PIN, LOW);
  }
  //отпустили кнопку
  timeDelayMs = 60000UL * numBlinkLed * ONE_DELAY_MIN;
  delay(timeDelayMs);
  digitalWrite(RELE_PIN, HIGH);//выкл.реле
  while(1){}
}

 

Araris
Offline
Зарегистрирован: 09.11.2012

andre13455 пишет:

При подаче напряжения по умолчанию реле включено, вентилятор крутится. Вентилятор включается отдельным выключателем из коридора, реле ставим в разрыв фазы. Далее нажал кнопку - мигает светик раз в сек - удерживаем кнопку и считаем количество вспышек светика. Одна вспышка = 15 мин. Набралось нужное количество вспышек - отпустил кнопку - и теперь контроллер ждёт заданное кол-во минут и затем отрубает реле. Всю схему планирую засунуть в корпус вентилятора. Контроллер запитывается с помошью б/п от сотового до реле, и после сработки реле остаётся запитан (выключатель в коридоре включен). Пришли мы домой. Чтобы теперь включить вентилятор, выключаем и включаем выключатель. Контроллер сбрасывается в исходное состояние, когда реле включено и вентилятор крутится. Если нам ничего не надо - включаем и выключаем вентилятор ыыключателем в коридоре, как обычно. Если нужно уйти, а в ванной высокая влажность (помылись только что) - нажимаем и удерживаем кнопку, вмонтированную в вентилятор, и считаем вспышки светика. От кнопки лучше вывести веревочку вниз, так будет удобнее, да и фабричные такие варианты есть.

Ой. Будет ли подобное устройство удобным в повседневном использовании, сомневаюсь. Может быть стоит доверить управление вентиляцией ванной автоматике ? Датчик уровня влажности воздуха поможет решить задачу вообще без выключателей, кнопок, мигающего светодиода и человека, всей этой хитромудрией рулящего.

andre13455
Offline
Зарегистрирован: 26.08.2016

Pyotr, спасибо, попробую, здесь защита от дребезга контактов не нужна?

Araris, да, на датчике влажности было бы удобно, но ручной режим всё равно нужен (например, просто включить проветрить и не быть привязанным к выключателю), поэтому в идеале можно конечно сделать и автоматический и ручной режим с переключением между ними. Но это уже будет следующая серия))...

Pyotr
Offline
Зарегистрирован: 12.03.2014

Строка 12 - защита от дребезга. Значение можно и больше 20.

Araris
Offline
Зарегистрирован: 09.11.2012

andre13455 пишет:

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

Поддерживаю, у меня так и сделано, рекомендую.

Joiner
Offline
Зарегистрирован: 04.09.2014

Предлагаю потенциометром на аналоговый вход подавать напряжение от 0 до 5 вольт по отградуированной шкале. Диапазон выдержек выбираете сами. По значению на аналоговом входе (0-1023) назначается выдержка таймера. Ну и естественно кнопочка "Старт-Стоп".

Pyotr
Offline
Зарегистрирован: 12.03.2014

Joiner пишет:

Предлагаю потенциометром на аналоговый вход подавать напряжение от 0 до 5 вольт по отградуированной шкале. Диапазон выдержек выбираете сами. По значению на аналоговом входе (0-1023) назначается выдержка таймера. Ну и естественно кнопочка "Старт-Стоп".

Тогда уж на таймере 555 сделать... Готовые модули есть и с уже с реле.

ВН
Offline
Зарегистрирован: 25.02.2016

для длительных выдержек времени мало что годится кроме проца.

Как-то ремонтировал кофемолку, так там  таймер оказался собран на целом рукотворном ЦАПе с кучей счетчиков и резисторов.

И это выпуск не 80-х годов, а нонешнея китайская продукция

Joiner
Offline
Зарегистрирован: 04.09.2014

Pyotr пишет:

Joiner пишет:

Предлагаю потенциометром на аналоговый вход подавать напряжение от 0 до 5 вольт по отградуированной шкале. Диапазон выдержек выбираете сами. По значению на аналоговом входе (0-1023) назначается выдержка таймера. Ну и естественно кнопочка "Старт-Стоп".

Тогда уж на таймере 555 сделать... Готовые модули есть и с уже с реле.

А чем мой вариант не нравится? Регулировка почти аналоговая....точностью не сверкнешь, но период "примерно 15 минут", примерно "полтора часа" запросто можно осуществить. И мне кажется, что ручку повернуть на нужную задержку по шкале гораздо приятнее и удобнее чем считать сколько раз моргнул светодиод.

Что касается 555, конечно же можно, но настоящий ардуинщик скорее всего сделает на ардуинке. Делал генератор на 555, но в конечном итоге он оказался на тринадцатой тиньке :), возможностей ведь больше, можно и еще какие-то функции навесить.

P.S. Можно програмно шкалу разбить, например, половина шкалы до одного часа цена деления 15 мин, вторая половина цена деления 30 мин-60мин. Допустим на шкале 8 делений, первые по 15 мин до часа, последующие по часу, то таймер до 5 часов можно установить. А если надо больше...да все что угодно можно сделать

Pyotr
Offline
Зарегистрирован: 12.03.2014

Конечно с 555 я загнул... Задержки больше десятка минут на нем лучше не делать. Но очень мне уж эта микруха нравится - чего на ней только не делал.

Вообще вариантов много. Есть из чего выбрать.

msng
Offline
Зарегистрирован: 07.06.2012

делал с датчиком влажности и освещенности

(DHT11 и фоторезистор)

при включенном свете и высокой влажности вентилятор не работает,

выходишь из ванной, выключаешь свет, (если влажность большая) включается вытяжка.

так же можно включить/выключить вытяжку кнопкой, на десять минут.

вот код:

#include "DHT.h"
#define DHTPIN    13        // pin DHT
byte relay      = 12;      // вентилятор на 12 ноге
int photoPin    = A0;      // фоторезистор подключаем к А0, другим концом к общему. пин подтягиваем к +5v через 10кОм
int keyPin      = A1;      // кнопку подключаем к А1, другим концом к общему. пин подтягиваем к +5v через 10кОм
int hidro       = 32;      // порог включение влажности 
#define DHTTYPE DHT11   
DHT dht(DHTPIN, DHTTYPE);
int hidroValue=0; 
int photoValue = 0;
int prephotoValue = 0;
int val=0;
unsigned int a=0;
byte b=1;
long premil=0;
int var=2; 
byte out=0; 

void setup() {
  pinMode(relay, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  dht.begin();}
 
void loop() {
int key = analogRead(keyPin);
  if (key > 500 && (millis() - premil > 600000)) var=2; 
  if (key < 50  && (millis() - premil > 400)) var=var+1;  
  if (key < 50  && (millis() - premil > 400)) premil=millis();
  if (var==3) var=0;
if (var==1) {out=0;} 
if (var==0) {out=1;}
if (var==2) 
    {a=(millis()/1000) ;
    
      if (a%10==0 && b==1) 
          {hidroValue = dht.readHumidity(); b=0;} 
    if (a%10!=0) b=1;
 
    photoValue = analogRead(photoPin);
    photoValue = map(photoValue, 0, 1023, 0, 255); 
    if (photoValue>191 && hidroValue>hidro) {out=1;} 
    if (hidroValue<=hidro-5 || photoValue<180 ) {out=0;} 
    }

if (hidroValue>hidro) {digitalWrite(2, HIGH);} else {digitalWrite(2, LOW);} 
if (photoValue>191) {digitalWrite(3, HIGH);} else {digitalWrite(3, LOW);} 


if (var==0) {digitalWrite(4, LOW);} 
if (var==1) {digitalWrite(4, HIGH);} 
if (var==2) {if (a%2==0) {digitalWrite(4, LOW);} else {digitalWrite(4, HIGH);}} 
if (out==0 ) {digitalWrite(relay, LOW);} 
if (out==1 ) {digitalWrite(relay, HIGH);}
}