Вроде доделал…
Передает сигнал по ИК-каналу на включение телевизора в заданное время,через 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){};
}