Ev, dizayn, təmir, dekorasiya.  Həyət və bağ.  Öz əlinizlə

Ev, dizayn, təmir, dekorasiya. Həyət və bağ. Öz əlinizlə

» DS1307 ilə AVR mikro nəzarətçisində saat. LED displeyli DIY saatı DIY böyük elektron saat

DS1307 ilə AVR mikro nəzarətçisində saat. LED displeyli DIY saatı DIY böyük elektron saat

Satışda siz elektron rəqəmsal saatların bir çox müxtəlif modellərini və variantlarını tapa bilərsiniz, lakin onların əksəriyyəti daxili istifadə üçün nəzərdə tutulmuşdur, çünki nömrələr kiçikdir. Ancaq bəzən küçədə - məsələn, bir evin divarında və ya bir stadionda, meydanda, yəni bir çox insan tərəfindən çox uzaqdan görünəcək bir saat yerləşdirmək lazımdır. Bu məqsədlə, istənilən ölçülü LED göstəricilərini (daxili tranzistor açarları vasitəsilə) birləşdirə biləcəyiniz böyük bir LED saatın bu sxemi hazırlanmış və uğurla yığılmışdır. Sxematik diaqramı üzərinə klikləməklə böyüdə bilərsiniz:

Saatın təsviri

  1. Bax. Bu rejimdə vaxt göstəricisinin standart növü mövcuddur. Saat dəqiqliyinin rəqəmsal korreksiyası var.
  2. Termometr. Bu halda, cihaz bir sensordan otağın və ya havanın temperaturunu ölçür. -55 ilə +125 dərəcə arasında dəyişir.
  3. Enerji təchizatına nəzarət təmin edilir.
  4. Göstəricidə məlumatları növbə ilə göstərir - saat və termometr.
  5. 220V itirildikdə parametrləri və parametrləri saxlamaq üçün qeyri-sabit yaddaş istifadə olunur.


Cihazın əsasını ATMega8 MK təşkil edir, o, cədvələ uyğun olaraq qoruyucuları təyin etməklə işıqlandırılır:

Əməliyyat və saat idarəetməsi

Saatı ilk dəfə yandırdığınız zaman ekranda reklam ekranı görünəcək, bundan sonra o, vaxtı göstərməyə keçəcək. Düyməni basmaq SET_TIME göstərici əsas rejimdən bir dairədə gedəcək:

  • dəqiqə və saniyə ekran rejimi. Bu rejimdə siz eyni vaxtda düyməni sıxırsınız PLUSMINUS, sonra saniyələr sıfırlanacaq;
  • cari vaxtın dəqiqələrinin təyin edilməsi;
  • cari saatın təyin edilməsi;
  • simvolu t. Saat ekranının müddətini təyin etmək;
  • simvolu o. Xarici temperatur göstəricilərinin simvollarının göstərilməsi vaxtı (çıxdı);
  • saat dəqiqliyinin gündəlik korreksiyasının miqdarı. Simvol c və düzəliş dəyəri. -25 ilə 25 saniyə arasında məhdudiyyətlərin qoyulması. Seçilmiş dəyər hər gün 0 saat 0 dəqiqə 30 saniyədə cari vaxtdan əlavə və ya çıxılacaq. Daha ətraflı məlumat üçün, proqram təminatı və çap dövrə lövhəsi faylları ilə arxivdə olan təlimatları oxuyun.

Saatın qurulması

Düymələri basılı tutarkən PLUS/MINUS Biz dəyərlərin sürətləndirilməsini həyata keçiririk. Hər hansı parametrləri dəyişdirdikdən sonra, 10 saniyədən sonra yeni dəyərlər qeyri-sabit yaddaşa yazılacaq və enerji yenidən işə salındıqda oradan oxunacaq. Yeni parametrlər quraşdırma zamanı qüvvəyə minir. Mikrokontroller əsas gücün mövcudluğuna nəzarət edir. Söndürüldükdə cihaz daxili mənbədən enerji alır. Ehtiyatlı güc modulunun diaqramı aşağıda göstərilmişdir:


Cari istehlakı azaltmaq üçün göstərici, sensorlar və düymələr söndürülür, lakin saatın özü vaxtı saymağa davam edir. 220V şəbəkə gərginliyi görünən kimi bütün göstərici funksiyaları bərpa olunur.


Cihaz böyük LED-saat kimi yaradıldığı üçün onun iki displeyi var: böyük LED - küçə üçün və kiçik LCD - əsas displeyin asan qurulması üçün. Böyük displey idarəetmə blokundan bir neçə metr məsafədə yerləşir və 8 naqildən ibarət iki kabellə birləşdirilir. Xarici göstərici göstəricisinin anodlarını idarə etmək üçün arxivdə verilmiş diaqrama uyğun olaraq tranzistor açarları istifadə olunur. Layihə müəllifləri: Alexandrovich & SOIR.

Elektron saatı öz əllərinizlə yığmağın bir çox yolu var: diaqramlar ədəbiyyatda və İnternetdə geniş şəkildə təqdim olunur. Müasir tətbiqlərin əksəriyyəti mikro nəzarətçilərə əsaslanır. Belə layihələrin həyata keçirilməsi tez-tez elektronika sahəsində geniş praktiki bacarıqlar və nəzəri biliklər tələb edir: xüsusi proqram təminatından istifadə etmək, dəmir xlorid aşındırmasından istifadə edərək evdə çap dövrə lövhələri yaratmaq və yaxşı lehimləmə bacarığı. Həm də müxtəlif alətlər və ləvazimatlara sahib olmalısınız.

Bununla belə, evdə öz əlinizlə elektron saat yığmağın sadə və sərfəli yolu var: Arduino platformasından istifadə edin. Bu, proqramlaşdırma və elektronikanın əsaslarını öyrətmək üçün xüsusi olaraq hazırlanmış proqram və aparat kompleksidir. Arduino-nun köməyi ilə hər kəs, hətta xüsusi hazırlıq olmadan da, öz əlləri ilə elektron saat qura bilər: dövrə diaqramları, mühəndislik proqramları və hətta bir lehimləmə dəmiri lazım deyil!

Bütün elektron komponentlərin qoşulması xüsusi kontakt (“lehimsiz”) çörək lövhəsində həyata keçirilir ki, bu da yanıqlar, kəsiklər və digər xəsarətlər riskini aradan qaldırır - buna görə də Arduino dizayneri ilə uşaqlarla birlikdə işləyə bilərsiniz. Bir dövrə diaqramını təqdim etməyin vizual üsulu cihazı yığarkən səhvlərdən qaçınmanıza kömək edəcəkdir.

Addım 1. Komponentlərin siyahısı

LED matrislərində sadə bir saat yığmaq üçün sizə yalnız bir neçə ucuz komponent lazımdır:

  • Arduino platforması. Ən sadə modellər edəcək - və ya Micro;
  • əlaqə çörək lövhəsi;
  • çörək lövhəsi üçün birləşdirici tellər;
  • Adafruit DS3231 real vaxt saat modulu;
  • LED matris modulu 32x8 MAX7219;
  • iki düymə.

Nəzarət proqramını yaddaşa yükləmək üçün fərdi kompüterə və USB-mini-USB kabelinə də ehtiyacınız olacaq. Hamısı budur - lehimləmə dəmiri, izolyasiya soyucular, montaj bıçaqları və digər peşəkar alətlər lazım deyil: bütün əməliyyatlar əl ilə aparılır. Bəlkə də bəzi hallarda cımbızdan istifadə etmək daha rahatdır, ancaq onsuz da edə bilərsiniz.


Addım 2. Elektron sxemin yığılması

Arduino istifadə edən LED displeyli elektron saatın sxemi hətta təcrübəsiz radio həvəskarları üçün olduqca sadə görünəcəkdir. Montaj üçün yalnız bir neçə tel tələb olunur. Bağlantı masası:

Arduino modulu → 32x8 MAX7219 LED matrisi

Arduino modulu → Adafruit DS3231 real vaxt saatı

Arduino modulu → düymələr

D2 - düymə 1

D3 - düymə 2

Düymələrin ikinci sancağı GND-yə bağlıdır.

Yalnız diqqət yetirmək və çörək lövhəsindəki təmas deliklərinin bir-birinə necə bağlandığını xatırlamaq lazımdır. Aşağıdakı diaqram kontakt dəliklərinin daxili birləşdirilməsi üsulunu göstərir:


Hər iki tərəfdən iki sıra (1 və 4) üfüqi olaraq birləşdirilir - onlar adətən +5V elektrik xətti və GND torpaq kimi istifadə olunur. Bütün daxili kontaktlar (2 və 3) şaquli olaraq bağlıdır. Bu vəziyyətdə, dövrə lövhəsi həm şaquli, həm də üfüqi olaraq bir-birindən asılı olmayan iki simmetrik hissəyə bölünür. Bu, məsələn, bir lövhədə iki fərqli cihazı yığmağa imkan verir.

LED göstəricisi olan elektron saatın diaqramı, eləcə də elektron lövhədə elementlərin düzülüşü şəkildə göstərilmişdir:

Bütün əlaqələrin göstərilən diaqrama uyğun olduğunu diqqətlə yoxlayın. Həmçinin keçiricilərin dövrə lövhəsinin təmas deliklərində yaxşı bərkidilmiş olduğundan əmin olun.


Addım 3. Arduino proqram təminatı

Dövrənin yığılması və sınaqdan keçirilməsi başa çatdıqdan sonra, siz idarəetmə proqramını (və ya “firmware”) Arduino yaddaşına yükləməyə başlaya bilərsiniz.


Bunun üçün pulsuz rəsmi inkişaf mühitini quraşdırmalısınız - . Layihənin mənbə koduna da ehtiyacınız olacaq, onu bütün kitabxanalar və eskizlə birlikdə aşağıda arxivə endirə bilərsiniz və sadəcə eskiz lazımdırsa, onu ayrıca köçürə bilərsiniz:

//kitabxanaları daxil edin: #include "LedControl.h" #include // Şrift kitabxanası #include // DS1307 saatı #daxil et "RTClib.h" // DS1307 saatı #daxil et // Alexander Brevig tərəfindən düymələr kitabxanası // Quraşdırma LED Matrisi // pin 12 displeydəki DataIn-ə qoşulur // pin 11 displeydəki CLK-ya qoşulur // pin 10 displeydə LOAD-a qoşulur LedControl lc = LedControl(6, 5, 4, 4); //3 pinləri 12, 11 və 10 olaraq təyin edir və sonra 4 displey təyin edir (maksimum 8 displeydir) //qlobal dəyişənlər bayt intensivliyi = 7; // Defolt intensivlik/parlaqlıq (0-15) bayt saat_rejimi = 0; // Standart saat rejimi. Defolt = 0 (əsas_rejim) bool təsadüfi_rejim = 0; // Təsadüfi rejimi müəyyənləşdirin - ekran tipini bir neçə saatdan bir dəyişir. Defolt = 0 (off) bayt köhnə_rejim = saat_rejimi; // Əvvəlki saat rejimini saxlayır, ona görə də tarixə getsək və ya nə olursa olsun, sonra hansı rejimə qayıtmağı bilirik. bool ampm = 0; // 12 və ya 24 saat vaxt təyin edin. 0 = 24 saat. 1 = 12 saat bayt dəyişdirmə_rejimi_zamanı = 0; // Təsadüfi rejimdə olduqda saat rejiminin növbəti dəyişəcəyi saatı saxlayır. imzalanmamış uzun gecikmə = 500; // Biz həmişə displey int rtc yeniləmələri arasında bir az gözləyirik; // Real vaxt saatı çıxışını saxlayır char günləri = ( "Günəş", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə", "Cümə", "Şənbə" ); //gün massivi - slayd, əsas_rejim və qarışıq rejimlərdə istifadə olunur (DS1307 həftənin günü üçün 1-7 dəyər verir) char daysfull = ( "Bazar", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə axşamı" ", "Cümə", "Şənbə" ); char şəkilçisi = ("st", "nd", "rd", "th" ); //tarix şəkilçisi massivi, slayd, əsas_rejim və qarışıq rejimlərdə istifadə olunur. məsələn, 1-ci 2-ci ... //sabitləri təyin edin #NUM_DISPLAY_MODES-i təyin edin 3 // Nömrəni göstərmə rejimləri (birinci rejim olaraq sıfırı təyin edin) #NUM_SETTINGS_MODES-i təyin edin 4 // Nömrə parametrləri rejimləri = 6 (birinci rejim olaraq sıfıra nəzarət) # SLIDE_DELAY 20 müəyyən et // Slayd rejimində hər simvol üçün slayd effekti üçün millisaniyələrlə vaxt. Daha yavaş effekt üçün bunu yüksək edin #define cls clear_display // Clear display RTC_DS1307 ds1307; // RTC obyekti yarat Button buttonA = Button(2, BUTTON_PULLUP); // Quraşdırma düyməsi A (düymə kitabxanasından istifadə etməklə) Düymə düyməsiB = Düymə (3, BUTTON_PULLUP); // Quraşdırma düyməsi B (düymə kitabxanasından istifadə etməklə) quraşdırmanı ləğv edin () ( digitalWrite(2, YÜKSEK); // 2-ci pindəki düymə üçün pullup rezistorunu yandırın digitalWrite(3, HIGH); // pin üzərindəki düymə üçün çəkmə rezistorunu yandırın 3 digitalWrite(4, HIGH); // 4-cü pin üzərindəki düymə üçün pullup rezistorunu yandırın Serial.begin(9600); //serialı başladın //4 matris panelini işə salın //biz yaradanda artıq cihazların sayını təyin etmişik. LedControl int cihazları = lc.getDeviceCount(); //biz (int ünvanı = 0; ünvan) üçün dövrədə bütün cihazları işə salmalıyıq.< devices; address++) { /*The MAX72XX is in power-saving mode on startup*/ lc.shutdown(3-address, false); /* Set the brightness to a medium values */ lc.setIntensity(3-address, intensity); /* and clear the display */ lc.clearDisplay(3-address); } //Setup DS1307 RTC #ifdef AVR Wire.begin(); #else Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino #endif ds1307.begin(); //start RTC Clock if (! ds1307.isrunning()) { Serial.println("RTC is NOT running!"); ds1307.adjust(DateTime(__DATE__, __TIME__)); // sets the RTC to the date & time this sketch was compiled } //Show software version & hello message printver(); //enable red led digitalWrite(13, HIGH); } void loop() { //run the clock with whatever mode is set by clock_mode - the default is set at top of code. switch (clock_mode){ case 0: basic_mode(); break; case 1: small_mode(); break; case 2: slide(); break; case 3: word_clock(); break; case 4: setup_menu(); break; } } //plot a point on the display void plot (byte x, byte y, byte val) { //select which matrix depending on the x coord byte address; if (x >= 0 && x<= 7) { address = 3; } if (x >= 8 && x<= 15) { address = 2; x = x - 8; } if (x >= 16 && x<= 23) { address = 1; x = x - 16; } if (x >= 24 && x<= 31) { address = 0; x = x - 24; } if (val == 1) { lc.setLed(address, y, x, true); } else { lc.setLed(address, y, x, false); } } //clear screen void clear_display() { for (byte address = 0; address < 4; address++) { lc.clearDisplay(address); } } //fade screen down void fade_down() { //fade from global intensity to 1 for (byte i = intensity; i >0; i--) ( üçün (bayt ünvanı = 0; ünvan< 4; address++) { lc.setIntensity(address, i); } delay(30); //change this to change fade down speed } clear_display(); //clear display completely (off) //reset intentsity to global val for (byte address = 0; address < 4; address++) { lc.setIntensity(address, intensity); } } //power up led test & display software version number void printver() { byte i = 0; char ver_a = "MADE"; char ver_b = "IN"; char ver_c = "RUSSIA"; //test all leds. for (byte x = 0; x <= 32; x++) { for (byte y = 0; y <= 7; y++) { plot(x, y, 1); } } delay(300); fade_down(); while (ver_a[i]) { puttinychar((i * 4), 1, ver_a[i]); delay(35); i++; } delay(500); fade_down(); i = 0; while (ver_b[i]) { puttinychar((i * 4), 1, ver_b[i]); delay(35); i++; } delay(500); fade_down(); i = 0; while (ver_c[i]) { puttinychar((i * 4), 1, ver_c[i]); delay(35); i++; } delay(500); fade_down(); } // puttinychar // Copy a 3x5 character glyph from the myfont data structure to display memory, with its upper left at the given coordinate // This is unoptimized and simply uses plot() to draw each dot. void puttinychar(byte x, byte y, char c) { byte dots; if (c >= "A" && c<= "Z" || (c >= "a" && c<= "z")) { c &= 0x1F; // A-Z maps to 1-26 } else if (c >= "0" && c<= "9") { c = (c - "0") + 32; } else if (c == " ") { c = 0; // space } else if (c == ".") { c = 27; // full stop } else if (c == ":") { c = 28; // colon } else if (c == "\"") { c = 29; // single quote mark } else if (c == "!") { c = 30; // single quote mark } else if (c == "?") { c = 31; // single quote mark } for (byte col = 0; col < 3; col++) { dots = pgm_read_byte_near(&mytinyfont[c]); for (char row = 0; row < 5; row++) { if (dots & (16 >> sıra)) süjet(x + col, y + sətir, 1); başqa süjet(x + col, y + sıra, 0); ) ) ) void putnormalchar(bayt x, bayt y, char c) ( bayt nöqtələri; // əgər (c >= "A" && c)<= "Z" || (c >= "a" && c<= "z")) { // c &= 0x1F; // A-Z maps to 1-26 // } if (c >= "A" && c<= "Z") { c &= 0x1F; // A-Z maps to 1-26 } else if (c >= "a" && c<= "z") { c = (c - "a") + 41; // A-Z maps to 41-67 } else if (c >= "0" && c<= "9") { c = (c - "0") + 31; } else if (c == " ") { c = 0; // space } else if (c == ".") { c = 27; // full stop } else if (c == "\"") { c = 28; // single quote mark } else if (c == ":") { c = 29; // clock_mode selector arrow } else if (c == ">") ( c = 30; // saat_rejimi seçici oxu ) əgər (c >= -80 && c)<= -67) { c *= -1; } for (char col = 0; col < 5; col++) { dots = pgm_read_byte_near(&myfont[c]); for (char row = 0; row < 7; row++) { //check coords are on screen before trying to plot //if ((x >= 0) && (x<= 31) && (y >= 0) && (y<= 7)){ if (dots & (64 >> sətir)) ( // yalnız 7 sıra. plot(x + col, y + row, 1); ) else ( plot(x + col, y + row, 0); ) //) ) ) ) //kiçik_rejim //saniyələrlə vaxtı kiçik 3x5 simvolda göstərin void small_mode() ( char textchar; // displeydəki 16 simvol bayt mins = 100; //dəqiqə bayt saniyə = rtc; //saniyə bayt old_san = saniyə; / /köhnə saniyə dəyərini saxlayır - son saniyələrin yeniləndiyi vaxtdan və ya displeydə - saniyələrin dəyişib-dəyişmədiyini yoxlamaq üçün istifadə olunur cls(); // run_mode true isə (run_mode()) ( get_time(); / /düyməni yoxlayın, əgər (buttonA.uniquePress()) ( switch_mode(); return; ) əgər (buttonB.uniquePress()) ( display_date(); return; ) //saniyələr dəyişibsə, onları displeydə yeniləyin saniyələr = rtc; if (san != old_secs) ( //san char bufer; itoa(san, bufer, 10); //düzelt - əks halda, əgər nömrənin başlanğıc sıfırı varsa, məsələn, "03" saniyə, itoa bunu boşluqlu simvolları əhatə edir "3" əgər (san< 10) { buffer = buffer; buffer = "0"; } puttinychar(20, 1, ":"); //seconds colon puttinychar(24, 1, buffer); //seconds puttinychar(28, 1, buffer); //seconds old_secs = secs; } //if minute changes change time if (mins != rtc) { //reset these for comparison next time mins = rtc; byte hours = rtc; if (hours > < 1) { hours = hours + ampm * 12; } //byte dow = rtc; // the DS1307 outputs 0 - 6 where 0 = Sunday0 - 6 where 0 = Sunday. //byte date = rtc; //set characters char buffer; itoa(hours, buffer, 10); //fix - as otherwise if num has leading zero, e.g. "03" hours, itoa coverts this to chars with space "3 ". if (hours < 10) { buffer = buffer; //if we are in 12 hour mode blank the leading zero. if (ampm) { buffer = " "; } else { buffer = "0"; } } //set hours chars textchar = buffer; textchar = buffer; textchar = ":"; itoa (mins, buffer, 10); if (mins < 10) { buffer = buffer; buffer = "0"; } //set mins characters textchar = buffer; textchar = buffer; //do seconds textchar = ":"; buffer; secs = rtc; itoa(secs, buffer, 10); //fix - as otherwise if num has leading zero, e.g. "03" secs, itoa coverts this to chars with space "3 ". if (secs < 10) { buffer = buffer; buffer = "0"; } //set seconds textchar = buffer; textchar = buffer; byte x = 0; byte y = 0; //print each char for (byte x = 0; x < 6 ; x++) { puttinychar(x * 4, 1, textchar[x]); } } delay(50); } fade_down(); } // basic_mode() // show the time in 5x7 characters void basic_mode() { cls(); char buffer; //for int to char conversion to turn rtc values into chars we can print on screen byte offset = 0; //used to offset the x postition of the digits and centre the display when we are in 12 hour mode and the clock shows only 3 digits. e.g. 3:21 byte x, y; //used to draw a clear box over the left hand "1" of the display when we roll from 12:59 ->12 saat rejimində saat 1:00. //amper 1 bayt saata təyin olunarsa, 12/24 saat çevrilmə edin = rtc; əgər (saat > 12) (saat = saat - ampm * 12; ) əgər (saat)< 1) { hours = hours + ampm * 12; } //do offset conversion if (ampm && hours < 10) { offset = 2; } //set the next minute we show the date at //set_next_date(); // initially set mins to value 100 - so it wll never equal rtc on the first loop of the clock, meaning we draw the clock display when we enter the function byte secs = 100; byte mins = 100; int count = 0; //run clock main loop as long as run_mode returns true while (run_mode()) { //get the time from the clock chip get_time(); //check for button press if (buttonA.uniquePress()) { switch_mode(); return; } if (buttonB.uniquePress()) { display_date(); return; } //check whether it"s time to automatically display the date //check_show_date(); //draw the flashing: as on if the secs have changed. if (secs != rtc) { //update secs with new value secs = rtc; //draw: plot (15 - offset, 2, 1); //top point plot (15 - offset, 5, 1); //bottom point count = 400; } //if count has run out, turn off the: if (count == 0) { plot (15 - offset, 2, 0); //top point plot (15 - offset, 5, 0); //bottom point } else { count--; } //re draw the display if button pressed or if mins != rtc i.e. if the time has changed from what we had stored in mins, (also trigggered on first entering function when mins is 100) if (mins != rtc) { //update mins and hours with the new values mins = rtc; hours = rtc; //adjust hours of ampm set to 12 hour mode if (hours >12) (saat = saat - ampm * 12; ) əgər (saat< 1) { hours = hours + ampm * 12; } itoa(hours, buffer, 10); //if hours < 10 the num e.g. "3" hours, itoa coverts this to chars with space "3 " which we dont want if (hours < 10) { buffer = buffer; buffer = "0"; } //print hours //if we in 12 hour mode and hours < 10, then don"t print the leading zero, and set the offset so we centre the display with 3 digits. if (ampm && hours < 10) { offset = 2; //if the time is 1:00am clear the entire display as the offset changes at this time and we need to blank out the old 12:59 if ((hours == 1 && mins == 0)) { cls(); } } else { //else no offset and print hours tens digit offset = 0; //if the time is 10:00am clear the entire display as the offset changes at this time and we need to blank out the old 9:59 if (hours == 10 && mins == 0) { cls(); } putnormalchar(1, 0, buffer); } //print hours ones digit putnormalchar(7 - offset, 0, buffer); //print mins //add leading zero if mins < 10 itoa (mins, buffer, 10); if (mins < 10) { buffer = buffer; buffer = "0"; } //print mins tens and ones digits putnormalchar(19 - offset, 0, buffer); putnormalchar(25 - offset, 0, buffer); } } fade_down(); } //like basic_mode but with slide effect void slide() { byte digits_old = {99, 99, 99, 99}; //old values we store time in. Set to somthing that will never match the time initially so all digits get drawn wnen the mode starts byte digits_new; //new digits time will slide to reveal byte digits_x_pos = {25, 19, 7, 1}; //x pos for which to draw each digit at char old_char; //used when we use itoa to transpose the current digit (type byte) into a char to pass to the animation function char new_char; //used when we use itoa to transpose the new digit (type byte) into a char to pass to the animation function //old_chars - stores the 5 day and date suffix chars on the display. e.g. "mon" and "st". We feed these into the slide animation as the current char when these chars are updated. //We sent them as A initially, which are used when the clocl enters the mode and no last chars are stored. //char old_chars = "AAAAA"; //plot the clock colon on the display cls(); putnormalchar(13, 0, ":"); byte old_secs = rtc; //store seconds in old_secs. We compare secs and old secs. WHen they are different we redraw the display //run clock main loop as long as run_mode returns true while (run_mode()) { get_time(); //check for button press if (buttonA.uniquePress()) { switch_mode(); return; } if (buttonB.uniquePress()) { display_date(); return; } //if secs have changed then update the display if (rtc != old_secs) { old_secs = rtc; //do 12/24 hour conversion if ampm set to 1 byte hours = rtc; if (hours >12) (saat = saat - ampm * 12; ) əgər (saat< 1) { hours = hours + ampm * 12; } //split all date and time into individual digits - stick in digits_new array //rtc = secs //array pos and digit stored //digits_new = (rtc%10); //0 - secs ones //digits_new = ((rtc/10)%10); //1 - secs tens //rtc = mins digits_new = (rtc % 10); //2 - mins ones digits_new = ((rtc / 10) % 10); //3 - mins tens //rtc = hours digits_new = (hours % 10); //4 - hour ones digits_new = ((hours / 10) % 10); //5 - hour tens //rtc = date //digits_new = (rtc%10); //6 - date ones //digits_new = ((rtc/10)%10); //7 - date tens //draw initial screen of all chars. After this we just draw the changes. //compare digits 0 to 3 (mins and hours) for (byte i = 0; i <= 3; i++) { //see if digit has changed... if (digits_old[i] != digits_new[i]) { //run 9 step animation sequence for each in turn for (byte seq = 0; seq <= 8 ; seq++) { //convert digit to string itoa(digits_old[i], old_char, 10); itoa(digits_new[i], new_char, 10); //if set to 12 hour mode and we"re on digit 2 (hours tens mode) then check to see if this is a zero. If it is, blank it instead so we get 2.00pm not 02.00pm if (ampm && i == 3) { if (digits_new == 0) { new_char = " "; } if (digits_old == 0) { old_char = " "; } } //draw the animation frame for each digit slideanim(digits_x_pos[i], 0, seq, old_char, new_char); delay(SLIDE_DELAY); } } } /* //compare date digit 6 (ones) and (7) tens - if either of these change we need to update the date line. We compare date tens as say from Jan 31 ->01 fevral onda birlərin rəqəmi dəyişmir, əgər ((rəqəmlər_köhnə != rəqəmlər_yeni) || (rəqəmlər_köhnə != rəqəmlər_yeni)) ( //göstərilən günü dəyişdirin. Aşağıdakı dövrə növbə ilə 3 simvolun hər birindən keçir, məsələn, "MON" üçün (bayt day_char = 0; day_char<=2 ; day_char++){ //run the anim sequence for each char for (byte seq = 0; seq <=8 ; seq++){ //the day (0 - 6) Read this number into the days char array. the seconds number in the array 0-2 gets the 3 chars of the day name, e.g. m o n slideanim(6*day_char,8,seq,old_chars,days); //6 x day_char gives us the x pos for the char delay(SLIDE_DELAY); } //save the old day chars into the old_chars array at array pos 0-2. We use this next time we change the day and feed it to the animation as the current char. The updated char is fed in as the new char. old_chars = days; } //change the date tens digit (if needed) and ones digit. (the date ones digit wil alwaus change, but putting this in the "if" loop makes it a bit neater code wise.) for (byte i = 7; i >= 6; i--)( əgər (rəqəmlər_köhnə[i] != rəqəmlər_yeni[i]) ( üçün (bayt ardıcıllığı = 0; ardıcıl)<=8 ; seq++){ itoa(digits_old[i],old_char,10); itoa(digits_new[i],new_char,10); slideanim(digits_x_pos[i],8,seq,old_char,new_char); delay(SLIDE_DELAY); } } } //print the day suffix "nd" "rd" "th" etc. First work out date 2 letter suffix - eg st, nd, rd, th byte s = 3; //the pos to read our suffix array from. byte date = rtc; if(date == 1 || date == 21 || date == 31) { s = 0; } else if (date == 2 || date == 22) { s = 1; } else if (date == 3 || date == 23) { s = 2; } for (byte suffix_char = 0; suffix_char <=1 ; suffix_char++){ for (byte seq = 0; seq <=8 ; seq++){ slideanim((suffix_char*6)+36,8,seq,old_chars,suffix[s]); // we pass in the old_char array char as the current char and the suffix array as the new char delay(SLIDE_DELAY); } //save the suffic char in the old chars array at array pos 3 and 5. We use these chars next time we change the suffix and feed it to the animation as the current char. The updated char is fed in as the new char. old_chars = suffix[s]; } }//end do date line */ //save digita array tol old for comparison next loop for (byte i = 0; i <= 3; i++) { digits_old[i] = digits_new[i]; } }//secs/oldsecs }//while loop fade_down(); } //called by slide //this draws the animation of one char sliding on and the other sliding off. There are 8 steps in the animation, we call the function to draw one of the steps from 0-7 //inputs are are char x and y, animation frame sequence (0-7) and the current and new chars being drawn. void slideanim(byte x, byte y, byte sequence, char current_c, char new_c) { // To slide one char off and another on we need 9 steps or frames in sequence... // seq# 0123456 <-rows of the display // | ||||||| // seq0 0123456 START - all rows of the display 0-6 show the current characters rows 0-6 // seq1 012345 current char moves down one row on the display. We only see it"s rows 0-5. There are at display positions 1-6 There is a blank row inserted at the top // seq2 6 01234 current char moves down 2 rows. we now only see rows 0-4 at display rows 2-6 on the display. Row 1 of the display is blank. Row 0 shows row 6 of the new char // seq3 56 0123 // seq4 456 012 half old / half new char // seq5 3456 01 // seq6 23456 0 // seq7 123456 // seq8 0123456 END - all rows show the new char //from above we can see... //currentchar runs 0-6 then 0-5 then 0-4 all the way to 0. starting Y position increases by 1 row each time. //new char runs 6 then 5-6 then 4-6 then 3-6. starting Y position increases by 1 row each time. //if sequence number is below 7, we need to draw the current char if (sequence < 7) { byte dots; // if (current_c >= "A" && || (cari_c >= "a" && cari_c<= "z")) { // current_c &= 0x1F; // A-Z maps to 1-26 // } if (current_c >= "A" && cari_c<= "Z") { current_c &= 0x1F; // A-Z maps to 1-26 } else if (current_c >= "a" && cari_c<= "z") { current_c = (current_c - "a") + 41; // A-Z maps to 41-67 } else if (current_c >= "0" && cari_c<= "9") { current_c = (current_c - "0") + 31; } else if (current_c == " ") { current_c = 0; // space } else if (current_c == ".") { current_c = 27; // full stop } else if (current_c == "\"") { current_c = 28; // single quote mark } else if (current_c == ":") { current_c = 29; //colon } else if (current_c == ">") ( cari_c = 30; // saat_rejimi seçici oxu ) bayt curr_char_row_max = 7 - ardıcıllıq; //çəkiləcək sətirlərin maksimum sayı 6-dır - sıra nömrəsi bayt start_y = ardıcıllıq; //başlamaq üçün y mövqeyi - eynidir ardıcıllıq nömrəsi. Biz bunu hər bir döngəyə daxil edirik // (bayt curr_char_row = 0; curr_char_row) üçün hər cərgəni maksimum sıraya qədər (ardıcıllıq nömrəsindən hesablanır) tərtib edirik<= curr_char_row_max; curr_char_row++) { for (byte col = 0; col < 5; col++) { dots = pgm_read_byte_near(&myfont); if (dots & (64 >> curr_char_row)) süjet(x + col, y + start_y, 1); //plot led on else plot(x + col, y + start_y, 0); //else plot led off ) start_y++;//y-ə bir əlavə edək ki, növbəti cərgə birini aşağı çəkək ) ) //ardıcıllıq 1 ilə 7 arasındadırsa simvollar arasında boş sətir çəkin. Bunu etməsək, əldə edirik. cari simvolların qalıqları ekranda qalan son mövqe əgər (ardıcıllıq >= 1 && ardıcıllığı<= 8) { for (byte col = 0; col < 5; col++) { plot(x + col, y + (sequence - 1), 0); //the y position to draw the line is equivalent to the sequence number - 1 } } //if sequence is above 2, we also need to start drawing the new char if (sequence >= 2) ( //xarakter bayt nöqtələrini işləyin; //əgər (new_c >= "A" && new_c<= "Z" || (new_c >= "a" && yeni_c<= "z")) { // new_c &= 0x1F; // A-Z maps to 1-26 //} if (new_c >= "A" && yeni_c<= "Z") { new_c &= 0x1F; // A-Z maps to 1-26 } else if (new_c >= "a" && yeni_c<= "z") { new_c = (new_c - "a") + 41; // A-Z maps to 41-67 } else if (new_c >= "0" && yeni_c<= "9") { new_c = (new_c - "0") + 31; } else if (new_c == " ") { new_c = 0; // space } else if (new_c == ".") { new_c = 27; // full stop } else if (new_c == "\"") { new_c = 28; // single quote mark } else if (new_c == ":") { new_c = 29; // clock_mode selector arrow } else if (new_c == ">") ( new_c = 30; // saat_rejimi seçici oxu ) bayt newcharrowmin = 6 - (ardıcıllıq - 2); //yeni simvol üçün çəkmək üçün minimum sətir nömrəsi - bu, 2-8 sıra nömrələri verildikdə 6-dan 0-a qədər nəticə yaradır . Bu, yeni simvol baytı üçün çəkiləcək minimum cərgədir start_y = 0; //y mövqeyindən başlamaq üçün - sıra nömrəsi ilə eynidir. biz onu hər cərgə daxil edirik //hər cərgəni minimum sətirdən yuxarı çəkirik (ardıcıllıq nömrəsi ilə hesablanır) ) üçün 6-ya qədər (bayt newcharrow = newcharrowmin; newcharrow<= 6; newcharrow++) { for (byte col = 0; col < 5; col++) { dots = pgm_read_byte_near(&myfont); if (dots & (64 >> newcharrow)) süjet(x + col, y + start_y, 1); //plot led on else plot(x + col, y + start_y, 0); //else plot led off ) start_y++;//y-ə bir əlavə edin ki, növbəti cərgə bir aşağı çəkək ) ) ) //rəqəmlərdən çox sözlərdən istifadə edərək saatı çap edin void word_clock() ( cls(); char numbers = ( "bir" ", "iki", "üç", "dörd", "beş", "altı", "yeddi", "səkkiz", "doqquz", "on", "on bir", "on iki", "on üç", "on dörd", "on beş", "on altı", "on yeddi", "on səkkiz", "on doqquz" ); simvol nömrələri = ( "on", "iyirmi", "otuz", "qırx", "əlli" ); //potensial olaraq 3 sətir char str_a; char str_b; char str_c; //bayt saat_y, mins_y; //saat və dəqiqələr və saatlar və dəqiqələr üçün mövqelər bayt saat = rtc; əgər (saat > 12) (saat = saat - ampm * 12; ) əgər (saat< 1) { hours = hours + ampm * 12; } get_time(); //get the time from the clock chip byte old_mins = 100; //store mins in old_mins. We compare mins and old mins & when they are different we redraw the display. Set this to 100 initially so display is drawn when mode starts. byte mins; //run clock main loop as long as run_mode returns true while (run_mode()) { //check for button press if (buttonA.uniquePress()) { switch_mode(); return; } if (buttonB.uniquePress()) { display_date(); } get_time(); //get the time from the clock chip mins = rtc; //get mins //if mins is different from old_mins - redraw display if (mins != old_mins) { //update old_mins with current mins value old_mins = mins; //reset these for comparison next time mins = rtc; hours = rtc; //make hours into 12 hour format if (hours >12) ( saat = saat - 12; ) if (saat == 0) (saat = 12; ) //mins dəyərini iki ayrı rəqəmə bölmək int minsdigit = rtc % 10; bayt minsdigitten = (rtc / 10) % 10; //əgər dəqiqə<= 10 , then top line has to read "minsdigti past" and bottom line reads hours if (mins < 10) { strcpy (str_a, numbers); strcpy (str_b, "PAST"); strcpy (str_c, numbers); } //if mins = 10, cant use minsdigit as above, so soecial case to print 10 past /n hour. if (mins == 10) { strcpy (str_a, numbers); strcpy (str_b, " PAST"); strcpy (str_c, numbers); } //if time is not on the hour - i.e. both mins digits are not zero, //then make first line read "hours" and 2 & 3rd lines read "minstens" "mins" e.g. "three /n twenty /n one" else if (minsdigitten != 0 && minsdigit != 0) { strcpy (str_a, numbers); //if mins is in the teens, use teens from the numbers array for the 2nd line, e.g. "fifteen" //if (mins >= 11 && dəq<= 19) { if (mins <= 19) { strcpy (str_b, numbers); } else { strcpy (str_b, numberstens); strcpy (str_c, numbers); } } // if mins digit is zero, don"t print it. read read "hours" "minstens" e.g. "three /n twenty" else if (minsdigitten != 0 && minsdigit == 0) { strcpy (str_a, numbers); strcpy (str_b, numberstens); strcpy (str_c, ""); } //if both mins are zero, i.e. it is on the hour, the top line reads "hours" and bottom line reads "o"clock" else if (minsdigitten == 0 && minsdigit == 0) { strcpy (str_a, numbers); strcpy (str_b, "O"CLOCK"); strcpy (str_c, ""); } }//end worknig out time //run in a loop //print line a "twelve" byte len = 0; while (str_a) { len++; }; //get length of message byte offset_top = (31 - ((len - 1) * 4)) / 2; // //plot hours line byte i = 0; while (str_a[i]) { puttinychar((i * 4) + offset_top, 1, str_a[i]); i++; } //hold display but check for button presses int counter = 1000; while (counter >0)( //düymənin basılıb-baxılmadığını yoxlayın if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) gecikmə(1); counter--; ) fade_down (); //çap xətti b len = 0; while (str_b) (len++; ); //mesajın uzunluğunu alın ofset_top = (31 - ((len - 1) * 4)) / 2; i = 0; while (str_b[i]) ( puttinychar((i * 4) + ofset_top, 1, str_b[i]); i++; ) //ekranı saxlayın, lakin düymələrin basıldığını yoxlayın counter = 1000; isə (counter > 0)( if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) delay(1); counter--; ) fade_down() ; //varsa c sətrini çap edin. len = 0; while (str_c) (len++; ); //mesajın uzunluğunu alın ofset_top = (31 - ((len - 1) * 4)) / 2; i = 0; while (str_c[i]) ( puttinychar((i * 4) + ofset_top, 1, str_c[i]); i++; ) counter = 1000; isə (sayğac > 0)( //düyməni basıb yoxlayın if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) gecikmə(1); counter- -; ) fade_down(); // ekranı boş saxlayın, lakin yenidən başlamazdan əvvəl düymələrin basılıb-baxılmadığını yoxlayın. sayğac = 1000; isə (sayğac > 0)( //düyməni basıb yoxlayın if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) gecikmə(1); counter- -; ) ) fade_down(); ) /// sürüşdürmə mesajı - hazırda istifadə edilmir - çox yavaş. void scroll() ( char message = ("Salam"); ​​cls(); bayt p = 6; //sətirdəki cari mövqe bayt chara = (0, 1, 2, 3, 4, 5); // simvollar sətirdən int x = (0, 6, 12, 18, 24, 30); //hər bayt üçün xpos y = 0; //y pos // clear_buffer(); while (message[p] != "\ 0") ( //bütün 6 simvolu çəkin (bayt c = 0; c< 6; c++) { putnormalchar(x[c],y,message[ chara[c] ]); //draw a line of pixels turned off after each char,otherwise the gaps between the chars have pixels left in them from the previous char for (byte yy = 0 ; yy < 8; yy ++) { plot(x[c] + 5, yy, 0); } //take one off each chars position x[c] = x[c] - 1; } //reset a char if it"s gone off screen for (byte i = 0; i <= 5; i++) { if (x[i] < -5) { x[i] = 31; chara[i] = p; p++; } } } } //display_date - print the day of week, date and month with a flashing cursor effect void display_date() { cls(); //read the date from the DS1307 byte dow = rtc; // day of week 0 = Sunday byte date = rtc; byte month = rtc - 1; //array of month names to print on the display. Some are shortened as we only have 8 characters across to play with char monthnames = { "January", "February", "March", "April", "May", "June", "July", "August", "Sept", "October", "November", "December" }; //print the day name //get length of text in pixels, that way we can centre it on the display by divindin the remaining pixels b2 and using that as an offset byte len = 0; while(daysfull) { len++; }; byte offset = (31 - ((len-1)*4)) / 2; //our offset to centre up the text //print the name int i = 0; while(daysfull[i]) { puttinychar((i*4) + offset , 1, daysfull[i]); i++; } delay(1000); fade_down(); cls(); // print date numerals char buffer; itoa(date,buffer,10); offset = 10; //offset to centre text if 3 chars - e.g. 3rd // first work out date 2 letter suffix - eg st, nd, rd, th etc // char suffix={"st", "nd", "rd", "th" }; is defined at top of code byte s = 3; if(date == 1 || date == 21 || date == 31) { s = 0; } else if (date == 2 || date == 22) { s = 1; } else if (date == 3 || date == 23) { s = 2; } //print the 1st date number puttinychar(0+offset, 1, buffer); //if date is under 10 - then we only have 1 digit so set positions of sufix etc one character nearer byte suffixposx = 4; //if date over 9 then print second number and set xpos of suffix to be 1 char further away if (date >9)( suffixposx = 8; puttinychar(4+ofset, 1, bufer); ofset = 8; //4 simvol olduqda mətnin mərkəzinə ofset ) //2 şəkilçi simvolu çap edin puttinychar(suffixposx+offset, 1, şəkilçi[s) ]); puttinychar(suffixposx+4+ofset, 1, şəkilçi[s]); gecikmə (1000); solğun_aşağı(); //ayın adını çap edin //mətnin uzunluğunu piksellə əldə edin, beləliklə, qalan pikselləri b2 bölməklə və onu ofset olaraq istifadə etməklə onu ekranda mərkəzləşdirə bilərik len = 0; while(ay adları) ( len++; ); ofset = (31 - ((len-1)*4)) / 2; //mətni mərkəzləşdirmək üçün ofsetimiz i = 0; while(ay adları[i]) ( puttinychar((i*4) +ofset, 1, ay adları[i]); i++; ) gecikmə(1000); solğun_aşağı(); ) //saat rejimini dəyişmək üçün dislpay menyusu void switch_mode() ( //bizim olduğumuz rejimi yadda saxla. Parametrlər rejiminə keçdiyimiz zaman bu dəyərdən istifadə edirik, ona görə də biz parametrlər rejimindən (6) istənilən rejimə qayıda bilərik. köhnə_rejim = saat_rejimi; char* rejimləri = ( "Əsas", "Kiçik", "Slayd", "Sözlər", "Quraşdırma"); bayt növbəti_saat_rejimi; bayt ilk iş = 1; //döyməni gözləyən dövrə (35-dən sonra vaxt aşımı) X rejiminə qayıtmaq üçün döngələr) for (int count = 0; count< 35 ; count++) { //if user hits button, change the clock_mode if (buttonA.uniquePress() || firstrun == 1) { count = 0; cls(); if (firstrun == 0) { clock_mode++; } if (clock_mode >NUM_DISPLAY_MODES + 1) ( clock_mode = 0; ) //birinci sətirdə oxu və cari saat_rejimi adını çap edin və ikinci sətirdə növbəti saat_rejiminin adını çap edin char str_top; //strcpy (str_top, "-"); strcpy (str_top, rejimlər); növbəti_saat_rejimi = saat_rejimi + 1; əgər (next_clock_rejimi > NUM_DISPLAY_MODES + 1) ( next_clock_rejimi = 0; ) bayt i = 0; while (str_top[i]) ( putnormalchar(i * 6, 0, str_top[i]); i++; ) firstrun = 0; ) gecikmə(50); ) ) //run_mode əsl baytı qaytardığı müddətcə saatın əsas dövrəsini işlədin run_mode() ( //təsadüfi rejim aktivdirsə... rejimi dəyişdiyimiz zaman saatı yoxlayın. if (təsadüfi_rejim) ( //əgər saat dəyərini dəyişmə rejimində vaxt = saat. sonra false = yəni çıxış rejiminə qayıt. if (change_mode_time == rtc) ( //növbəti təsadüfi saat rejimini və onu dəyişdirmək üçün vaxtı təyin edin set_next_random(); //cari rejimdən çıxın. 0; ) ) / /else return 1 - bu rejimdə işləməyə davam edin qaytarın 1; ) //təsadüfi rejim boş olduqda saat rejimi dəyişəcək növbəti saatı təyin edin set_next_random() ( //saat rejiminin dəyişəcəyi növbəti saatı təyin edin - cari vaxt plus 1 - 4 saat get_time(); change_mode_time = rtc + təsadüfi (1, 5); //dəyişiklik_rejimi_zamanı indi 23-dən çox olarsa, onu səhər saat 1 ilə 3 arasında təyin edin, əgər (dəyişiklik_rejimi_zamanı > 23) (dəyişiklik_rejimi_zamanı = təsadüfi (1) , 4); ) //yeni saat rejimini təyin edin clock_mode = random(0, NUM_DISPLAY_MODES + 1); //yeni təsadüfi saat rejimi seçin ) //saat parametrlərini dəyişmək üçün dislpay menyusu void setup_menu() ( char* set_modes = () "Rndom", "24 Hr", "Set", "Brght", "Exit"); əgər (ampm == 0) ( set_rejimləri = ("12 Hr"); ) bayt ayarı_rejimi = 0; bayt sonrakı_setting_rejimi; bayt ilk iş = 1; // düyməni gözləyən dövrə (X rejiminə qayıtmaq üçün 35 döngədən sonra fasilə) for(int count=0; count< 35 ; count++) { //if user hits button, change the clock_mode if(buttonA.uniquePress() || firstrun == 1){ count = 0; cls(); if (firstrun == 0) { setting_mode++; } if (setting_mode >NUM_SETTINGS_MODES) ( settings_mode = 0; ) //birinci sətirdə oxu və cari saat_rejimi adını çap edin və ikinci sətirdə növbəti saat_rejiminin adını çap edin char str_top; strcpy (str_top, set_rejimləri); sonrakı_setting_rejimi = quraşdırma_rejimi + 1; əgər (next_setting_rejimi > NUM_SETTINGS_MODES) ( next_setting_rejim = 0; ) bayt i = 0; while(str_top[i]) ( putnormalchar(i*6, 0, str_top[i]); i++; ) firstrun = 0; ) gecikmə(50); ) //rejim keçidini seçin(setting_rejim)( hal 0: set_random(); fasilə; hal 1: set_ampm(); fasilə; hal 2: set_time(); fasilə; hal 3: set_intensity(); fasilə; hal 4: //menyunun fasiləsindən çıxmaq; ) //saatı 6-cı rejimdən (parametrlər) clock_mode=old_mode-dan əvvəlki vəziyyətə dəyişdirin; ) //təsadüfi rejimi dəyişdirin - bir neçə saatdan bir fərqli saat rejimi seçin void set_random())( cls(); char text_a = "Off"; char text_b = "On"; bayt i = 0; //təsadüfi rejimdirsə yandırın, onu söndürün, əgər (təsadüfi_rejim)( //təsadüfi rejimi söndürün random_mode = 0; //ekranda mesajı çap edin while(text_a[i]) ( putnormalchar((i*6), 0, text_a[i] ) ; i++; ) ) else ( //təsadüfi rejimi yandırın. random_mode = 1; //saat rejimini təyin edin set_next_random(); //ekranda mesajı çap edin while(text_b[i]) ( putnormalchar((i) * 6), 0, text_b[i]); i++; ) ) gecikmə (1500); //mesajı bir saniyə yuxarı buraxın ) //12 və ya 24 saatlıq saat boşluğunu təyin edin set_ampm() ( // AM/ PM və ya 24 saatlıq saat rejimi - biti çevirin (ampm rejimi üçün 0-ı 1-ə və ya 1-i 0-a çevirir) ampm = (ampm ^ 1); cls(); ) //ekran intensivliyini dəyişdirin void set_intensity() ( cls() ; bayt i = 0; char mətn = "Parlaq"; while(text[i]) ( puttinychar((i*4)+4, 0, text[i]); i++; ) // düymənin daxil edilməsini gözləyin ( ! buttonA.uniquePress()) ( səviyyə çubuğu (0.6,(intensivlik*2)+2.2); //intensivlik səviyyəsini bar kimi göstərərkən (buttonB.isPressed()) ( if(intensity == 15) ( intensity = 0; cls (); ) else ( intensity++; ) //yeni dəyəri çap edin i = 0; while(text[i]) ( puttinychar((i*4)+4, 0, text[i]); i++; ) //intensivlik səviyyəsini bar səviyyə çubuğu kimi göstərin (0,6,(intensivlik*2)+ 2,2); // üçün displeylərdə parlaqlıq parametrlərini dəyişdirin (bayt ünvanı = 0; ünvan< 4; address++) { lc.setIntensity(address, intensity); } delay(150); } } } // display a horizontal bar on the screen at offset xposr by ypos with height and width of xbar, ybar void levelbar (byte xpos, byte ypos, byte xbar, byte ybar) { for (byte x = 0; x < xbar; x++) { for (byte y = 0; y <= ybar; y++) { plot(x+xpos, y+ypos, 1); } } } //set time and date routine void set_time() { cls(); //fill settings with current clock values read from clock get_time(); byte set_min = rtc; byte set_hr = rtc; byte set_date = rtc; byte set_mnth = rtc; int set_yr = rtc; //Set function - we pass in: which "set" message to show at top, current value, reset value, and rollover limit. set_date = set_value(2, set_date, 1, 31); set_mnth = set_value(3, set_mnth, 1, 12); set_yr = set_value(4, set_yr, 2013, 2099); set_hr = set_value(1, set_hr, 0, 23); set_min = set_value(0, set_min, 0, 59); ds1307.adjust(DateTime(set_yr, set_mnth, set_date, set_hr, set_min)); cls(); } //used to set min, hr, date, month, year values. pass //message = which "set" message to print, //current value = current value of property we are setting //reset_value = what to reset value to if to rolls over. E.g. mins roll from 60 to 0, months from 12 to 1 //rollover limit = when value rolls over int set_value(byte message, int current_value, int reset_value, int rollover_limit){ cls(); char messages = { "Set Mins", "Set Hour", "Set Day", "Set Mnth", "Set Year"}; //Print "set xyz" top line byte i = 0; while(messages[i]) { puttinychar(i*4 , 1, messages[i]); i++; } delay(2000); cls(); //print digits bottom line char buffer = " "; itoa(current_value,buffer,10); puttinychar(0 , 1, buffer); puttinychar(4 , 1, buffer); puttinychar(8 , 1, buffer); puttinychar(12, 1, buffer); delay(300); //wait for button input while (!buttonA.uniquePress()) { while (buttonB.isPressed()){ if(current_value < rollover_limit) { current_value++; } else { current_value = reset_value; } //print the new value itoa(current_value, buffer ,10); puttinychar(0 , 1, buffer); puttinychar(4 , 1, buffer); puttinychar(8 , 1, buffer); puttinychar(12, 1, buffer); delay(150); } } return current_value; } void get_time() { //get time DateTime now = ds1307.now(); //save time to array rtc = now.year(); rtc = now.month(); rtc = now.day(); rtc = now.dayOfWeek(); //returns 0-6 where 0 = Sunday rtc = now.hour(); rtc = now.minute(); rtc = now.second(); //flash arduino led on pin 13 every second //if ((rtc % 2) == 0) { // digitalWrite(13, HIGH); //} //else { // digitalWrite(13, LOW); //} //print the time to the serial port - useful for debuging RTC issues /* Serial.print(rtc); Serial.print(":"); Serial.print(rtc); Serial.print(":"); Serial.println(rtc); */ }

İndi cihazda işi başa çatdırmaq üçün yalnız bir sıra sadə əməliyyatları yerinə yetirməlisiniz:


Proqram kodunu tərtib etmək və daha sonra mikrokontrolörün yaddaşına yükləmək bir az vaxt aparacaq, adətən bir dəqiqədən çox deyil. Əməliyyatın uğurla başa çatması barədə Arduino IDE konsolunda məlumat veriləcək. Bundan sonra cihazdakı Reset düyməsini istifadə edərək Arduino-nu yenidən başlatmaq qalır - LED matrislərində sadə bir saat hazırdır!

Arduino-da hazır saat

Saat iki düymədən istifadə etməklə qurulur. Cihaz 12 və 24 saatlıq vaxt formatlarını dəstəkləyir, həftənin tarixini və gününü göstərir və vaxtı saniyələrlə və ya saniyəsiz göstərir. LED-lərin parlaqlığını dəyişdirmək də mümkündür.


Yəqin ki, gələcəkdə daha çox funksiya əlavə etmək istəyəcəksiniz (məsələn, termometr) və ya cihazı öz dizaynınız olan bir gövdəyə quraşdırmaq - lazer kəsmə maşınlarında istehsal etməklə yaxşı nəticələr əldə etmək olar. Ancaq indi əminliklə deyə bilərsiniz ki, öz əllərinizlə tam hüquqlu bir elektron saat yığmısınız!

Bir müddət əvvəl evdə saatın olmasına ehtiyac yarandı, ancaq elektron saat, çünki saatları sevmirəm, çünki onlar işarələnir. Lehimləmə və aşındırma sxemlərində kifayət qədər təcrübəm var. İnterneti araşdırdıqdan və bəzi ədəbiyyat oxuduqdan sonra ən sadə sxemi seçmək qərarına gəldim, çünki zəngli saata ehtiyacım yoxdur.

Asan olduğu üçün bu sxemi seçdim öz saatınızı düzəldin

Başlayaq, bəs öz əlimizlə saat düzəltmək üçün bizə nə lazımdır? Əlbətdə ki, əllər, dövrə diaqramlarını oxumaq, lehimləmə dəmiri və hissələri bacarıq (hətta böyük deyil). İstifadə etdiklərimin tam siyahısı budur:

10 MHz kvars – 1 əd., ATtiny 2313 mikrokontroller, 100 Ohm rezistorlar – 8 əd., 3 əd. 10 kOhm, 22 pF-lik 2 kondansatör, 4 tranzistor, 2 düymə, LED göstərici 4 bitlik KEM-5641-ASR (RL-F5610SBAW/D15). Quraşdırmanı birtərəfli PCB-də həyata keçirdim.

Ancaq bu sxemdə bir qüsur var: boşalmalara nəzarət etmək üçün cavabdeh olan mikrokontrolörün (bundan sonra MK adlandırılacaq) sancaqları kifayət qədər layiqli bir yük alır. Ümumi cərəyan maksimum port cərəyanından çox yüksəkdir, lakin dinamik göstərici ilə MK-nın həddindən artıq istiləşmə vaxtı yoxdur. MK-nın işləməməsinin qarşısını almaq üçün, boşalma dövrələrinə 100 Ohm rezistorlar əlavə edirik.

Bu sxemdə göstərici dinamik göstərici prinsipinə uyğun olaraq idarə olunur, buna görə göstərici seqmentləri MK-nın müvafiq çıxışlarından gələn siqnallarla idarə olunur. Bu siqnalların təkrarlanma tezliyi 25 Hz-dən çoxdur və buna görə də göstərici nömrələrinin parıltısı davamlı görünür.

Elektron saatlar yuxarıdakı sxemə uyğun olaraq hazırlanmışdır yalnız vaxtı (saat və dəqiqə) göstərə bilər və saniyələr seqmentlər arasında nöqtə ilə göstərilir, yanıb-sönür. Saatın iş rejiminə nəzarət etmək üçün onun strukturunda saatların və dəqiqələrin tənzimlənməsinə nəzarət edən düymələr var. Bu dövrə 5V enerji təchizatı ilə təchiz edilmişdir. Çap dövrə lövhəsinin istehsalı zamanı dövrəyə 5V zener diodu daxil edilmişdir.

5V enerji təchizatına malik olduğum üçün zener diodunu dövrədən xaric etdim.

Lövhəni hazırlamaq üçün bir dəmir istifadə edərək dövrə tətbiq edildi. Yəni, çap sxemi parlaq kağızdan istifadə edərək inkjet printerdə çap edilmişdir, müasir parlaq jurnallardan götürülə bilər. Daha sonra tələb olunan ölçüdə tekstolit kəsilib. Mənim ölçüsüm 36*26 mm oldu. Belə kiçik ölçü, bütün hissələrin SMD paketində seçildiyinə görədir.

Lövhə dəmir xlorid (FeCl 3) ilə işlənmişdir. Lövhə ilə vanna kamin üzərində olduğu üçün aşındırma təxminən bir saat çəkdi; aşındırma müddətinə yüksək temperatur təsir göstərir, lövhədə mis istifadə edilməmişdir. Ancaq temperaturu aşmayın.

Oxunma prosesi davam edərkən beynimi sındırmamaq və saatın işləməsi üçün proqram təminatı yazmamaq üçün İnternetə girdim və bu sxem üçün proqram təminatı tapdım. MK-ni necə yandırmaq olar İnternetdə də tapıla bilər. Mən yalnız ATMEGA MK-ləri yandıran bir proqramçı istifadə etdim.

Və nəhayət, lövhəmiz hazırdır və biz saatlarımızı lehimləməyə başlaya bilərik. Lehimləmə üçün MK və digər hissələri yandırmamaq üçün nazik bir ucu olan 25 Vt gücündə bir lehimləmə dəmirinə ehtiyacınız var. Lehimləməni diqqətlə həyata keçiririk və tercihen ilk dəfə MK-nın bütün ayaqlarını lehimləyirik, ancaq ayrıca. Bilməyənlər üçün, SMD paketində hazırlanmış hissələrin sürətli lehimləmə üçün terminallarında qalay olduğunu bilin.

Və lövhənin lehimlənmiş hissələri ilə belə görünür.

Yadımdadır... Otuz il əvvəl altı göstərici kiçik bir xəzinə idi. Daha sonra belə göstəricilərlə TTL məntiqindən istifadə edərək saat düzəldə bilən hər kəs öz sahəsində mükəmməl mütəxəssis hesab olunurdu.

Qaz-boşaltma göstəricilərinin parıltısı daha isti görünürdü. Bir neçə dəqiqədən sonra bu köhnə lampaların işləyə biləcəyini düşündüm və onlarla nəsə etmək istədim. İndi belə bir saat düzəltmək çox asandır. Sizə lazım olan tək şey mikrokontrollerdir...

Eyni zamanda yüksək səviyyəli dillərdə mikrokontrollerlərin proqramlaşdırılması ilə maraqlandığım üçün bir az oynamağa qərar verdim. Rəqəmsal qaz boşalma göstəricilərindən istifadə edərək sadə bir saat qurmağa çalışdım.

Dizaynın məqsədi

Qərara gəldim ki, saat altı rəqəmdən ibarət olmalıdır və vaxt minimum sayda düymə ilə təyin olunmalıdır. Bundan əlavə, müxtəlif istehsalçıların ən çox yayılmış mikrokontroller ailələrindən bir neçəsini istifadə etməyə çalışmaq istədim. Proqramı C dilində yazmaq niyyətində idim.

Qaz boşaltma göstəriciləri işləmək üçün yüksək gərginlik tələb edir. Amma mən təhlükəli şəbəkə gərginliyi ilə məşğul olmaq istəmədim. Saatın zərərsiz 12 V gərginliyi ilə işləməsi nəzərdə tutulurdu.

Əsas məqsədim oyun olduğu üçün burada mexaniki dizaynın və ya bədən təsvirlərinin heç bir təsvirini tapa bilməzsiniz. İstəyirsinizsə, zövqünüzə və təcrübənizə uyğun olaraq saatı özünüz dəyişə bilərsiniz.

Əldə etdiyim budur:

  • Vaxt göstəricisi: HH MM SS
  • Siqnal göstəricisi: HH MM --
  • Vaxt göstərmə rejimi: 24 saat
  • Dəqiqlik gündə ±1 saniyə (kvars kristalından asılı olaraq)
  • Təchizat gərginliyi: 12 V
  • Cari istehlak: 100 mA

Saat diaqramı

Altı rəqəmli rəqəmsal displeyi olan bir cihaz üçün multipleks rejimi təbii bir həll idi.

Blok diaqramının əksər elementlərinin məqsədi (Şəkil 1) şərhsiz aydındır. Müəyyən dərəcədə qeyri-standart vəzifə TTL səviyyələrinin yüksək gərginlikli göstərici idarəetmə siqnallarına çevrilməsinin yaradılması idi. Anod sürücüləri yüksək gərginlikli NPN və PNP tranzistorlarından istifadə etməklə hazırlanır. Diaqram Stefan Knellerdən götürülmüşdür (http://www.stefankneller.de).

74141 TTL çipində hər bir rəqəm üçün BCD dekoderi və yüksək gərginlikli sürücü var. Bir çip sifariş etmək çətin ola bilər. (Baxmayaraq ki, artıq onları kimsə düzəldirmi bilmirəm). Ancaq qaz boşalma göstəricilərini tapsanız, 74141 yaxın bir yerdə ola bilər :-). TTL məntiqi dövründə 74141 çipinə praktiki olaraq alternativ yox idi. Buna görə bir yerdə tapmağa çalışın.

Göstəricilər təxminən 170 V gərginlik tələb edir. Gərginlik çeviricisi üçün xüsusi bir dövrə hazırlamaq mənasızdır, çünki çox sayda gücləndirici çevirici çip var. Mən ucuz və geniş yayılmış IC34063-ü seçdim. Konverter sxemi demək olar ki, tamamilə MC34063 məlumat vərəqindən kopyalanır. T13 güc açarı ona yeni əlavə edilib. Daxili keçid belə yüksək gərginlik üçün uyğun deyil. Konvertor üçün endüktans kimi boğucu istifadə etdim. Şəkil 2-də göstərilmişdir; diametri 8 mm, uzunluğu 10 mm-dir.

Konvertorun səmərəliliyi olduqca yaxşıdır və çıxış gərginliyi nisbətən təhlükəsizdir. 5 mA yük cərəyanı ilə çıxış gərginliyi 60 V-ə düşür. R32 cərəyanı hiss edən rezistor kimi çıxış edir.

Məntiqi gücləndirmək üçün xətti tənzimləyici U4 istifadə olunur. Dövrə və lövhədə ehtiyat batareya üçün yer var. (3,6 V - NiMH və ya NiCd). D7 və D8 Schottky diodlarıdır və R37 rezistoru batareyanın xüsusiyyətlərinə görə şarj cərəyanını məhdudlaşdırmaq üçün nəzərdə tutulmuşdur. Yalnız əylənmək üçün saatlar tikirsinizsə, D7, D8 və R37 batareyasına ehtiyacınız olmayacaq.

Son dövrə Şəkil 3-də göstərilmişdir.

Şəkil 3.

Vaxt təyini düymələri diodlar vasitəsilə birləşdirilir. Düymələrin vəziyyəti müvafiq çıxışda məntiqi “1” təyin edilməklə yoxlanılır. Bonus xüsusiyyəti olaraq, mikrokontrolörün çıxışına bir piezo emitter qoşulur. Bu murdar cığıltını söndürmək üçün kiçik açardan istifadə edin. Bir çəkic bunun üçün olduqca uyğun olardı, amma bu son çarədir :-).

Dövrə komponentlərinin siyahısı, PCB rəsmi və layout diaqramı "Yükləmələr" bölməsində tapıla bilər.

CPU

Minimum tələb olunan sayı Cədvəl 1-də göstərilən kifayət qədər sayda sancaqlı demək olar ki, hər hansı bir mikrokontroller bu sadə cihazı idarə edə bilər.

Cədvəl 1.
Funksiya nəticələr
Qidalanma 2
Kvars rezonatoru 2
Anod idarəetmə 6
Sürücü 74141 4
Düymə girişi 1
Piezo emitent 1
Ümumi 16

Hər bir istehsalçı öz ailələrini və mikrokontroller növlərini inkişaf etdirir. Sancaqların yeri hər bir növ üçün fərdi. Bir neçə növ mikrokontroller üçün universal lövhə hazırlamağa çalışdım. Lövhədə 20 pinli rozetka var. Bir neçə keçid naqili ilə onu müxtəlif mikro nəzarətçilərə uyğunlaşdıra bilərsiniz.

Bu dövrədə sınaqdan keçirilmiş mikrokontrollerlər aşağıda verilmişdir. Digər növlərlə təcrübə edə bilərsiniz. Sxemin üstünlüyü müxtəlif prosessorlardan istifadə etmək imkanıdır. Radio həvəskarları, bir qayda olaraq, bir mikrokontroller ailəsindən istifadə edirlər və müvafiq proqramçı və proqram vasitələrinə malikdirlər. Digər istehsalçıların mikrokontrolörlərində problemlər ola bilər, ona görə də sizə sevimli ailənizdən bir prosessor seçmək imkanı verdim.

Müxtəlif mikrokontrollerlərin işə salınmasının bütün xüsusiyyətləri Cədvəl 2...5 və Şəkil 4...7-də öz əksini tapmışdır.

Cədvəl 2.
Sərbəst miqyas
Növ MC68HC908QY1
Kvars rezonatoru 12 MHz
Kondansatörler C1, C2 22 pF
Proqram freescale.zip
("Yükləmələr" bölməsinə baxın)
Parametrlər

Qeyd: Kvars rezonatoru ilə paralel olaraq 10 MΩ rezistor birləşdirilir.

Cədvəl 3.
Mikroçip
Növ PIC16F628A
Kvars rezonatoru 32,768 kHz
Kondansatörler C1, C2 22 pF
Proqram pic628.zip
("Yükləmələr" bölməsinə baxın)
Parametrlər Int. 4 MHz generator - I/O RA6,
MCLR OFF, WDT OFF, LVP OFF,
BROUT OFF, CP OFF, PWRUP OFF

Qeyd: Mikrosxem rozetkada 180° döndərilməlidir.

Cədvəl 4.
Atmel
Növ ATtiny2313
Kvars rezonatoru 12 MHz
Kondansatörler C1, C2 15 pF
Proqram attiny.zip
("Yükləmələr" bölməsinə baxın)
Parametrlər kv. 8 MHz osilator, RESET ON

Qeyd: RESET pininə (10 kΩ və 100 nF) SMD komponentləri R və C əlavə edin.

Cədvəl 5.
Atmel
Növ AT89C2051
Kvars rezonatoru 12 MHz
Kondansatörler C1, C2 22 pF
Proqram at2051.zip
("Yükləmələr" bölməsinə baxın)
Parametrlər --

Qeyd: SMD komponentləri R və C RESET pininə əlavə edin (10 kΩ və 100 nF); ulduzlarla işarələnmiş sancaqları 3,3 kOhm SMD rezistorları vasitəsilə +Ub enerji avtobusuna birləşdirin.

Müxtəlif mikrokontrollerlər üçün kodları müqayisə etdikdə, onların çox oxşar olduğunu görəcəksiniz. Limanlara giriş və kəsmə funksiyalarının tərifində, eləcə də aparat komponentlərindən asılı olanda fərqlər var.

Mənbə kodu iki bölmədən ibarətdir. Funksiya əsas() portları konfiqurasiya edir və kəsmə siqnallarını yaradan taymeri işə salır. Bundan sonra proqram basılan düymələri skan edir və müvafiq vaxt və həyəcan dəyərlərini təyin edir. Orada əsas döngədə cari vaxt zəngli saatla müqayisə edilir və piezo emitent işə salınır.

İkinci hissə taymer kəsmələrini idarə etmək üçün alt proqramdır. Hər millisaniyədə çağırılan alt proqram (taymerin imkanlarından asılı olaraq) vaxt dəyişənlərini artırır və ekran rəqəmlərinə nəzarət edir. Bundan əlavə, düymələrin vəziyyəti yoxlanılır.

Dövrəni işə salmaq

Komponentləri quraşdırarkən və quraşdırarkən enerji mənbəyindən başlayın. U4 tənzimləyicisini və ətrafdakı komponentləri lehimləyin. U2 üçün 5 V, U1 üçün 4,6 V gərginliyi yoxlayın. Növbəti addım yüksək gərginlikli çeviricinin yığılmasıdır. Gərginliyi 170 V-a təyin etmək üçün R36 kəsmə rezistorundan istifadə edin. Tənzimləmə diapazonu kifayət deyilsə, R33 rezistorunun müqavimətini bir qədər dəyişdirin. İndi U2 çipini, anod və rəqəmsal sürücü dövrəsinin tranzistorlarını və rezistorlarını quraşdırın. U2 girişlərini GND avtobusuna qoşun və R25 - R30 rezistorlarından birini ardıcıl olaraq +Ub enerji avtobusuna qoşun. Göstərici nömrələri müvafiq mövqelərdə yanmalıdır. Dövrənin yoxlanılmasının son mərhələsində U1 mikrosxeminin 19-cu pinini yerə qoşun - piezo emitter səs verməlidir.

Mənbə kodları və tərtib edilmiş proqramları “Yükləmələr” bölməsində müvafiq ZIP faylında tapa bilərsiniz. Proqramı mikrokontrollerə yandırdıqdan sonra U1 mövqeyində olan hər bir pinini diqqətlə yoxlayın və lazımi tel və lehim keçidlərini quraşdırın. Yuxarıdakı mikrokontroller şəkillərinə baxın. Mikrokontroller proqramlaşdırılıbsa və düzgün qoşulubsa, onun generatoru işə başlamalıdır. Siz vaxt və həyəcanı təyin edə bilərsiniz. Diqqət! Lövhədə daha bir düymə üçün yer var - bu gələcək genişləndirmələr üçün ehtiyat düymədir :-).

Generator tezliyinin düzgünlüyünü yoxlayın. Gözlənilən diapazonda deyilsə, C1 və C2 kondansatörlərinin dəyərlərini bir az dəyişdirin. (Kiçik kondensatorları paralel olaraq lehimləyin və ya başqaları ilə əvəz edin). Saatın dəqiqliyi yaxşılaşmalıdır.

Nəticə

Kiçik 8 bitlik prosessorlar yüksək səviyyəli dillər üçün olduqca uyğundur. C əvvəlcə kiçik mikrokontrollerlər üçün nəzərdə tutulmamışdı, lakin sadə proqramlar üçün ondan yaxşı istifadə edə bilərsiniz. Assembly dili kritik vaxtlar və ya maksimum CPU yükü tələb edən mürəkkəb tapşırıqlar üçün daha uyğundur. Əksər radio həvəskarları üçün C kompilyatorunun həm pulsuz, həm də shareware məhdud versiyaları uyğun gəlir.

C proqramlaşdırması bütün mikrokontrollerlər üçün eynidir. Siz seçilmiş mikrokontroller növünün aparat funksiyalarını (registrlər və periferiyalar) bilməlisiniz. Bit əməliyyatları ilə diqqətli olun - ATtiny üçün orijinalın nümunəsində göründüyü kimi, C dili fərdi bitləri manipulyasiya etmək üçün uyğun deyil.

Bitirdiniz? Sonra vakuum borularını nəzərdən keçirin və baxın...

...köhnə günlər qayıtdı... :-)

Redaktorun qeydi

SN74141-in tam analoqu Minsk Integral proqramı tərəfindən istehsal olunan K155ID1 mikrosxemdir.
Mikrosxem İnternetdə asanlıqla tapıla bilər.

Böyük rəqəmlərlə saat anlayışı

Struktur olaraq, cihaz iki lövhədən ibarət olacaq - biri digərinin üstündə. Birinci lövhə saat və dəqiqələri təşkil edən LED-lərin matrisidir, ikincisi güc hissəsidir (LED nəzarəti), məntiq və enerji təchizatı. Bu dizayn saatı daha yığcam edəcək (korpussuz, təxminən 22 sm x 9 sm, qalınlığı 4-5 santimetr) + bir şey səhv olarsa, matrisi başqa bir layihəyə vidalamağa imkan verəcəkdir.

Güc hissəsi UL2003 sürücüsü və tranzistor açarları əsasında qurulacaq. Məntiqi - Atmega8 və DS1307-də. Enerji təchizatı: 220V - transformator; lojik 5V (7805 vasitəsilə), güc hissəsi - 12V (LM2576ADJ vasitəsilə). Real vaxt saatının avtonom enerji təchizatı üçün 3V batareya üçün ayrıca bölmə olacaq - DS1307.

Mən Atmega8 və DS1307-dən istifadə etməyi düşünürəm (saatı tavandan asmağı planlaşdırıram, belə ki, elektrik kəsildiyi zaman hər dəfə parametrləri axtarmağa məcbur olmayacağam), lakin lövhənin tərtibatı cihazı DS1307 olmadan idarə etmək imkanı (ilk dəfə və bəlkə də əbədi - necə işləyəcək).

Beləliklə, konfiqurasiyadan asılı olaraq, saat proqramının iş alqoritmi aşağıdakı kimi olacaqdır:

Atmega8- taymer ilə vaxt sayğacı. Fasiləsiz bir dövrədə işləyin: klaviaturada səsvermə, vaxtı tənzimləmək (lazım olduqda), 4 rəqəm və ayırıcı göstərmək.

Atmega8+DS1307. Fasiləsiz bir dövrədə işləyin: klaviaturada səsvermə, DS1307 vaxtını tənzimləmək (lazım olduqda), DS1307-dən vaxtı oxumaq, 4 rəqəm və ayırıcı göstərmək. Və ya başqa bir seçim - DS1307-dən bir taymerdə oxumaq, qalanı bir döngədə (hələ ən yaxşısını bilmirəm).

Seqment ardıcıl olaraq birləşdirilmiş 4 qırmızı LED-dən ibarətdir. Bir rəqəm - ümumi anodlu 7 seqment. Adi göstəricilərdə olduğu kimi, səkkiz rəqəmindən istifadə edərək seqmentləri ayırmağı planlaşdırmıram.

Saatın güc hissəsi

Saatın güc hissəsi UL2003 sürücüsü və VT1 və VT2 tranzistor açarları üzərində qurulub.

UL2003 göstərici seqmentlərinə, düymələr isə rəqəmlərə nəzarət etmək üçün cavabdehdir.

Saat və dəqiqə ayırıcısı ayrıca idarə olunur (siqnal K8).

Seqmentlər, bitlər və separator K1-K8, Z1-Z4-ə müsbət potensial tətbiq etməklə (yəni +5V tətbiq etməklə) mikrokontroller tərəfindən idarə olunur.

İnformasiyanın dinamik çıxışını (saat və dəqiqə) təmin etmək üçün seqmentlərə və bitlərə siqnallar sinxron və müəyyən tezliklə verilməlidir.

Transistor BCP52 tranzistor VT1 (BCP53) kimi istifadə edilə bilər.

Böyük rəqəmlərlə saatın güc hissəsinin sxemi

Böyük nömrələri olan bir saat üçün yeddi seqmentli göstəricinin çap dövrə lövhəsi

Daha əvvəl dediyim kimi, saat iki çaplı elektron lövhədən ibarət olacaq - göstərici lövhəsi + məntiq və güc hissəsi.

Göstərici dövrə lövhəsinin dizaynı və istehsalı ilə başlayaq.

Böyük rəqəmləri olan saat üçün yeddi seqmentli göstərici üçün çap dövrə lövhəsinin hazırlanması

"Lay" formatında böyük nömrələri olan saat üçün yeddi seqmentli göstəricinin çap dövrə lövhəsi məqalənin sonunda, əlavə edilmiş fayllarda yerləşir. LUT metodundan istifadə edərək çap dövrə lövhələrinin istehsalı texnologiyası haqqında oxuya bilərsiniz.

Hər şeyi düzgün etmisinizsə, bitmiş PCB bu kimi görünəcək.

Böyük nömrələri olan bir saat üçün yeddi seqmentli göstəricinin bitmiş çap dövrə lövhəsi

Yeddi seqmentli göstəricinin yığılması

Göstərici lövhəsi iki tərəfli olduğundan, ediləcək ilk şey interlayer keçidləri etməkdir. Mən bunu lazımsız hissələrin ayaqlarından istifadə edərək edirəm - onları deliklərdən keçirib hər iki tərəfdən lehimləyirəm. Bütün keçidlər başa çatdıqda, onları düz, incə bir fayl ilə təmizləyirəm - çox səliqəli və gözəl çıxır.

Göstərici lövhəsində interlayer flakonlar

Növbəti addım, əslində, göstəricinin yığılmasıdır. Niyə bir paket qırmızı (yaşıl, ağ, mavi) LEDlərə ehtiyacımız var? Məsələn, mən bunları götürdüm.

Göstəricini yığmağa hazırlaşır

Diyotları quraşdırarkən, ümumi bir anod ilə bir göstərici hazırladığımızı unutmayın - yəni. "+" diodları bir-birinə birləşdirilməlidir. PCB-də ümumi anodlar böyük mis parçalarıdır. Bölmə nöqtəsi anoduna diqqət yetirdiyinizə əmin olun.

Göstərici çaplı elektron lövhədə anodların yeri

Nəticədə, 2 saatlıq əziyyətli işdən sonra bunu əldə etməlisiniz:

Yeddi seqment göstəricisi

Saatın rəqəmsal hissəsi

Aşağıdakı sxemə uyğun olaraq böyük nömrələrlə saatın rəqəmsal hissəsini yığacağıq:

Böyük rəqəmlərlə saat diaqramı

Saat dövrəsi olduqca şəffafdır, ona görə də onun necə işlədiyini izah etməkdə heç bir məna görmürəm. *.lay formatında çap edilmiş elektron lövhəni məqalənin sonunda yükləmək olar. Qeyd edək ki, çap dövrə lövhəsi əsasən səthə quraşdırılan hissələr üçün nəzərdə tutulub.

Beləliklə, istifadə etdiyim element bazası:

1. Diod körpüsü DFA028 (yerüstü montaj üçün hər hansı bir kompakt olacaq);
2. D2PAK korpusunda LM2576ADJ gərginlik tənzimləyiciləri, HSOP3-P-2.30A korpusunda 78M05;
3. Transistor açarları BCP53 (SOT223 korpusu) və BC847 (SOT23 korpusu);
4. Atmega8 mikro nəzarət cihazı (TQFP);
5. Real vaxt saatı DS1307 (SO8);
6. Bəzi köhnə cihazdan 14V 1.2A enerji təchizatı;
7. Qalan hissələr istənilən tipdir, çap elektron platada quraşdırmaq üçün uyğun ölçülüdür.

Əlbəttə ki, digər hissə paketlərindən istifadə etmək istəyirsinizsə, PCB-də bəzi dəyişikliklər etməlisiniz.

R3 və R4 müqavimət dəyərlərinə diqqət yetirin - onlar diaqramda göstərildiyi kimi olmalıdır - nə çox, nə də az. Bu, LM2576ADJ gərginlik tənzimləyicisinin çıxışında tam olaraq 12V təmin etmək üçün edilir. Əgər hələ də belə rezistor dəyərlərini tapa bilmirsinizsə, R4 müqavimətinin dəyəri düsturla hesablana bilər:

R4=R3(12/1.23-1) və ya R4=8.76R3

Rəqəmsal hissənin yığılması. Versiya 1, DS1307 olmadan

Saat üçün çap dövrə lövhəsi hazırlayarkən burada göstərilən tövsiyələrə əməl etmisinizsə, o zaman sizə xatırlatmağa ehtiyac yoxdur ki, montajdan əvvəl çap dövrə lövhəsi qazılmalı, üzərindəki bütün görünən qısa qapanmalar aradan qaldırılmalıdır və lövhə maye rozin ilə örtülməlidir? Sonra saatı yığmağa başlayırıq.

Enerji təchizatının yığılması ilə başlamağı və yalnız bundan sonra rəqəmsal hissəni quraşdırmağı məsləhət görürəm. Bu, cihazların öz-özünə yığılması üçün ümumi bir tövsiyədir. Niyə? Sadəcə ona görə ki, enerji təchizatı xəta ilə yığılıbsa, bu enerji təchizatı ilə təchiz edilməli olan bütün aşağı gərginlikli elektronikanı yandıra bilərsiniz.

Hər şey düzgün aparılırsa, enerji təchizatı dərhal işləməlidir. Enerji təchizatının yığılmasını yoxlayırıq - sınaq nöqtələrində gərginliyi ölçün.

Şəkil, təchizatı gərginliyinin yoxlanılmalı olduğu sınaq nöqtələrini göstərir. Gərginlik elan edilənə uyğundursa, saatın rəqəmsal hissəsini yığmağa başlaya bilərsiniz. Əks təqdirdə, enerji təchizatı elementlərinin quraşdırılmasını və funksionallığını yoxlayırıq.

Saat enerji təchizatı üçün sınaq nöqtələri və gərginlik dəyərləri

Enerji təchizatını yoxladıqdan sonra saatın rəqəmsal hissəsini yığmağa davam edirik - bütün digər elementləri çap dövrə lövhəsinə quraşdırırıq. Xüsusilə Atmega mikro nəzarət cihazının və UL2003 sürücüsünün ayaqlarında qısa qapanma olub olmadığını yoxlayırıq.

Saatın rəqəmsal hissəsinin quraşdırılması

Nəzərə alın ki, biz saatı DS1307 real vaxt saatını quraşdırmadan yığırıq, lakin bu çipin bütün naqilləri tamamlanmalıdır. Gələcəkdə, ehtiyac yaranarsa, bu, DS1307-də ​​ayrıca, müstəqil real vaxt saatının hələ də istifadə olunacağı ikinci versiya üçün saatı dəyişdirmək üçün vaxtımıza qənaət edəcəkdir.

ATMEGA8 mikro nəzarətçisinin ilkin sınağı

Mikrokontrolörün düzgünlüyünü və funksionallığını yoxlamaq üçün bizə lazımdır:

1. Proqramçı, məsələn.
2. mikrokontrollerin sxemdaxili proqramlaşdırılması üçün.
3. AVRDUDESHELL proqramı.

Saat lövhəsini məlumat kabelinə bağlayırıq. Məlumat kabelini proqramçıya bağlayırıq. AVRDUDESHELL proqramının quraşdırıldığı kompüter üçün proqramçı. Saat lövhəsi 220V enerji təchizatına qoşulmamalıdır.

AVRDUDESHELL proqramı tərəfindən mikrokontrollerdən verilənlərin müvəffəqiyyətlə oxunması

Qoruyucuları oxuyarkən problemlər yaranarsa, quraşdırmanı yoxlayın - bir yerdə qısa qapanma və ya "itkin əlaqə" ola bilər. Başqa bir ipucu - bəlkə də mikro nəzarətçi aşağı sürətli proqramlaşdırma rejimindədir, onda proqramçını bu rejimə keçirin (