Ардуино и DS3231 не корректируется время

veroni0803
Offline
Зарегистрирован: 18.01.2018

Уважаемые специалисты! Прошу помощи. Собрал из различных источников многофункциональное устройство с двумя будильниками и таймером с возможность переключения выходов и настройкой ШИМ (последнее пока не доделано). Почему-то не хочет записывать корректировку даты и времени. Будильники и таймер работают нормально. Из примера другой библиотеки часы настраиваются. Не знаю как присоединить файлы библиотеки и скетч. Библиотека DS3231.

Скетч:

#include <avr/io.h>

#include <avr/eeprom.h>
#include <avr/sleep.h>
#include <Wire.h>
#include <IRremote.h>           // Здесь задействован 2-й таймер
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);   //0x3F - адрес LCD
 
// С этой библиотекой установка даты и времени почему-то не происходит!!!!!!!
#include <DS3231.h>                   // 0x68 - адрес часов
DS3231 clock;                         // 0х57 - адрес EEPROM в часах
RTCDateTime dt;
RTCAlarmTime a1;
RTCAlarmTime a2;
 
decode_results results;
const uint8_t RECV_PIN = 10;          // PB0 PCINT0
IRrecv irrecv(RECV_PIN);
/*
#define chip1 0x50          // Адрес внешнего EEPROM
unsigned int pointer;
byte d=0;
*/
//const uint8_t SQW_INT =2;
//#define ON_SQW clock.setOutput(1)
//#define OFF_SQW clock.setOutput(0)
 
const uint8_t alarmLED = 13;            // PB5 SCK
const uint8_t alarmPWM = 8;             // выход PWM PB1 OC1A
const uint8_t PinBuzzer = 9;            // PB2 
const uint8_t LED = 13;
 
volatile boolean alarm_on  = false;     // Статус 1-го будильника  
volatile boolean alarm_on1 = false;     // Статус 2-го будильника 
volatile boolean alarm_on2 = false;     // Статус таймера
const uint8_t addr_al2 = 0;             // ячейка EEPROM состояние таймера вкл/выкл
const uint8_t addr_ah2 = 1;             // ячейка EEPROM часы в таймере
const uint8_t addr_am2 = 2;             // ячейка EEPROM минуты в таймере
const uint8_t addr_ahout2 = 3;          // ячейка EEPROM часы в таймере для обратного отсчета
const uint8_t addr_amout2 = 4;          // ячейка EEPROM минуты в таймере для обратного отсчета
const uint8_t addr_q = 5;               // ячейка EEPROM скважность
const uint16_t addr_f = 6;              // ячейка EEPROM частота 
volatile int8_t var_q = 0;              // переменная скважности
volatile int16_t var_f = 0;             // переменная частоты старшие разряды
 
volatile int8_t ah = 0;
volatile int8_t am = 0;
 
volatile uint8_t regim = 0;             // переменная для переходов при настройках
volatile uint8_t pmenu = 9;             // меню: в меню  пункта 9 не должно быть
volatile uint8_t blinkCursor = 0;
 
long button = 0;
const long bmenu    = 10039503;          //menu для просмотра кодов кнопок при выкл таймере pmenu=55
const long balarm1  = 10063983;          // <1> 1-й будильник                   pmenu=6
const long balarm2  = 10074183;          // <2> 2-й будильник                   pmenu=7
const long btimer   = 10090503;          // <3> таймер                          pmenu=0
const long btime    = 10072143;          // <4> корректировка часов             pmenu=3
const long bPWM     = 10066023;          // <5> Регулировка скважности          pmenu=10
const long bF       = 10082343;          // <6> Регулировка частоты             pmenu=12
const long bout_t   = 10061943;          // <7> Выбор выхода по таймеру         pmenu=13
const long bout_a1  = 10070103;          // <8> Выбор выхода по 1-му будильнику pmenu=14
const long bout_a2  = 10086423;          // <9> Выбор выхода по 2-му будильнику pmenu=15
const long bout_PWM = 10053783;          // <+10> Выбор выхода PWM              pmenu=11
const long bright   = 10091013;          // <RIGHT>                             pmenu=8
const long bleft    = 10058373;          // <LEFT>                              pmenu=8
const long bplus    = 10042053;          // <UP> Прибавляем значения            pmenu=1
const long bminus   = 10074693;          // <DOWN> Уменьшаем значения           pmenu=2
const long bcancel  = 10084383;          // <ESC> Top menu                      pmenu=4
const long bselect  = 10037463;          // OK                                  pmenu=5
 
//const long bset    = 10072653;          //SETUP
//10045623 - 10/0
//10047663 - return
//10027773 -card/usb
//10056333-OSD, 10054293-SUBTITLE, 10078773-O)), 10037973-камера это 4 верхних кнопки
//10057863-влево, 10082853-вправо большая нижняя кнопка, 10033383-AUDIO MODE, 10080303-DIGEST
 
volatile int8_t th, tm, da, mo, se;
uint16_t ye;
 
uint8_t bell[8]  = {0x4, 0xe, 0xe, 0xe, 0x1f, 0x0, 0x4};   //колокольчик
uint8_t temp_cel[8] = {B00111, B00101, B00111, B00000, B00000, B00000, B00000};  // Градус
 
// Переменные для генератора с регулировкой частоты и скважности
volatile uint8_t duty=50;
#define set_duty() {OCR1A=(uint16_t)ICR1*duty/100;}
//--------------------------------------------------------------------------
//Предопределение функций
void blink_temp_rh(unsigned long interval);       // Основной экран, переключаемый на таймер
void SET_A1();
void SET_outA1();
void SET_A2();
void SET_outA2();
void SET_T();
void SET_outT();
void SET_outPWM();      // На каком выходе будет PWM
void SET_PWM();         // Регулировка скважности
void SET_F();           // Регулировка частоты PWM
void blink_set_time (unsigned long interval);                        //мигаем переменной настройки часов
void SET_Timer();
void blink_set_timer (unsigned long interval);                        //мигаем переменной настройки таймера
void Timer_off();
void Timer_on();
void blink_alarm_on(unsigned long interval);
void blink_alarm_off(unsigned long interval);
void blink_set_alarm (unsigned long interval, uint8_t nom);            //мигаем переменной включаем будильник
void dump(decode_results *results); // Дешифрация нажатых ИК-кнопок
void buttons();                     // Обработка кнопок
void myTone(uint32_t i){ 
  i+=(millis()); 
  while(i>millis()){
    digitalWrite(PinBuzzer, HIGH); 
    delayMicroseconds(500); 
    digitalWrite(PinBuzzer, LOW); 
    delayMicroseconds(300);
  } 
}
void SET_freq();             // Изменение частоты генератора
void SET_duty();             // Изменение скважности генератора
void blink_set_qf (unsigned long interval, uint16_t qf);
 
/*  Делал для внешнего EEPROM, но пка не работает
byte decToBcd(byte val) //Преобразует обычное десятичное число в двоично-десятичное
{
return( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val)  //Преобразует двоично-десятичное число в обычное десятичное
{
return( (val/16*10) + (val%16) );
}
void writeData(int device, unsigned int address, byte data)
// записывает байт данных 'data' в ЭСППЗУ с I2C-адресом 'device'
// в ячейку с номером 'address'
{
Wire.beginTransmission(device);
Wire.write((byte)(address >> 8)); // старший байт номера ячейки
Wire.write((byte)(address & 0xFF)); // и младший байт
Wire.write(decToBcd(data));
Wire.endTransmission();
delay(10);
}
byte readData(int device, unsigned int address)
// читает байт данных из ячейки с номером 'address'
// в ЭСППЗУ с I2C-адресом 'device'
{
byte result; // возвращаемое значение
Wire.beginTransmission(device);
Wire.write((byte)(address >> 8)); // старший байт номера ячейки
Wire.write((byte)(address & 0xFF)); // и младший байт
Wire.endTransmission();
Wire.requestFrom(device,1);
result = Wire.read();
return bcdToDec(result); // вернуть прочитанный байт как
// результат функции readData
}
*/
//==========================================================================
void setup()
{
//  Serial.begin(9600);
  Wire.begin();
  irrecv.enableIRIn();
  lcd.begin();
  clock.begin();
  DDRD = 0;
  PORTD = 0;
  DDRB |= (1<<alarmPWM) | (1<<alarmLED) | (1<<PinBuzzer) | (1<<LED);
  PORTB = 0;
  alarm_on = (clock.isAlarm1())? true: false;   // Инициализaция будильников при перезагрузке
  alarm_on1 = (clock.isAlarm2())? true: false;
  if (eeprom_read_byte(addr_ah2) == 255) {
    eeprom_update_byte(addr_ah2,0);
    eeprom_update_byte(addr_am2,0);
  }
/*
  if (readData(chip1,addr_ah2) == 255) {
    writeData(chip1,addr_ah2,0);
    writeData(chip1,addr_am2,0);  
  }
//writeData(chip1,a,a);
//d=readData(chip1,a);
*/
  lcd.createChar(0, bell);         //колокольчик
  lcd.createChar(1, temp_cel);     //цельсии
  TCCR1A=1<<COM1A1; //подключить выход OC1A первого таймера
  TCCR1B=0;//
  OCR1A = eeprom_read_byte(addr_q);           //читаем скважность выхода для PB1 (OC1A)
  ICR1 = eeprom_read_word(addr_f);            //читаем частоту выхода для PB1 (OC1A)
}
//==========================================================================
void loop()
{
  while(1)
  {
    buttons();                                //Проверяем нажатия клавиш
// Здесь надо сделать проверку кодов клавиш при pmenu=55
    while (regim==55){
      lcd.clear();
      lcd.setCursor(0,0);
      if (pmenu == 4) {                      // Прервать настройку, ничего не менять
        lcd.clear();
        regim = 1;
      }
    }
    dt = clock.getDateTime();
    a1 = clock.getAlarm1();
    a2 = clock.getAlarm2();
    if (clock.isAlarm1())
    {
      myTone(1000);
      alarm_on = false;
      clock.armAlarm1(alarm_on);
    }
    if (clock.isAlarm2())
    {
      myTone(1000);
      alarm_on1 = false;
      clock.armAlarm2(alarm_on1);
    }
    if (pmenu == 9) {
      lcd.setCursor(0, 0);
      lcd.print(clock.dateFormat("H:i:s ", dt));
      lcd.print(clock.readTemperature());     // Считываем температуру с DS3231
      lcd.write(1);
      lcd.print("C");                         //цельсия  lcd.setCursor(0, 1);
      blink_temp_rh(2000);                    //показ таймера и даты (смена каждые 3 сек)
    }
  }
}
//==========================================================================
void SET_freq(){
  uint16_t icr=ICR1;
  uint16_t divider=1;               //переменная коэфф. деления прескалера
  static boolean gen_mode=0;        //флаг режима управления частотой
  regim = 2;
  uint8_t i = 1;
  int16_t f = eeprom_read_word (addr_f);        //читаем частоту выхода для PB1 (OC1A)
  while (regim==2) {                       //задание скважности
    buttons();
    blinkCursor = 1;
    blink_set_qf(250, f);
    if (f <= 15) i=1;
    else if ((f > 10) && (f <= 50)) i=5;
    else if ((f > 50) && (f <=200)) i=10;
    else if ((f > 200) && (f <= 2000)) i=100;
    else if ((f >2000) && (f <= 12000)) i=1000;
    else i=5000;
    if (pmenu == 1) f += i;
    if (pmenu == 2) f -= i;
    if ((f > 65535) || (f < 0))  f = 0;
    if (f > 2848) gen_mode=1;          //переключение режима управления по OCR
    else gen_mode=0;                    //переключение режима управления по частоте
    if ((pmenu == 5) || (pmenu == 8) || (pmenu == 4)) {
      lcd.clear();
      regim = 1;
    }
  }
  if(gen_mode){ 
    ICR1 = f; 
    set_duty(); 
  } 
  else {                              //расчёт прескалера и ICR по нужной частоте
    icr = (F_CPU / f /2 /divider); 
    byte shifts[] = {3,3,2,2};
    for(byte i = 0; i < 4; i++){
      if (icr > 65536) {
          divider <<= shifts[i];
          icr = F_CPU / f /2 /divider;
      }
      else {                          //запись в регистр прескалера
        TCCR1B = (i+1)|(1<<WGM13);  
        break;
      }
    }
    ICR1=icr-1; 
    set_duty();
  }                                   //конец "если  частота менее 2848 герц)
  eeprom_update_word(addr_f, ICR1);
}
//------------------------------------------------------------   
void blink_set_qf (unsigned long interval, uint16_t qf){
    static unsigned long prevTime=0;
    if(millis() - prevTime > interval){
      static boolean flag = false;
      prevTime = millis();
      lcd.clear();
      flag = !flag;
      lcd.setCursor(0,0);
//      if (blinkCursor == 1)
      lcd.print((blinkCursor == 1)? "Worked frequenze":  "Worked sqwaiuer");
      lcd.setCursor(5, 1);
      if(flag){
        lcd.print(qf);
      }
      else {
        lcd.print("  ");
      }
    }
}
//------------------------------------------------------------   
void SET_duty(){
  regim = 2;
  uint8_t i = 1;
  int8_t q = eeprom_read_byte(addr_q);        //читаем скважность выхода для PB1 (OC1A)
  var_q = q;
  while (regim==2) {                       //задание скважности
    buttons();
    blinkCursor = 2;
    blink_set_qf(250, q);
    if (q <= 10) i=1;
    else if ((q > 10) && (q <= 30)) i=5;
    else i=10;
    if (pmenu == 1) q += i;
    if (pmenu == 2) q -= i;
    if ((q >= 100) || (q < 0))  q = 0;
    if ((pmenu == 5) || (pmenu == 8)) {
      if (var_q != q) 
      duty = q;
      set_duty();
      eeprom_update_byte(addr_q, OCR1A);
      lcd.clear();
      regim = 1;
    }
    if (pmenu == 4) {
      lcd.clear();
      regim = 1;
    }
  }
}
//------------------------------------------------------------   
void blink_temp_rh(unsigned long interval){
    static unsigned long prevTime=0;
    uint8_t ah=0, am=0, ahout=0, amout=0;
    uint16_t t_sec = 0, a_sec = 0;
//    alarm_on2 = readData(chip1,addr_al2);
    alarm_on2 = eeprom_read_byte(addr_al2);            //читаем состояние Timer
//    alarm_on2 = clock.EEPROM_ReadByte(addr_al2);
    buttons();
    switch (pmenu) {
      case (0) :
        SET_Timer();                              // Timer
        break;
      case (3) :                                  // Часы
        SET_T();
        break;
      case (6) : 
        SET_A1();                                // 1-й       
        break;
      case (7) :
        SET_A2();                               // 2-й 
        break;
    case (10) :                                 // <5> Регулировка скважности
        SET_duty();
        break;
    case (11) :                                 // <+10> Выбор выхода PWM
        pmenu = 11;
        break;
    case (12) :                                 // <6> Регулировка частоты PWM
        SET_freq();
        break;
    case (13) :                                 // <7> Выбор выхода по таймеру
        break;
    case (14) :                                 // <8> Выбор выхода по 1-му будильнику
        break;
    case (15) :                                 // <9> Выбор выхода по 2-му будильнику
        break;
    }
    if (millis() - prevTime > interval){
    static boolean flag = 0;
    prevTime = millis();
    flag = !flag;
    lcd.setCursor(0, 1);
    if(flag){                                         
      lcd.print(clock.dateFormat("d-m-y     l", dt));
      lcd.setCursor(9,1);
      if (alarm_on)  lcd.write(0);                   // Колокольчик 1-го будильника
      else lcd.print("-");
      if (alarm_on1) lcd.write(0);                   // Колокольчик 2-го будильника
      else lcd.print("-");
      if (alarm_on2){
        lcd.write(0);                                // Колокольчик таймера
        lcd.print(" ");
      }
      else lcd.print("- ");
    }
    else {
      lcd.print("                ");
      lcd.setCursor(0, 1);                          // Не успевала срабатывать команда пробелов
      if (alarm_on2) {
        ah = eeprom_read_byte(addr_ah2);
        am = eeprom_read_byte(addr_am2);
        ahout = eeprom_read_byte(addr_ahout2);
        amout = eeprom_read_byte(addr_amout2);
/*
        ah = readData(chip1,addr_ah2);
        am = readData(chip1,addr_am2);        
        ahout = readData(chip1,addr_ahout2);
        amout = readData(chip1,addr_amout2);        
*/        t_sec = (dt.hour*3600) + (dt.minute*60);    // Текущее время в секундах
        a_sec = (ahout*3600) + (amout*60);
        ahout = (a_sec - t_sec)/3600;
        amout = (((a_sec - t_sec)-(ahout*3600))/60);
        if ((ahout==0) && (amout==0)) {             // Проверка таймера
          Timer_off();
        }
        if (ah<10) lcd.print("0");
        lcd.print(ah);
        lcd.print(":");
        if (am<10) lcd.print("0");
        lcd.print(am);
        lcd.print("m");
        lcd.print(" >>");
        if (ahout<10) lcd.print("0");
        lcd.print(ahout);
        lcd.print(":");
        if (amout<10) lcd.print("0");
        lcd.print(amout);
        lcd.print("<<");
      }
      else lcd.print("Timer not includ");
    }
  }
}
//------------------------------------------------------------  
//----------- Работа с ИК-пультом 2 функции ниже -------------   
// Здесь будем расшифровывать нажатые клавиши
void dump(decode_results *results) {
  pmenu = 9;
  int count = results->rawlen;
  long button = results->value;
/*   Для просмотра кодов кнопок раскомментировать
  lcd.setCursor(0,1);
  int tt = millis();
  while (millis< tt+3000) lcd.print(button);
*/
  if (button > 10000000) {
  switch (button) {
    case (balarm1) :        // 1-й будильник. Используется EEPROM
        pmenu = 6;
        break;
    case (balarm2) :        // 2-ой будильник. Используется EEPROM
        pmenu = 7;
        break;
    case (btimer) :         // 3 Таймер. Используется EEPROM
        pmenu = 0;
        break;
    case (bplus) :          // Приращение переменной(UP)
        pmenu = 1;
        break;
    case (bminus):          // Уменьшение переменной(DOWN)
        pmenu = 2;
        break;
    case (btime) :          // 4 Коррект часов
        pmenu = 3;
        break;
    case (bPWM) :           // <5> Регулировка скважности
        pmenu = 10;
        break;
    case (bout_PWM) :       // <+10> Выбор выхода PWM
        pmenu = 11;
        break;
    case (bF) :             // <6> Регулировка частоты PWM
        pmenu = 12;
        break;
    case (bout_t) :         // <7> Выбор выхода по таймеру
        pmenu = 13;
        break;
    case (bout_a1) :        // <8> Выбор выхода по 1-му будильнику
        pmenu = 14;
        break;
    case (bout_a2) :        // <9> Выбор выхода по 2-му будильнику
        pmenu = 15;
        break;
    case (bcancel):         // Прерывание/Сброс(Top menu)
        pmenu = 4;
        break;
    case (bselect):         // OK
        pmenu = 5;
        break;
    case (bright) :         // RIGHT
        pmenu = 8;
        break;
    case (bleft):           // LEFT
        pmenu = 8;
        break;
    case (bmenu) :
        pmenu = 55;
        regim = 55;
        break;
    default:
        pmenu = 9;
  }
  }
}
//------------------------------------------------------------
void buttons() {
    static unsigned long prevTime=0;
    pmenu = 9;
    if (irrecv.decode(&results)) {
      if (millis() - prevTime > 250) {    // Если прошло по крайней мере 1/4 секунды с момента нажатия
        dump(&results);
      }
      prevTime = millis();
      irrecv.resume();                // Receive the next value
    }
}
//--------------------------------------------------------------------------
//----- Настройка и включение/выключение таймера 4 функции ниже   
void Timer_on () {
// Включаем что-нибудь
  digitalWrite(LED, 1);
//  myTone(1000);
}//------------------------------------------------------------   
void Timer_off() {
    uint8_t ahout=0, amout=0;
    uint16_t t_sec = 0, a_sec = 0;
    myTone(1000);
    PORTB &= !(1<<LED);
    SET_Timer();
}
//------------------------------------------------------------   
void SET_Timer () {   // Пробуем настраивать один таймер
  regim=2;
  digitalWrite(LED, 0);
  uint8_t ahout=0, amout=0, ahout1=0, amout1=0, ah1=0, am1=0, al1=alarm_on2;
  uint16_t t_sec = 0, a_sec = 0;
  lcd.clear();
  lcd.setCursor(1, 0);
  while (regim==2) {                      //включение отключение таймеров
    buttons();
    lcd.print("on Timer  off");
//    al1 = readData(chip1,addr_al2);
    if ((pmenu == 1) ||(pmenu == 2)) alarm_on2 = !alarm_on2;
    if (alarm_on2) blink_alarm_on(250);
    else blink_alarm_off(250);
    ah = eeprom_read_byte(addr_ah2);
    am = eeprom_read_byte(addr_am2);
//    ah = readData(chip1,addr_ah2);
//    am = readData(chip1,addr_am2);   
//    ah1 = ah;
//    am1 = am;     
    lcd.setCursor(5, 1);
    if (ah<10) lcd.print("0");
    lcd.print(ah);
    lcd.print(":");
    if (am<10) lcd.print("0");
    lcd.print(am);
    if ((pmenu == 5) || (pmenu == 8)) {
      eeprom_update_byte(addr_al2, alarm_on2);
//      if (al1 != alarm_on2) writeData(chip1,addr_al2,alarm_on2);
//      al1 = alarm_on2;
      if (alarm_on2) {
        t_sec = (dt.hour*3600) + (dt.minute*60); // Текущее время в секундах
        a_sec = (ah*3600) + (am*60);
        ahout = (a_sec + t_sec)/3600;
        amout = (((a_sec + t_sec)-(ahout*3600))/60);
        eeprom_update_byte(addr_ahout2, ahout);
        eeprom_update_byte(addr_amout2, amout);
//        writeData(chip1,addr_ahout2,ahout);
//        ahout1 = ahout;
//        writeData(chip1,addr_amout2,amout);
//        amout1 = amout;
        if (pmenu == 5) regim++;
        else {
          regim = 1; 
          lcd.clear();
          Timer_on();
        }
      }
      else {
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      lcd.clear();
      regim = 1;
      return;
    }
  }
  while (regim==3) {                      //установка часов таймеров
    buttons();
    blinkCursor = 1;
    blink_set_timer(250);
    if (pmenu == 1) ah++;
    if (pmenu == 2) ah--;
    if (ah>23) ah=0;
    if (ah<0) ah=23;
    if ((pmenu == 5) || (pmenu == 8)) {
      if (alarm_on2) {
        eeprom_update_byte(addr_ah2, ah);
        t_sec = (dt.hour*3600) + (dt.minute*60); // Текущее время в секундах
        a_sec = (ah*3600) + (am*60);
        ahout = (a_sec + t_sec)/3600;
        amout = (((a_sec + t_sec)-(ahout*3600))/60);
        eeprom_update_byte(addr_ahout2, ahout);
        eeprom_update_byte(addr_amout2, amout);
/*        if (ah1 != ah) writeData(chip1,addr_ah2,ah);
        ah1 = ah;
        if (am != am1) writeData(chip1,addr_am2,am);
        am1 = am;
        if (ahout != ahout1) writeData(chip1,addr_ahout2,ahout);
        ahout1 = ahout;
        if (amout != amout1) writeData(chip1,addr_amout2,amout);
        amout1 = amout;
*/
        if (pmenu == 5) regim++;
        else {
          regim = 1; 
          lcd.clear();
          Timer_on();
        }
      }
      else {
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      lcd.clear();
      regim = 1;
      return;
    }
  }
  while(regim==4){                        //установка минут таймеров
    buttons();
    blinkCursor = 2;
    blink_set_timer(250);
    if (pmenu == 1) am++;
    if (pmenu == 2) am--;
    if (am>59) am=0;
    if (am<0) am=59;
    if ((pmenu == 5) || (pmenu == 8)) {
      eeprom_update_byte(addr_am2, am);
      t_sec = (dt.hour*3600) + (dt.minute*60); // Текущее время в секундах
      a_sec = (ah*3600) + (am*60);
      ahout = (a_sec + t_sec)/3600;
      amout = (((a_sec + t_sec)-(ahout*3600))/60);
//      eeprom_update_byte(addr_ahout2, ahout);
      eeprom_update_byte(addr_amout2, amout);
/*      if (am1 != am) writeData(chip1,addr_am2,am);  
      if (ahout1 != ahout) writeData(chip1,addr_ahout2,ahout);
      if (amout1 != amout) writeData(chip1,addr_amout2,amout);  
*/      regim = 1; 
      pmenu = 9;
      Timer_on();
    }
    if (pmenu == 4) {
      pmenu = 9;
      regim = 1;
      return;}
  }
}
//------------------------------------------------------------  
void blink_set_timer (unsigned long interval){   //мигаем переменной включаем будильник
    static unsigned long prevTime=0;
    if(millis() - prevTime > interval){
      static boolean flag = 0;
      prevTime = millis();
      flag = !flag;
      if(flag){
        lcd.clear();
        lcd.setCursor(1, 0);
        lcd.print("on Timer  off");
        lcd.setCursor(5, 1);
        if (ah<10) lcd.print("0");
        lcd.print(ah);
        lcd.print(":");
        if (am<10) lcd.print("0");
        lcd.print(am);
      }
      else {
        switch (blinkCursor) {
          case 1: lcd.setCursor(5, 1); break;
          case 2: lcd.setCursor(8, 1); break;
      }
      lcd.print("  ");
    }
  }
}
//--------------------------------------------------------------------------
void SET_T(){    
  regim=2;
  ye = dt.year;
  mo = dt.month;
  da = dt.day;
  th = dt.hour;
  tm = dt.minute;
  se = dt.second;
  while (regim == 2) {  //установка часов
    buttons();
    blinkCursor = 1;
    blink_set_time(250);
    if (pmenu == 1) th++;
    if (pmenu == 2) th--;
    if (th>23) th=0;
    if (th<0) th=23;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim++;
  if (pmenu == 5) clock.setDateTime(2018, 2, 25, 18, 12, se); 
  else regim = 1;
    }
    if (pmenu == 4) regim = 1;
  }
  while (regim == 3) {   //установка минут
    buttons();
    blinkCursor = 2;
    blink_set_time(250);
    if (pmenu == 1) tm++;
    if (pmenu == 2) tm--;
    if (tm>59) tm=0;
    if (tm<0) tm=59;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim++;
  if (pmenu == 5) clock.setDateTime(2018, 2, 25, th, tm, se); 
      else regim = 1;
    }
    if (pmenu == 4) regim = 1;
  }
  while (regim == 4) {  //установка числа
    buttons();
    blinkCursor = 3;
    blink_set_time(250);
    if (pmenu == 1) da++;
    if (pmenu == 2) da--;
    if (da>31)da=1;
    if (da<1)da=31;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim++;
      if (pmenu == 5) clock.setDateTime(2018, 2, da, th, tm, se); 
      else regim = 1;
    }
    if (pmenu == 4) regim = 1;
  }
  while (regim == 5) {   //установка месяца
    buttons();
    blinkCursor = 4;
    blink_set_time(250);
    if (pmenu == 1) mo++;
    if (pmenu == 2) mo--;
    if (mo>12) mo=1;
    if (mo<1) mo=12;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim++;
      if (pmenu == 5) clock.setDateTime(ye, mo, da, th, tm, se); 
      else regim = 1;
    }
    if (pmenu == 4) regim = 1;
  }
  while (regim == 6) {   //установка года
    buttons();
    blinkCursor = 5;
    blink_set_time(250);
    if (pmenu == 1) ye++;
    if (pmenu == 2) ye--;
    if (ye>2100) ye=2018;
    if (ye<2018) ye=2099;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim=1;
      if (pmenu == 5) clock.setDateTime(ye, mo, da, th, tm, se); 
    }
    if (pmenu == 4) regim = 1;
  }   
}
//------------------------------------------------------------      
void blink_set_time(unsigned long interval){   //мигаем переменной в установке даты и времени
  static unsigned long prevTime=0;
  if(millis() - prevTime > interval){
    static boolean flag = 0;
    prevTime = millis();
    flag = !flag;
    lcd.setCursor(0, 0);
    if(flag){
      if (th<10) lcd.print("0");
      lcd.print(th);                          //показать врем
      lcd.print(":");
      if (tm<10) lcd.print("0");
      lcd.print(tm);
      lcd.setCursor(0, 1);
      if (da<10) lcd.print("0");
      lcd.print(da);                          //показать дату
      lcd.print(".");
      if (mo<10) lcd.print("0");
      lcd.print(mo);
      lcd.print(".");
      lcd.print(ye);
      lcd.print("   ");
      lcd.print(clock.dateFormat("D ", dt));      // Думаю, что день недели
    }
    else {
      switch (blinkCursor) {
        case 1: lcd.setCursor(0, 0); break;
        case 2: lcd.setCursor(3, 0); break;
        case 3: lcd.setCursor(0, 1); break;
        case 4: lcd.setCursor(3, 1); break;
        case 5: lcd.setCursor(8, 1); break;
      }
      lcd.print("  ");
    }
  }
}
//--------------------------------------------------------------------------
void SET_A1 () {   // Пробуем настраивать будильник1
  regim=2;
  lcd.clear();
  lcd.setCursor(1, 0);
  uint8_t da=a1.day, as=a1.second;
  ah=a1.hour;
  am=a1.minute;
  alarm_on = (clock.isArmed1()) ? true: false;
  lcd.print("on Alarm1 off");
  while (regim==2) {
    buttons();
    if ((pmenu == 1) || (pmenu == 2)) alarm_on = !alarm_on;
//    if (pmenu == 2) alarm = !alarm;
    if (alarm_on) blink_alarm_on(250);
    else blink_alarm_off(250);
    if ((pmenu == 5) || (pmenu == 8)) {           //Сохранить настройку
      if (alarm_on) {
        if (pmenu == 5) regim++;
        else {
          if (ah || am) {
            clock.armAlarm1(true);
            regim = 1; 
            lcd.clear();
          }
          else {
            clock.armAlarm1(false);
            alarm_on = false;
            regim = 1; 
            lcd.clear();
          }
        }
      }
      else {
        clock.armAlarm1(false);
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {                      // Прервать настройку, ничего не менять
      lcd.clear();
      regim = 1;
    }
  }
  while (regim==3) {                       //установка часов таймеров
    buttons();
    blinkCursor = 1;
    blink_set_alarm(250);
    if (pmenu == 1) ah++;
    if (pmenu == 2) ah--;
    if (ah>23) ah=0;
    if (ah<0) ah=23;
    if ((pmenu == 5) || (pmenu == 8)) {
      if (ah || am) {
        clock.armAlarm1(true);
        clock.setAlarm1(0, ah, am, 0, DS3231_MATCH_H_M_S);
      }
      if (pmenu == 5) regim++;
      else {
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      lcd.clear();
      regim = 1;
    }
  }
  while(regim==4){                        //установка минут таймеров
    buttons();
    blinkCursor = 2;
    blink_set_alarm(250);
    if (pmenu == 1) am++;
    if (pmenu == 2) am--;
    if (am>59) am=0;
    if (am<0) am=59;
    if ((pmenu == 5) || (pmenu == 8)) {
      if (ah || am) {
        clock.armAlarm1(true);
        clock.setAlarm1(0, ah, am, dt.second, DS3231_MATCH_H_M_S);
      }
      else {
        clock.armAlarm1(false); alarm_on = false;
      }
      if (pmenu == 5) regim++;
      else {
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      pmenu = 9;
      regim = 1;
    }
  }
}
//------------------------------------------------------------   
void SET_A2 () {
  regim=2;
  lcd.clear();
  uint8_t da=a1.day;
  ah=a2.hour;
  am=a2.minute;
  alarm_on1 = (clock.isArmed2()) ? true : false;
  lcd.setCursor(1, 0);
  lcd.print("on Alarm2 off");
  while (regim==2) {
    buttons();
    if ((pmenu == 1) || (pmenu == 2)) alarm_on1 = !alarm_on1;
//    if (pmenu == 2) alarm_on1 = !alarm_on1;
    if (alarm_on1) blink_alarm_on(250);
    else blink_alarm_off(250);
    if ((pmenu == 5) || (pmenu == 8)) {           //Сохранить настройку
      if (alarm_on1) {
        clock.armAlarm2(true);
        if (pmenu == 5) regim++;
        else {
          regim = 1; 
          lcd.clear();
        }
      }
      else {
        clock.armAlarm2(false);
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      lcd.clear();
      regim = 1;
      return;
    }
  }
  while (regim==3) {                      //установка часов таймеров
    buttons();
    blinkCursor = 1;
    blink_set_alarm(300);
    if (pmenu == 1) ah++;
    if (pmenu == 2) ah--;
    if (ah>23) ah=0;
    if (ah<0) ah=23;
    if ((pmenu == 5) || (pmenu == 8)) {
      clock.setAlarm2(0, ah, 0, DS3231_MATCH_H_M);
      if (pmenu == 5) regim++;
      else {
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      lcd.clear();
      regim = 1;
      return;
    }
  }
  while(regim==4){                        //установка минут таймеров
    buttons();
    blinkCursor = 2;
    blink_set_alarm(250);
    if (pmenu == 1) am++;
    if (pmenu == 2) am--;
    if (am>59) am=0;
    if (am<0) am=59;
    if ((pmenu == 5) || (pmenu == 8)) {
      if (!ah && !am) {
        clock.armAlarm2(false); !alarm_on1;
      }
      else clock.setAlarm2(0, ah, am, DS3231_MATCH_H_M);
      if (pmenu == 5) regim++;
      else {
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      pmenu = 9;
      regim = 1;
      return;}
  }
}
//------------------------------------------------------------
void blink_alarm_on(unsigned long interval){
    static unsigned long prevTime=0;
    if(millis() - prevTime > interval){
      static boolean flag = false;
      prevTime = millis();
      flag = !flag;
      lcd.setCursor(1, 0);
      if (flag) lcd.print("on");
      else lcd.print("  ");
    }
}
//------------------------------------------------------------   
void blink_alarm_off(unsigned long interval){
    static unsigned long prevTime=0;
    if(millis() - prevTime > interval){
      static boolean flag = false;
      prevTime = millis();
      flag = !flag;
      lcd.setCursor(11, 0);
      if(flag) lcd.print("off");
      else lcd.print("   ");
    }
}
//------------------------------------------------------------  
void blink_set_alarm (unsigned long interval){   //мигаем переменной настройки часов/минут будильников
    static unsigned long prevTime=0;
    if(millis() - prevTime > interval){
      static boolean flag = false;
      prevTime = millis();
      flag = !flag;
      if(flag){
        lcd.setCursor(5, 1);
        if (ah<10) lcd.print("0");
        lcd.print(ah);
        lcd.print(":");
        if (am<10) lcd.print("0");
        lcd.print(am);
      }
      else {
        switch (blinkCursor) {
          case 1: lcd.setCursor(5, 1); break;
          case 2: lcd.setCursor(8, 1); break;
          case 3: lcd.setCursor(11, 1); break;
        }
        lcd.print("  ");
      }
    }
}
//------------------------------------------------------------   
 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Если хотите продолжения разговора, то

1. Вставьте код как положено

2. Дайте ссылку на библиотеку.

А то в той библиотеке DS3231, что есть у меня просто нет функции setDateTime, которую Вы дважды используете в ... ХЗ какой строке (это к правильности вставки кода)

veroni0803
Offline
Зарегистрирован: 18.01.2018

Вот хеадер библиотеки

/*
DS3231.h - Header file for the DS3231 Real-Time Clock
 
Version: 1.0.1
(c) 2014 Korneliusz Jarzebski
www.jarzebski.pl
 
This program is free software: you can redistribute it and/or modify
it under the terms of the version 3 GNU General Public License as
published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
 
#ifndef DS3231_h
#define DS3231_h
 
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
 
#define DS3231_ADDRESS              (0x68)
#define DS3231_EEPROM               (0x57)
 
#define DS3231_REG_TIME             (0x00)
#define DS3231_REG_ALARM_1          (0x07)
#define DS3231_REG_ALARM_2          (0x0B)
#define DS3231_REG_CONTROL          (0x0E)
#define DS3231_REG_STATUS           (0x0F)
#define DS3231_REG_TEMPERATURE      (0x11)
 
#ifndef RTCDATETIME_STRUCT_H
#define RTCDATETIME_STRUCT_H
struct RTCDateTime
{
    uint16_t year;
    uint8_t month;
    uint8_t day;
    uint8_t hour;
    uint8_t minute;
    uint8_t second;
    uint8_t dayOfWeek;
    uint32_t unixtime;
};
 
struct RTCAlarmTime
{
    uint8_t day;
    uint8_t hour;
    uint8_t minute;
    uint8_t second;
};
#endif
 
typedef enum
{
    DS3231_1HZ          = 0x00,
    DS3231_4096HZ       = 0x01,
    DS3231_8192HZ       = 0x02,
    DS3231_32768HZ      = 0x03
} DS3231_sqw_t;
 
typedef enum
{
    DS3231_EVERY_SECOND   = 0b00001111,
    DS3231_MATCH_S        = 0b00001110,
    DS3231_MATCH_M_S      = 0b00001100,
    DS3231_MATCH_H_M_S    = 0b00001000,
    DS3231_MATCH_DT_H_M_S = 0b00000000,
    DS3231_MATCH_DY_H_M_S = 0b00010000
} DS3231_alarm1_t;
 
typedef enum
{
    DS3231_EVERY_MINUTE   = 0b00001110,
    DS3231_MATCH_M        = 0b00001100,
    DS3231_MATCH_H_M      = 0b00001000,
    DS3231_MATCH_DT_H_M   = 0b00000000,
    DS3231_MATCH_DY_H_M   = 0b00010000
} DS3231_alarm2_t;
 
class DS3231
{
    public:
 
bool begin(void);
 
void setDateTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second);
void setDateTime(uint32_t t);
void setDateTime(const char* date, const char* time);
RTCDateTime getDateTime(void);
uint8_t isReady(void);
 
DS3231_sqw_t getOutput(void);
void setOutput(DS3231_sqw_t mode);
void enableOutput(bool enabled);
bool isOutput(void);
void enable32kHz(bool enabled);
bool is32kHz(void);
 
void forceConversion(void);
float readTemperature(void);
 
void setAlarm1(uint8_t dydw, uint8_t hour, uint8_t minute, uint8_t second, DS3231_alarm1_t mode, bool armed = true);
RTCAlarmTime getAlarm1(void);
DS3231_alarm1_t getAlarmType1(void);
bool isAlarm1(bool clear = true);
void armAlarm1(bool armed);
bool isArmed1(void);
void clearAlarm1(void);
 
void setAlarm2(uint8_t dydw, uint8_t hour, uint8_t minute, DS3231_alarm2_t mode, bool armed = true);
RTCAlarmTime getAlarm2(void);
DS3231_alarm2_t getAlarmType2(void);
bool isAlarm2(bool clear = true);
void armAlarm2(bool armed);
bool isArmed2(void);
void clearAlarm2(void);
 
void setBattery(bool timeBattery, bool squareBattery);
 
char* dateFormat(const char* dateFormat, RTCDateTime dt);
char* dateFormat(const char* dateFormat, RTCAlarmTime dt);
 
void writeRegister8(uint8_t reg, uint8_t value); // Я перенес из private
 
void EEPROM_WriteByte(uint8_t address, uint8_t data);   // Я добавил для работы с EEPROM
byte EEPROM_ReadByte(uint8_t address);
 
    private:
RTCDateTime t;
 
char *strDayOfWeek(uint8_t dayOfWeek);
char *strMonth(uint8_t month);
char *strAmPm(uint8_t hour, bool uppercase);
char *strDaySufix(uint8_t day);
 
uint8_t hour12(uint8_t hour24);
uint8_t bcd2dec(uint8_t bcd);
uint8_t dec2bcd(uint8_t dec);
 
long time2long(uint16_t days, uint8_t hours, uint8_t minutes, uint8_t seconds);
uint16_t date2days(uint16_t year, uint8_t month, uint8_t day);
uint8_t daysInMonth(uint16_t year, uint8_t month);
uint16_t dayInYear(uint16_t year, uint8_t month, uint8_t day);
bool isLeapYear(uint16_t year);
uint8_t dow(uint16_t y, uint8_t m, uint8_t d);
 
uint32_t unixtime(void);
uint8_t conv2d(const char* p);
 
uint8_t readRegister8(uint8_t reg);
};
 
#endif
Если надо могу разместить .срр. Брал с гитхаба, но адреса нет. Архив есть.
А как надо код вставлять? Пишу первый раз.
 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

veroni0803 пишет:

А как надо код вставлять? Пишу первый раз.

У Вас нет привычки читать форум, прежде, чем писать в него?

http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukomment...

Встаьте нормально Ваш код

Что, до библиотеки, достаточно ссылки, где Вы её скачивали.

 

veroni0803
Offline
Зарегистрирован: 18.01.2018

Нашел ссылку на библиотеку

https://github.com/jarzebski/Arduino-DS3231

veroni0803
Offline
Зарегистрирован: 18.01.2018
#include <avr/io.h>
#include <avr/eeprom.h>
#include <avr/sleep.h>
#include <Wire.h>
#include <IRremote.h>				          // Здесь задействован 2-й таймер
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);   //0x3F - адрес LCD

// С этой библиотекой установка даты и времени почему-то не происходит!!!!!!!
#include <DS3231.h>                   // 0x68 - адрес часов
DS3231 clock;                         // 0х57 - адрес EEPROM в часах
RTCDateTime dt;
RTCAlarmTime a1;
RTCAlarmTime a2;

decode_results results;
const uint8_t RECV_PIN = 10;          // PB0 PCINT0
IRrecv irrecv(RECV_PIN);
/*
#define chip1 0x50          // Адрес внешнего EEPROM
unsigned int pointer;
byte d=0;
*/
//const uint8_t SQW_INT =2;
//#define ON_SQW clock.setOutput(1)
//#define OFF_SQW clock.setOutput(0)

const uint8_t alarmLED = 13;            // PB5 SCK
const uint8_t alarmPWM = 8;             // выход PWM PB1 OC1A
const uint8_t PinBuzzer = 9;            // PB2 
const uint8_t LED = 13;

volatile boolean alarm_on  = false;     // Статус 1-го будильника  
volatile boolean alarm_on1 = false;     // Статус 2-го будильника 
volatile boolean alarm_on2 = false;     // Статус таймера
const uint8_t addr_al2 = 0;             // ячейка EEPROM состояние таймера вкл/выкл
const uint8_t addr_ah2 = 1;             // ячейка EEPROM часы в таймере
const uint8_t addr_am2 = 2;             // ячейка EEPROM минуты в таймере
const uint8_t addr_ahout2 = 3;          // ячейка EEPROM часы в таймере для обратного отсчета
const uint8_t addr_amout2 = 4;          // ячейка EEPROM минуты в таймере для обратного отсчета
const uint8_t addr_q = 5;               // ячейка EEPROM скважность
const uint16_t addr_f = 6;              // ячейка EEPROM частота 
volatile int8_t var_q = 0;              // переменная скважности
volatile int16_t var_f = 0;             // переменная частоты старшие разряды

volatile int8_t ah = 0;
volatile int8_t am = 0;

volatile uint8_t regim = 0;             // переменная для переходов при настройках
volatile uint8_t pmenu = 9;             // меню: в меню  пункта 9 не должно быть
volatile uint8_t blinkCursor = 0;

long button = 0;
const long bmenu    = 10039503;          //menu для просмотра кодов кнопок при выкл таймере pmenu=55
const long balarm1  = 10063983;          // <1> 1-й будильник                   pmenu=6
const long balarm2  = 10074183;          // <2> 2-й будильник                   pmenu=7
const long btimer   = 10090503;          // <3> таймер                          pmenu=0
const long btime    = 10072143;          // <4> корректировка часов             pmenu=3
const long bPWM     = 10066023;          // <5> Регулировка скважности          pmenu=10
const long bF       = 10082343;          // <6> Регулировка частоты             pmenu=12
const long bout_t   = 10061943;          // <7> Выбор выхода по таймеру         pmenu=13
const long bout_a1  = 10070103;          // <8> Выбор выхода по 1-му будильнику pmenu=14
const long bout_a2  = 10086423;          // <9> Выбор выхода по 2-му будильнику pmenu=15
const long bout_PWM = 10053783;          // <+10> Выбор выхода PWM              pmenu=11
const long bright   = 10091013;          // <RIGHT>                             pmenu=8
const long bleft    = 10058373;          // <LEFT>                              pmenu=8
const long bplus    = 10042053;          // <UP> Прибавляем значения            pmenu=1
const long bminus   = 10074693;          // <DOWN> Уменьшаем значения           pmenu=2
const long bcancel  = 10084383;          // <ESC> Top menu                      pmenu=4
const long bselect  = 10037463;          // OK                                  pmenu=5

//const long bset    = 10072653;          //SETUP
//10045623 - 10/0
//10047663 - return
//10027773 -card/usb
//10056333-OSD, 10054293-SUBTITLE, 10078773-O)), 10037973-камера это 4 верхних кнопки
//10057863-влево, 10082853-вправо большая нижняя кнопка, 10033383-AUDIO MODE, 10080303-DIGEST

volatile int8_t th, tm, da, mo, se;
uint16_t ye;

uint8_t bell[8]  = {0x4, 0xe, 0xe, 0xe, 0x1f, 0x0, 0x4};   //колокольчик
uint8_t temp_cel[8] = {B00111, B00101, B00111, B00000, B00000, B00000, B00000};  // Градус

// Переменные для генератора с регулировкой частоты и скважности
volatile uint8_t duty=50;
#define set_duty() {OCR1A=(uint16_t)ICR1*duty/100;}
//--------------------------------------------------------------------------
//Предопределение функций
void blink_temp_rh(unsigned long interval);       // Основной экран, переключаемый на таймер
void SET_A1();
void SET_outA1();
void SET_A2();
void SET_outA2();
void SET_T();
void SET_outT();
void SET_outPWM();      // На каком выходе будет PWM
void SET_PWM();         // Регулировка скважности
void SET_F();           // Регулировка частоты PWM
void blink_set_time (unsigned long interval);                        //мигаем переменной настройки часов
void SET_Timer();
void blink_set_timer (unsigned long interval);                        //мигаем переменной настройки таймера
void Timer_off();
void Timer_on();
void blink_alarm_on(unsigned long interval);
void blink_alarm_off(unsigned long interval);
void blink_set_alarm (unsigned long interval, uint8_t nom);            //мигаем переменной включаем будильник
void dump(decode_results *results); // Дешифрация нажатых ИК-кнопок
void buttons();                     // Обработка кнопок
void myTone(uint32_t i){ 
  i+=(millis()); 
  while(i>millis()){
    digitalWrite(PinBuzzer, HIGH); 
    delayMicroseconds(500); 
    digitalWrite(PinBuzzer, LOW); 
    delayMicroseconds(300);
  } 
}
void SET_freq();             // Изменение частоты генератора
void SET_duty();             // Изменение скважности генератора
void blink_set_qf (unsigned long interval, uint16_t qf);

/*  Делал для внешнего EEPROM, но пка не работает
byte decToBcd(byte val) //Преобразует обычное десятичное число в двоично-десятичное
{
return( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val)  //Преобразует двоично-десятичное число в обычное десятичное
{
return( (val/16*10) + (val%16) );
}
void writeData(int device, unsigned int address, byte data)
// записывает байт данных 'data' в ЭСППЗУ с I2C-адресом 'device'
// в ячейку с номером 'address'
{
Wire.beginTransmission(device);
Wire.write((byte)(address >> 8)); // старший байт номера ячейки
Wire.write((byte)(address & 0xFF)); // и младший байт
Wire.write(decToBcd(data));
Wire.endTransmission();
delay(10);
}
byte readData(int device, unsigned int address)
// читает байт данных из ячейки с номером 'address'
// в ЭСППЗУ с I2C-адресом 'device'
{
byte result; // возвращаемое значение
Wire.beginTransmission(device);
Wire.write((byte)(address >> 8)); // старший байт номера ячейки
Wire.write((byte)(address & 0xFF)); // и младший байт
Wire.endTransmission();
Wire.requestFrom(device,1);
result = Wire.read();
return bcdToDec(result); // вернуть прочитанный байт как
// результат функции readData
}
*/
//==========================================================================
void setup()
{
//  Serial.begin(9600);
  Wire.begin();
  irrecv.enableIRIn();
  lcd.begin();
  clock.begin();
  DDRD = 0;
  PORTD = 0;
  DDRB |= (1<<alarmPWM) | (1<<alarmLED) | (1<<PinBuzzer) | (1<<LED);
  PORTB = 0;
  alarm_on = (clock.isAlarm1())? true: false;   // Инициализaция будильников при перезагрузке
  alarm_on1 = (clock.isAlarm2())? true: false;
  if (eeprom_read_byte(addr_ah2) == 255) {
    eeprom_update_byte(addr_ah2,0);
    eeprom_update_byte(addr_am2,0);
  }
/*
  if (readData(chip1,addr_ah2) == 255) {
    writeData(chip1,addr_ah2,0);
    writeData(chip1,addr_am2,0);  
  }
//writeData(chip1,a,a);
//d=readData(chip1,a);
*/
  lcd.createChar(0, bell);         //колокольчик
  lcd.createChar(1, temp_cel);     //цельсии
  TCCR1A=1<<COM1A1; //подключить выход OC1A первого таймера
  TCCR1B=0;//
  OCR1A = eeprom_read_byte(addr_q);           //читаем скважность выхода для PB1 (OC1A)
  ICR1 = eeprom_read_word(addr_f);            //читаем частоту выхода для PB1 (OC1A)
}
//==========================================================================
void loop()
{
  while(1)
  {
    buttons();                                //Проверяем нажатия клавиш
// Здесь надо сделать проверку кодов клавиш при pmenu=55
    while (regim==55){
      lcd.clear();
      lcd.setCursor(0,0);
      if (pmenu == 4) {                      // Прервать настройку, ничего не менять
        lcd.clear();
        regim = 1;
      }
    }
    dt = clock.getDateTime();
    a1 = clock.getAlarm1();
    a2 = clock.getAlarm2();
    if (clock.isAlarm1())
    {
      myTone(1000);
      alarm_on = false;
      clock.armAlarm1(alarm_on);
    }
    if (clock.isAlarm2())
    {
      myTone(1000);
      alarm_on1 = false;
      clock.armAlarm2(alarm_on1);
    }
    if (pmenu == 9) {
      lcd.setCursor(0, 0);
      lcd.print(clock.dateFormat("H:i:s ", dt));
      lcd.print(clock.readTemperature());     // Считываем температуру с DS3231
      lcd.write(1);
      lcd.print("C");                         //цельсия  lcd.setCursor(0, 1);
      blink_temp_rh(2000);                    //показ таймера и даты (смена каждые 3 сек)
    }
  }
}
//==========================================================================
void SET_freq(){
  uint16_t icr=ICR1;
  uint16_t divider=1;               //переменная коэфф. деления прескалера
  static boolean gen_mode=0;        //флаг режима управления частотой
  regim = 2;
  uint8_t i = 1;
  int16_t f = eeprom_read_word (addr_f);        //читаем частоту выхода для PB1 (OC1A)
  while (regim==2) {                       //задание скважности
    buttons();
    blinkCursor = 1;
    blink_set_qf(250, f);
    if (f <= 15) i=1;
    else if ((f > 10) && (f <= 50)) i=5;
    else if ((f > 50) && (f <=200)) i=10;
    else if ((f > 200) && (f <= 2000)) i=100;
    else if ((f >2000) && (f <= 12000)) i=1000;
    else i=5000;
    if (pmenu == 1) f += i;
    if (pmenu == 2) f -= i;
    if ((f > 65535) || (f < 0))  f = 0;
    if (f > 2848) gen_mode=1;          //переключение режима управления по OCR
    else gen_mode=0;                    //переключение режима управления по частоте
    if ((pmenu == 5) || (pmenu == 8) || (pmenu == 4)) {
      lcd.clear();
      regim = 1;
    }
  }
  if(gen_mode){ 
    ICR1 = f; 
    set_duty(); 
  } 
  else {                              //расчёт прескалера и ICR по нужной частоте
    icr = (F_CPU / f /2 /divider); 
    byte shifts[] = {3,3,2,2};
    for(byte i = 0; i < 4; i++){
      if (icr > 65536) {
          divider <<= shifts[i];
          icr = F_CPU / f /2 /divider;
      }
      else {                          //запись в регистр прескалера
        TCCR1B = (i+1)|(1<<WGM13);  
        break;
      }
    }
    ICR1=icr-1; 
    set_duty();
  }                                   //конец "если  частота менее 2848 герц)
  eeprom_update_word(addr_f, ICR1);
}
//------------------------------------------------------------   
void blink_set_qf (unsigned long interval, uint16_t qf){
    static unsigned long prevTime=0;
    if(millis() - prevTime > interval){
      static boolean flag = false;
      prevTime = millis();
      lcd.clear();
      flag = !flag;
      lcd.setCursor(0,0);
//      if (blinkCursor == 1)
      lcd.print((blinkCursor == 1)? "Worked frequenze":  "Worked sqwaiuer");
      lcd.setCursor(5, 1);
      if(flag){
        lcd.print(qf);
      }
      else {
        lcd.print("  ");
      }
    }
}
//------------------------------------------------------------   
void SET_duty(){
  regim = 2;
  uint8_t i = 1;
  int8_t q = eeprom_read_byte(addr_q);        //читаем скважность выхода для PB1 (OC1A)
  var_q = q;
  while (regim==2) {                       //задание скважности
    buttons();
    blinkCursor = 2;
    blink_set_qf(250, q);
    if (q <= 10) i=1;
    else if ((q > 10) && (q <= 30)) i=5;
    else i=10;
    if (pmenu == 1) q += i;
    if (pmenu == 2) q -= i;
    if ((q >= 100) || (q < 0))  q = 0;
    if ((pmenu == 5) || (pmenu == 8)) {
      if (var_q != q) 
      duty = q;
      set_duty();
      eeprom_update_byte(addr_q, OCR1A);
      lcd.clear();
      regim = 1;
    }
    if (pmenu == 4) {
      lcd.clear();
      regim = 1;
    }
  }
}
//------------------------------------------------------------   
void blink_temp_rh(unsigned long interval){
    static unsigned long prevTime=0;
    uint8_t ah=0, am=0, ahout=0, amout=0;
    uint16_t t_sec = 0, a_sec = 0;
//    alarm_on2 = readData(chip1,addr_al2);
    alarm_on2 = eeprom_read_byte(addr_al2);            //читаем состояние Timer
//    alarm_on2 = clock.EEPROM_ReadByte(addr_al2);
    buttons();
    switch (pmenu) {
      case (0) :
        SET_Timer();                              // Timer
        break;
      case (3) :                                  // Часы
        SET_T();
        break;
      case (6) : 
        SET_A1();                                // 1-й       
        break;
      case (7) :
        SET_A2();                               // 2-й 
        break;
    case (10) :                                 // <5> Регулировка скважности
        SET_duty();
        break;
    case (11) :                                 // <+10> Выбор выхода PWM
        pmenu = 11;
        break;
    case (12) :                                 // <6> Регулировка частоты PWM
        SET_freq();
        break;
    case (13) :                                 // <7> Выбор выхода по таймеру
        break;
    case (14) :                                 // <8> Выбор выхода по 1-му будильнику
        break;
    case (15) :                                 // <9> Выбор выхода по 2-му будильнику
        break;
    }
    if (millis() - prevTime > interval){
    static boolean flag = 0;
    prevTime = millis();
    flag = !flag;
    lcd.setCursor(0, 1);
    if(flag){                                         
      lcd.print(clock.dateFormat("d-m-y     l", dt));
      lcd.setCursor(9,1);
      if (alarm_on)  lcd.write(0);                   // Колокольчик 1-го будильника
      else lcd.print("-");
      if (alarm_on1) lcd.write(0);                   // Колокольчик 2-го будильника
      else lcd.print("-");
      if (alarm_on2){
        lcd.write(0);                                // Колокольчик таймера
        lcd.print(" ");
      }
      else lcd.print("- ");
    }
    else {
      lcd.print("                ");
      lcd.setCursor(0, 1);                          // Не успевала срабатывать команда пробелов
      if (alarm_on2) {
        ah = eeprom_read_byte(addr_ah2);
        am = eeprom_read_byte(addr_am2);
        ahout = eeprom_read_byte(addr_ahout2);
        amout = eeprom_read_byte(addr_amout2);
/*
        ah = readData(chip1,addr_ah2);
        am = readData(chip1,addr_am2);        
        ahout = readData(chip1,addr_ahout2);
        amout = readData(chip1,addr_amout2);        
*/        t_sec = (dt.hour*3600) + (dt.minute*60);    // Текущее время в секундах
        a_sec = (ahout*3600) + (amout*60);
        ahout = (a_sec - t_sec)/3600;
        amout = (((a_sec - t_sec)-(ahout*3600))/60);
        if ((ahout==0) && (amout==0)) {             // Проверка таймера
          Timer_off();
        }
        if (ah<10) lcd.print("0");
        lcd.print(ah);
        lcd.print(":");
        if (am<10) lcd.print("0");
        lcd.print(am);
        lcd.print("m");
        lcd.print(" >>");
        if (ahout<10) lcd.print("0");
        lcd.print(ahout);
        lcd.print(":");
        if (amout<10) lcd.print("0");
        lcd.print(amout);
        lcd.print("<<");
      }
      else lcd.print("Timer not includ");
    }
  }
}
//------------------------------------------------------------  
//----------- Работа с ИК-пультом 2 функции ниже -------------   
// Здесь будем расшифровывать нажатые клавиши
void dump(decode_results *results) {
  pmenu = 9;
  int count = results->rawlen;
  long button = results->value;
/*   Для просмотра кодов кнопок раскомментировать
  lcd.setCursor(0,1);
  int tt = millis();
  while (millis< tt+3000) lcd.print(button);
*/
  if (button > 10000000) {
  switch (button) {
    case (balarm1) :        // 1-й будильник. Используется EEPROM
        pmenu = 6;
        break;
    case (balarm2) :        // 2-ой будильник. Используется EEPROM
        pmenu = 7;
        break;
    case (btimer) :         // 3 Таймер. Используется EEPROM
        pmenu = 0;
        break;
    case (bplus) :          // Приращение переменной(UP)
        pmenu = 1;
        break;
    case (bminus):          // Уменьшение переменной(DOWN)
        pmenu = 2;
        break;
    case (btime) :          // 4 Коррект часов
        pmenu = 3;
        break;
    case (bPWM) :           // <5> Регулировка скважности
        pmenu = 10;
        break;
    case (bout_PWM) :       // <+10> Выбор выхода PWM
        pmenu = 11;
        break;
    case (bF) :             // <6> Регулировка частоты PWM
        pmenu = 12;
        break;
    case (bout_t) :         // <7> Выбор выхода по таймеру
        pmenu = 13;
        break;
    case (bout_a1) :        // <8> Выбор выхода по 1-му будильнику
        pmenu = 14;
        break;
    case (bout_a2) :        // <9> Выбор выхода по 2-му будильнику
        pmenu = 15;
        break;
    case (bcancel):         // Прерывание/Сброс(Top menu)
        pmenu = 4;
        break;
    case (bselect):         // OK
        pmenu = 5;
        break;
    case (bright) :         // RIGHT
        pmenu = 8;
        break;
    case (bleft):           // LEFT
        pmenu = 8;
        break;
    case (bmenu) :
        pmenu = 55;
        regim = 55;
        break;
    default:
        pmenu = 9;
  }
  }
}
//------------------------------------------------------------
void buttons() {
    static unsigned long prevTime=0;
    pmenu = 9;
    if (irrecv.decode(&results)) {
      if (millis() - prevTime > 250) {    // Если прошло по крайней мере 1/4 секунды с момента нажатия
        dump(&results);
      }
      prevTime = millis();
      irrecv.resume();                // Receive the next value
    }
}
//--------------------------------------------------------------------------
//----- Настройка и включение/выключение таймера 4 функции ниже   
void Timer_on () {
// Включаем что-нибудь
  digitalWrite(LED, 1);
//  myTone(1000);
}//------------------------------------------------------------   
void Timer_off() {
    uint8_t ahout=0, amout=0;
    uint16_t t_sec = 0, a_sec = 0;
    myTone(1000);
    PORTB &= !(1<<LED);
    SET_Timer();
}
//------------------------------------------------------------   
void SET_Timer () {   // Пробуем настраивать один таймер
  regim=2;
  digitalWrite(LED, 0);
  uint8_t ahout=0, amout=0, ahout1=0, amout1=0, ah1=0, am1=0, al1=alarm_on2;
  uint16_t t_sec = 0, a_sec = 0;
  lcd.clear();
  lcd.setCursor(1, 0);
  while (regim==2) {                      //включение отключение таймеров
    buttons();
    lcd.print("on Timer  off");
//    al1 = readData(chip1,addr_al2);
    if ((pmenu == 1) ||(pmenu == 2)) alarm_on2 = !alarm_on2;
    if (alarm_on2) blink_alarm_on(250);
    else blink_alarm_off(250);
    ah = eeprom_read_byte(addr_ah2);
    am = eeprom_read_byte(addr_am2);
//    ah = readData(chip1,addr_ah2);
//    am = readData(chip1,addr_am2);   
//    ah1 = ah;
//    am1 = am;     
    lcd.setCursor(5, 1);
    if (ah<10) lcd.print("0");
    lcd.print(ah);
    lcd.print(":");
    if (am<10) lcd.print("0");
    lcd.print(am);
    if ((pmenu == 5) || (pmenu == 8)) {
      eeprom_update_byte(addr_al2, alarm_on2);
//      if (al1 != alarm_on2) writeData(chip1,addr_al2,alarm_on2);
//      al1 = alarm_on2;
      if (alarm_on2) {
        t_sec = (dt.hour*3600) + (dt.minute*60); // Текущее время в секундах
        a_sec = (ah*3600) + (am*60);
        ahout = (a_sec + t_sec)/3600;
        amout = (((a_sec + t_sec)-(ahout*3600))/60);
        eeprom_update_byte(addr_ahout2, ahout);
        eeprom_update_byte(addr_amout2, amout);
//        writeData(chip1,addr_ahout2,ahout);
//        ahout1 = ahout;
//        writeData(chip1,addr_amout2,amout);
//        amout1 = amout;
        if (pmenu == 5) regim++;
        else {
          regim = 1; 
          lcd.clear();
          Timer_on();
        }
      }
      else {
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      lcd.clear();
      regim = 1;
      return;
    }
  }
  while (regim==3) {                      //установка часов таймеров
    buttons();
    blinkCursor = 1;
    blink_set_timer(250);
    if (pmenu == 1) ah++;
    if (pmenu == 2) ah--;
    if (ah>23) ah=0;
    if (ah<0) ah=23;
    if ((pmenu == 5) || (pmenu == 8)) {
      if (alarm_on2) {
        eeprom_update_byte(addr_ah2, ah);
        t_sec = (dt.hour*3600) + (dt.minute*60); // Текущее время в секундах
        a_sec = (ah*3600) + (am*60);
        ahout = (a_sec + t_sec)/3600;
        amout = (((a_sec + t_sec)-(ahout*3600))/60);
        eeprom_update_byte(addr_ahout2, ahout);
        eeprom_update_byte(addr_amout2, amout);
/*        if (ah1 != ah) writeData(chip1,addr_ah2,ah);
        ah1 = ah;
        if (am != am1) writeData(chip1,addr_am2,am);
        am1 = am;
        if (ahout != ahout1) writeData(chip1,addr_ahout2,ahout);
        ahout1 = ahout;
        if (amout != amout1) writeData(chip1,addr_amout2,amout);
        amout1 = amout;
*/
        if (pmenu == 5) regim++;
        else {
          regim = 1; 
          lcd.clear();
          Timer_on();
        }
      }
      else {
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      lcd.clear();
      regim = 1;
      return;
    }
  }
  while(regim==4){                        //установка минут таймеров
    buttons();
    blinkCursor = 2;
    blink_set_timer(250);
    if (pmenu == 1) am++;
    if (pmenu == 2) am--;
    if (am>59) am=0;
    if (am<0) am=59;
    if ((pmenu == 5) || (pmenu == 8)) {
      eeprom_update_byte(addr_am2, am);
      t_sec = (dt.hour*3600) + (dt.minute*60); // Текущее время в секундах
      a_sec = (ah*3600) + (am*60);
      ahout = (a_sec + t_sec)/3600;
      amout = (((a_sec + t_sec)-(ahout*3600))/60);
//      eeprom_update_byte(addr_ahout2, ahout);
      eeprom_update_byte(addr_amout2, amout);
/*      if (am1 != am) writeData(chip1,addr_am2,am);  
      if (ahout1 != ahout) writeData(chip1,addr_ahout2,ahout);
      if (amout1 != amout) writeData(chip1,addr_amout2,amout);  
*/      regim = 1; 
      pmenu = 9;
      Timer_on();
    }
    if (pmenu == 4) {
      pmenu = 9;
      regim = 1;
      return;}
  }
}
//------------------------------------------------------------  
void blink_set_timer (unsigned long interval){   //мигаем переменной включаем будильник
    static unsigned long prevTime=0;
    if(millis() - prevTime > interval){
      static boolean flag = 0;
      prevTime = millis();
      flag = !flag;
      if(flag){
        lcd.clear();
        lcd.setCursor(1, 0);
        lcd.print("on Timer  off");
        lcd.setCursor(5, 1);
        if (ah<10) lcd.print("0");
        lcd.print(ah);
        lcd.print(":");
        if (am<10) lcd.print("0");
        lcd.print(am);
      }
      else {
        switch (blinkCursor) {
          case 1: lcd.setCursor(5, 1); break;
          case 2: lcd.setCursor(8, 1); break;
      }
      lcd.print("  ");
    }
  }
}
//--------------------------------------------------------------------------
void SET_T(){    
  regim=2;
  ye = dt.year;
  mo = dt.month;
  da = dt.day;
  th = dt.hour;
  tm = dt.minute;
  se = dt.second;
  while (regim == 2) {  //установка часов
    buttons();
    blinkCursor = 1;
    blink_set_time(250);
    if (pmenu == 1) th++;
    if (pmenu == 2) th--;
    if (th>23) th=0;
    if (th<0) th=23;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim++;
	  if (pmenu == 5) clock.setDateTime(2018, 2, 25, 18, 12, se); 
	  else regim = 1;
    }
    if (pmenu == 4) regim = 1;
  }
  while (regim == 3) {   //установка минут
    buttons();
    blinkCursor = 2;
    blink_set_time(250);
    if (pmenu == 1) tm++;
    if (pmenu == 2) tm--;
    if (tm>59) tm=0;
    if (tm<0) tm=59;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim++;
	  if (pmenu == 5) clock.setDateTime(2018, 2, 25, th, tm, se); 
      else regim = 1;
    }
    if (pmenu == 4) regim = 1;
  }
  while (regim == 4) {  //установка числа
    buttons();
    blinkCursor = 3;
    blink_set_time(250);
    if (pmenu == 1) da++;
    if (pmenu == 2) da--;
    if (da>31)da=1;
    if (da<1)da=31;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim++;
      if (pmenu == 5) clock.setDateTime(2018, 2, da, th, tm, se); 
      else regim = 1;
    }
    if (pmenu == 4) regim = 1;
  }
  while (regim == 5) {   //установка месяца
    buttons();
    blinkCursor = 4;
    blink_set_time(250);
    if (pmenu == 1) mo++;
    if (pmenu == 2) mo--;
    if (mo>12) mo=1;
    if (mo<1) mo=12;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim++;
      if (pmenu == 5) clock.setDateTime(ye, mo, da, th, tm, se); 
      else regim = 1;
    }
    if (pmenu == 4) regim = 1;
  }
  while (regim == 6) {   //установка года
    buttons();
    blinkCursor = 5;
    blink_set_time(250);
    if (pmenu == 1) ye++;
    if (pmenu == 2) ye--;
    if (ye>2100) ye=2018;
    if (ye<2018) ye=2099;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim=1;
      if (pmenu == 5) clock.setDateTime(ye, mo, da, th, tm, se); 
    }
    if (pmenu == 4) regim = 1;
  }   
}
//------------------------------------------------------------      
void blink_set_time(unsigned long interval){   //мигаем переменной в установке даты и времени
  static unsigned long prevTime=0;
  if(millis() - prevTime > interval){
    static boolean flag = 0;
    prevTime = millis();
    flag = !flag;
    lcd.setCursor(0, 0);
    if(flag){
      if (th<10) lcd.print("0");
      lcd.print(th);                          //показать врем
      lcd.print(":");
      if (tm<10) lcd.print("0");
      lcd.print(tm);
      lcd.setCursor(0, 1);
      if (da<10) lcd.print("0");
      lcd.print(da);                          //показать дату
      lcd.print(".");
      if (mo<10) lcd.print("0");
      lcd.print(mo);
      lcd.print(".");
      lcd.print(ye);
      lcd.print("   ");
      lcd.print(clock.dateFormat("D ", dt));      // Думаю, что день недели
    }
    else {
      switch (blinkCursor) {
        case 1: lcd.setCursor(0, 0); break;
        case 2: lcd.setCursor(3, 0); break;
        case 3: lcd.setCursor(0, 1); break;
        case 4: lcd.setCursor(3, 1); break;
        case 5: lcd.setCursor(8, 1); break;
      }
      lcd.print("  ");
    }
  }
}
//--------------------------------------------------------------------------
void SET_A1 () {   // Пробуем настраивать будильник1
  regim=2;
  lcd.clear();
  lcd.setCursor(1, 0);
  uint8_t da=a1.day, as=a1.second;
  ah=a1.hour;
  am=a1.minute;
  alarm_on = (clock.isArmed1()) ? true: false;
  lcd.print("on Alarm1 off");
  while (regim==2) {
    buttons();
    if ((pmenu == 1) || (pmenu == 2)) alarm_on = !alarm_on;
//    if (pmenu == 2) alarm = !alarm;
    if (alarm_on) blink_alarm_on(250);
    else blink_alarm_off(250);
    if ((pmenu == 5) || (pmenu == 8)) {           //Сохранить настройку
      if (alarm_on) {
        if (pmenu == 5) regim++;
        else {
          if (ah || am) {
            clock.armAlarm1(true);
            regim = 1; 
            lcd.clear();
          }
          else {
            clock.armAlarm1(false);
            alarm_on = false;
            regim = 1; 
            lcd.clear();
          }
        }
      }
      else {
        clock.armAlarm1(false);
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {                      // Прервать настройку, ничего не менять
      lcd.clear();
      regim = 1;
    }
  }
  while (regim==3) {                       //установка часов таймеров
    buttons();
    blinkCursor = 1;
    blink_set_alarm(250);
    if (pmenu == 1) ah++;
    if (pmenu == 2) ah--;
    if (ah>23) ah=0;
    if (ah<0) ah=23;
    if ((pmenu == 5) || (pmenu == 8)) {
      if (ah || am) {
        clock.armAlarm1(true);
        clock.setAlarm1(0, ah, am, 0, DS3231_MATCH_H_M_S);
      }
      if (pmenu == 5) regim++;
      else {
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      lcd.clear();
      regim = 1;
    }
  }
  while(regim==4){                        //установка минут таймеров
    buttons();
    blinkCursor = 2;
    blink_set_alarm(250);
    if (pmenu == 1) am++;
    if (pmenu == 2) am--;
    if (am>59) am=0;
    if (am<0) am=59;
    if ((pmenu == 5) || (pmenu == 8)) {
      if (ah || am) {
        clock.armAlarm1(true);
        clock.setAlarm1(0, ah, am, dt.second, DS3231_MATCH_H_M_S);
      }
      else {
        clock.armAlarm1(false); alarm_on = false;
      }
      if (pmenu == 5) regim++;
      else {
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      pmenu = 9;
      regim = 1;
    }
  }
}
//------------------------------------------------------------   
void SET_A2 () {
  regim=2;
  lcd.clear();
  uint8_t da=a1.day;
  ah=a2.hour;
  am=a2.minute;
  alarm_on1 = (clock.isArmed2()) ? true : false;
  lcd.setCursor(1, 0);
  lcd.print("on Alarm2 off");
  while (regim==2) {
    buttons();
    if ((pmenu == 1) || (pmenu == 2)) alarm_on1 = !alarm_on1;
//    if (pmenu == 2) alarm_on1 = !alarm_on1;
    if (alarm_on1) blink_alarm_on(250);
    else blink_alarm_off(250);
    if ((pmenu == 5) || (pmenu == 8)) {           //Сохранить настройку
      if (alarm_on1) {
        clock.armAlarm2(true);
        if (pmenu == 5) regim++;
        else {
          regim = 1; 
          lcd.clear();
        }
      }
      else {
        clock.armAlarm2(false);
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      lcd.clear();
      regim = 1;
      return;
    }
  }
  while (regim==3) {                      //установка часов таймеров
    buttons();
    blinkCursor = 1;
    blink_set_alarm(300);
    if (pmenu == 1) ah++;
    if (pmenu == 2) ah--;
    if (ah>23) ah=0;
    if (ah<0) ah=23;
    if ((pmenu == 5) || (pmenu == 8)) {
      clock.setAlarm2(0, ah, 0, DS3231_MATCH_H_M);
      if (pmenu == 5) regim++;
      else {
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      lcd.clear();
      regim = 1;
      return;
    }
  }
  while(regim==4){                        //установка минут таймеров
    buttons();
    blinkCursor = 2;
    blink_set_alarm(250);
    if (pmenu == 1) am++;
    if (pmenu == 2) am--;
    if (am>59) am=0;
    if (am<0) am=59;
    if ((pmenu == 5) || (pmenu == 8)) {
      if (!ah && !am) {
        clock.armAlarm2(false); !alarm_on1;
      }
      else clock.setAlarm2(0, ah, am, DS3231_MATCH_H_M);
      if (pmenu == 5) regim++;
      else {
        regim = 1; 
        lcd.clear();
      }
    }
    if (pmenu == 4) {
      pmenu = 9;
      regim = 1;
      return;}
  }
}
//------------------------------------------------------------
void blink_alarm_on(unsigned long interval){
    static unsigned long prevTime=0;
    if(millis() - prevTime > interval){
      static boolean flag = false;
      prevTime = millis();
      flag = !flag;
      lcd.setCursor(1, 0);
      if (flag) lcd.print("on");
      else lcd.print("  ");
    }
}
//------------------------------------------------------------   
void blink_alarm_off(unsigned long interval){
    static unsigned long prevTime=0;
    if(millis() - prevTime > interval){
      static boolean flag = false;
      prevTime = millis();
      flag = !flag;
      lcd.setCursor(11, 0);
      if(flag) lcd.print("off");
      else lcd.print("   ");
    }
}
//------------------------------------------------------------  
void blink_set_alarm (unsigned long interval){   //мигаем переменной настройки часов/минут будильников
    static unsigned long prevTime=0;
    if(millis() - prevTime > interval){
      static boolean flag = false;
      prevTime = millis();
      flag = !flag;
      if(flag){
        lcd.setCursor(5, 1);
        if (ah<10) lcd.print("0");
        lcd.print(ah);
        lcd.print(":");
        if (am<10) lcd.print("0");
        lcd.print(am);
      }
      else {
        switch (blinkCursor) {
          case 1: lcd.setCursor(5, 1); break;
          case 2: lcd.setCursor(8, 1); break;
          case 3: lcd.setCursor(11, 1); break;
        }
        lcd.print("  ");
      }
    }
}
//------------------------------------------------------------   

А что изменилось?

veroni0803
Offline
Зарегистрирован: 18.01.2018

Понял.

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

Вы пытаетесь устанавливать время аж в пяти местах (это, кстати, говорит о том, что структура программы недостаточно продумана). Это строки №№ 701, 716, 731, 746 и 761. Все эти строки выглядят одинаково

if (pmenu == 5) clock.setDateTime(...

Вы уверены что время не устанавливается? Может Вы просто не пытаетесь его устанавливать. Попробуйте вставить контрольную печать в Serial. т.е. во всех пяти местах замените строку "if (pmenu ..." на примерно такое:

if (pmenu == 5) {
	clock.setDateTime(..<оставьте что было>...); 
	RTCDateTime control = clock.getDateTime();
	Serial.print("Line "); 
	Serial.print(__LINE__);
	Serial.print(": ");
	Serial.println(clock.dateFormat("d-m-Y H:i:s", control));
}

И не забудьте потавить Serial.begin в setup.

Теперь Вы сможете поконтролировать попытки установки времени и точно понять оно действительно не устанавливается или Вы его не устанавливаете. Сделайте и покажите, что выдаёт.

 

veroni0803
Offline
Зарегистрирован: 18.01.2018
 
Сделал так
void SET_T(){    
  regim=2;
  ye = dt.year;
  mo = dt.month;
  da = dt.day;
  th = dt.hour;
  tm = dt.minute;
  se = dt.second;
  while (regim == 2) {  //установка часов
    buttons();
    blinkCursor = 1;
    blink_set_time(250);
    if (pmenu == 1) th++;
    if (pmenu == 2) th--;
    if (th>23) th=0;
    if (th<0) th=23;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim++;
	  if (pmenu == 5){ clock.setDateTime(2018, 2, 25, 18, 12, se); 
    RTCDateTime control = clock.getDateTime();
  Serial.print("Line "); 
  Serial.print(__LINE__);
  Serial.print(": ");
  Serial.println(clock.dateFormat("d-m-Y H:i:s", control));
	  } else regim = 1;
    }
    if (pmenu == 4) regim = 1;
  }
  while (regim == 3) {   //установка минут
    buttons();
    blinkCursor = 2;
    blink_set_time(250);
    if (pmenu == 1) tm++;
    if (pmenu == 2) tm--;
    if (tm>59) tm=0;
    if (tm<0) tm=59;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim++;
	  if (pmenu == 5) { 
	    clock.setDateTime(2018, 2, 25, th, tm, se); 
      RTCDateTime control = clock.getDateTime();
  Serial.print("Line "); 
  Serial.print(__LINE__);
  Serial.print(": ");
  Serial.println(clock.dateFormat("d-m-Y H:i:s", control));
	  }
      else regim = 1;
    }
    if (pmenu == 4) regim = 1;
  }
  while (regim == 4) {  //установка числа
    buttons();
    blinkCursor = 3;
    blink_set_time(250);
    if (pmenu == 1) da++;
    if (pmenu == 2) da--;
    if (da>31)da=1;
    if (da<1)da=31;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim++;
      if (pmenu == 5){ clock.setDateTime(2018, 2, da, th, tm, se); 
      RTCDateTime control = clock.getDateTime();
  Serial.print("Line "); 
  Serial.print(__LINE__);
  Serial.print(": ");
  Serial.println(clock.dateFormat("d-m-Y H:i:s", control));
      } else regim = 1;
    }
    if (pmenu == 4) regim = 1;
  }
  while (regim == 5) {   //установка месяца
    buttons();
    blinkCursor = 4;
    blink_set_time(250);
    if (pmenu == 1) mo++;
    if (pmenu == 2) mo--;
    if (mo>12) mo=1;
    if (mo<1) mo=12;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim++;
      if (pmenu == 5){ clock.setDateTime(ye, mo, da, th, tm, se); 
      RTCDateTime control = clock.getDateTime();
  Serial.print("Line "); 
  Serial.print(__LINE__);
  Serial.print(": ");
  Serial.println(clock.dateFormat("d-m-Y H:i:s", control));
      } else regim = 1;
    }
    if (pmenu == 4) regim = 1;
  }
  while (regim == 6) {   //установка года
    buttons();
    blinkCursor = 5;
    blink_set_time(250);
    if (pmenu == 1) ye++;
    if (pmenu == 2) ye--;
    if (ye>2100) ye=2018;
    if (ye<2018) ye=2099;
    if ((pmenu == 5) || (pmenu == 8)) {
      regim=1;
      if (pmenu == 5){ clock.setDateTime(ye, mo, da, th, tm, se); 
      RTCDateTime control = clock.getDateTime();
  Serial.print("Line "); 
  Serial.print(__LINE__);
  Serial.print(": ");
  Serial.println(clock.dateFormat("d-m-Y H:i:s", control));
    }}
    if (pmenu == 4) regim = 1;
  }   
}

Получил результат:

Line 704: 12-18-2007 08:01:14
Line 725: 04-11-2007 08:01:23
Line 746: 04-11-2006 08:01:44
Line 766: 04-11-2002 08:01:54
Line 786: 04-11-2002 08:01:58 Это и на индикаторе после настройки. А вводил сегодняшнюю дату и время.
Похоже напутан порядок часы, минуты и т.д.
А пять сделано, чтобы можно было откорректировать что-то одно. Там временно цифры остались от предыдущих мучений
 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

veroni0803 пишет:
А вводил сегодняшнюю дату и время.

Так, давайте смотреть что Вы вводили. Привыкайте работать с открытыми глазами. Вот смотрите, сейчас у Вас вот так:

if (pmenu == 5){
	clock.setDateTime(ye, mo, da, th, tm, se); 
	RTCDateTime control = clock.getDateTime();
	Serial.print("Line "); 
	Serial.print(__LINE__);
	Serial.print(": ");
	Serial.println(clock.dateFormat("d-m-Y H:i:s", control));
}

Теперь добавляйте печать того, что Вы передаёте часам

if (pmenu == 5){
	Serial.print("ye=); Serial.println(ye);
	Serial.print("mo=); Serial.println(mo);
	Serial.print("th=); Serial.println(th);
	Serial.print("tm=); Serial.println(tm);
	Serial.print("se=); Serial.println(se);
	clock.setDateTime(ye, mo, da, th, tm, se); 
	RTCDateTime control = clock.getDateTime();
	Serial.print("Line "); 
	Serial.print(__LINE__);
	Serial.print(": ");
	Serial.println(clock.dateFormat("d-m-Y H:i:s", control));
}

Теперь Вы будете видеть что Вы пихаете часам. Если пихаете то, что надо, а часы ставятся не так, разбирайтесь с setDateTime (порядок параметров и т.п.). А если пихаете не то что надо, то разбирайтесь почему эти переменные имеют неверные значения.

Т.е. мы разделили программу и немного локализовали проблему. Вот так мы и работаем.

veroni0803
Offline
Зарегистрирован: 18.01.2018

Перед первым set задал жестко

void SET_T(){    
  regim=2;
  /*
  ye = dt.year;
  mo = dt.month;
  da = dt.day;
  th = dt.hour;
  tm = dt.minute;
*/
  ye = "2018";
  mo = "04";
  da = "03";
  th = "20";
  tm = "";
  se = dt.second;
  ye = "2018";
  mo = "04";
  da = "03";
  th = "20";
  tm = "";
Получил
ye=389
mo=-118
th=20
tm=-23
se=24
Line 717: 04-11-2002 09:10:38
Почему такой ye и mo не понятно. Ну и в часах совершенно другие цифры.

Потом цифры поправил

ye=389
mo=-118
th=20
tm=10
se=24
Line 743: 04-11-2002 09:11:15
ye=389
mo=-118
th=20
tm=10
se=24
Line 770: 04-11-2002 09:11:50
ye=389
mo=4
th=20
tm=10
se=24
Line 796: 04-11-2002 09:12:15
ye=2018
mo=4
th=20
tm=10
se=24
Line 822: 04-11-2002 09:12:25
Но часы вообще ничего не воспринимают. Наверное что-то в библиотеке не так?
И с переменными ye, mo непонятки.
 
veroni0803
Offline
Зарегистрирован: 18.01.2018

Надо было

  ye = 2018;
  mo = 04;
  da = 03;
  th = 20;
  tm = 25;
  se = dt.second;
Но не работает
ye=2018
mo=4
th=20
tm=25
se=56
Line 718: 04-11-2002 09:26:58
ye=2018
mo=4
th=20
tm=25
se=56
Line 744: 04-11-2002 09:27:01
ye=2018
mo=4
th=20
tm=25
se=56
Line 771: 04-11-2002 09:27:07
ye=2018
mo=4
th=20
tm=25
se=56
Line 797: 04-11-2002 09:27:08
ye=2018
mo=4
th=20
tm=25
se=56
Line 823: 04-11-2002 09:27:11
Хотя при наборе на индикаторе все правильно. Видимо библиотека виновата, а что там не так мне не понятно.

 

veroni0803
Offline
Зарегистрирован: 18.01.2018

Надо, наверное, в библиотеку Serial куда-то вставить?

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

veroni0803 пишет:

Перед первым set задал жестко

void SET_T(){    
  regim=2;
  /*
  ye = dt.year;
  mo = dt.month;
  da = dt.day;
  th = dt.hour;
  tm = dt.minute;
*/
  ye = "2018";
  mo = "04";
  da = "03";
  th = "20";
  tm = "";
  se = dt.second;

Наверное что-то в библиотеке не так?

Да, нет, это в голове у Вас непонятки.

Нафига Вы строки присваивали, когда там числа нужны? Ставьте ЧИСЛА, а не строки!

Это вообще Ваш скетч?

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

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

Это вообще Ваш скетч?

конечно нет. Он бы на десятой строчке завопил "Памагите" с такими знаниями...

veroni0803
Offline
Зарегистрирован: 18.01.2018

Спасибо за помощь.

vadim82
Offline
Зарегистрирован: 12.05.2018

Здравствуйте ! У меня такая проблема..не идут часы. Показывает одно и то же время, хотя дата по прошествии суток изменяется Пара Arduino nano и RTC3231 Перепробовал с десяток библиотек, но безуспешно. Взял библиотеку из этой темы (https://github.com/jarzebski/Arduino-DS3231) но как и ожидалось, не тикают часы Скетч:




#include <Wire.h>
#include <DS3231.h>

DS3231 clock;
RTCDateTime dt;

void setup()
{
  Serial.begin(9600);

  // Initialize DS3231
  Serial.println("Initialize DS3231");;
  clock.begin();

  // Set sketch compiling time
  clock.setDateTime(__DATE__, __TIME__);
}

void loop()
{
  dt = clock.getDateTime();

  // For leading zero look to DS3231_dateformat example

  Serial.print("Raw data: ");
  Serial.print(dt.year);   Serial.print("-");
  Serial.print(dt.month);  Serial.print("-");
  Serial.print(dt.day);    Serial.print(" ");
  Serial.print(dt.hour);   Serial.print(":");
  Serial.print(dt.minute); Serial.print(":");
  Serial.print(dt.second); Serial.println("");

  delay(1000);
}

Проверил сканнером, все находит:

I2C Scanner
Scanning...
I2C device found at address 0x57  !
I2C device found at address 0x68  !
done

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