Часы без DS3231 с будильником и "кукушкой"

AlexRamos
Offline
Зарегистрирован: 15.06.2017
Хочу представить Вам свой проект часов.
Все началось с того что мы решили что настенные часы очень громко тикают ночью и время в темноте не видно.
Решил сделать свои и чтоб были так как хочу.
За основу взял светодиоды от светодиодной ленты. Сначала пытался выпаивать, но потом заметил что много ломается. И решил (тупо) нарезать ножницами и приклеить к пластику.
Лицо сделано из акрила-хамелиона (который черный, но может пропускать свет). Корпус из пластика ПВХ 5 мм.
Светодиоды наклеяны на пластик.
Таким образом было сделано шесть 8-сегментных индикаторов в едином корпусе.
Светодиоды подключены с общим катодом. На который подключил резистор в 200 Ом.
Я прекрасно понимаю, что надо было сажать каждый светодиод в отдельности на анод, но меня жаба задавила и в плане резисторов и в плане времени все это делать. Потому решил "и так сойдет".
На каждый сегмент была подключена микросхема 74НС595, и все они были собраны в единый последовательный каскад.
В итоге из "табло" получилось 4 выхода. Не считая питания.
Все питание идет через Arduino от зарядника для сотового.
Также подключил ИК-пульт (Н-29) с датчиком VS-1838B для настройки часов и вкл\выкл будильника.
А также какой-то динамик, который нашел ХЗ где.
 
[code]
#include <TimerOne.h>

#include <boarddefs.h>
#include <IRremote.h>
#include <IRremoteInt.h>

byte N[]={252,96,218,242,102,182,190,224,254,246}; // цифры для табло 0-9
int N1[]={16730805,16738455,16750695,16756815,16724175,16718055,16743045,16716015,16726215,16734885,
16712445,16736925,16754775,16720605,16761405,16728765,16732845}; // коды с пульта
int G; // Для сверки кода с пульта
byte N2[]={156,29,238}; // буквы для табло C L. A

byte s=0; byte s1=0; byte s2=1;
byte m=0; byte m1=0; byte m2=0; byte ma1; byte ma2;
byte h=0; byte h1=0; byte h2=0; byte ha; byte ha1; byte ha2;

unsigned long t; unsigned long tp; long pm; // переменные для подсчета мС
boolean a=false; // Флаг будильника
byte H=HIGH; byte L=LOW; // мне лень писать длинные слова
byte oe=1; // Яркость (1 самая яркая, 255 - самая тусклая

byte Q; byte W; byte E; byte R; byte T; byte Y; // Имена сегментов табло


byte OE = 5;//Пин подключен к ОЕ входу 74НС595
byte ST = 8;//Пин подключен к ST_CP входу 74HC595
byte SH = 12;//Пин подключен к SH_CP входу 74HC595
byte DS = 11;//Пин подключен к DS входу 74HC595
byte ton=9; // Пин звука
byte irr=2; //Пин подключения IR приемника

IRrecv irrecv(irr);
decode_results results;


void setup() {
Serial.begin (9600); 
irrecv.enableIRIn(); // Включаем IR приемник
  
  pinMode(OE, OUTPUT);
  pinMode(ST, OUTPUT);
  pinMode(SH, OUTPUT);
  pinMode(DS, OUTPUT);
  pinMode (ton, OUTPUT);
  pinMode (irr,INPUT);
 
  pinMode (7,OUTPUT); digitalWrite (7,HIGH); // Убрать, пока там воткнут IR
  pinMode (6,OUTPUT); digitalWrite (6, LOW); // Убрать, пока там воткнут IR
  
  Timer1.initialize(1000000); // Время равное 1 секунде
  Timer1.attachInterrupt( timerIsr ); // Выполняем функцию через заданный интервал
   }

void timerIsr(){s2++;}   //Подсчет секунд

 void cotime(){          //Подсчет времени
   if(s2>=10){s2=0; s1++;}
   if(s1>=6) {s1=0;s2=0; m2++;}
   if(m2>=10){m2=0; m1++;}
   if(m1>=6){m1=0; h++;}
   if(h>=24){h=0;}
   h1=h/10; h2=h-h1*10;} 

void tablo(){                   // Вывод показаний на табло
  digitalWrite(ST, LOW);
    shiftOut(DS, SH, LSBFIRST,Q); 
    shiftOut(DS, SH, LSBFIRST,W); 
    shiftOut(DS, SH, LSBFIRST,E);
    shiftOut(DS, SH, LSBFIRST,R);
    shiftOut(DS, SH, LSBFIRST,T);
    shiftOut(DS, SH, LSBFIRST,Y); 
    digitalWrite(ST, HIGH); }

// Лень было это писать 10 раз
void ust4(){Q=N2[0]; W=N2[1]; E=N[h1]; R=N[h2]+1; T=N[m1]; Y=N[m2];tablo();}
void usta4(){Q=N2[2]; W=N2[1]; E=N[ha1]; R=N[ha2]+1; T=N[ma1]; Y=N[ma2];tablo();}


void sound(){            //Звук
  int pmm=pm/2; byte pn=pm-(pmm*2);
    if(pn==0){digitalWrite (ton,H);}
    if (pn==1){digitalWrite(ton,L);}
}

    // Основная программа

void loop() { CLOCK:
cotime();
if (a==true){Y=N[s2]+1;} else {Y=N[s2];};  // Проверка включености будильника
  
if (irrecv.decode(&results)) {
irrecv.resume();G=(results.value);

   if(G==N1[12]){oe+=50;min(oe,1);analogWrite(OE, oe);}//Установка яркости свечения (убавить)
   if(G==N1[11]){oe-=50;max(oe,250);analogWrite(OE, oe);}//Установка яркости свечения (прибавить)
   if (G==N1[10]){goto SET;} // В подпрограмму установки времени
   if (G==N1[15]){if (a==false){a=true; Y=N[0]+1;}      // В подпрограмму проверки будильника
                  else {a=false; Y=N[0];};goto ALARM;}  // и вкл/выкл будильника
   if (G==N1[16]){goto USTA;}  // В подпрограмму установки будильника
}
 
t=millis()/1000; pm=(millis()-t*1000);//Подсчет милисекунд


        // Кукушка
if (m1==0&&m2==0&&s1==0&&s2==0){
  if (pm<500){sound();}  // 500 - продолжительность сигнала в мС
 }if (m1==0&&m2==0&&s1==0&&s2==1){digitalWrite(ton,L);} //Выключает кукушку в любом случае

    // Будильник
    if (a==true){
if (m1==ma1&&m2==ma2&&h1==ha1&&h2==ha2){sound();} // Сработал будильник
if (m1==ma1+1&&m2==ma2&&h1==ha1&&h2==ha2&&s2==0){digitalWrite(ton,L);a=false;}} // Выключился через минуту
if (irrecv.decode(&results)) {a=false; Y=N[s2]; digitalWrite(ton,L);} // Выключить с любого пульта любой кнопкой

if(pm<500){Q=N[h1]; W=N[h2]+1; E=N[m1]; R=N[m2]+1; T=N[s1];}  //Мигают разделительные точки
if(pm>=500){Q=N[h1]; W=N[h2]; E=N[m1]; R=N[m2]; T=N[s1];}
tablo(); // Показания
    
goto CLOCK;

            //Подпрограмма установки времени

SET:
Q=N2[0]; W=N2[1]; E=0; R=1; T=0; Y=0;
tablo(); 

if (irrecv.decode(&results)) {
irrecv.resume();G=(results.value);

if(G==N1[0]){m2=0;goto UST1;}
if(G==N1[1]){m2=1;goto UST1;}
if(G==N1[2]){m2=2;goto UST1;}
if(G==N1[3]){m2=3;goto UST1;}
if(G==N1[4]){m2=4;goto UST1;}
if(G==N1[5]){m2=5;goto UST1;}
if(G==N1[6]){m2=6;goto UST1;}
if(G==N1[7]){m2=7;goto UST1;}
if(G==N1[8]){m2=8;goto UST1;}
if(G==N1[9]){m2=9;goto UST1;}
}
goto SET;

UST1:
Q=N2[0]; W=N2[1]; E=0; R=1; T=0; Y=N[m2];
tablo(); 

if (irrecv.decode(&results)) {
irrecv.resume();G=(results.value);

if(G==N1[0]){m1=m2; m2=0;goto UST2;}
if(G==N1[1]){m1=m2; m2=1;goto UST2;}
if(G==N1[2]){m1=m2; m2=2;goto UST2;}
if(G==N1[3]){m1=m2; m2=3;goto UST2;}
if(G==N1[4]){m1=m2; m2=4;goto UST2;}
if(G==N1[5]){m1=m2; m2=5;goto UST2;}
if(G==N1[6]){m1=m2; m2=6;goto UST2;}
if(G==N1[7]){m1=m2; m2=7;goto UST2;}
if(G==N1[8]){m1=m2; m2=8;goto UST2;}
if(G==N1[9]){m1=m2; m2=9;goto UST2;}
}
goto UST1;


UST2:
Q=N2[0]; W=N2[1]; E=0; R=1; T=N[m1]; Y=N[m2];
tablo();

if (irrecv.decode(&results)) {
irrecv.resume();G=(results.value);

if(G==N1[0]){h2=m1;m1=m2; m2=0;h=h2;goto UST3;}
if(G==N1[1]){h2=m1;m1=m2; m2=1;h=h2;goto UST3;}
if(G==N1[2]){h2=m1;m1=m2; m2=2;h=h2;goto UST3;}
if(G==N1[3]){h2=m1;m1=m2; m2=3;h=h2;goto UST3;}
if(G==N1[4]){h2=m1;m1=m2; m2=4;h=h2;goto UST3;}
if(G==N1[5]){h2=m1;m1=m2; m2=5;h=h2;goto UST3;}
if(G==N1[6]){h2=m1;m1=m2; m2=6;h=h2;goto UST3;}
if(G==N1[7]){h2=m1;m1=m2; m2=7;h=h2;goto UST3;}
if(G==N1[8]){h2=m1;m1=m2; m2=8;h=h2;goto UST3;}
if(G==N1[9]){h2=m1;m1=m2; m2=9;h=h2;goto UST3;}
}
goto UST2;


UST3:
Q=N2[0]; W=N2[1]; E=0; R=N[h2]+1; T=N[m1]; Y=N[m2];
tablo(); 
UST4:

if (irrecv.decode(&results)) {
irrecv.resume();G=(results.value);

if(G==N1[0]){h1=h2;h2=m1;m1=m2; m2=0;h=(h1*10)+h2;ust4();goto UST4;}
if(G==N1[1]){h1=h2;h2=m1;m1=m2; m2=1;h=(h1*10)+h2;ust4();goto UST4;}
if(G==N1[2]){h1=h2;h2=m1;m1=m2; m2=2;h=(h1*10)+h2;ust4();goto UST4;}
if(G==N1[3]){h1=h2;h2=m1;m1=m2; m2=3;h=(h1*10)+h2;ust4();goto UST4;}
if(G==N1[4]){h1=h2;h2=m1;m1=m2; m2=4;h=(h1*10)+h2;ust4();goto UST4;}
if(G==N1[5]){h1=h2;h2=m1;m1=m2; m2=5;h=(h1*10)+h2;ust4();goto UST4;}
if(G==N1[6]){h1=h2;h2=m1;m1=m2; m2=6;h=(h1*10)+h2;ust4();goto UST4;}
if(G==N1[7]){h1=h2;h2=m1;m1=m2; m2=7;h=(h1*10)+h2;ust4();goto UST4;}
if(G==N1[8]){h1=h2;h2=m1;m1=m2; m2=8;h=(h1*10)+h2;ust4();goto UST4;}
if(G==N1[9]){h1=h2;h2=m1;m1=m2; m2=9;h=(h1*10)+h2;ust4();goto UST4;}
  
if (G==N1[10]){s1=0;s2=0;goto CLOCK;}
}
goto UST4;


           // Подпрограмма показаний и включения будильника

ALARM:
Q=N[ha1]; W=N[ha2]+1; E=N[ma1]; R=N[ma2]+1; T=N[0];
tablo(); 
cotime();

 if (irrecv.decode(&results)) {
irrecv.resume();G=(results.value);

if(G==N1[15]){goto CLOCK;}}
goto ALARM;



            //Подпрограмма установки будильника

USTA:
Q=N2[2]; W=N2[1]; E=0; R=1; T=0; Y=0;
tablo(); 
cotime();
if (irrecv.decode(&results)) {
irrecv.resume();G=(results.value);

if(G==N1[0]){ma2=0;goto USTA1;}
if(G==N1[1]){ma2=1;goto USTA1;}
if(G==N1[2]){ma2=2;goto USTA1;}
if(G==N1[3]){ma2=3;goto USTA1;}
if(G==N1[4]){ma2=4;goto USTA1;}
if(G==N1[5]){ma2=5;goto USTA1;}
if(G==N1[6]){ma2=6;goto USTA1;}
if(G==N1[7]){ma2=7;goto USTA1;}
if(G==N1[8]){ma2=8;goto USTA1;}
if(G==N1[9]){ma2=9;goto USTA1;}
}
goto USTA;

USTA1:
Q=N2[2]; W=N2[1]; E=0; R=1; T=0; Y=N[ma2];
tablo(); 
cotime();
if (irrecv.decode(&results)) {
irrecv.resume();G=(results.value);

if(G==N1[0]){ma1=ma2; ma2=0;goto USTA2;}
if(G==N1[1]){ma1=ma2; ma2=1;goto USTA2;}
if(G==N1[2]){ma1=ma2; ma2=2;goto USTA2;}
if(G==N1[3]){ma1=ma2; ma2=3;goto USTA2;}
if(G==N1[4]){ma1=ma2; ma2=4;goto USTA2;}
if(G==N1[5]){ma1=ma2; ma2=5;goto USTA2;}
if(G==N1[6]){ma1=ma2; ma2=6;goto USTA2;}
if(G==N1[7]){ma1=ma2; ma2=7;goto USTA2;}
if(G==N1[8]){ma1=ma2; ma2=8;goto USTA2;}
if(G==N1[9]){ma1=ma2; ma2=9;goto USTA2;}
}
goto USTA1;


USTA2:
Q=N2[2]; W=N2[1]; E=0; R=1; T=N[ma1]; Y=N[ma2];
tablo();
cotime();
if (irrecv.decode(&results)) {
irrecv.resume();G=(results.value);

if(G==N1[0]){ha2=ma1;ma1=ma2; ma2=0;ha=ha2;goto USTA3;}
if(G==N1[1]){ha2=ma1;ma1=ma2; ma2=1;ha=ha2;goto USTA3;}
if(G==N1[2]){ha2=ma1;ma1=ma2; ma2=2;ha=ha2;goto USTA3;}
if(G==N1[3]){ha2=ma1;ma1=ma2; ma2=3;ha=ha2;goto USTA3;}
if(G==N1[4]){ha2=ma1;ma1=ma2; ma2=4;ha=ha2;goto USTA3;}
if(G==N1[5]){ha2=ma1;ma1=ma2; ma2=5;ha=ha2;goto USTA3;}
if(G==N1[6]){ha2=ma1;ma1=ma2; ma2=6;ha=ha2;goto USTA3;}
if(G==N1[7]){ha2=ma1;ma1=ma2; ma2=7;ha=ha2;goto USTA3;}
if(G==N1[8]){ha2=ma1;ma1=ma2; ma2=8;ha=ha2;goto USTA3;}
if(G==N1[9]){ha2=ma1;ma1=ma2; ma2=9;ha=ha2;goto USTA3;}
}
goto USTA2;


USTA3:
Q=N2[2]; W=N2[1]; E=0; R=N[ha2]+1; T=N[ma1]; Y=N[ma2];
tablo(); 
USTA4:
cotime();
if (irrecv.decode(&results)) {
irrecv.resume();G=(results.value);

if(G==N1[0]){ha1=ha2;ha2=ma1;ma1=ma2; ma2=0;ha=(ha1*10)+ha2;usta4();goto USTA4;}
if(G==N1[1]){ha1=ha2;ha2=ma1;ma1=ma2; ma2=1;ha=(ha1*10)+ha2;usta4();goto USTA4;}
if(G==N1[2]){ha1=ha2;ha2=ma1;ma1=ma2; ma2=2;ha=(ha1*10)+ha2;usta4();goto USTA4;}
if(G==N1[3]){ha1=ha2;ha2=ma1;ma1=ma2; ma2=3;ha=(ha1*10)+ha2;usta4();goto USTA4;}
if(G==N1[4]){ha1=ha2;ha2=ma1;ma1=ma2; ma2=4;ha=(ha1*10)+ha2;usta4();goto USTA4;}
if(G==N1[5]){ha1=ha2;ha2=ma1;ma1=ma2; ma2=5;ha=(ha1*10)+ha2;usta4();goto USTA4;}
if(G==N1[6]){ha1=ha2;ha2=ma1;ma1=ma2; ma2=6;ha=(ha1*10)+ha2;usta4();goto USTA4;}
if(G==N1[7]){ha1=ha2;ha2=ma1;ma1=ma2; ma2=7;ha=(ha1*10)+ha2;usta4();goto USTA4;}
if(G==N1[8]){ha1=ha2;ha2=ma1;ma1=ma2; ma2=8;ha=(ha1*10)+ha2;usta4();goto USTA4;}
if(G==N1[9]){ha1=ha2;ha2=ma1;ma1=ma2; ma2=9;ha=(ha1*10)+ha2;usta4();goto USTA4;}
  
if (G==N1[10]){goto CLOCK;}
}
goto USTA4;


}



[/code]

 

Управление:

Кнопка "ОК" - установка времени.

Кнопки "вверх", "вниз" - установка яркости свечения индикатора. Я сделал 5 градаций, но на практике достаточно двух (самая яркая и самая темная). Изначально пытался подключить датчик освещенности, чтобы автоматически переключала, но на практике оказалось - это от лукавого. Не нужно словом. Изменение яркости необходимо, чтобы ночью когда темно убавлять яркость, а то спать мешают, а когда светло прибавлять.

Кнопка "*" - включает\выключает установку будильника. Заодно показывает на какое время он настроен. Точка у секунд индицирует включен или выключен будильник.

Кнопка *#* - включает режим установки времени будильника. По установке "ОК"

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

"Кукушка" - ежечасный короткий сигнал. Работает круглосуточно.

Итог:

Часы работают исправно. Почти все устраивает.

Хотелось бы совета, как сделать звук несколько приятней.

Дело в том что функция tone()  "отказывается" работать совместно с библиотеками TimerOne  и IRremote.

И не могу придумать что сделать с "кукушкой". Как ее включать\выключать. Точнее как показывать что она включена. Может "тупо" тумблер поставить и подключить на любой свободный порт?

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

Если будет кому интересно постараюсь "залить" видео работы часов.

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

AlexRamos пишет:

Лицо сделано из акрила-хамелиона (который черный, но может пропускать свет). 

Можно с этого места поподробнее. Где такой берут? Ссылочкой не поделитесь? Бывают ли других цветов?

AlexRamos
Offline
Зарегистрирован: 15.06.2017

Обзвоните в своем городе фирмы которые занимаются изготовлением наружной рекламы. У них могут быть обрезки.

А так продается в фирмах по продаже материалов для наружной рекламы. Там будет только листами. Обычно 2Х3 м или 1,2Х2,4 м.

Цвет будет такой каким будете подсвечивать.

Если подсветка белая. Можно изнутри наклеить транслюцентную пленку нужного цвета, но при этом очень сильно падает яркость. Такое не практикуют.

Еще как вариант можно прозрачный акрил заклеить тонировочной пленкой. (чисто теоретически, сам не пробовал)