Уход в сон через минуту после подачи питания

Arduino nano,в моем проекте необходимо уходить в сон через минуту ( точность не принципиальна) после подачи питания
При этом не использовать миллис,так как таймеры 0 и 2 заняты в программе
Подскажите пожалуйста-как это организовать правильно?
Пробовал сам но максимум получается 7 секунд

Короткое описание-после подачи питания можно установить через UART необходимые данные (текущее время и время будильника на DS3231),в процессе установки эта самая минута начинается заново,после того как все установили-проходит минута,ардуино уходит в сон

Показывай свой код. От настройки твоих таймеров зависит. Вполне в +/- можно уложиться, но нужно смотреть…

ЗЫ: или тс поправил первый пост, или я не углядел при первом прочтении. Поэтому правлю свой.

Arduino nano,Atmega328p,что-то я не подумал про таймер1,спасибо за наводку
Код длинный,как его вставить правильно точно не знаю,попробую,может не забанят за такую простыню…

//Программа включения тв по будильнику,подробнее- https://forum.arduino.ru/t/schityvanie-ik-priemnika-kod-ot-pulta-lyustry-po-protokolu-nec/14053/6?u=gusev

#include <Wire.h>
#include <avr/sleep.h>
int pin = 13;
//Константы для интервалов
//const unsigned int  Preset_110ms=977;    // Предустановка счетчика на 110 мс      
//const unsigned int  Preset_40ms=360;     //Предустановка счетчика на 40 мс    для повтора 
const byte          Preset_9ms=80;       // Предустановка счетчика на 9 мс
const byte          Preset_4_5ms=40;     // Предустановка счетчика на 4,5 мс
//const byte          Preset_2_25ms= 20;    // Предустановка счетчика на 2,25 мс
const byte          Preset_1_6875ms=15;  // Предустановка счетчика на 1,6875 мс
const byte          Preset_562_5us=5;    // Предустановка счетчика на 562,5 мкс
volatile unsigned int Count_set;         //Для задания кол-ва тактов   
unsigned int Count;                      //Для отсчета тактов,1 такт=112,5 мксек
volatile boolean Flag=0,SLEEP_flag=0;                 //Флаг что отсчет закончен
byte Address1=0,Address2 = 254;          //Адресс NEC устройства
byte Command1= 207,Command2 = 48;        //Команда NEC устройства
byte data,SERIAL_FLAG=0;
byte HOUR=22,MIN=00,SEC=00,BUD_HOUR,BUD_MIN,BUD_SEC,BUD_flag=1;
volatile int state = LOW;



 
ISR (TIMER0_COMPA_vect) {                                    // 112.5 usec
  Count++; 
  if (Count==Count_set){Count=0;Flag=0;}
  //if (Count==65534)SLEEP_flag=1;       
}

void setup() {
  Serial.begin(9600);Serial.println("     166_TIMER2_DS3231     ");
  pinMode (6,OUTPUT); // выход генератора
//Настраиваем вывод таймера OC2A (PB3) на выход
  PORTB&= ~(1<<PINB3);         //Значение по умолчанию 0.
  DDRB|= (1<<DDB3);            //Вывод PB3 - выход
  PORTD&= (1<<PIND2);         //Внешнее прерывание от SQW DS3231
  DDRD|= (0<<DDD2);            // вход
//Настраиваем Таймер2
  TCCR2A=0;TCCR2B=0;
  TCCR2A|= (1<<WGM21); //Выставляем режим CTC
  TCCR2B|= (1<<CS20);  //Ставим предделитель на значение 1. CS02=1. CS00=1. Запускаем генерацию
  OCR2A=0xD1;          //Выставляем значение счетчика (к примеру 0xFA)
  TCCR2A|= (1<<COM2A0); //Инвертируем значение OC2A (PB3) по срабатыванию таймера.

  TCCR0A = 0;TCCR0B = 0; 
  OCR0A = 225;                                               // F=16000000/Prescale*Ocr2a = 8888,88 Ãö  = 112,5 ìêñ 
  TCCR0A = (1 << WGM01);                                     // CTC режим
  TIMSK0 |= (1 << OCIE0A);                                   // включение прерываний по совпадению
  TCCR0B = 1 << CS01;          // запуск с таймера с делителем на 8
  IR_send(0, 0x7F, 0xF3,0x0C);
  Wire.begin(); // активируем шину
  attachInterrupt(0, BUDILMIK, FALLING);
  //SET_SQW_2BUD();//каждую минуту
  SET_SQW_1BUD();
  RESET_FLAG_BUD();
  SERIAL_FLAG=0;
  BUD_flag=1;
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
}

void loop() {
 //sleep_mode();
 //Установка текущего времени и будильника
  if (Serial.available() > 0) {
    Count=0;
    int  data = Serial.parseInt();
    if (SERIAL_FLAG==0){
       if (data==1)Serial.print("Введите час  ");
       if (data==2)Serial.print("Введите мин  ");
       if (data==3)Serial.print("Введите сек  ");
       if (data==4)Serial.print("Будильник час  ");
       if (data==5)Serial.print("Будильник мин  ");
       if (data==98){IR_send(0, 0x7F, 0xF3,0x0C);Serial.println("IR SEND OK");data = 0;}//для проверки-отправляем команду вкл тв
       if (data==96){data = 0;SLEEP_flag=1;}//Serial.println("SLEEP ON");               //так в сон уходит замечательно
       if (data>5&&data<90)Serial.println("Не правильный ввод!!!");                     //если выбрано не правильно
       if (data<6)SERIAL_FLAG=data;data =99;                                            //если выбрано правильно переход на след меню
       }
    if (data<99){
       Serial.println(data);
       if (SERIAL_FLAG==1){SERIAL_FLAG=100;if (data<24)SET_REG3231(2,data);HOUR=READ_DS3231(0x02);}//уст часов
       if (SERIAL_FLAG==2){SERIAL_FLAG=100;if (data<60)SET_REG3231(1,data);MIN=READ_DS3231(0x01);}//уст минут
       if (SERIAL_FLAG==3){SERIAL_FLAG=100;if (data<60)SET_REG3231(0,data);SEC=READ_DS3231(0x00);}//уст секунд
       if (SERIAL_FLAG==4){SERIAL_FLAG=100;if (data<24)SET_REG3231(9,data);SET_REG3231(10,0B10000000);BUD_HOUR=READ_DS3231(0x09);}//будильник часы
       if (SERIAL_FLAG==5){SERIAL_FLAG=100;if (data<60)SET_REG3231(8,data);SET_REG3231(10,0B10000000);BUD_MIN=READ_DS3231(0x08);}//будильник минуты
       if (SERIAL_FLAG==100){SERIAL_FLAG=0;}
       }             
    Serial.end();//выкл и вкл уарт-только так работают таймеры,иначе глючат
    Serial.begin(9600);
    BUD_flag=1;//Чтоб сразу в мониторе отобразилось текущее время и время будильника
    }
 if (BUD_flag==1){
            BUD_flag=READ_DS3231(0x0F) & 0x01;
            SEC=READ_DS3231(0x00);
            MIN=READ_DS3231(0x01);
            HOUR=READ_DS3231(0x02);
            BUD_SEC=READ_DS3231(0x07);
            BUD_MIN=READ_DS3231(0x08);
            BUD_HOUR=READ_DS3231(0x09);
            if (BUD_flag==1){  //если сработал будильник1
              Serial.println("Будильник сработал ");
              int  data=50;//задержка между коммандой "вкл тв" и "вкл HDMI" 
              if(BUD_SEC==0){  //если секунды будильника=0 то вкл тв,через data сек отправляет "ОК"
                IR_send(0, 0x7F, 0xF3,0x0C);SET_REG3231(7,data);Serial.println("TV ON   ");digitalWrite(pin, 1);SERIAL_FLAG=100;//чтоб в уарт не улетело ничего
              }
              if(BUD_SEC==data){ //спустя data сек отправляем ок и ставим секунды=0 
                IR_send(0, 0x7F, 0xE8,0x17);SET_REG3231(7,0);Serial.println("TV OKEI ");digitalWrite(pin,0);SERIAL_FLAG=0;//чтоб в уарт улетело инфа
              }
              BUD_SEC=READ_DS3231(0x07);
            SLEEP_flag=1;
            }
            //if (SERIAL_FLAG==0&&SLEEP_flag==0){UART();}
            if (SERIAL_FLAG==0){UART();}
            Flag=1;//взводим флаг
            Count_set=Preset_9ms; // Уснавливаем задержку 9 мсек,иначе в уарт не успевают уйти данные
            TCCR0B = 1 << CS01;
            TCCR2A|= (1<<WGM21); //Выставляем режим CTC
            while (Flag==1){};
            
            RESET_FLAG_BUD();
            //son();
}
if (SLEEP_flag==1){SLEEP_flag=0;son();}//уходим в сон

}
//***********Подпрограммы***************
//***********Срабатываение будильника***
void BUDILMIK(){//прерывание1 
  BUD_flag=1;//Устанавливаем флаг что будильник сработал
  }
//***********Вывод в уарт информации о времени и будильнике,меню настроек**********
void UART(){
            Serial.println("---------------------------");
            //Serial.println("     001_TV_ON_DS3231     ");номер прошивки
            Serial.print("   Текущее время   ");
            if (HOUR<10)Serial.print("0");Serial.print(HOUR);Serial.print(":");
            if (MIN<10)Serial.print("0");Serial.print(MIN);Serial.print(":");
            if (SEC<10)Serial.print("0");Serial.println(SEC);
            Serial.print("Будильник сработает в ");
            if (BUD_HOUR<10)Serial.print("0");Serial.print(BUD_HOUR);Serial.print(":");
            if (BUD_MIN<10)Serial.print("0");Serial.println(BUD_MIN);//Serial.print(":");
                Serial.println("***Установка времени******");
                Serial.println("  1=ЧАСЫ  2=МИН   3=СЕК");
                Serial.println("***Установка БУДИЛЬНИКА***");
                Serial.println("     4=ЧАС  5=МИНУТЫ");
}
//***********Установка будильника1***************
void SET_SQW_1BUD(){
  
  Wire.begin();
  Wire.beginTransmission(0x68);
  Wire.write(0x0A);      //1 будильник
  Wire.write(0B10000000);//A1M4  каждый день
  Wire.endTransmission();
  Wire.beginTransmission(0x68);
  Wire.write(0x07);      //
  Wire.write(0B0000000);//секунды будильника1=00
  Wire.endTransmission();
  Wire.beginTransmission(0x68);
  Wire.write(0x0E);      //Разрешение работы будильника1 =
  Wire.write(0B00000101);//EOSC BBSQW CONV RS2 RS1 INTCN A2IE A1IE
  Wire.endTransmission();
  
}
void RESET_FLAG_BUD(){//Сброс флага срабатывания будильника
  BUD_flag=0;
  Wire.beginTransmission(0x68);
  Wire.write(0x0F);      
  Wire.write(0B10001000);
  Wire.endTransmission();
  
}
void SET_REG3231(byte reg, byte data){
  Wire.beginTransmission(0x68);
  Wire.write(reg);      //номер регистра
  data=bin2bcd(data);
  Wire.write(data);
  Wire.endTransmission();
  }
int READ_DS3231(byte reg){ 
  byte result;
  Wire.beginTransmission(0x68);
  Wire.write(reg);
  Wire.endTransmission();
  Wire.requestFrom(0x68, 1);
  result   = bcd2bin(Wire.read() & 0x7F);
  Wire.endTransmission();
  return result;
}


uint8_t bin2bcd(uint8_t val) {
  return val%10 +  ((val / 10)<<4);
  //return val + 6 * (val / 10);
}

uint8_t bcd2bin(uint8_t val) {
  return val - 6 * (val >> 4);
}
void son() {
  Serial.println("SLEEP ON");
  Count=0;Count_set=500;Flag=1;while (Flag==1){};
  sleep_mode();
  Count=0;Count_set=Preset_9ms;Flag=1;while (Flag==1){};
}
void IR_send(byte Address1, byte Address2, byte Command1,   byte Command2){  
  Flag=1;//взводим флаг
 Count_set=Preset_9ms; // Уснавливаем задержку 9000/112,5=80
 Count=0; 
 TCCR0B = 1 << CS01;
 TCCR2A|= (1<<WGM21); //Выставляем режим CTC
 TCCR2A|= (1<<COM2A0); //Инвертируем значение OC0A (PD6) по срабатыванию таймера.
 while (Flag==1){};
 TCCR2A= 0<<COM2A0;//останавливаем генерацию 38 кГц 
 //пауза 4,5 мсек
 Count_set=Preset_4_5ms; // Уснавливаем задержку 4500/112,5=40
 Flag=1;
 while (Flag==1){}; 
 //передаем адресс1,вкл генерацию на 560 мксек
 for(uint8_t j = 0; j <4; j++) {
         switch (j) {
              case 0:data=Address1;break;
              case 1:data=Address2;break;
              case 2:data=Command1;break;
              case 3:data=Command2;break;
                }
    for(uint8_t i = 0; i <8; i++) {
       TCCR2A|= (1<<WGM21); //Выставляем режим CTC
       TCCR2A|= (1<<COM2A0); //Инвертируем значение OC0A (PD6) по срабатыванию таймера.
       Count_set=Preset_562_5us; // Уснавливаем задержку 4500/112,5=40
       Flag=1;
       while (Flag==1){};
       TCCR2A= 0<<COM2A0;//останавливаем генерацию 38 кГц 
    //пауза,лог 0=560 мксек,1=1_6875 мсек
      if (bitRead(data, i)==0)
        {Count_set=Preset_562_5us;}
      else
        {Count_set=Preset_1_6875ms;}
      Flag=1;
      while (Flag==1){};
  }
 }

  
    TCCR2A|= (1<<WGM21); //Выставляем режим CTC
    TCCR2A|= (1<<COM2A0); //Инвертируем значение OC0A (PD6) по срабатыванию таймера. 
    Count_set=Preset_562_5us; // Уснавливаем задержку 4500/112,5=40
    Flag=1;
    while (Flag==1){};
    TCCR2A= 0<<COM2A0;//останавливаем генерацию 38 кГц
  
  //просто пауза-ВРЕМЕННО!
  Count_set=Preset_9ms;
  Flag=1;
  while (Flag==1){};
  Count_set=Preset_9ms;
  Flag=1;
  while (Flag==1){};
  
  
}

В строке 29 пробовал включать-задержка всего около 7 сек…

Жаваный крот!
Перенеси с таймер0 всё на таймер1 и останутся у тебя и millis() и analogwrite() (если надо) и тп.

1 лайк

Вот что значит ответ знатока! Спасибо!
можно же перенести отсчет 112,5 мксек на таймер1

Я далеко не знаток, это просто очевидно.

Можно по другому, если интересно…

Вспомнилось еще - “Щука, брат”))

1 лайк

Вот так еще можно:
Заведи еще одну переменную счетчик


ISR (TIMER0_COMPA_vect) {                                    // 112.5 usec
  Count++;
  if (Count==8000) // лень считать, сам посчитай когда примерно 1 сек. будет
  {
    CountMS++
  }
}

Как в основном цикле CountMS будет больше 60 - выполняй свои действия и не забудь обнулить CountMS.

1 лайк

Вроде доделал…
Передает сигнал по ИК-каналу на включение телевизора в заданное время,через 59 секунд передает комманду “ОК” (тв после включения подключается к сети интернет по Wi-Fi,примерно через 30-40 сек появляется выбор входа HDMI1,HDMI2,HDMI3 и т д,активно окно HDMI1,надо нажать ОК чтоб тв включился по нормальному)
ТВ откровенный валенок,чуть что вылезает алиса и спрашивает “чем могу помочь”,знал бы что он такой ни за что не купил бы
Код,ток потребления в режиме сна 0,7 мА (0,6 мА жрет DS3231 и CH340)

//Программа включения тв по будильнику,подробнее- https://forum.arduino.ru/t/schityvanie-ik-priemnika-kod-ot-pulta-lyustry-po-protokolu-nec/14053/6?u=gusev

#include <Wire.h>
#include <avr/sleep.h>
int pin = 13;//светодиод,когда атмега активно-горит,в режиме сна гаснет
const byte          Preset_9ms=80;       // Предустановка счетчика на 9 мс
const byte          Preset_4_5ms=40;     // Предустановка счетчика на 4,5 мс
const byte          Preset_1_6875ms=15;  // Предустановка счетчика на 1,6875 мс
const byte          Preset_562_5us=5;    // Предустановка счетчика на 562,5 мкс
volatile unsigned int Count_set=8889,Countsec=0;         //Для задания кол-ва тактов   
unsigned int Count;                      //Для отсчета тактов,1 такт=112,5 мксек
volatile boolean Flag=0,SLEEP_flag=0;                 //Флаг что отсчет закончен
byte Address1=0,Address2 = 254;          //Адресс NEC устройства
byte Command1= 207,Command2 = 48;        //Команда NEC устройства
byte data,SERIAL_FLAG=0;
byte HOUR=22,MIN=00,SEC=00,BUD_HOUR,BUD_MIN,BUD_SEC,BUD_flag=1;
//volatile int state = LOW,CountMS;



 
ISR (TIMER0_COMPA_vect) {                                    // 112.5 usec
  Count++; 
  if (Count==Count_set){Count=0;Flag=0;if(Count_set==8889)Countsec++; else Countsec=0;Count_set=8889;}
  if (Countsec==60)SLEEP_flag=1; //счет секундных  интервалов     
}

void setup() {
  Serial.begin(9600);Serial.println("     003_TV_ON_DS3231     ");
//  pinMode (6,OUTPUT); // выход генератора
//Настраиваем вывод таймера OC2A (PB3) на выход
  PORTB&= ~(1<<PINB3);         //Значение по умолчанию 0.
  DDRB|= (1<<DDB3);            //Вывод PB3 - выход
  PORTD&= (1<<PIND2);         //Внешнее прерывание от SQW DS3231
  DDRD|= (0<<DDD2);            // вход
//Настраиваем Таймер2
  TCCR2A=0;TCCR2B=0;
  TCCR2A|= (1<<WGM21); //Выставляем режим CTC
  TCCR2B|= (1<<CS20);  //Ставим предделитель на значение 1. CS02=1. CS00=1. Запускаем генерацию
  OCR2A=0xD1;          //Выставляем значение счетчика (к примеру 0xFA)
  TCCR2A|= (1<<COM2A0); //Инвертируем значение OC2A (PB3) по срабатыванию таймера.

  TCCR0A = 0;TCCR0B = 0; 
  OCR0A = 225;                                               // F=16000000/Prescale*Ocr2a = 8888,88 Ãö  = 112,5 ìêñ 
  TCCR0A = (1 << WGM01);                                     // CTC режим
  TIMSK0 |= (1 << OCIE0A);                                   // включение прерываний по совпадению
  TCCR0B = 1 << CS01;          // запуск с таймера с делителем на 8
  IR_send(0, 0x7F, 0xF3,0x0C);
  Wire.begin(); // активируем шину
  attachInterrupt(0, BUDILMIK, FALLING);
  //SET_SQW_2BUD();//каждую минуту-отключен
  SET_SQW_1BUD();//разрешаем работу будильника-каждый день
  RESET_FLAG_BUD();//флаг срабатывания будильника-сброс
  SERIAL_FLAG=0;   //
  BUD_flag=1;      //взводим флаг срабатывания будильника чтоб при включении прибора в уарт передалось меню установок
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);//режим сна
  digitalWrite(pin, 1);
}

void loop() {
 //Установка текущего времени и будильника
  if (Serial.available() > 0) {
    Count=0;Countsec=0;
    int  data = Serial.parseInt();
    if (SERIAL_FLAG==0){
       if (data==1)Serial.print("Введите час  ");
       if (data==2)Serial.print("Введите мин  ");
       if (data==3)Serial.print("Введите сек  ");
       if (data==4)Serial.print("Будильник час  ");
       if (data==5)Serial.print("Будильник мин  ");
       if (data==98){IR_send(0, 0x7F, 0xF3,0x0C);Serial.println("IR SEND OK");data = 0;}//для проверки-отправляем команду вкл тв
       if (data==96){data = 0;SLEEP_flag=1;}//Serial.println("SLEEP ON");               //так в сон уходит замечательно,для проверки
       if (data>5&&data<90)Serial.println("Не правильный ввод!!!");                     //если выбрано не правильно
       if (data<6)SERIAL_FLAG=data;data =99;                                            //если выбрано правильно переход на след меню
       }
    if (data<99){
       Serial.println(data);
       if (SERIAL_FLAG==1){SERIAL_FLAG=100;if (data<24)SET_REG3231(2,data);HOUR=READ_DS3231(0x02);}//уст часов
       if (SERIAL_FLAG==2){SERIAL_FLAG=100;if (data<60)SET_REG3231(1,data);MIN=READ_DS3231(0x01);}//уст минут
       if (SERIAL_FLAG==3){SERIAL_FLAG=100;if (data<60)SET_REG3231(0,data);SEC=READ_DS3231(0x00);}//уст секунд
       if (SERIAL_FLAG==4){SERIAL_FLAG=100;if (data<24)SET_REG3231(9,data);SET_REG3231(10,0B10000000);BUD_HOUR=READ_DS3231(0x09);}//будильник часы
       if (SERIAL_FLAG==5){SERIAL_FLAG=100;if (data<60)SET_REG3231(8,data);SET_REG3231(10,0B10000000);BUD_MIN=READ_DS3231(0x08);}//будильник минуты
       if (SERIAL_FLAG==100){SERIAL_FLAG=0;}
       }             
    Serial.end();//выкл и вкл уарт-только так работают таймеры,иначе глючат-работают по переполнению
    Serial.begin(9600);
    BUD_flag=1;//Чтоб сразу в мониторе отобразилось текущее время и время будильника
    }
 if (BUD_flag==1){
            BUD_flag=READ_DS3231(0x0F) & 0x01;
            SEC=READ_DS3231(0x00);
            MIN=READ_DS3231(0x01);
            HOUR=READ_DS3231(0x02);
            BUD_SEC=READ_DS3231(0x07);
            BUD_MIN=READ_DS3231(0x08);
            BUD_HOUR=READ_DS3231(0x09);
            if (BUD_flag==1){  //если сработал будильник1
              Serial.println("Будильник сработал ");
              int  data=59;//задержка между коммандой "вкл тв" и "вкл HDMI" 
              if(BUD_SEC==0){  //если секунды будильника=0 то вкл тв,через data сек отправляет "ОК"
                IR_send(0, 0x7F, 0xF3,0x0C);SET_REG3231(7,data);Serial.println("TV ON   ");SERIAL_FLAG=100;//чтоб в уарт не улетело ничего
              }
              if(BUD_SEC==data){ //спустя data сек отправляем ок и ставим секунды=0 
                IR_send(0, 0x7F, 0xE8,0x17);SET_REG3231(7,0);Serial.println("TV OKEI ");SERIAL_FLAG=100;//чтоб в уарт улетело инфа
              }
              BUD_SEC=READ_DS3231(0x07);
            SLEEP_flag=1;
            }
            //if (SERIAL_FLAG==0&&SLEEP_flag==0){UART();}
            if (SERIAL_FLAG==0){UART();}
            //Flag=1;//взводим флаг
            //Count_set=Preset_9ms; // Уснавливаем задержку 9 мсек,иначе в уарт не успевают уйти данные
            //TCCR0B = 1 << CS01;
            //TCCR2A|= (1<<WGM21); //Выставляем режим CTC
            //while (Flag==1){};
            
            RESET_FLAG_BUD();
            //son();
}
if (SLEEP_flag==1){SLEEP_flag=0;son();}//уходим в сон
//son();
}
//***********Подпрограммы***************
//***********Срабатываение будильника***
void BUDILMIK(){//прерывание1 
  BUD_flag=1;//Устанавливаем флаг что будильник сработал
  SLEEP_flag=1;//Взводим флаг что надо уйти в сон
  }
//***********Вывод в уарт информации о времени и будильнике,меню настроек**********
void UART(){
            Serial.println("---------------------------");
            //Serial.println("     001_TV_ON_DS3231     ");номер прошивки
            Serial.print("   Текущее время   ");
            if (HOUR<10)Serial.print("0");Serial.print(HOUR);Serial.print(":");
            if (MIN<10)Serial.print("0");Serial.print(MIN);Serial.print(":");
            if (SEC<10)Serial.print("0");Serial.println(SEC);
            Serial.print("Будильник сработает в ");
            if (BUD_HOUR<10)Serial.print("0");Serial.print(BUD_HOUR);Serial.print(":");
            if (BUD_MIN<10)Serial.print("0");Serial.println(BUD_MIN);//Serial.print(":");
                Serial.println("***Установка времени******");
                Serial.println("  1=ЧАСЫ  2=МИН   3=СЕК");
                Serial.println("***Установка БУДИЛЬНИКА***");
                Serial.println("     4=ЧАС  5=МИНУТЫ");
}
//***********Установка будильника1***************
void SET_SQW_1BUD(){
  
  Wire.begin();
  Wire.beginTransmission(0x68);
  Wire.write(0x0A);      //1 будильник
  Wire.write(0B10000000);//A1M4  каждый день
  Wire.endTransmission();
  Wire.beginTransmission(0x68);
  Wire.write(0x07);      //
  Wire.write(0B0000000);//секунды будильника1=00
  Wire.endTransmission();
  Wire.beginTransmission(0x68);
  Wire.write(0x0E);      //Разрешение работы будильника1 =
  Wire.write(0B00000101);//EOSC BBSQW CONV RS2 RS1 INTCN A2IE A1IE
  Wire.endTransmission();
  
}
void RESET_FLAG_BUD(){//Сброс флага срабатывания будильника
  BUD_flag=0;
  Wire.beginTransmission(0x68);
  Wire.write(0x0F);      
  Wire.write(0B10001000);
  Wire.endTransmission();
  
}
void SET_REG3231(byte reg, byte data){//записаь в регистры DS3231
  Wire.beginTransmission(0x68);
  Wire.write(reg);      //номер регистра
  data=bin2bcd(data);
  Wire.write(data);
  Wire.endTransmission();
  }
int READ_DS3231(byte reg){           //чтение из регистра DS3231
  byte result;
  Wire.beginTransmission(0x68);
  Wire.write(reg);
  Wire.endTransmission();
  Wire.requestFrom(0x68, 1);
  result   = bcd2bin(Wire.read() & 0x7F);
  Wire.endTransmission();
  return result;
}


uint8_t bin2bcd(uint8_t val) {return val%10 +  ((val / 10)<<4);}

uint8_t bcd2bin(uint8_t val) {return val - 6 * (val >> 4);}
void son() {
  Serial.println("SLEEP ON");
  digitalWrite(pin, 0);                                    //гасим светодиод 
  Count=0;Count_set=10*Preset_9ms;Flag=1;while (Flag==1){};//ждем когда информация уйдет полностью по UART
  sleep_mode();                                            //спим
  digitalWrite(pin, 1);                                    //зажигаем светодиод
  Count=0;Count_set=10*Preset_9ms;Flag=1;while (Flag==1){};//
}
void IR_send(byte Address1, byte Address2, byte Command1,   byte Command2){  
  Flag=1;//взводим флаг
 Count_set=Preset_9ms; // Уснавливаем задержку 9000/112,5=80
 Count=0; 
 TCCR0B = 1 << CS01;
 TCCR2A|= (1<<WGM21); //Выставляем режим CTC
 TCCR2A|= (1<<COM2A0); //Инвертируем значение OC0A (PD6) по срабатыванию таймера.
 while (Flag==1){};
 TCCR2A= 0<<COM2A0;//останавливаем генерацию 38 кГц 
 //пауза 4,5 мсек
 Count_set=Preset_4_5ms; // Уснавливаем задержку 4500/112,5=40
 Flag=1;
 while (Flag==1){}; 
 //передаем адресс1,вкл генерацию на 560 мксек
 for(uint8_t j = 0; j <4; j++) {
         switch (j) {
              case 0:data=Address1;break;
              case 1:data=Address2;break;
              case 2:data=Command1;break;
              case 3:data=Command2;break;
                }
    for(uint8_t i = 0; i <8; i++) {
       TCCR2A|= (1<<WGM21); //Выставляем режим CTC
       TCCR2A|= (1<<COM2A0); //Инвертируем значение OC0A (PD6) по срабатыванию таймера.
       Count_set=Preset_562_5us; // Уснавливаем задержку 4500/112,5=40
       Flag=1;
       while (Flag==1){};
       TCCR2A= 0<<COM2A0;//останавливаем генерацию 38 кГц 
    //пауза,лог 0=560 мксек,1=1_6875 мсек
      if (bitRead(data, i)==0)
        {Count_set=Preset_562_5us;}
      else
        {Count_set=Preset_1_6875ms;}
      Flag=1;
      while (Flag==1){};
  }
 }

  
    TCCR2A|= (1<<WGM21); //Выставляем режим CTC
    TCCR2A|= (1<<COM2A0); //Инвертируем значение OC0A (PD6) по срабатыванию таймера. 
    Count_set=Preset_562_5us; // Уснавливаем задержку 4500/112,5=40
    Flag=1;
    while (Flag==1){};
    TCCR2A= 0<<COM2A0;//останавливаем генерацию 38 кГц
  
  //просто пауза-ВРЕМЕННО!
  Count_set=Preset_9ms;
  Flag=1;
  while (Flag==1){};
  Count_set=Preset_9ms;
  Flag=1;
  while (Flag==1){};
  
  
}

Что-то ты “перемудрил” на мой взгляд ))

Вот так попробуй:

//....
volatile unsigned int Count = 0, CountMS = 0;    // Счетчик входов в прерывание и секунд.
//.....
ISR (TIMER0_COMPA_vect) {                                    // 112.5 usec
  Count++;
  if (Count > 8888) { // прошла 1 секунда
    CountMS++;
    Count = 0;
  }
  if (CountMS > 59) { // прошла 1 минута
    CountMS = 0;
    Count = 0;
    SLEEP_flag = 1;
  }
}

Можно “перебздеть” вот так (не знаю только зачем :slight_smile: ):

  if (Count > 8888 && !SLEEP_flag) { // прошла 1 секунда

Так у меня в этом обработчике отсчет промежутков для длительностей импульсов ик-передатчика 560 мксек,1,69 мсек,4,5 мсек,9 мсек,строки 201 и ниже
То есть если надо установить задержку 560 мксек я просто делаю так-

Count_set=Preset_562_5us; // Уснавливаем задержку 
    Flag=1;
    while (Flag==1){};

Просто когда по ик ничего не передается идет отсчет этих 60 сек,и то этот отсчет нужен только один раз-при подаче питания на ардуино или его сбросе,больше эта минута нигде не нужна

Понятно… ))