ВКЛ/ВЫКЛ Реле по заданному времени

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017

Привет всем!

задача: пользователь задает период работы реле (например 30мин) это инфу хранит переменная 'time'

              на lcd 2004 выводится обратный отчет? по окончании 30 мин реле отключается

Подскажите как это реализовать, нужны ли  будут часы реального времени?

был тут но не понял((

http://arduino.ru/forum/obshchii/vkl-i-vykl-rele-po-vremeni

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Если точночть в районе 1% устраивает, то RTC не обязателен.

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017

если разбег 1% то не страшно

как проще реализовать? с ним или без модуля р.в.

sadman41
Offline
Зарегистрирован: 19.10.2016

Включать реле умеете? А выключать? Про миллис, про то как вычитать и сравнивать - тоже?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Начните со словесного описания алгорима.

Вот что лично Вы делали бы, окажись на месте контроллера?

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017

есть lcd, энкодер, движок и мр3 модуль.

пользователь задает время работы реле и двиготеля т.е

например задал 30мин. 

вкл. двигатель и реле на 30 мин. потом выключатся и надо реализовать еще чтобы на 10той минуте отключался только движок на 5ть минут потом через 5 мин (в сумме 15мин) включался

я такое делал на нектионе там есть таймер а в ардуино не разобрался)

 

b707
Offline
Зарегистрирован: 26.05.2017

nurgazin_d@mail.ru пишет:

есть lcd, энкодер, движок и мр3 модуль.

пользователь задает время работы реле и двиготеля т.е

например задал 30мин. 

вкл. двигатель и реле на 30 мин. потом выключатся и надо реализовать еще чтобы на 10той минуте отключался только движок на 5ть минут потом через 5 мин (в сумме 15мин) включался

я такое делал на нектионе там есть таймер а в ардуино не разобрался)

 

батенька, ну куда ж вы полезли? Вам бы для начала "мама" выговаривать научиться...

Начните с простого - опишите, как вас просили, алгоритм работы контроллера для одного реле с простой задержкой 30 минут

FREEKER
Offline
Зарегистрирован: 04.03.2019

Присоединяюсь к вопросу. Так же и мне надо на один из портов установить "1" через 2 минуты, сделать замер и опять порт в "0" вернуть.

Должен же быть в ардуино таймер.

В моей програмке уже используется SimpleTimer


#include <SimpleTimer.h>
void setup() 
{ timer.setInterval(10000L, sendSensor);
} 
void sendSensor() 
{ float h = dht.readHumidity();
 Blynk.virtualWrite(V5, h);
}
void loop()
{ timer.run(); // Initiates SimpleTimer
}

Т.е. Проверять датчики, включать релюшки через заданный интервал могу.

Можно на основе этого решить задачу nurgazin_d@ma, завести переменную t и в функции "sendSensor" простейший счётчик t++;  Как натикало нужное время, так сделать действие.

Но вопрос остаётся. Может уже есть, что то готовое.  А это решение комуто покажется костылями.

b707
Offline
Зарегистрирован: 26.05.2017

FREEKER пишет:

Должен же быть в ардуино таймер.

почитайте про функцию millis() - это все. что нужно для подобного типа задачек. Никакие "таймеры" для включения лампочки раз в 30 минут не требуются.

FREEKER
Offline
Зарегистрирован: 04.03.2019

Прочитал про millis(), И также почитал про SimpleTimer он так же базируется на millis.

Правильно понимаю, что аппаратного таймера с прерываниями в ардуино нет? Т.е. CPU никогда не спит или это всё скрыто от юзера, и что на самом деле происходит, знают только единицы.

sadman41
Offline
Зарегистрирован: 19.10.2016

Аппаратных часов в ATMega328 нет. А таймеры - есть. Но вы под "таймером" подразумеваете аппаратные часы, видимо.

b707
Offline
Зарегистрирован: 26.05.2017

FREEKER пишет:

Правильно понимаю, что аппаратного таймера с прерываниями в ардуино нет?

есть и даже обычно не один. В Атмеге328 (той. что стоит в Уно и Нано) - три аппаратных таймера.

Только повторяю, для решения задачки зажечь лампочку на 30 минут - нет никакой надобности привлекать такие высокие материи, как "аппаратные ьаймеры с прерываниями" - все решается обычным миллис.

Хотя безусловно. "под капотом" у миллис аппаратный таймер

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017

попытаюсь обьяснить на примере кода из некстион дисплея - где есть таймер 

val=это типа captiоn из паскаля(я на паскале пишу в основном) label.captiоn:="1268654" типа такого

т.е va0.val=1                    va0 будет 1

va0=переменная 

n2=хранит секунды

n1=хранит минуты

va0.val=va0.val+1               //счетчик

n2.val=va0.val                   // показываю секунды на экране
if(va0.val==60)                  // если секунды =60 то
{
  n1.val=n1.val+1                //переменную минуты +1         переменую секунды обнуляем
  va0.val=0                    
  j0.val=j0.val+4
}
if(n1.val==10)                    //если минут натикало 10 то оправляю команду (print "200") в ардуино на отключение реле   
{
  bt0.val=0
  bt1.val=0
  bt2.val=1
  bt3.val=0
  print "200"
}
if(n1.val==15)                     //если минут натикало 15 то оправляю команду (print "300") в ардуино на включение реле   
{
  bt0.val=1
  bt1.val=0
  bt2.val=1
  bt3.val=0
  print "300"
}
if(n1.val==20)                       //если минут натикало 20 то оправляю команду (print "200") в ардуино на отключение реле   
{
  bt0.val=0
  bt1.val=0
  bt2.val=1
  bt3.val=0
  print "200"
}
if(n1.val==25)                   //  если минут натикало 25 то оправляю команду (print "100") в ардуино на отключение реле   
{
  bt0.val=0
  bt1.val=1
  bt2.val=0
  bt3.val=0
  tm0.en=0
  tm1.en=0
  va0.val=0
  va1.val=0
  n1.val=0
  n2.val=0
  j0.val=0
  print "100"

т.е. реле работает сначала 10 мин. потом 5 мин. отдыхает затем после 15й минуты. вкл. еще на 5мин. после 5ти мин. отключается еще на 5ть минут (в сумме цикл работы занимает 25 минут) 

надеюсь объяснил уф.

спасибо.

ребята помогите разобраться с этой проблемой, про millis смотрел тут https://www.youtube.com/watch?v=Ik7SwQ477mA но из-за больших пока пробелов знаний в программировании ардуино не понимаю о чем речь, ну т.е. японимаю millis это счетчик ардуино который начинат отчет времени с момента вкл. ардуино и переполняется через 50 дней но не могу понять как это применить к моей задаче покажите наглядно для чайника

я думал реализовать задачу используя часы реального времени

при включении цикла работы реле ардуино снимает показания с часов допусти сейчас там 12:50:20

и записывает значения переменную min

и условие 

if min+10 то отключаю реле

if min+5 то вкл реле

if min+5 то выкл реле

if min+5 то вкл реле

вот опять из-за пробелов в знании работы с часами и вообще, я не понимаю как реализовать скетч

УМОЛЯЮ приведите пример где бы были переменные отвечающие за время цикла (мин) (секунды) они будут отправлятся на лсд дисплей 

ПОМОГИТЕ СРОЧНО НАДО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО 

sadman41
Offline
Зарегистрирован: 19.10.2016

Берите учебник по ардуине и срочно-срочно его читайте. Можете даже не спать, чтобы успеть заполнить все пробелы и понять, как реализовать скетч.

Или есть второй вариант: идете в "ищу исполнителя" и обмениваете свои деньги на чужое время.

bwn
Offline
Зарегистрирован: 25.08.2014

Вам в #4 сказали, что нужно сделать. Вы походу не поняли, а уперлись в свои реле.
А фактически, надо было расписать, как вы, сами, отслеживаете время - посмотрели на часы, запомнили текущее время, занимаетесь своими делами и посматриваете на часы. Прошел требуемый интервал, совершили действие и так по кругу. Миллис - это ваши часы на стенке, ток считает не часы и минуты, а миллисекунды.

Здесь про миллис хорошо.

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017

sadman41 пишет:

Берите учебник по ардуине и срочно-срочно его читайте. Можете даже не спать, чтобы успеть заполнить все пробелы и понять, как реализовать скетч.

Или есть второй вариант: идете в "ищу исполнителя" и обмениваете свои деньги на чужое время.

не будь я голодным студентом - а будь я толтосуммом вроде Вас, так бы и поступил, я думаю что такие площадки и создавались для общения и помощи начинающим а не язвительных коментариев проходимцев вроде вас.

bwn
Offline
Зарегистрирован: 25.08.2014

nurgazin_d@mail.ru пишет:

 я думаю что такие площадки и создавались для общения и помощи начинающим а не язвительных коментариев проходимцев вроде вас.

Почитайте начало песочницы и не хамите старожилам, которые еще и знают на три порядка больше вас.

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017

Я всегда отношусь с уважением к старшим и опытным собеседникам, но зачем вы пишете такое о чем я и без вас знаю, ят пришел за помощью а не за демогогией.

ИЗВЕНИТЕ МЕНЯ ПОЖАЛУЙСТА, ЧТО НАХОМИЛ, просто зачем писать не о чем. еще раз извените!!!!!

sadman41
Offline
Зарегистрирован: 19.10.2016

nurgazin_d@mail.ru пишет:

не будь я голодным студентом - а будь я толтосуммом вроде Вас, так бы и поступил, я думаю что такие площадки и создавались для общения и помощи начинающим а не язвительных коментариев проходимцев вроде вас.

Голодного студента я могу накормить, а ленивого - нет. И, к слову, проходимцем всегда называли того, кто жил за чужой счёт, обманом получая то, чего сам делать не желал.

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017

bwn пишет:

nurgazin_d@mail.ru пишет:

 я думаю что такие площадки и создавались для общения и помощи начинающим а не язвительных коментариев проходимцев вроде вас.

Почитайте начало песочницы и не хамите старожилам, которые еще и знают на три порядка больше вас.

посоветуйте пожалуйста литературу, СПАСИБО

bwn
Offline
Зарегистрирован: 25.08.2014

Я же в #14 дал ссылку на Лешака и расписал, что с этим делать.

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017

sadman41 пишет:

nurgazin_d@mail.ru пишет:

не будь я голодным студентом - а будь я толтосуммом вроде Вас, так бы и поступил, я думаю что такие площадки и создавались для общения и помощи начинающим а не язвительных коментариев проходимцев вроде вас.

Голодного студента я могу накормить, а ленивого - нет. И, к слову, проходимцем всегда называли того, кто жил за чужой счёт, обманом получая то, чего сам делать не желал.

да понял я все ребята простите пожалуйста! 

буду учить!

тему  "ВКЛ/ВЫКЛ Реле по заданному времени" можно считать закрытой спасибо всем.

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017

bwn пишет:

Вам в #4 сказали, что нужно сделать. Вы походу не поняли, а уперлись в свои реле.
А фактически, надо было расписать, как вы, сами, отслеживаете время - посмотрели на часы, запомнили текущее время, занимаетесь своими делами и посматриваете на часы. Прошел требуемый интервал, совершили действие и так по кругу. Миллис - это ваши часы на стенке, ток считает не часы и минуты, а миллисекунды.

Здесь про миллис хорошо.

да вы описали задачу мою так просто и доступно) я так не могу излогать свои мысли-это плохо(

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017
FREEKER
Offline
Зарегистрирован: 04.03.2019

unsigned long Time; // время с начала включения
// On
#define T1 10 // время первое
// Off
#define T2 15
// On
#define T3 20
// Off
#define T4 25
Time = millis();
void loop{
if((millis()-Time)>=T4*60000)
{ReleOn;
Time = millis();
}
else if((millis()-Time)>=T3*60000)
ReleOff;
else if((millis()-Time)>=T2*60000)
ReleOn;
else if((millis()-Time)>=T1*60000)
ReleOff;
delay(1000); // поковырять в носу секунду
}
Как то так. Заменить ReleOff и On на команду включения.

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017

FREEKER пишет:

Огромное вам спасибо очень помогли!

FREEKER
Offline
Зарегистрирован: 04.03.2019

Но выше представленый метод, мне не очень нравится, это если помимо этого цикла ничего нет.

Я бы чуть усложнил.

#include <SimpleTimer.h>
SimpleTimer timer;

void Relay()
{

Сюда попадаем каждую минуту Можно и switch использовать или if else

Min++;
}

void setup()
{unsigned short Min;
  timer.setInterval(60000L, Relay);    // Каждую минуту вызывает функцию Relay
  pinMode(PIN_Relay, OUTPUT);     // Initialize the pin as an output
}

void loop()
{
  timer.run(); // Initiates SimpleTimer
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Реле будет очень весело пощёлкивать, начиная с  16-й минуты, когда станет проходить условия "через 5 минут выключить" и "через 15 минут включить".

FREEKER
Offline
Зарегистрирован: 04.03.2019

В первом примере в каждом отрезке времени программа будет отправлять значение в регистр порта

digitalWrite(PIN_HeatMQ4, LOW);  // например

Это не значит что реле будет счёлкать. Так как направление порта pinMode(PIN_HeatMQ4, OUTPUT); и само значение "LOW" не меняется.

Должно рабоатать, можно ещё тупее написать используя delay().

sadman41
Offline
Зарегистрирован: 19.10.2016

А, там else расставлены. Тогда да, щёлкать не станет. Просто любой интервал больше 10 сек будет попадать во второе условие.

Сорри, был невнимателен днём - не заметил, что ещё и порядок обратный. 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

А все потому что народ не хочет учить  !!! автоматы. Ничего пойдет в армию и будет учить афтамат Калашникова.

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017
Сделал так 

unsigned long previousMillis = 0;
int sec = 0;
int Smin,Qmin=0;
const int DV=3;           //ШИМ ДВИЖКА           (ПИН 3)
#define DV_VKL 4          //ВКД/ВЫКЛ ДВИЖКА      (ПИН 4)


 unsigned long currentMillis = millis ( );
  if ( currentMillis - previousMillis >= 1000 ) 
  { 
  previousMillis = currentMillis;
  lcd.setCursor(0,0);lcd.print("====Seans_VREMYA====");
   lcd.setCursor(9, 2);lcd.print(" ");
   lcd.setCursor(8, 2); lcd.print(Smin); 
  lcd.setCursor(10, 2); lcd.print(":");
  lcd.setCursor(12, 2);lcd.print(" ");
  lcd.setCursor(11, 2); lcd.print(sec++); 
  if (sec==59){sec=0; Smin++;}
   }

    digitalWrite(DV_VKL, 1);
    analogWrite (DV, Silla);
    digitalWrite(RELAY8, 0); 
    digitalWrite(RELAY9, 1); 
    digitalWrite(RELAY10,1); 
    if(encoderButton.flagClick == true)
    {
    encoderButton.flagClick = false;
    MENU = 0; pos = 1; lcd.clear();sec=0;
    }
    
  } 
  if (Seans==25)
  {   
  if (Smin==10){digitalWrite(DV_VKL, 0);}  
    if (Smin==11){digitalWrite(DV_VKL, 0);}
    if (Smin==12){digitalWrite(DV_VKL, 0);}
    if (Smin==13){digitalWrite(DV_VKL, 0);}
    if (Smin==14){digitalWrite(DV_VKL, 0);}
  if (Smin==15){digitalWrite(DV_VKL, 1);}  
    if (Smin==16){digitalWrite(DV_VKL, 1);}
    if (Smin==17){digitalWrite(DV_VKL, 1);}
    if (Smin==18){digitalWrite(DV_VKL, 1);}
    if (Smin==19){digitalWrite(DV_VKL, 1);}
  if (Smin==20){digitalWrite(DV_VKL, 0);}
    if (Smin==21){digitalWrite(DV_VKL, 0);}
    if (Smin==22){digitalWrite(DV_VKL, 0);}
    if (Smin==23){digitalWrite(DV_VKL, 0);}
    if (Smin==24){digitalWrite(DV_VKL, 0);}
    if (Smin==25){digitalWrite(DV_VKL, 0);}
  }

Ребята огромное вам спасибо за отзывчивость и помощь в проекте!!!!!!!

FREEKER тебе особенно

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ненадежно это: шаг (currentMilis - previousMillis) может быть больше 1000, а дальше сравнение происходит на равенство. Ошибка (превышение над 1000) будет накапливаться и периодически приводить к пропускам.

Гораздо лучше либо сравнивать sec на неравенство с prevSec, либо previoыMillis вычислять не как currentMillis, а как previousMillis + 1000.

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017

andriano пишет:

Ненадежно это: шаг (currentMilis - previousMillis) может быть больше 1000, а дальше сравнение происходит на равенство. Ошибка (превышение над 1000) будет накапливаться и периодически приводить к пропускам.

Гораздо лучше либо сравнивать sec на неравенство с prevSec, либо previoыMillis вычислять не как currentMillis, а как previousMillis + 1000.

Спасибо за совет, таких циклов будет 5-8 раз потом будут отключать от сети - наверное погрешность не критична))

FREEKER
Offline
Зарегистрирован: 04.03.2019

nurgazin_d@mail.ru пишет:

Сделал так 

  if (Smin==10){digitalWrite(DV_VKL, 0);}  
    if (Smin==11){digitalWrite(DV_VKL, 0);}
    if (Smin==12){digitalWrite(DV_VKL, 0);}
    if (Smin==13){digitalWrite(DV_VKL, 0);}
    if (Smin==14){digitalWrite(DV_VKL, 0);}
  if (Smin==15){digitalWrite(DV_VKL, 1);}  
    if (Smin==16){digitalWrite(DV_VKL, 1);}
    if (Smin==17){digitalWrite(DV_VKL, 1);}
    if (Smin==18){digitalWrite(DV_VKL, 1);}
    if (Smin==19){digitalWrite(DV_VKL, 1);}
  if (Smin==20){digitalWrite(DV_VKL, 0);}
    if (Smin==21){digitalWrite(DV_VKL, 0);}
    if (Smin==22){digitalWrite(DV_VKL, 0);}
    if (Smin==23){digitalWrite(DV_VKL, 0);}
    if (Smin==24){digitalWrite(DV_VKL, 0);}
    if (Smin==25){digitalWrite(DV_VKL, 0);}

Зачем так сложно, дублировать каждую минуту?

Smin Ты ведь сам щёлкаешь, т.е. можешь использовать "==" и не бояться пропустить

Но Я не настаиваю, дело Ваше. Но глазам больно, даже по меркам ардуино. :)

nurgazin_d@mail.ru
Offline
Зарегистрирован: 18.12.2017

FREEKER пишет:

nurgazin_d@mail.ru пишет:

Сделал так 

  if (Smin==10){digitalWrite(DV_VKL, 0);}  
    if (Smin==11){digitalWrite(DV_VKL, 0);}
    if (Smin==12){digitalWrite(DV_VKL, 0);}
    if (Smin==13){digitalWrite(DV_VKL, 0);}
    if (Smin==14){digitalWrite(DV_VKL, 0);}
  if (Smin==15){digitalWrite(DV_VKL, 1);}  
    if (Smin==16){digitalWrite(DV_VKL, 1);}
    if (Smin==17){digitalWrite(DV_VKL, 1);}
    if (Smin==18){digitalWrite(DV_VKL, 1);}
    if (Smin==19){digitalWrite(DV_VKL, 1);}
  if (Smin==20){digitalWrite(DV_VKL, 0);}
    if (Smin==21){digitalWrite(DV_VKL, 0);}
    if (Smin==22){digitalWrite(DV_VKL, 0);}
    if (Smin==23){digitalWrite(DV_VKL, 0);}
    if (Smin==24){digitalWrite(DV_VKL, 0);}
    if (Smin==25){digitalWrite(DV_VKL, 0);}

Зачем так сложно, дублировать каждую минуту?

Smin Ты ведь сам щёлкаешь, т.е. можешь использовать "==" и не бояться пропустить

Но Я не настаиваю, дело Ваше. Но глазам больно, даже по меркам ардуино. :)

Сам не восторге))) пробывал так:

 if (Smin==10){digitalWrite(DV_VKL, 0);}
 if (Smin==15){digitalWrite(DV_VKL, 1);}
 if (Smin==20){digitalWrite(DV_VKL, 0);}
......

но работать начинает smin==10 как и положено не работает а потом на smin==11 начинает работать мистика

b707
Offline
Зарегистрирован: 26.05.2017

nurgazin_d@mail.ru пишет:

Сам не восторге))) пробывал так:

 if (Smin==10){digitalWrite(DV_VKL, 0);}
 if (Smin==15){digitalWrite(DV_VKL, 1);}
 if (Smin==20){digitalWrite(DV_VKL, 0);}
......

но работать начинает smin==10 как и положено не работает а потом на smin==11 начинает работать мистика

Пишите четко - что работает и что нет. И, желательно, со знаками препинания, а то ничего не понятно.

Код, плиз, выложите полный - а то выше какие-то обрывки. Совершенно непонятно - этот код расположен внутри loop(), setup() или сам по себе?

Чайник в ардуино
Offline
Зарегистрирован: 10.06.2016

nurgazin_d@mail.ru пишет:

Привет всем!

задача: пользователь задает период работы реле (например 30мин) это инфу хранит переменная 'time'

              на lcd 2004 выводится обратный отчет? по окончании 30 мин реле отключается

Подскажите как это реализовать, нужны ли  будут часы реального времени?

был тут но не понял((

http://arduino.ru/forum/obshchii/vkl-i-vykl-rele-po-vremeni

 
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
 
LiquidCrystal_I2C lcd(0x27,16,2);
 
int ON_state = EEPROM.read(0);
int OFF_state = EEPROM.read(1);
int ON_state_current = ON_state;
int OFF_state_current = OFF_state;
int state_position = 0;
int seconds = 60;
int fadeAmount = 1; // изменение на
 
unsigned long currentTime;
unsigned long loopTime;
unsigned long loopTime2 = 0;
const int pin_A = 12;  // пин1 энкодера
const int pin_B = 11;  // пин2 энкодера
const int button = 5;  // кнопка энкодера
const int relay = 8;  // реле
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;
int st=0;
int buttonState = 0;
int buttonBlock = 0;
 
void setup()  {
  Serial.begin(9600);
  lcd.init(); 
  lcd.backlight();
  pinMode(relay, OUTPUT);
  digitalWrite(relay, LOW);
  pinMode(pin_A, INPUT);
  pinMode(pin_B, INPUT);
  pinMode(button, INPUT);
  currentTime = millis();
  loopTime = currentTime;
  lcd_update(); 
 
void loop()  {
  // читаем кнопку
  buttonState = digitalRead(button);
  if (buttonState == LOW) {
     if (buttonBlock == 0) {    
        switch (st) {
          case 1:
            st=st+1;
            EEPROM.write(0, ON_state);
            EEPROM.write(1, OFF_state);            
            break;          
          case 2:
            st=0;
            seconds = 60;
            EEPROM.write(0, ON_state);
            EEPROM.write(1, OFF_state);
            ON_state_current = ON_state;
            OFF_state_current = OFF_state;            
            break;
          default: 
            st=st+1;
        }
        buttonBlock=1;
        lcd_update();        
     }
  } 
  else {
     buttonBlock=0;
  } 
  
 
  // заходит каждые 2мс
  currentTime = millis();
  if(currentTime >= (loopTime + 2)){ 
    encoder_A = digitalRead(pin_A);    // Read encoder pins
    encoder_B = digitalRead(pin_B);   
    if((!encoder_A) && (encoder_A_prev)){
      // УВЕЛИЧЕНИЕ 
      if(encoder_B) {
        switch (st) {
          case 1: // редактор ON
            if (ON_state + fadeAmount <= 255) ON_state += fadeAmount;
            lcd_update();
            break;
          case 2: // редактор OFF
            if (OFF_state + fadeAmount <= 255) OFF_state += fadeAmount;
            lcd_update();
            break;
          default: // начальный экран, редактор текущего режима
            // какой текущий режим?
            if (state_position==1)
            {
              if (ON_state_current + fadeAmount <= 255) ON_state_current += fadeAmount;
            }
            if (state_position==0)
            {
              if (OFF_state_current + fadeAmount <= 255) OFF_state_current += fadeAmount;
            }   
            lcd_update();         
            break;
         }        
      }   
      else {
        // УМЕНЬШЕНИЕ     
        switch (st) {
          case 1: // редактор ON
            if (ON_state - fadeAmount > 0) ON_state -= fadeAmount;
            lcd_update();
            break;
          case 2: // редактор OFF
            if (OFF_state - fadeAmount > 0) OFF_state -= fadeAmount;
            lcd_update();
            break;
          default: // начальный экран, редактор текущего режима
            // какой текущий режим?
            if (state_position==1)
            {
              if (ON_state_current - fadeAmount >= 1) ON_state_current -= fadeAmount;
              if (ON_state_current <= 0 ) ON_state_current = 1;
            }
            if (state_position==0)
            {
              if (OFF_state_current - fadeAmount >= 1) OFF_state_current -= fadeAmount;
              if (OFF_state_current <= 0 ) OFF_state_current = 1;            
            }   
            seconds = 60;
            lcd_update();         
            break;
         }               
      }   
 
    }   
    encoder_A_prev = encoder_A;     // Store value of A for next time    
    loopTime = currentTime;  // Updates loopTime
  }
  
  // Второе прерывание - обратный отсчет, заходит каждую 1 сек
  if(currentTime >= (loopTime2 + 1000)){
    loopTime2 = currentTime;
    // какой текущий режим?
    if (seconds - 1 >= 0)
    {
      seconds -= 1;
      Serial.print(ON_state_current); Serial.print(" ");
      Serial.print(OFF_state_current); Serial.print(" ");
      Serial.print(seconds); Serial.print(" ");   
      Serial.print(state_position); Serial.println(" ");
    } else
    {
      seconds = 60;
      if (state_position==1) // ON
      {
        
        if (ON_state_current - 1 >= 1) {ON_state_current -= 1;} else {OFF_state_current = OFF_state;ON_state_current = ON_state; state_position = 0; digitalWrite(relay, LOW);}
      } else // OFF
      {
        if (state_position==0)
        {
          
          if (OFF_state_current - 1 >= 1) {OFF_state_current -= 1;} else {OFF_state_current = OFF_state;ON_state_current = ON_state; state_position = 1;digitalWrite(relay, HIGH);}
        }
      }
      lcd_update();
    }
  }    
}
 
void lcd_update() {
    lcd.clear();
    switch (st) {
      case 1: // редактор ON
        lcd.setCursor(0, 0); lcd.print("Select value ON");
        lcd.setCursor(0, 1); lcd.print("ON:");
        lcd.setCursor(4, 1); lcd.print(ON_state);
        lcd.setCursor(8, 1); lcd.print("OFF:");
        lcd.setCursor(13, 1); lcd.print(OFF_state);        
        break;
      case 2: // редактор OFF
        lcd.setCursor(0, 0); lcd.print("Select value OFF");
        lcd.setCursor(0, 1); lcd.print("ON:");
        lcd.setCursor(4, 1); lcd.print(ON_state);
        lcd.setCursor(8, 1); lcd.print("OFF:");
        lcd.setCursor(13, 1); lcd.print(OFF_state);
        break;
      default: // начальный экран, редактор текущего режима
        // какой текущий режим?
        if (state_position==1)
        {
          lcd.setCursor(0, 0); lcd.print("Active ON");
          lcd.setCursor(11, 0); lcd.print(ON_state_current);
          lcd.setCursor(0, 1); lcd.print("ON:");
          lcd.setCursor(4, 1); lcd.print(ON_state);
          lcd.setCursor(8, 1); lcd.print("OFF:");
          lcd.setCursor(13, 1); lcd.print(OFF_state);
        }
        if (state_position==0)
        {
          lcd.setCursor(0, 0); lcd.print("Active OFF");
          lcd.setCursor(11, 0); lcd.print(OFF_state_current);
          lcd.setCursor(0, 1); lcd.print("ON:");
          lcd.setCursor(4, 1); lcd.print(ON_state);
          lcd.setCursor(8, 1); lcd.print("OFF:");
          lcd.setCursor(13, 1); lcd.print(OFF_state);
        }         
        break;
     }  
}

Модератор: Дальнейшие попытки выкладывания кода в нечитаемом виде будут пресекаться путем удаления в спам. Почитайте тему - "Вставка кода в тему, комментарий"

vlad072
Offline
Зарегистрирован: 01.08.2017

Я для временнЫх событий пользую примерно такие конструкции:

uint32_t t30sec    = 0;
uint32_t t1min     = 0;
uint32_t t3hour    = 1;

//........................

void loop() {
  if ( (millis() - t30sec) > 30000 ) { t30sec = millis();
    /// то что нужно делать каждые 30 сек.
  }
  if ( (millis() - t1min) > 60000 ) { t1min = millis();
    /// то что нужно делать каждую минуту
  }
  if ( t3hour && (millis() - t3hour) > 10800000 ) { t3hour = 0;
    // то что нужно cделать один раз после 3 часов ожидания
    // "перезаряжать" можно из любого места этим: t3hour = millis();
  }
  //...................
}

В библиотечных таймерах никакого смысла не вижу.