Часы (DS3231) с будильником (Arduino)

Часы с будильником состоят из платы Arduino Nano (Uno), LCD индикатора 1602 и модуля часов реального времени DS3231 (ZS-042). Помимо текущего времени на экране индикатора отображается дата, день недели, месяц, год и температура. Будильник в часах один, он позволяет выставить время срабатывания в минутах и часах, так же предусмотрено его отключение, а так же работа каждый день, в будние дни и по выходным. Установка времени срабатывания будильника осуществляется кнопками «К», «+» и «-«. Сигнал будильника звучит в течении одной минуты, но если нажать на одну из кнопок «+» или «-«. сигнал будильника можно прервать. Время срабатывания будильника и режим его работы сохраняются в энергонезависимой памяти.

Устанавливать время на часах не нужно, так как предусмотрена коррекция времени при прошивке микроконтроллера. Для этого необходимо раскомментировать строчку:

// clock.setDateTime(__DATE__, __TIME__);

Далее залейте скетч в плату, закомментируйте строчку и залейте скетч повторно.

#include <Wire.h>
#include <DS3231.h>//https://github.com/jarzebski/Arduino-DS3231/archive/master.zip // DS3231.zip
DS3231 clock;RTCDateTime DateTime;
#include <LiquidCrystal.h>  
#include <EEPROM.h> //#include <EEPROMex.h> 
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);// RS,E,D4,D5,D6,D7
 
int k,m,h,i,w,reg,ton;
byte rom0,rom1,rom2;
unsigned long eeprom;
 
void setup(){Serial.begin(9600);
   lcd.begin(16,2);// LCD 16X2 
   Wire.begin(); clock.begin();
   pinMode(2,INPUT);pinMode(3,INPUT);pinMode(4,INPUT);
 //  clock.setDateTime(__DATE__, __TIME__); // Устанавливаем время на часах, основываясь на времени компиляции скетча
  rom0 = EEPROM.read(0);if(rom0>59){EEPROM.update(0,0);}
  rom1 = EEPROM.read(1);if(rom1>23){EEPROM.update(1,0);}
  rom2 = EEPROM.read(2);if(rom2>3){EEPROM.update(2,0);}
  m=rom0;h=rom1;w=rom2;
}
 
void loop(){i++;if(i>4){i=0;}
 if(digitalRead(2)==HIGH){k++;reg=1;delay(300);}if(k>3){k=0;reg=0;}
 
 if(reg==1) {
 if(k==1){
 if(digitalRead(3)==HIGH){m++;}if(m>59){m=59;}
 if(digitalRead(4)==HIGH){m--;}if(m<0){m=0;}}
 if(k==2){
 if(digitalRead(3)==HIGH){h++;}if(h>23){h=23;}
 if(digitalRead(4)==HIGH){h--;}if(h<0){h=0;}}
 if(k==3){
 if(digitalRead(3)==HIGH){w++;delay(300);}if(w>3){w=0;}
 if(digitalRead(4)==HIGH){w--;delay(300);}if(w<0){w=3;}
 } 
 lcd.setCursor(0,0);lcd.print("Alarm ");
 if(i==1&&k==2){lcd.print("  ");}else{if(h < 10 ){lcd.print("0");}lcd.print(h);} lcd.print(":");
 if(i==1&&k==1){lcd.print("  ");}else{if(m < 10 ){lcd.print("0");}lcd.print(m);} 
 lcd.setCursor(0,1);
 if(i==1&&k==3){lcd.print("                 ");}
 if(w==0){lcd.print("every day");}  //каждый день 1234567
 if(w==1){lcd.print("on weekdays");}//по будням 12345
 if(w==2){lcd.print("on weekends");}//по выходным 67
 if(w==3){lcd.print("off");}
 rom0=m;rom1=h;rom2=w;
 eeprom=0;
 }
 
 if(reg==0){if(eeprom==1){EEPROM.update(0,rom0);EEPROM.update(1,rom1);EEPROM.update(2,rom2);}
 DateTime=clock.getDateTime();   // Считываем c часов текущие значения даты и времени в сущность DateTime
 lcd.setCursor(0,0);
 lcd.print(clock.dateFormat("H:i:s ",DateTime));// выводим часы, минуты и секунды
 lcd.print(clock.readTemperature(),1);lcd.print((char)223);lcd.print("C");// выводим значение температуры
 lcd.setCursor(0,1);lcd.print(clock.dateFormat("D d M Y", DateTime));// выводим день недели, дату, месяц и год
 }
if(digitalRead(3)==HIGH||digitalRead(4)==HIGH){ton=1;}
if(DateTime.hour*60+DateTime.minute!=h*60+m){ton=0;}
 
 if(w==0){pic();}
 if(w==1&&(DateTime.dayOfWeek<6)){pic();}
 if(w==2&&(DateTime.dayOfWeek>5)){pic();}
 
 eeprom++;
 delay(200);
 lcd.clear();
 
}
 
void pic(){if(ton==0&&(DateTime.hour*60+DateTime.minute==h*60+m)){tone(5,1200,500);delay(500);}}

// форум - http://forum.rcl-radio.ru/viewtopic.php?pid=927#p927

Второй вариант часов с будильником выполнен с использованием четырех разрядного семисегментного индикатора на базе драйвера TM1637 (модуль TM1637).

При нажимании кнопки «К» происходит перебор элементов меню, вывод секунд, даты и месяца, температуры, установка времени будильника, включение или отключение будильника, яркость индикатора.

#include <Wire.h>
#include <TM1637Display.h>
#include <DS3231.h>
#include <EEPROM.h>  //#include <EEPROMex.h>
DS3231 clock; // ПОДКЛЮЧЕНИЕ DS3231 SDA, SCL, SQW / A4, A5, D6
RTCDateTime DateTime;
TM1637Display display(4, 5);// ПОДКЛЮЧЕНИЕ TM1637 CLK,DIO / 4, 5
 
int k,alarm_m,alarm_h;
byte w = 1,x,y,z,menu,ton,on=1;
uint8_t date_s[]{0,0,0,0};// second
uint8_t date_t[]{0x78,0,0,0};// t
uint8_t date_on[]{0,0,0x3f,0x37};// ON
uint8_t date_off[]{0,0x3f,0x71,0x71};// OFF
 
void setup() {
  // clock.setDateTime(__DATE__, __TIME__);
   display.setBrightness(1);// яркость TM1637 0-7
   Wire.begin(); clock.begin();
   pinMode(6,INPUT);pinMode(10,INPUT);pinMode(11,INPUT);pinMode(12,INPUT);
   alarm_m = EEPROM.read(0);alarm_h = EEPROM.read(1);z = EEPROM.read(3);// ЧТЕНИЕ EEPROM
}
 
void loop() {
     DateTime = clock.getDateTime(); // ОПРОС ВРЕМЕНИ
     k = DateTime.hour*100+DateTime.minute; // ВРЕМЯ КАК ЧИСЛО ННММ
 
if(digitalRead(6) == HIGH){x = 0x40;}else{x = 0x00;} // МИГАНИЕ ДВОЕТОЧИЯ 
if(digitalRead(10) == HIGH){menu++;delay(300);if(menu > 6){menu = 0;}} // ПЕРЕБОР МЕНЮ
 
if(menu == 0){y = true;if(w == 0){EEPROM.update(0,alarm_m);EEPROM.update(1,alarm_h);EEPROM.update(3,z);}
w = 1;}  // ПРИ ВЫХОДЕ ИЗ МЕНЮ ОБНОВЛЕНИЕ EEPROM
 
if(menu == 1){k = DateTime.second;date_s[2] = display.encodeDigit((k/10)%10);
date_s[3] = display.encodeDigit((k%10)%10);display.setSegments(date_s);
} // ВЫВОД СЕКУНД
 
if(menu == 2){k = DateTime.day*100 + DateTime.month;x = 0x40;} // ВЫВОД ДАТЫ И МЕСЯЦА
 
if(menu == 3){k = clock.readTemperature();date_t[2] = display.encodeDigit((k/10)%10);
date_t[3] = display.encodeDigit((k%10)%10);display.setSegments(date_t);} // ВЫВОД ТЕМПЕРАТУРЫ
 
if(menu == 4){y = true;x = 0x40;k = alarm_h*100+alarm_m; // УСТАНОВКА БУДИЛЬНИКА
if(digitalRead(12) == HIGH){alarm_m++;delay(300);}if(alarm_m > 59){alarm_m = 0;} // МИНУТЫ БУДИЛЬНИКА
if(digitalRead(11) == HIGH){alarm_h++;delay(500);}if(alarm_h > 23){alarm_h = 0;} // ЧАСЫ БУДИЛЬНИКА
w = 0;}
 
if(menu == 5){
if(digitalRead(11) == HIGH){on=1;delay(300);}if(on==1){display.setSegments(date_on);} // БУДИЛЬНИК ВКЛЮЧЕН
if(digitalRead(12) == HIGH){on=0;delay(300);}if(on==0){display.setSegments(date_off);} // БУДИЛЬНИК ВЫКЛЮЧЕН
}
 
if(menu == 6){y = false;x = 0x00;k = z; // НАСТРОЙКА ЯРКОСТИ ИНДИКАТОРА
if(digitalRead(11) == HIGH){z++;delay(500);}if(z > 7){z = 0;}
if(digitalRead(12) == HIGH){z--;delay(500);}if(z > 8){z = 7;}
w = 0;}
 
if(digitalRead(11)==HIGH||digitalRead(12)==HIGH){ton=1;} // ПРИ НАЖАТИИ НА КНОПУ + ИЛИ - ПРЕРЫВАЕТСЯ СИГНАЛ БУДИЛНИКА
if(DateTime.hour*100+DateTime.minute!=alarm_h*100+alarm_m){ton=0;}
if(on==1){pic();}
 
display.setBrightness(z);
if(menu == 3 || menu == 5 || menu == 1){}else{display.showNumberDecEx(k,x,y);}
 
}
void pic(){if(ton==0&&(DateTime.hour*100+DateTime.minute==alarm_h*100+alarm_m)){tone(7,1000,500);delay(1000);}} // СИГНАЛ БУДИЛЬНИКА, 7 ЦИФРОВОЙ ВЫХОД

 

Comments

  1. модуль рабочий DS3231 на другом скетче работает отлично, думаю что проблема с кодом, может подставил значения не правильно, вот код из двух частей на фото

    1. При старте надо переменным задать уже установленные значения времени. Перед строкой:

      if(digitalRead(9) == HIGH){menu1++;delay(300);if(menu1 > 3){menu1 = 0;}}

      вставьте следующий код:

      set_y=DateTime.year;
      set_mon=DateTime.month;
      set_d=DateTime.day;
      set_h=DateTime.hour;
      set_m=DateTime.minute;

    2. также нужно поменять код:
      // корректировка года

      if(menu1 == 1){y = true;x = 0x00;k = set_y; //выводим на индикатор год
      if(digitalRead(12) == HIGH){set_y++;delay(300);}if(set_y > 2100){set_y = 2019;}
      if(digitalRead(11) == HIGH){set_y—;delay(300);}if(set_y < 2019){set_y= 2019;} w1 = 0;} // корректировка месяца и даты if(menu1 == 2){y = true;x = 0x00;k = set_mon*100+set_d; //выводим на индикатор месяц и день if(digitalRead(12) == HIGH){set_mon++;delay(300);}if(set_mon > 12){set_mon = 1;}// прибавляет месяц
      if(digitalRead(11) == HIGH){set_d++;delay(300);}if(set_d > 31){set_d= 1;} // прибавляем дату
      w1 = 0;}

      // корректировка часов и минут

      if(menu1 == 3){y = true;x = 0x40;k = set_h*100+set_m; //выводим на индикатор часы и минуты
      if(digitalRead(12) == HIGH){set_h++;delay(300);}if(set_h > 24){set_h = 0;}// прибавляет часы
      if(digitalRead(11) == HIGH){set_m++;delay(300);}if(set_m > 59){set_m= 0;} // прибавляем минуты
      w1 = 0;}

      на:

      // корректировка года
      if(menu1 == 1){y = true;x = 0x00;k = set_y; //выводим на индикатор год
      if(digitalRead(12) == HIGH){set_y++;delay(300);}if(set_y > 2100){set_y = 2019;w1 = 0;}
      if(digitalRead(11) == HIGH){set_y—;delay(300);}if(set_y < 2019){set_y= 2019;w1 = 0;} }

      // корректировка месяца и даты

      if(menu1 == 2){y = true;x = 0x00;k = set_mon*100+set_d; //выводим на индикатор месяц и день
      if(digitalRead(12) == HIGH){set_mon++;delay(300);}if(set_mon > 12){set_mon = 1;w1 = 0;}// прибавляет месяц
      if(digitalRead(11) == HIGH){set_d++;delay(300);}if(set_d > 31){set_d= 1;w1 = 0;} // прибавляем дату
      }

      // корректировка часов и минут

      if(menu1 == 3){y = true;x = 0x40;k = set_h*100+set_m; //выводим на индикатор часы и минуты
      if(digitalRead(12) == HIGH){set_h++;delay(300);}if(set_h > 24){set_h = 0;w1 = 0;}// прибавляет часы
      if(digitalRead(11) == HIGH){set_m++;delay(300);}if(set_m > 59){set_m= 0;w1 = 0;} // прибавляем минуты
      }

      Я перенеc переменную w1, теперь обновление времени будет происходить если нажаты кнопки + и —

      Также в коде нет изминений:

      // разграничение menu1 и menu
      // заменяем строку
      if(menu == 3 || menu == 5 || menu == 1){}else{display.showNumberDecEx(k,x,y);}
      на новую
      if(menu1>0){display.showNumberDecEx(k,x,y);}
      if(menu1==0){if(menu == 3 || menu == 5 || menu == 1){}else{display.showNumberDecEx(k,x,y);}}

    3. Дополнительно можно разграничить меню и меню1:

      if(digitalRead(10) == HIGH){menu++;delay(300);if(menu > 6){menu = 0;}} // ПЕРЕБОР МЕНЮ
      можно заменить на:
      if(digitalRead(10) == HIGH){menu++;delay(300);menu1=100;if(menu > 6){menu = 0;}} // ПЕРЕБОР МЕНЮ
      а стороку:
      if(digitalRead(9) == HIGH){menu1++;delay(300);if(menu1 > 3){menu1 = 0;}} // ПЕРЕБОР настроек редактирования времени
      на
      if(digitalRead(9) == HIGH){menu1++;delay(300);menu=100;if(menu1 > 3){menu1 = 0;}} // ПЕРЕБОР настроек редактирования времени

      это позволит полностью изолировать одно меню от другого.
      Но все это рекомендации, как эти изминения отразятся в коде я мого только предполагать, надо тестировать.

  2. работает, есть еще не большие нюансы при настройки времени

    if(menu1 == 3){y = true;x = 0x40;k = set_h*100+set_m; //выводим на индикатор часы и минуты
    if(digitalRead(12) == HIGH){set_h++;delay(300);}if(set_h > 24){set_h = 0;}// прибавляет часы
    if(digitalRead(11) == HIGH){set_m++;delay(300);}if(set_m > 59){set_m= 0;} // прибавляем минуты
    w1 = 0;}

    когда выставляешь полночь ,то за место 0 остаеться 24часа а нуля нет

    1. if(digitalRead(12) == HIGH){set_h++;delay(300);}if(set_h > 24){set_h = 0;}// прибавляет часы

      заменить на :

      if(digitalRead(12) == HIGH){set_h++;delay(300);}if(set_h > 23){set_h = 0;}// прибавляет часы

    1. y = false; — должно работать, команда зажигает 00

      В меню можно добавить новый пункт изменить имеющиеся:
      /// редактирование часов +-
      if(menu1 == 3){y = true;x = 0x40;k = set_h; //выводим на индикатор часы
      if(digitalRead(12) == HIGH){set_h++;delay(300);w1 = 0;}if(set_h > 23){set_h = 0;}// прибавляет часы
      if(digitalRead(11) == HIGH){set_h—;delay(300);w1 = 0;}if(set_h < 0){set_h= 0;} // убавляем часы }

      /// редактирование минут +-
      if(menu1 == 4){y = true;x = 0x40;k = set_m; //выводим на индикатор минуты
      if(digitalRead(12) == HIGH){set_m++;delay(300);w1 = 0;}if(set_m > 59){set_m = 0;}// прибавляет минуты
      if(digitalRead(11) == HIGH){set_m—;delay(300);w1 = 0;}if(set_m < 0){set_m = 0;} // убавляем минуты }

      меняем код:

      if(digitalRead(9) == HIGH){menu1++;delay(300);if(menu1 > 3){menu1 = 0;}} // ПЕРЕБОР настроек редактирования времени
      // menu1 = 1 — установка года
      // menu1 = 2 — установка месяца и даты
      // menu1 = 3 — установка часов и минут
      // menu1 = 0 — корректировка времени не активна

      на:

      if(digitalRead(9) == HIGH){menu1++;delay(300);if(menu1 > 4){menu1 = 0;}} // ПЕРЕБОР настроек редактирования времени
      // menu1 = 1 — установка года
      // menu1 = 2 — установка месяца и даты
      // menu1 = 3 — установка часов
      // menu1 = 4 — установка минут
      // menu1 = 0 — корректировка времени не активна

    1. Если посмотреть код установки будильника, который аналогичен редактированию часов и минут, то в нем все верно работает, если например 0 часов и 3 минуты то отображается как 00:03

      if(menu == 4){y = true;x = 0x40;k = alarm_h*100+alarm_m; // УСТАНОВКА БУДИЛЬНИКА
      if(digitalRead(12) == HIGH){alarm_m++;delay(300);}if(alarm_m > 59){alarm_m = 0;} // МИНУТЫ БУДИЛЬНИКА
      if(digitalRead(11) == HIGH){alarm_h++;delay(500);}if(alarm_h > 23){alarm_h = 0;} // ЧАСЫ БУДИЛЬНИКА
      w = 0;}

      что аналогично коду:
      // корректировка часов и минут

      if(menu1 == 3){y = true;x = 0x40;k = set_h*100+set_m; //выводим на индикатор часы и минуты
      if(digitalRead(12) == HIGH){set_h++;delay(300);w1 = 0;}if(set_h > 23){set_h = 0;}// прибавляет часы
      if(digitalRead(11) == HIGH){set_m++;delay(300);w1 = 0;}if(set_m > 59){set_m = 0;} // прибавляем минуты
      }

      Оба кода аналогичны, нули должны гореть.

      В принципе на индикаторе отображается четырехзначное число:
      k = set_h*100+set_m — то есть часы * 100 + минуты

      Информация на экран выводится командой:

      display.showNumberDecEx(k,x,y);

      k — число
      x — двоеточие
      y — отображать нули когда true или false — гасить индикатор

      Все должно работать, проще было бы видеть весь код целиком, проще видеть неполадки с кодом.

  3. #include
    #include
    #include
    #include //#include
    DS3231 clock; // ПОДКЛЮЧЕНИЕ DS3231 SDA, SCL, SQW / A4, A5, D6
    RTCDateTime DateTime;
    TM1637Display display(4, 5);// ПОДКЛЮЧЕНИЕ TM1637 CLK,DIO / 4, 5

    int k,alarm_m,alarm_h;
    byte w = 1,x,y,z,menu,ton,on=1;

    uint8_t date_s[]{0,0,0,0};// second
    uint8_t date_t[]{0x78,0,0,0};// t
    uint8_t date_on[]{0,0,0x3f,0x37};// ON
    uint8_t date_off[]{0,0x3f,0x71,0x71};// OFF
    int set_y,set_mon,set_d,set_h,set_m;// год, месяц, дата, часы и минуты
    int menu1,w1;

    void setup() {
    //clock.setDateTime(__DATE__, __TIME__);
    display.setBrightness(1);// яркость TM1637 0-7
    Wire.begin(); clock.begin();
    pinMode(6,INPUT);pinMode(10,INPUT_PULLUP);pinMode(11,INPUT_PULLUP);pinMode(12,INPUT_PULLUP);pinMode(9,INPUT_PULLUP);
    alarm_m = EEPROM.read(0);alarm_h = EEPROM.read(1);z = EEPROM.read(3);// ЧТЕНИЕ EEPROM
    //set_h = EEPROM.read(4);set_m = EEPROM.read(5);// ЧТЕНИЕ EEPROM
    }

    void loop() {

    DateTime = clock.getDateTime(); // ОПРОС ВРЕМЕНИ
    k = DateTime.hour*100+DateTime.minute; // ВРЕМЯ КАК ЧИСЛО ННММ

    if(digitalRead(6) == HIGH){x = 0x40;}else{x = 0x00;} // МИГАНИЕ ДВОЕТОЧИЯ

    set_y=DateTime.year;
    set_mon=DateTime.month;
    set_d=DateTime.day;
    set_h=DateTime.hour;
    set_m=DateTime.minute;

    if(digitalRead(9) == HIGH){menu1++;delay(300);if(menu1 > 3){menu1 = 0;}} // ПЕРЕБОР настроек редактирования времени
    // menu1 = 1 — установка года
    // menu1 = 2 — установка месяца и даты
    // menu1 = 3 — установка часов и минут
    // menu1 = 0 — корректировка времени не активна

    // корректировка года
    if(menu1 == 1){y = true;x = 0x00;k = set_y; //выводим на индикатор год
    if(digitalRead(12) == HIGH){set_y++;delay(300);}if(set_y > 2100){set_y = 2019;w1 = 0;}
    if(digitalRead(11) == HIGH){set_y—;delay(300);}if(set_y 12){set_mon = 1;w1 = 0;}// прибавляет месяц
    if(digitalRead(11) == HIGH){set_d++;delay(300);}if(set_d > 31){set_d = 1;w1 = 0;} // прибавляем дату
    }

    // корректировка часов и минут

    /// редактирование часов +-
    if(menu1 == 3){y = true;x = 0x40;k = set_h*100+set_m; //выводим на индикатор часы и минуты
    if(digitalRead(12) == HIGH){set_h++;delay(300);w1 = 0;}if(set_h > 23){set_h = 0;}// прибавляет часы
    if(digitalRead(11) == HIGH){set_m++;delay(300);w1 = 0;}if(set_m > 59){set_m = 0;} // прибавляем минуты
    }

    // записываем в память часов новые значения времени

    if(w1==0){clock.setDateTime(set_y, set_mon, set_d, set_h, set_m, 0);w1=1;}

    if(digitalRead(10) == HIGH){menu++;delay(300);menu1=100;if(menu > 6){menu = 0;}} // ПЕРЕБОР МЕНЮ

    if(menu == 0){y = false;if(w == 0){EEPROM.update(0,alarm_m);EEPROM.update(1,alarm_h);EEPROM.update(3,z);}
    w = 1;} // ПРИ ВЫХОДЕ ИЗ МЕНЮ ОБНОВЛЕНИЕ EEPROM

    if(menu == 1){k = DateTime.second;date_s[2] = display.encodeDigit((k/10)%10);
    date_s[3] = display.encodeDigit((k%10)%10);display.setSegments(date_s);} // ВЫВОД СЕКУНД

    if(menu == 2){k = DateTime.day*100 + DateTime.month;x = 0x00;} // ВЫВОД ДАТЫ И МЕСЯЦА

    if(menu == 3){k = clock.readTemperature();date_t[2] = display.encodeDigit((k/10)%10);
    date_t[3] = display.encodeDigit((k%10)%10);display.setSegments(date_t);} // ВЫВОД ТЕМПЕРАТУРЫ

    if(menu == 4){y = true;x = 0x40;k = alarm_h*100+alarm_m; // УСТАНОВКА БУДИЛЬНИКА
    if(digitalRead(12) == HIGH){alarm_m++;delay(300);}if(alarm_m > 59){alarm_m = 0;} // МИНУТЫ БУДИЛЬНИКА
    if(digitalRead(11) == HIGH){alarm_h++;delay(300);}if(alarm_h > 24){alarm_h = 0;} // ЧАСЫ БУДИЛЬНИКА
    w = 0;}

    if(menu == 5){
    if(digitalRead(11) == HIGH){on=1;delay(300);}if(on==1){display.setSegments(date_on);} // БУДИЛЬНИК ВКЛЮЧЕН
    if(digitalRead(12) == HIGH){on=0;delay(300);}if(on==0){display.setSegments(date_off);} // БУДИЛЬНИК ВЫКЛЮЧЕН
    }

    if(menu == 6){y = false;x = 0x00;k = z; // НАСТРОЙКА ЯРКОСТИ ИНДИКАТОРА
    if(digitalRead(11) == HIGH){z++;delay(500);}if(z > 7){z = 0;}
    if(digitalRead(12) == HIGH){z—;delay(500);}if(z > 8){z = 7;}
    w = 0;}

    if(digitalRead(11)==HIGH||digitalRead(12)==HIGH){ton=1;} // ПРИ НАЖАТИИ НА КНОПУ + ИЛИ — ПРЕРЫВАЕТСЯ СИГНАЛ БУДИЛНИКА
    if(DateTime.hour*100+DateTime.minute!=alarm_h*100+alarm_m){ton=0;}}
    if(on==1){pic();}

    display.setBrightness(z);
    if(menu1>0){display.showNumberDecEx(k,x,y);}
    if(menu1==0){if(menu == 3 || menu == 5 || menu == 1){}else{display.showNumberDecEx(k,x,y);}}
    }
    void pic(){if(ton==0&&(DateTime.hour*100+DateTime.minute==alarm_h*100+alarm_m)){tone(7,1000,500);delay(1000);}} // СИГНАЛ БУДИЛЬНИКА, 7 ЦИФРОВОЙ ВЫХОД

            1. Здравствуйте! В том виде как сейчас работает код это невозможно, так как корректировка минут и часов объединены в одно меню. Программа не знает что именно Вы будете редактировать минуты или часы пока не нажмете на соответствующую кнопку.
              Мигание можно встроить если редактирование минут и часов разделить на разные меню, и сделать -+ отдельное для часов и минут.

          1. к примеру
            /// редактирование часов +-
            if(menu1 == 4){y = true;x = 0x40;k = set_h*100+set_m; //выводим на индикатор часы
            if(digitalRead(12) == HIGH){set_h++;delay(300);w1 = 0;}if(set_h > 23){set_h = 0;}// прибавляет часы
            if(digitalRead(11) == HIGH){set_h—;delay(300);w1 = 0;}if(set_h 59){set_m = 0;}// прибавляет минуты
            if(digitalRead(11) == HIGH){set_m—;delay(300);w1 = 0;}if(set_m < 0){set_m = 0;} // убавляем минуты
            }
            при установки получается одно и тоже , тока меняется установки, я пытался сделать если устанавливаю часы чтобы выводилось значение часов 14 а заместо минут — в целом 14:—, создал uint8_t date_f[]{0,0,0×40,0×40};// 0X40 выводит —, подставить так и не получилось

            1. Это очень усложнит код, без макетной платы не смогу написать. Могу просто разделить корректировку минут и часов, а перед корректировкой минут и часов на 1 сек вывести надпись min и hour. будет типа:
              hour (горит 1 сек)
              __12 (12 часов)
              min (горит 1 сек)
              __34 (34 минуты)

            1. В момент корректировки часов можно временно минутам присвоить 0 и гасить нули переменной y = true; в течении 0,2 секунд, следющие 0,2 минутам присвоить реальное значение а переменной y присвоить false.

          2. void setup() {
            set_h = EEPROM.read(4);set_m = EEPROM.read(5);
            добавил строчку и
            void loop() {
            if(menu1 == 0){y = false;if(w1 == 0){EEPROM.update(4,set_h);EEPROM.update(5,set_m);}
            w1 = 1;} // ПРИ ВЫХОДЕ ИЗ МЕНЮ ОБНОВЛЕНИЕ EEPROM

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

            1. Что то не то с часами реального времени, эта строка записывает время в часы реального времени:
              if(w1==0){clock.setDateTime(set_y, set_mon, set_d, set_h, set_m, 0);w1=1;}
              а эти строки считывают время с часов реального времени:
              set_y=DateTime.year;
              set_mon=DateTime.month;
              set_d=DateTime.day;
              set_h=DateTime.hour;
              set_m=DateTime.minute;

              В Вашем варианте:
              EEPROM.update(4,set_h);EEPROM.update(5,set_m)
              записываются часы и минуты в память eeprom arduino, это не верно, при старте будет время на момент сохранения.

            1. Порядок основных команд для часов реального времени:
              DateTime = clock.getDateTime(); // ОПРОС ВРЕМЕНИ
              //////////считываем время
              set_y=DateTime.year;
              set_mon=DateTime.month;
              set_d=DateTime.day;
              set_h=DateTime.hour;
              set_m=DateTime.minute;
              /////////// записываем новое время если оно изменилось
              if(w1==0){clock.setDateTime(set_y, set_mon, set_d, set_h, set_m, 0);w1=1;}

              Так же переменной задайте значение 1 (перед setup())
              int w1=1;

              В скетче при старте считываются значения времени, далее если время корректируется происходит перезапись времени, если при корректировке времени не нули, то все нормально, в каждом цикле программы время считывается с часов реального времени. А если сбросить питание и снова подать оно опять считывается с часов реального времени для корректировки.
              если дело только в секундах то добавьте следующий код:
              добавьте новую переменную перед setup(); int set_s;
              после set_m=DateTime.minute; добавьте:
              set_s=DateTime.second;
              а строку :
              if(w1==0){clock.setDateTime(set_y, set_mon, set_d, set_h, set_m, 0);w1=1;}
              замените на :
              if(w1==0){clock.setDateTime(set_y, set_mon, set_d, set_h, set_m, set_s);w1=1;}

          1. все дело было в переменной w1, при старте она была равна 0, а это приводило к перезаписи времени, все время кроме секунд считывалось с часов, а секунды нет, поэтому при старте секунды каждый раз обнулялись.

            1. вот часть кода как вставил
              void loop() {

              DateTime = clock.getDateTime(); // ОПРОС ВРЕМЕНИ
              k = DateTime.hour*100+DateTime.minute; // ВРЕМЯ КАК ЧИСЛО ННММ

              if(digitalRead(6) == HIGH){x = 0x40;}else{x = 0x00;} // МИГАНИЕ ДВОЕТОЧИЯ

              ////////////////////////////// корректировка часов ////////////////////////////////////////////////

              //////////считываем время
              set_y=DateTime.year;
              set_mon=DateTime.month;
              set_d=DateTime.day;
              set_h=DateTime.hour;
              set_m=DateTime.minute;
              set_s=DateTime.second;

              /////////// записываем новое время если оно изменилось

              if(w1==0){clock.setDateTime(set_y, set_mon, set_d, set_h, set_m, 0);w1=1;}

              if(digitalRead(9) == HIGH){menu1++;delay(300);menu=100;pause=1;if(menu1 > 4){menu1 = 0;}} // ПЕРЕБОР настроек редактирования времени
              // menu1 = 1 — установка года
              // menu1 = 2 — установка месяца и даты
              // menu1 = 3 — установка часов
              // menu1 = 4 — установка минут
              // menu1 = 0 — корректировка времени не активна

                1. да работают , при этом секунды не сбрасываются, а останавливаются , потом продолжают идти, получилось отследить за счет двух индикаторов ))))

                  void loop() {

                  DateTime = clock.getDateTime(); // ОПРОС ВРЕМЕНИ
                  k = DateTime.hour*100+DateTime.minute; // ВРЕМЯ КАК ЧИСЛО ННММ
                  k2 = DateTime.second*100+DateTime.day; y1 = true; //

                  if(digitalRead(6) == HIGH){x = 0x40;}else{x = 0x00;} // МИГАНИЕ ДВОЕТОЧИЯ

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

                      #include
                      #include
                      #include
                      #include //#include

                      DS3231 clock; // ПОДКЛЮЧЕНИЕ DS3231 SDA, SCL, SQW / A4, A5, D6
                      RTCDateTime DateTime;
                      TM1637Display display(4, 5);// ПОДКЛЮЧЕНИЕ TM1637 CLK,DIO / 4, 5

                      int k,alarm_m,alarm_h;
                      byte w = 1,x,y,z,menu,ton,on=1;

                      uint8_t date_s[]{0,0,0,0};// second
                      uint8_t date_t[]{0x78,0,0,0};// t
                      uint8_t date_on[]{0,0,0x3f,0x37};// ON
                      uint8_t date_off[]{0,0x3f,0x71,0x71};// OFF
                      uint8_t date_h[]{0x3f,0x3f,0x40,0x40};// часы
                      uint8_t date_m[]{0x40,0x40,0x3f,0x3f};// мин
                      int set_y,set_mon,set_d,set_h,set_m,set_s;// год, месяц, дата, часы и минуты
                      int menu1,w1=1,pause;

                      void setup() {
                      //clock.setDateTime(__DATE__, __TIME__);
                      display.setBrightness(1);// яркость TM1637 0-7
                      Wire.begin(); clock.begin();
                      pinMode(6,INPUT);pinMode(10,INPUT_PULLUP);pinMode(11,INPUT_PULLUP);pinMode(12,INPUT_PULLUP);pinMode(9,INPUT_PULLUP);
                      alarm_m = EEPROM.read(0);alarm_h = EEPROM.read(1);z = EEPROM.read(3);// ЧТЕНИЕ EEPROM
                      }

                      void loop() {

                      DateTime = clock.getDateTime(); // ОПРОС ВРЕМЕНИ
                      k = DateTime.hour*100+DateTime.minute; // ВРЕМЯ КАК ЧИСЛО ННММ

                      if(digitalRead(6) == HIGH){x = 0x40;}else{x = 0x00;} // МИГАНИЕ ДВОЕТОЧИЯ

                      ////////////////////////////// корректировка часов ////////////////////////////////////////////////

                      //////////считываем время
                      set_y=DateTime.year;
                      set_mon=DateTime.month;
                      set_d=DateTime.day;
                      set_h=DateTime.hour;
                      set_m=DateTime.minute;
                      set_s=DateTime.second;

                      /////////// записываем новое время если оно изменилось

                      if(w1==0){clock.setDateTime(set_y, set_mon, set_d, set_h, set_m, 0);w1=1;}

                      if(digitalRead(9) == HIGH){menu1++;delay(300);menu=100;pause=1;if(menu1 > 4){menu1 = 0;}} // ПЕРЕБОР настроек редактирования времени
                      // menu1 = 1 — установка года
                      // menu1 = 2 — установка месяца и даты
                      // menu1 = 3 — установка часов
                      // menu1 = 4 — установка минут
                      // menu1 = 0 — корректировка времени не активна

                      // корректировка года
                      if(menu1 == 1){y = true;x = 0x00;k = set_y; //выводим на индикатор год
                      if(digitalRead(12) == HIGH){set_y++;delay(300);w1 = 0;}if(set_y > 2100){set_y = 2019;}
                      if(digitalRead(11) == HIGH){set_y—;delay(300);w1 = 0;}if(set_y 12){set_mon = 1;}// прибавляем месяц
                      if(digitalRead(11) == HIGH){set_d++;delay(300);w1 = 0;}if(set_d > 31){set_d = 1;}// прибавляем год
                      }

                      // корректировка часов

                      if(menu1 == 3){
                      if(pause==1){display.setSegments(date_h);delay(1000);pause=0;}
                      y = true;x = 0x40;k = set_h; //выводим на индикатор часы и минуты
                      if(digitalRead(12) == HIGH){set_h++;delay(300);w1 = 0;}if(set_h > 23){set_h = 0;}// прибавляет часы
                      if(digitalRead(11) == HIGH){set_h—;delay(300);w1 = 0;}if(set_h 59){set_m = 0;}// прибавляет минуты
                      if(digitalRead(11) == HIGH){set_m—;delay(300);w1 = 0;}if(set_m 6){menu = 0;}} // ПЕРЕБОР МЕНЮ

                      if(menu == 0){y = false;if(w == 0){EEPROM.update(0,alarm_m);EEPROM.update(1,alarm_h);EEPROM.update(3,z);}
                      w = 1;} // ПРИ ВЫХОДЕ ИЗ МЕНЮ ОБНОВЛЕНИЕ EEPROM

                      if(menu == 1){k = DateTime.second;date_s[2] = display.encodeDigit((k/10)%10);
                      date_s[3] = display.encodeDigit((k%10)%10);display.setSegments(date_s);} // ВЫВОД СЕКУНД

                      if(menu == 2){k = DateTime.day*100 + DateTime.month;x = 0x00;} // ВЫВОД ДАТЫ И МЕСЯЦА

                      if(menu == 3){k = clock.readTemperature();date_t[2] = display.encodeDigit((k/10)%10);
                      date_t[3] = display.encodeDigit((k%10)%10);display.setSegments(date_t);} // ВЫВОД ТЕМПЕРАТУРЫ

                      if(menu == 4){y = true;x = 0x40;k = alarm_h*100+alarm_m; // УСТАНОВКА БУДИЛЬНИКА
                      if(digitalRead(12) == HIGH){alarm_m++;delay(300);}if(alarm_m > 59){alarm_m = 0;} // МИНУТЫ БУДИЛЬНИКА
                      if(digitalRead(11) == HIGH){alarm_h++;delay(300);}if(alarm_h > 24){alarm_h = 0;} // ЧАСЫ БУДИЛЬНИКА
                      w = 0;}

                      if(menu == 5){
                      if(digitalRead(11) == HIGH){on=1;delay(300);}if(on==1){display.setSegments(date_on);} // БУДИЛЬНИК ВКЛЮЧЕН
                      if(digitalRead(12) == HIGH){on=0;delay(300);}if(on==0){display.setSegments(date_off);} // БУДИЛЬНИК ВЫКЛЮЧЕН
                      }

                      if(menu == 6){y = false;x = 0x00;k = z; // НАСТРОЙКА ЯРКОСТИ ИНДИКАТОРА
                      if(digitalRead(11) == HIGH){z++;delay(500);}if(z > 7){z = 0;}
                      if(digitalRead(12) == HIGH){z—;delay(500);}if(z > 8){z = 7;}
                      w = 0;}

                      if(digitalRead(11)==HIGH||digitalRead(12)==HIGH){ton=1;} // ПРИ НАЖАТИИ НА КНОПУ + ИЛИ — ПРЕРЫВАЕТСЯ СИГНАЛ БУДИЛНИКА
                      if(DateTime.hour*100+DateTime.minute!=alarm_h*100+alarm_m){ton=0;}
                      if(on==1){pic();}

                      display.setBrightness(z);

                      if(menu1>0&&menu1<100){display.showNumberDecEx(k,x,y);}
                      if(menu1==0){if(menu == 3 || menu == 5 || menu == 1){}else{display.showNumberDecEx(k,x,y);}}
                      }
                      void pic(){if(ton==0&&(DateTime.hour*100+DateTime.minute==alarm_h*100+alarm_m)){tone(7,1000,500);delay(1000);}} // СИГНАЛ БУДИЛЬНИКА, 7 ЦИФРОВОЙ ВЫХОД

                    2. Очень много кода убрано, так вообще не должно работать, наверное при копировании часть кода обрезало.

                    3. Скетч сжать в zip архив и загрузить на сайт (добавить медиафайл), а комментариях оставить на него ссылку.

                    4. #include
                      #include
                      #include
                      #include //#include

                      DS3231 clock; // ПОДКЛЮЧЕНИЕ DS3231 SDA, SCL, SQW / A4, A5, D6
                      RTCDateTime DateTime;
                      TM1637Display display(4, 5);// ПОДКЛЮЧЕНИЕ TM1637 CLK,DIO / 4, 5

                      int k,alarm_m,alarm_h;
                      byte w = 1,x,y,z,menu,ton,on=1;

                      uint8_t date_s[]{0,0,0,0};// second
                      uint8_t date_t[]{0x78,0,0,0};// t
                      uint8_t date_on[]{0,0,0x3f,0x37};// ON
                      uint8_t date_off[]{0,0x3f,0x71,0x71};// OFF
                      uint8_t date_h[]{0x3f,0x3f,0x40,0x40};// часы
                      uint8_t date_m[]{0x40,0x40,0x3f,0x3f};// мин
                      int set_y,set_mon,set_d,set_h,set_m,set_s;// год, месяц, дата, часы и минуты
                      int menu1,w1=1,pause;

                      void setup() {
                      //clock.setDateTime(__DATE__, __TIME__);
                      display.setBrightness(1);// яркость TM1637 0-7
                      Wire.begin(); clock.begin();
                      pinMode(6,INPUT);pinMode(10,INPUT_PULLUP);pinMode(11,INPUT_PULLUP);pinMode(12,INPUT_PULLUP);pinMode(9,INPUT_PULLUP);
                      alarm_m = EEPROM.read(0);alarm_h = EEPROM.read(1);z = EEPROM.read(3);// ЧТЕНИЕ EEPROM
                      }

                      void loop() {

                      DateTime = clock.getDateTime(); // ОПРОС ВРЕМЕНИ
                      k = DateTime.hour*100+DateTime.minute; // ВРЕМЯ КАК ЧИСЛО ННММ

                      if(digitalRead(6) == HIGH){x = 0x40;}else{x = 0x00;} // МИГАНИЕ ДВОЕТОЧИЯ

                      ////////////////////////////// корректировка часов ////////////////////////////////////////////////

                      //////////считываем время
                      set_y=DateTime.year;
                      set_mon=DateTime.month;
                      set_d=DateTime.day;
                      set_h=DateTime.hour;
                      set_m=DateTime.minute;
                      set_s=DateTime.second;

                      /////////// записываем новое время если оно изменилось

                      if(w1==0){clock.setDateTime(set_y, set_mon, set_d, set_h, set_m, 0);w1=1;}

                    5. if(digitalRead(9) == HIGH){menu1++;delay(300);menu=100;pause=1;if(menu1 > 4){menu1 = 0;}} // ПЕРЕБОР настроек редактирования времени
                      // menu1 = 1 — установка года
                      // menu1 = 2 — установка месяца и даты
                      // menu1 = 3 — установка часов
                      // menu1 = 4 — установка минут
                      // menu1 = 0 — корректировка времени не активна

                      // корректировка года
                      if(menu1 == 1){y = true;x = 0x00;k = set_y; //выводим на индикатор год
                      if(digitalRead(12) == HIGH){set_y++;delay(300);w1 = 0;}if(set_y > 2100){set_y = 2019;}
                      if(digitalRead(11) == HIGH){set_y—;delay(300);w1 = 0;}if(set_y 12){set_mon = 1;}// прибавляем месяц
                      if(digitalRead(11) == HIGH){set_d++;delay(300);w1 = 0;}if(set_d > 31){set_d = 1;}// прибавляем год
                      }

                      // корректировка часов

                      if(menu1 == 3){
                      if(pause==1){display.setSegments(date_h);delay(1000);pause=0;}
                      y = true;x = 0x40;k = set_h; //выводим на индикатор часы и минуты
                      if(digitalRead(12) == HIGH){set_h++;delay(300);w1 = 0;}if(set_h > 23){set_h = 0;}// прибавляет часы
                      if(digitalRead(11) == HIGH){set_h—;delay(300);w1 = 0;}if(set_h 59){set_m = 0;}// прибавляет минуты
                      if(digitalRead(11) == HIGH){set_m—;delay(300);w1 = 0;}if(set_m 6){menu = 0;}} // ПЕРЕБОР МЕНЮ

                      if(menu == 0){y = false;if(w == 0){EEPROM.update(0,alarm_m);EEPROM.update(1,alarm_h);EEPROM.update(3,z);}
                      w = 1;} // ПРИ ВЫХОДЕ ИЗ МЕНЮ ОБНОВЛЕНИЕ EEPROM

                      if(menu == 1){k = DateTime.second;date_s[2] = display.encodeDigit((k/10)%10);
                      date_s[3] = display.encodeDigit((k%10)%10);display.setSegments(date_s);} // ВЫВОД СЕКУНД

                      if(menu == 2){k = DateTime.day*100 + DateTime.month;x = 0x00;} // ВЫВОД ДАТЫ И МЕСЯЦА

                      if(menu == 3){k = clock.readTemperature();date_t[2] = display.encodeDigit((k/10)%10);
                      date_t[3] = display.encodeDigit((k%10)%10);display.setSegments(date_t);} // ВЫВОД ТЕМПЕРАТУРЫ

                      if(menu == 4){y = true;x = 0x40;k = alarm_h*100+alarm_m; // УСТАНОВКА БУДИЛЬНИКА
                      if(digitalRead(12) == HIGH){alarm_m++;delay(300);}if(alarm_m > 59){alarm_m = 0;} // МИНУТЫ БУДИЛЬНИКА
                      if(digitalRead(11) == HIGH){alarm_h++;delay(300);}if(alarm_h > 24){alarm_h = 0;} // ЧАСЫ БУДИЛЬНИКА
                      w = 0;}

                      if(menu == 5){
                      if(digitalRead(11) == HIGH){on=1;delay(300);}if(on==1){display.setSegments(date_on);} // БУДИЛЬНИК ВКЛЮЧЕН
                      if(digitalRead(12) == HIGH){on=0;delay(300);}if(on==0){display.setSegments(date_off);} // БУДИЛЬНИК ВЫКЛЮЧЕН
                      }

                      if(menu == 6){y = false;x = 0x00;k = z; // НАСТРОЙКА ЯРКОСТИ ИНДИКАТОРА
                      if(digitalRead(11) == HIGH){z++;delay(500);}if(z > 7){z = 0;}
                      if(digitalRead(12) == HIGH){z—;delay(500);}if(z > 8){z = 7;}
                      w = 0;}

                      if(digitalRead(11)==HIGH||digitalRead(12)==HIGH){ton=1;} // ПРИ НАЖАТИИ НА КНОПУ + ИЛИ — ПРЕРЫВАЕТСЯ СИГНАЛ БУДИЛНИКА
                      if(DateTime.hour*100+DateTime.minute!=alarm_h*100+alarm_m){ton=0;}
                      if(on==1){pic();}

                      display.setBrightness(z);

                      if(menu1>0&&menu1<100){display.showNumberDecEx(k,x,y);}
                      if(menu1==0){if(menu == 3 || menu == 5 || menu == 1){}else{display.showNumberDecEx(k,x,y);}}
                      }
                      void pic(){if(ton==0&&(DateTime.hour*100+DateTime.minute==alarm_h*100+alarm_m)){tone(7,1000,500);delay(1000);}} // СИГНАЛ БУДИЛЬНИКА, 7 ЦИФРОВОЙ ВЫХОД

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

                    7. Попробуйте заменить строку:
                      if(menu == 0){y = false;if(w == 0){EEPROM.update(0,alarm_m);EEPROM.update(1,alarm_h);EEPROM.update(3,z);}
                      w = 1;} // ПРИ ВЫХОДЕ ИЗ МЕНЮ ОБНОВЛЕНИЕ EEPROM

                      на

                      if(menu == 0){y = true;if(w == 0){EEPROM.update(0,alarm_m);EEPROM.update(1,alarm_h);EEPROM.update(3,z);}
                      w = 1;} // ПРИ ВЫХОДЕ ИЗ МЕНЮ ОБНОВЛЕНИЕ EEPROM

                    8. все заработало, впереди появился ноль

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

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

                    11. Можете ссылку оставить на страницу с программой в комментарии, может кому пригодится.

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

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