8-и канальное реле времени (Arduino)

На рисунке показана схема 8-и канального реле времени, в реле времени используется Arduino Nano, часы реального времени DS3231 (модуль), семисегментный четырех-разрядный индикатор  на базе драйвера TM1637 (модуль TM1637) и четыре кнопки управления.

DS3231

В каждом канале можно задать время включения и выключения реле, все значения времени включения и выключения реле сохраняются в энергонезависимой памяти.

Управление реле времени:

  • Первая кнопка — «часы», она позволяет просматривать текущее время (по умолчанию), секунды, дату, месяц и год.
  • Вторая кнопка — редактирование времени реле, при нажатии на кнопку поочередно появляются показания включения и выключения реле для каждого канала. Для выхода из режима редактирования можно поочередно пролистать все каналы или нажать на первую кнопку «часы».

    TM1637

    При выходе из режима редактирования происходит сохранение в энергонезависимой памяти всех измененных значений времени реле.

  • Третья кнопка «+HH» используется при редактировании времени реле для часов, четвертая «+MM» для минут. При нажатии на третью или четвертую кнопку показания меняются только в большую сторону, при достижении 23 часов или 59 минут показания обнуляются.
  • При нажатии на кнопки три и четыре («+HH» «+MM») в режиме показания часов, можно изменить яркость свечения индикатора (0-7 уровней яркости).

Для управления нагрузкой можно использовать реле, подключение которого показано на рисунке или модуль реле которое можно подключать непосредственно к цифровым выходам Arduino.

#include <Wire.h>
#include <EEPROM.h>//#include <EEPROMex.h>
#include <TM1637Display.h>
#include <DS3231.h>
DS3231 clock;RTCDateTime DateTime;
TM1637Display display(2, 3);// CLK,DIO
 
int t,time,min,hour,write;
int alarm1_on,alarm1_of,alarm2_on,alarm2_of,alarm3_on,alarm3_of,alarm4_on,alarm4_of,alarm5_on,alarm5_of,alarm6_on,alarm6_of,alarm7_on,alarm7_of,alarm8_on,alarm8_of;
byte x,w,i,b,menu,alarm=16;
uint8_t date_alarm1on[]{0x77,0x30,0x5c,0x54};uint8_t date_alarm2on[]{0x77,0x5b,0x5c,0x54};uint8_t date_alarm3on[]{0x77,0x4f,0x5c,0x54};uint8_t date_alarm4on[]{0x77,0x66,0x5c,0x54};
uint8_t date_alarm5on[]{0x77,0x6d,0x5c,0x54};uint8_t date_alarm6on[]{0x77,0x7d,0x5c,0x54};uint8_t date_alarm7on[]{0x77,0x07,0x5c,0x54};uint8_t date_alarm8on[]{0x77,0x7f,0x5c,0x54};
uint8_t date_alarm1of[]{0x77,0x30,0x5c,0x71};uint8_t date_alarm2of[]{0x77,0x5b,0x5c,0x71};uint8_t date_alarm3of[]{0x77,0x4f,0x5c,0x71};uint8_t date_alarm4of[]{0x77,0x66,0x5c,0x71};
uint8_t date_alarm5of[]{0x77,0x6d,0x5c,0x71};uint8_t date_alarm6of[]{0x77,0x7d,0x5c,0x71};uint8_t date_alarm7of[]{0x77,0x07,0x5c,0x71};uint8_t date_alarm8of[]{0x77,0x7f,0x5c,0x71};
uint8_t data[]{0x50,0x7b,0x58,0};// rec
 
void setup(){
  // clock.setDateTime(__DATE__, __TIME__);// установка времени DS3231, раскомментировать и залить скетч, далее закомментировать и залить скетч повторно
  Serial.begin(9600);
  Wire.begin(); clock.begin(); clock.setOutput(DS3231_1HZ);
  pinMode(4,INPUT);// SQW модуля часов реального времени подключить к D4
  pinMode(A0,INPUT); pinMode(A1,INPUT); pinMode(A2,INPUT); pinMode(A3,INPUT);// кнопки управления А0 - часы, А1 - время реле, А2 - "часы +", А3 - "минуты +"
  pinMode(5,OUTPUT);pinMode(6,OUTPUT);pinMode(7,OUTPUT);pinMode(8,OUTPUT);pinMode(9,OUTPUT);pinMode(10,OUTPUT);pinMode(11,OUTPUT);pinMode(12,OUTPUT);// выходы реле
  alarm1_on=EEPROM.read(1)*100+EEPROM.read(2);alarm1_of=EEPROM.read(3)*100+EEPROM.read(4);
  alarm2_on=EEPROM.read(5)*100+EEPROM.read(6);alarm2_of=EEPROM.read(7)*100+EEPROM.read(8);
  alarm3_on=EEPROM.read(9)*100+EEPROM.read(10);alarm3_of=EEPROM.read(11)*100+EEPROM.read(12);
  alarm4_on=EEPROM.read(13)*100+EEPROM.read(14);alarm4_of=EEPROM.read(15)*100+EEPROM.read(16); 
  alarm5_on=EEPROM.read(17)*100+EEPROM.read(18);alarm5_of=EEPROM.read(19)*100+EEPROM.read(20);
  alarm6_on=EEPROM.read(21)*100+EEPROM.read(22);alarm6_of=EEPROM.read(23)*100+EEPROM.read(24); 
  alarm7_on=EEPROM.read(25)*100+EEPROM.read(26);alarm7_of=EEPROM.read(27)*100+EEPROM.read(28);
  alarm8_on=EEPROM.read(29)*100+EEPROM.read(30);alarm8_of=EEPROM.read(31)*100+EEPROM.read(32);
}
 
void loop(){Serial.println(write);
  display.setBrightness(b);        
  DateTime=clock.getDateTime();t=DateTime.hour*100+DateTime.minute;
 
  if(analogRead(A0)>600&&alarm==16){menu++;delay(200);if(menu>3){menu=0;}}     // кнопка часов      
  if(analogRead(A1)>600){alarm++;w=1;delay(200);if(alarm>16){alarm=0;}}  // кнопка времени реле
 
  switch(alarm){ // установка времение 1-8 реле
  case 0:  x=0x40; if(w==1){hour=alarm1_on/100;min=alarm1_on-hour*100;time=alarm1_on;display.setSegments(date_alarm1on);delay(2000);} w=0;alarm1_on=time; break; 
  case 1:  x=0x40; if(w==1){hour=alarm1_of/100;min=alarm1_of-hour*100;time=alarm1_of;display.setSegments(date_alarm1of);delay(2000);} w=0;alarm1_of=time; break;        
  case 2:  x=0x40; if(w==1){hour=alarm2_on/100;min=alarm2_on-hour*100;time=alarm2_on;display.setSegments(date_alarm2on);delay(2000);} w=0;alarm2_on=time; break;  
  case 3:  x=0x40; if(w==1){hour=alarm2_of/100;min=alarm2_of-hour*100;time=alarm2_of;display.setSegments(date_alarm2of);delay(2000);} w=0;alarm2_of=time; break;   
  case 4:  x=0x40; if(w==1){hour=alarm3_on/100;min=alarm3_on-hour*100;time=alarm3_on;display.setSegments(date_alarm3on);delay(2000);} w=0;alarm3_on=time; break;  
  case 5:  x=0x40; if(w==1){hour=alarm3_of/100;min=alarm3_of-hour*100;time=alarm3_of;display.setSegments(date_alarm3of);delay(2000);} w=0;alarm3_of=time; break; 
  case 6:  x=0x40; if(w==1){hour=alarm4_on/100;min=alarm4_on-hour*100;time=alarm4_on;display.setSegments(date_alarm4on);delay(2000);} w=0;alarm4_on=time; break;  
  case 7:  x=0x40; if(w==1){hour=alarm4_of/100;min=alarm4_of-hour*100;time=alarm4_of;display.setSegments(date_alarm4of);delay(2000);} w=0;alarm4_of=time; break;  
  case 8:  x=0x40; if(w==1){hour=alarm5_on/100;min=alarm5_on-hour*100;time=alarm5_on;display.setSegments(date_alarm5on);delay(2000);} w=0;alarm5_on=time; break; 
  case 9:  x=0x40; if(w==1){hour=alarm5_of/100;min=alarm5_of-hour*100;time=alarm5_of;display.setSegments(date_alarm5of);delay(2000);} w=0;alarm5_of=time; break;        
  case 10: x=0x40; if(w==1){hour=alarm6_on/100;min=alarm6_on-hour*100;time=alarm6_on;display.setSegments(date_alarm6on);delay(2000);} w=0;alarm6_on=time; break;  
  case 11: x=0x40; if(w==1){hour=alarm6_of/100;min=alarm6_of-hour*100;time=alarm6_of;display.setSegments(date_alarm6of);delay(2000);} w=0;alarm6_of=time; break;   
  case 12: x=0x40; if(w==1){hour=alarm7_on/100;min=alarm7_on-hour*100;time=alarm7_on;display.setSegments(date_alarm7on);delay(2000);} w=0;alarm7_on=time; break;  
  case 13: x=0x40; if(w==1){hour=alarm7_of/100;min=alarm7_of-hour*100;time=alarm7_of;display.setSegments(date_alarm7of);delay(2000);} w=0;alarm7_of=time; break; 
  case 14: x=0x40; if(w==1){hour=alarm8_on/100;min=alarm8_on-hour*100;time=alarm8_on;display.setSegments(date_alarm8on);delay(2000);} w=0;alarm8_on=time; break;  
  case 15: x=0x40; if(w==1){hour=alarm8_of/100;min=alarm8_of-hour*100;time=alarm8_of;display.setSegments(date_alarm8of);delay(2000);} w=0;alarm8_of=time; break; 
  case 16: write++;      
  switch(menu){  // часы
  case 0:  if(digitalRead(4)==HIGH){x=0x40;}else{x=0x00;}      // мигание двоеточия
           time=t; break;                                      // время
  case 1:  x=0x00;time=DateTime.second;break;                  // секунды
  case 2:  x=0x40;time=DateTime.day*100+DateTime.month; break; // число и месяц
  case 3:  x=0x00;time=DateTime.year; break;  } break;}        // год  
 
  if(analogRead(A2)>600&&alarm<16){hour++;delay(300);if(hour>23){hour=0;}time=hour*100+min;}// редактирование часов реле времени
  if(analogRead(A3)>600&&alarm<16){min++;delay(200);if(min>59){min=0;}time=hour*100+min;}   // редактирование минут реле времени
 
  if(analogRead(A2)>600&&alarm==16){b++;delay(300);}if(analogRead(A3)>600&&alarm==16){b--;delay(300);}if(b>7){b=0;} // яркость TM1637 0-7
 
  if(analogRead(A0)>600&&alarm<16){alarm=16;menu=0;w=1;write++;delay(200);} // возврат из времени реле в часы
 
  if(alarm<16||menu==0){i=true;}else{i=false;}
 
  if(alarm<16){write=0;}
  if(write>10000){write=2;}
  if(write==1){// запись в EEPROM значений времени реле при выходе из режима редактирования
  EEPROM.update(1, alarm1_on/100);EEPROM.update(2, alarm1_on-alarm1_on/100*100);
  EEPROM.update(3, alarm1_of/100);EEPROM.update(4, alarm1_of-alarm1_of/100*100);
  EEPROM.update(5, alarm2_on/100);EEPROM.update(6, alarm2_on-alarm2_on/100*100);
  EEPROM.update(7, alarm2_of/100);EEPROM.update(8, alarm2_of-alarm2_of/100*100);
  EEPROM.update(9, alarm3_on/100);EEPROM.update(10, alarm3_on-alarm3_on/100*100);
  EEPROM.update(11, alarm3_of/100);EEPROM.update(12, alarm3_of-alarm3_of/100*100);
  EEPROM.update(13, alarm4_on/100);EEPROM.update(14, alarm4_on-alarm4_on/100*100);
  EEPROM.update(15, alarm4_of/100);EEPROM.update(16, alarm4_of-alarm4_of/100*100);
  EEPROM.update(17, alarm5_on/100);EEPROM.update(18, alarm5_on-alarm5_on/100*100);
  EEPROM.update(19, alarm5_of/100);EEPROM.update(20, alarm5_of-alarm5_of/100*100);
  EEPROM.update(21, alarm6_on/100);EEPROM.update(22, alarm6_on-alarm6_on/100*100);
  EEPROM.update(23, alarm6_of/100);EEPROM.update(24, alarm6_of-alarm6_of/100*100);
  EEPROM.update(25, alarm7_on/100);EEPROM.update(26, alarm7_on-alarm7_on/100*100);
  EEPROM.update(27, alarm7_of/100);EEPROM.update(28, alarm7_of-alarm7_of/100*100);
  EEPROM.update(29, alarm8_on/100);EEPROM.update(30, alarm8_on-alarm8_on/100*100);
  EEPROM.update(32, alarm8_of/100);EEPROM.update(32, alarm8_of-alarm8_of/100*100);
  display.setSegments(data);delay(1000);// rec - запись
  }
 
  // активация 1-8 реле по времени
  if(t>=alarm1_on&&t<alarm1_of){digitalWrite(5,HIGH);}else{digitalWrite(5,LOW);}
  if(t>=alarm2_on&&t<alarm2_of){digitalWrite(6,HIGH);}else{digitalWrite(6,LOW);}
  if(t>=alarm3_on&&t<alarm3_of){digitalWrite(7,HIGH);}else{digitalWrite(7,LOW);}
  if(t>=alarm4_on&&t<alarm4_of){digitalWrite(8,HIGH);}else{digitalWrite(8,LOW);}
  if(t>=alarm5_on&&t<alarm5_of){digitalWrite(9,HIGH);}else{digitalWrite(9,LOW);}
  if(t>=alarm6_on&&t<alarm6_of){digitalWrite(10,HIGH);}else{digitalWrite(10,LOW);}
  if(t>=alarm7_on&&t<alarm7_of){digitalWrite(11,HIGH);}else{digitalWrite(11,LOW);}
  if(t>=alarm8_on&&t<alarm8_of){digitalWrite(12,HIGH);}else{digitalWrite(12,LOW);}
 
  display.showNumberDecEx(time,x,i); // вывод информации на индикатор TM1637
}

DS3231.h

TM1637Display.h


Дополнительные материалы

  • Скетч — 8rele.ino
  • Для управления радио-модулями используются выводы D9, D10, D11, D12. Также можно изменять длительность управляющего импульса.

Comments

  1. Здравствуйте!
    Не получается запрограммировать Arduino Nano — ошибки. Опыта в программировании никакого, но понравилось устройство. Подскажите, код, указанный на странице, нужно оформить в файл *.ino или как-то ещё?

    1. Здравствуйте! Просто скопируйте скетч в arduino IDE, добавьте библиотеки которые указаны в статье. Если есть ошибки компилирования, то скопируйте их и опубликуйте в комментариях.

  2. Здравствуйте!
    Собрал устройство (модуль DS3231 без батарейки), индикатор ТМ1637 не светится, на кнопки никакой реакции. С чем это может быть связано?

    1. Здравствуйте! Сложно сказать что делать. Просто проверьте все подключения. Особенно scl и sda, если они перепутаны то цикл программы останавливается и ни чего работать не будет.

  3. При заливке общего скетча по новой нужно отсоединять другие модули?
    Если добавить разархивированные DS3231.h TM1637Display.h в папку libraries Arduino, то нужно ли подключать эти библиотеки перед заливкой скетча?

    1. Ни чего отсоединять не нужно, если библиотеки уже установлены, то по новой их ставить не нужно, если все же копируете файлы библиотек в папку libraries Arduino, без установки, перезагрузите Arduino Ide.
      Если возникли проблемы с модулями проверьте их работоспособность, в каждой библиотеке есть примеры (скетчи). Протестируйте каждый модуль отдельно от других, отсоединив временно не используемые.

Добавить комментарий

Войти с помощью: