Zegarek binarny to stosunkowo popularny gadżet wśród informatyków w wielu sklepach można zakupić wersję budzikową bądź na rękę. Niemniej nic nie cieszy bardziej niż stworzenie takiego zegarka własnoręcznie. W niniejszym wpisie pokaże jak zbudować własny zegarek binarny korzystając z Ardunio i kilku elektronicznych komponentów.
Materiały:
1 x Atmega 328P-PU
20 x dioda led najlepiej w 3 rożnych kolorach
20 x rezystor 200 omów
3 x rezystor 4,7k omów
3x układy scalony 74HC595
1x RTC DS1307
3x Przyciski
1x przełącznik on-off
2x 22nf kondensator
1x 16 MHz rezonator kwarcowy
1x 5V zasilanie
Poniżej możemy zobaczyć schemat całej konstrukcji:
Schemat przedstawia rozbudowaną wersje zegarka binarnego z możliwością zmiany godziny za pomocą guzików i zegarka która zapamiętuje nasz czas ale zacznijmy od początku. Większość operacji wykonywana jest przez moduł atmega 328P-PU. Kawałek to tak naprawdę Breduino o którym dokładnie możemy poczytać tutaj httpss://www.arduino.cc/en/Main/Standalone
Niemniej żeby moduł ten mógł pracować musimy podłączyć pod niego zasilanie o mocy 5 V. Zasilanie + podłączamy pod piny 7,20,21. Minus zaś pod piny8,22. Całość jest przedtem podłączona do przycisku on-off. Pod piny 9,10 podłączmy 16 MHz rezonator kwarcowy a ten następnie z kondensatorami i je ostatecznie uziemiamy. Niestety moduł atmega ma ograniczoną liczbę wyjść my zaś mamy do obsłużenia 20 diod przyciski i zegar. Dlatego musimy skorzystać z modułu 74hc595. Więcej o nim możecie poczytać pod tym adresem: httpss://www.arduino.cc/en/Tutorial/ShiftOut Dzięki niego możemy podzielić nasz sygnał na 8 strumieni korzystając jedynie z 3 wejść atmegi co jest szczególnie użyteczne przy naszych diodach.
Dla każdego z układów 74hc595 na pinach 11,12,14 przypisujemy 3 piny z danymi do atmegi. Każdemu też zasilamy na pinach 10 i 16 uziemiamy piny 8,13. Wyjścia od 1 do 7 lub od 2 do 7 w przypadku ostatniego układu podłączamy do rezystora 200 omowego a ten następnie do diody.
W zasadzie to już nam starczy aby zbudować zegar binarny. Niestety jednak godzinne w takiej zabawce moglibyśmy ustalić jedynie w programie atmegi i byłby on zawsze resetowany gdy odłączymy zasilanie, także jednego dokładność by była coraz mniejsza wraz z upływem czasu. Dla wielu osób może to być wystarczające niemniej możemy do tego podpiąć przyciski ustawiające nam godzinne oraz zegar który będzie i dokładniejszy jak też będzie nam zapamiętywał czas nawet gdy urządzenie zostanie odłączone od prądu.
Przyciski są zasadniczo proste są to zwykłe buttony które po naciśnięciu wysyłają impuls do atmegi. Gdy ta ją otrzyma dolicza do wybranej godziny jedną jednostkę Każde wejście jest chronione rezystorem 4,7K omów. Zegar 1307 posiada własną baterie dzięki czego nawet bez zasilania jest w stanie dalej monitorować upływ czasu. Jego podłączenie wygląda następująco. Zasilanie 5V oraz uziemienie należy podpiąć do odpowiednio podpisanych pinów. piny SCL i SDA podłączamy do atmegi według schematu. SCL jest linią zegarową. SDA zaś linią danych.
Przygotowany powyżej projekt jest gotowy do wytrawienia na płytce dwustronnej o wymiarach 120×160 mm. Czerwone linie oznaczają górną warstwę niebieskie dolną.
W projekcie będzie nam potrzebna biblioteka RTClib odpowiedzialna za działanie zegara DS 1307 można ją ściągnąć z httpss://github.com/adafruit/RTClib
Poniżej kod źródłowy dla oprogramowania:
#include <Wire.h>
#include "RTClib.h"
volatile RTC_DS1307 RTC;
int SH_CP1 = 13; //clock pin
int ST_CP1 = 12; // latch pin
int Data1 = 11; // data pin
int SH_CP2 = 10; //clock pin
int ST_CP2 = 9; // latch pin
int Data2 = 8; // data pin
int SH_CP3 = 5; //clock pin
int ST_CP3 = 6; // latch pin
int Data3 = 7; // data pin
//8=18 latchpin,12=19 clockpin,11=17 datapin
int analog1 = 4;
int analog2 = 3;
int analog3 = 2;
volatile boolean on = false;
void setup() {
Serial.begin(57600);
Wire.begin();
RTC.begin();
if (! RTC.isrunning()) {
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));
}
pinMode(SH_CP1, OUTPUT);
pinMode(ST_CP1, OUTPUT);
pinMode(Data1, OUTPUT);
pinMode(analog1, INPUT);
pinMode(SH_CP2, OUTPUT);
pinMode(ST_CP2, OUTPUT);
pinMode(Data2, OUTPUT);
pinMode(analog2, INPUT);
pinMode(SH_CP3, OUTPUT);
pinMode(ST_CP3, OUTPUT);
pinMode(Data3, OUTPUT);
pinMode(analog3, INPUT);
}
void loop() {
DateTime now = RTC.now();
if (digitalRead(analog3)==HIGH){//if button pressed
plusTime(1,0,0);
}
else if(digitalRead(analog2)==HIGH){
plusTime(0,1,0);
}
else if(digitalRead(analog1)==HIGH){
plusTime(0,0,1);
}
else{
on=false;
digitalWrite(ST_CP1, LOW);
int addNumber1=6*(now.second()/10); //add 6(00010000) after every 10 seconds
shiftOut(Data1, SH_CP1, LSBFIRST, now.second()+addNumber1);
digitalWrite(ST_CP1, HIGH);
digitalWrite(ST_CP2, LOW);
int addNumber2=6*(now.hour()/10); //add 6(00010000) after every 10 seconds
shiftOut(Data2, SH_CP2, LSBFIRST, now.hour()+addNumber2);
digitalWrite(ST_CP2, HIGH);
digitalWrite(ST_CP3, LOW);
int addNumber3=6*(now.minute()/10); //add 6(00010000) after every 10 seconds
shiftOut(Data3, SH_CP3, LSBFIRST, now.minute()+addNumber3);
digitalWrite(ST_CP3, HIGH);
}
}
void plusTime(int secunds, int minutes, int hours){
DateTime now = RTC.now();
if(on==false){
DateTime newTime = DateTime(now.year(), now.month(), now.day(), now.hour()+hours, now.minute()+minutes, now.second()+secunds);
RTC.adjust(newTime);
on=true;
}
}
Gotowy projekt wygląda następująco:
Dla każdego kto chcę w jakikolwiek sposób zmodyfikować to rozwiązanie w referencjach zostawiam plik eagle oraz kod źródłowy
Ciekawe referencje:
Eagle schematy
Kod zródłowy