07.10.2023
Dom / Trajno / Kako sastaviti elektronski sat vlastitim rukama. Domaći ručni sat

Kako sastaviti elektronski sat vlastitim rukama. Domaći ručni sat

Ovaj sat je već nekoliko puta recenziran, ali nadam se da će i vama moja recenzija biti zanimljiva. Dodan opis posla i uputstva.

Dizajner je kupljen na ebay.com za 1,38 funti (0,99+0,39 dostava), što je ekvivalentno 2,16 dolara. U trenutku kupovine ovo je najniža ponuđena cijena.

Isporuka je trajala oko 3 sedmice, set je došao u običnoj plastičnoj vrećici, koja je pak bila upakovana u malu vrećicu. Na terminalima indikatora bio je mali komadić pjene, ostali dijelovi su bili bez ikakve zaštite.

Od dokumentacije postoji samo mali A5 list papira sa listom radio komponenti na jednoj strani i dijagramu na drugoj strani.

1. Šema električnog kola, korišteni dijelovi i princip rada



Osnova ili „srce“ sata je 8-bitni CMOS mikrokontroler AT89C2051-24PU opremljen sa 2kb Flash programabilnim i izbrisivim ROM-om.
Čvor generatora takta sastavljena prema kolu (slika 1) i sastoji se od kvarcnog rezonatora Y1, dva kondenzatora C2 i C3, koji zajedno čine paralelni oscilatorni krug.


Promjenom kapacitivnosti kondenzatora, možete promijeniti u malim granicama frekvenciju generatora takta i, shodno tome, točnost sata. Slika 2 prikazuje varijantu kola generatora takta sa mogućnošću podešavanja greške takta.

Početni čvor za resetiranje služi za postavljanje internih registara mikrokontrolera u početno stanje. Služi za napajanje, nakon priključenja napajanja, na 1 pin MK-a jednim impulsom u trajanju od najmanje 1 μs (12 taktova).
Sastoji se od RC kola formiranog od otpornika R1 i kondenzatora C1.

Ulazni krug sastoji se od dugmadi S1 ​​i S2. Softver je osmišljen tako da kada jednom pritisnete bilo koje dugme, u zvučniku se čuje jedan signal, a kada ga držite, čuje se dvostruki signal.

Display modul sastavljen na četverocifrenom sedmosegmentnom indikatoru sa zajedničkom katodom DS1 i otpornim sklopom PR1.
Otpornički sklop je skup otpornika u jednom kućištu:


Zvučni dio Krug je sklop sastavljen pomoću otpornika od 10 kOhm R2, pnp tranzistora Q1 SS8550 (koji djeluje kao pojačalo) i piezoelektričnog elementa LS1.

Ishrana napaja se preko konektora J1 sa kondenzatorom za izravnavanje C4 spojenim paralelno. Opseg napona napajanja od 3 do 6V.

2. Sastavljanje konstruktora

Montaža nije izazvala nikakve poteškoće, na ploči je bilo napisano gdje lemiti koje dijelove.

Puno slika - sklop dizajnera je skriven ispod spojlera

Počeo sam sa utičnicom, pošto ona jedina nije radio komponenta:

Sljedeći korak je bio lemljenje otpornika. Nemoguće ih je zbuniti, oba su 10 kOhm:


Nakon toga sam instalirao na ploču, promatrajući polaritet, elektrolitički kondenzator, sklop otpornika (također obraćajući pažnju na prvi pin) i elemente generatora takta - 2 kondenzatora i kvarcni rezonator

Sljedeći korak je lemljenje dugmadi i kondenzatora filtera napajanja:

Nakon toga, vrijeme je za zvučni piezoelektrični element i tranzistor. Glavna stvar u tranzistoru je instalirati ga na ispravnu stranu i ne zbuniti terminale:

Na kraju, zalemio sam indikator i konektor za napajanje:

Priključujem ga na 5V izvor. Sve radi!!!


3. Podešavanje trenutnog vremena, alarma i satnog signala.

Nakon uključivanja napajanja, displej je u režimu "SATI: MINUTE" i prikazuje podrazumevano vreme 12:59. Satni zvučni signal je uključen. Oba alarma su uključena. Prvi će raditi u 13:01, a drugi u 13:02.


Svaki put kada kratko pritisnete dugme S2, ekran će se prebacivati ​​između režima (“SATI: MINUTE”) i (“MINUTE: SEKUNDE”).
Dugim pritiskom na dugme S1 ulazite u meni podešavanja koji se sastoji od 9 podmenija, označenih slovima A, B, C, D, E, F, G, H, I. Podmenije se menjaju pomoću Dugme S1, vrijednosti se mijenjaju tipkom S2. Podmeni I prati izlazak iz menija podešavanja.

O: Podešavanje trenutnog sata
Kada pritisnete dugme S2, vrednost sata se menja od 0 do 23. Nakon podešavanja sata, morate pritisnuti S1 da biste otišli u podmeni B.

B: Podešavanje minuta trenutnog vremena


C: Uključite zvučni signal po satu
Podrazumevano je UKLJUČENO – zvučni signal se čuje svaki sat od 8:00 do 20:00. Pritiskom na tipku S2 mijenja se vrijednost između ON i OFF. Nakon podešavanja vrijednosti, morate pritisnuti S1 da biste otišli u podmeni D.

D: Uključite/isključite prvi alarm
Podrazumevano, alarm je UKLJUČEN. Pritiskom na tipku S2 mijenja se vrijednost između ON i OFF. Nakon postavljanja vrijednosti, morate pritisnuti S1 da biste prešli na sljedeći podmeni. Ako je alarm isključen, podmeniji E i F se preskaču.

E: Podešavanje prvog budilnika
Kada pritisnete dugme S2, vrednost sata se menja od 0 do 23. Nakon podešavanja sata, morate pritisnuti S1 da biste otišli u podmeni F.

F: Podešavanje minuta prvog alarma
Kada pritisnete dugme S2, vrednost minuta se menja od 0 do 59. Nakon podešavanja minuta, morate pritisnuti S1 da biste otišli u podmeni C.

G: Uključite/isključite drugi budilnik
Podrazumevano, alarm je UKLJUČEN. Pritiskom na tipku S2 mijenja se vrijednost između ON i OFF. Nakon postavljanja vrijednosti, morate pritisnuti S1 da biste prešli na sljedeći podmeni. Ako je alarm isključen, podmeniji H i I se preskaču i izlazi se iz menija podešavanja.

H: Podešavanje drugog budilnika
Kada pritisnete dugme S2, vrednost sata se menja od 0 do 23. Nakon podešavanja sata, morate pritisnuti S1 da biste otišli u podmeni I.

I: Podešavanje minuta drugog alarma
Kada pritisnete dugme S2, vrednost minuta se menja od 0 do 59. Nakon podešavanja minuta, morate pritisnuti S1 da izađete iz menija podešavanja.

Korekcija sekundi
U režimu (“MINUTE: SEKUNDNE”), morate držati pritisnuto dugme S2 da resetujete sekunde. Zatim kratko pritisnite dugme S2 da započnete odbrojavanje sekundi.

4. Opšti utisci o satu.

Pros:
+ Niska cijena
+ Jednostavna montaža, minimum dijelova
+ Zadovoljstvo samostalnog sklapanja
+ Prilično mala greška (zaostao sam nekoliko sekundi tokom dana)

Minusi:
- Ne zadržava vrijeme nakon isključenja
- Nedostatak bilo koje druge dokumentacije osim dijagrama (ovaj članak je djelimično riješio ovaj nedostatak)
- Firmver u mikrokontroleru je zaštićen od čitanja

5. Dodatno:

1) Na beskrajnim prostranstvima interneta pronašao sam uputstva za ovaj sat na engleskom i preveo ga na ruski. Možete ga preuzeti

Za one koji imaju barem malo znanja o mikrokontrolerima i žele kreirati jednostavan i koristan uređaj za dom, nema ništa bolje od sklopa sa LED indikatorima. Takva stvar može ukrasiti vašu sobu, ili se može koristiti kao unikatan ručno rađen poklon, od čega će dobiti dodatnu vrijednost. Kolo radi kao sat i kao termometar - režimi se prebacuju dugmetom ili automatski.

Električni dijagram domaćeg sata s termometrom

Mikrokontroler PIC18F25K22 brine o svim obradama podataka i vremenu, kao i dijeljenju ULN2803A Ostaje samo koordinirati njegove izlaze sa LED indikatorom. Mali čip DS1302 radi kao tajmer preciznih sekundarnih signala, njegova frekvencija je stabilizirana standardnim kvarcnim rezonatorom od 32768 Hz. Ovo donekle komplikuje dizajn, ali nećete morati stalno prilagođavati i podešavati vrijeme, koje će neizbježno biti odgođeno ili požureno ako se snađete sa slučajnim nepodešenim kvarcnim rezonatorom od nekoliko MHz. Ovakav sat više je jednostavna igračka nego visokokvalitetan, precizan sat.

Ako je potrebno, senzori temperature mogu se nalaziti daleko od glavne jedinice - povezani su s njom trožičnim kabelom. U našem slučaju jedan temperaturni senzor je ugrađen u blok, a drugi se nalazi spolja, na kablu dužine oko 50 cm.Kada smo probali kabl od 5 m, takođe je funkcionisao savršeno.

Displej sata je napravljen od četiri velika LED digitalna indikatora. Prvobitno su bile obične katode, ali su u konačnoj verziji promijenjene u zajedničku anodu. Možete instalirati bilo koje druge, a zatim jednostavno odaberite otpornike za ograničavanje struje R1-R7 na osnovu potrebne svjetline. Mogli biste ga postaviti na zajedničku ploču sa elektronskim dijelom sata, ali ovo je mnogo univerzalnije - odjednom poželite staviti jako veliki LED indikator kako bi se mogli vidjeti sa velike udaljenosti. Primjer takvog dizajna uličnog sata je ovdje.

Sama elektronika počinje od 5 V, ali da bi LED diode blistale potrebno je koristiti 12 V. Iz mreže se napajanje napaja preko adaptera step-down transformatora do stabilizatora 7805 , koji proizvodi napon od striktno 5 V. Obratite pažnju na malu zelenu cilindričnu bateriju - služi kao rezervni izvor napajanja u slučaju nestanka mreže od 220 V. Nije potrebno uzimati je na 5 V - litijum-jonska ili Ni-MH baterija za 3,6 volti je dovoljna.

Za kućište možete koristiti različite materijale - drvo, plastiku, metal ili integrirati cijelu strukturu domaćeg sata u gotov industrijski, na primjer, od multimetra, tjunera, radio prijemnika i tako dalje. Napravili smo ga od pleksiglasa jer se lako obrađuje i omogućava vam da vidite unutrašnjost tako da svi mogu vidjeti - ovaj sat je sastavljen vlastitim rukama. I što je najvažnije, bio je dostupan :)

Ovdje možete pronaći sve potrebne detalje o predloženom dizajnu domaćeg digitalnog sata, uključujući dijagram kola, raspored PCB-a, PIC firmver i

Postoji mnogo načina da sastavite elektronski sat vlastitim rukama: dijagrami su široko predstavljeni u literaturi i na Internetu. Većina modernih implementacija bazirana je na mikrokontrolerima. Implementacija ovakvih projekata često zahtijeva opsežne praktične vještine i teoretsko znanje iz područja elektronike: sposobnost korištenja specijaliziranog softvera, kreiranje tiskanih ploča kod kuće pomoću jetkanja željeznog klorida i dobrog lemljenja. Također morate imati razne alate i potrepštine.

Međutim, postoji jednostavan i pristupačan način da sastavite elektronski sat vlastitim rukama kod kuće: koristite Arduino platformu. To je softverski i hardverski kompleks posebno dizajniran za podučavanje osnova programiranja i elektronike. Uz pomoć Arduina, svatko, čak i bez posebne prethodne obuke, može napraviti elektronički sat vlastitim rukama: dijagrami kola, inženjerski programi, pa čak i lemilica nisu potrebni!

Povezivanje svih elektronskih komponenti vrši se na posebnoj kontaktnoj („bez lemnoj“) matičnoj ploči, što eliminira rizik od opekotina, posjekotina i drugih ozljeda - stoga možete raditi s Arduino dizajnerom zajedno s djecom. Vizualni način predstavljanja dijagrama strujnog kola pomoći će vam da izbjegnete greške pri sastavljanju uređaja.

Korak 1. Lista komponenti

Za sastavljanje jednostavnog sata na LED matricama trebat će vam samo nekoliko jeftinih komponenti:

  • Arduino platforma. Najjednostavniji modeli će raditi - ili Micro;
  • contact breadboard;
  • Spojne žice za matičnu ploču;
  • Adafruit DS3231 modul sata realnog vremena;
  • LED matrični modul 32x8 MAX7219;
  • dva dugmeta.

Takođe će vam trebati personalni računar i USB-mini-USB kabl da biste učitali kontrolni program u memoriju. To je sve - nisu potrebni lemilica, skidači izolacije, noževi za montažu i drugi profesionalni alati: sve se operacije izvode ručno. Možda je u nekim slučajevima prikladnije koristiti pincetu, ali možete i bez nje.


Korak 2. Sastavljanje elektronskog kola

Krug elektronskog sata s LED displejom pomoću Arduina činit će se prilično jednostavnim čak i za neiskusne radio amatere. Za montažu je potrebno samo nekoliko žica. Tablica za povezivanje:

Arduino modul → 32x8 MAX7219 LED matrica

Arduino modul → Adafruit DS3231 sat realnog vremena

Arduino modul → dugmad

D2 - dugme 1

D3 - dugme 2

Drugi pin dugmadi je spojen na GND.

Samo trebate obratiti pažnju i zapamtiti kako su kontaktne rupe na matičnoj ploči međusobno povezane. Sljedeći dijagram ilustruje način unutrašnjeg povezivanja kontaktnih rupa:


Dva reda (1 i 4) sa obe strane su povezana horizontalno - obično se koriste kao +5V strujni vod i GND uzemljenje. Svi unutrašnji kontakti (2 i 3) su zatvoreni okomito. U ovom slučaju, ploča je podijeljena i vertikalno i horizontalno na dva simetrična dijela neovisna jedan o drugom. Ovo omogućava, na primjer, sklapanje dva različita uređaja na jednoj ploči.

Dijagram elektronskog sata sa LED indikacijom, kao i raspored elemenata na ploči, prikazan je na ilustraciji:

Pažljivo provjerite da li su svi priključci u skladu s prikazanim dijagramom. Također provjerite jesu li provodnici dobro pričvršćeni u kontaktne rupe na ploči.


Korak 3. Arduino firmver

Nakon što je sastavljanje i testiranje kola završeno, možete početi učitavati kontrolni program (ili "firmware") u Arduino memoriju.


Da biste to učinili, morate instalirati besplatno službeno razvojno okruženje - . Trebat će vam i izvorni kod projekta koji možete preuzeti ispod u arhivi sa svim bibliotekama i skicom, a ako vam je potrebna samo skica, možete je zasebno kopirati:

//uključi biblioteke: #include "LedControl.h" #include // Biblioteka fontova #include // DS1307 sat #include "RTClib.h" // DS1307 sat #include // Biblioteka dugmadi Aleksandra Breviga // Setup LED Matrix // pin 12 je povezan na DataIn na displeju // pin 11 je povezan sa CLK na displeju // pin 10 je povezan sa LOAD na displeju LedControl lc = LedControl(6, 5, 4, 4); //postavlja 3 pina kao 12, 11 & 10 i zatim postavlja 4 prikaza (maksimalno 8 prikaza) //globalne varijable intenzitet bajta = 7; // Zadani intenzitet/svjetlina (0-15) bajt clock_mode = 0; // Zadani način rada sata. Default = 0 (basic_mode) bool random_mode = 0; // Definiraj nasumični način rada - mijenja tip prikaza svakih nekoliko sati. Zadano = 0 (isključeno) bajt old_mode = clock_mode; // Pohranjuje prethodni način rada sata, tako da ako idemo na datum ili bilo šta drugo, znamo na koji način da se vratimo nakon toga. bool ampm = 0; // Definirajte vrijeme od 12 ili 24 sata. 0 = 24 sata. 1 = 12 sati bajta change_mode_time = 0; // Zadržava sat kada će se način sata sljedeće promijeniti ako je u nasumičnom modu. nepotpisano dugo kašnjenje = 500; // Uvijek čekamo malo između ažuriranja prikaza int rtc; // Sadrži izlaz sata realnog vremena char days = ( "Ned", "Mon", "Uto", "Wed", "Thu", "Fri", "Sat" ); //dnevni niz - koristi se u režimima slajdova, basic_mode i jumble (DS1307 daje 1-7 vrijednosti za dan u sedmici) char daysfull = ( "Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "Četvrtak ", "petak", "subota" ); char sufiks = ("st", "nd", "rd", "th" ); // niz datumskih sufiksa, koji se koristi u režimima slajdova, basic_mode i jumble. npr. 1st 2nd ... //definirajte konstante #define NUM_DISPLAY_MODES 3 // Načini prikaza brojeva (sa nulom kao prvim modom) #define NUM_SETTINGS_MODES 4 // Načini podešavanja brojeva = 6 (sa nulom kao prvim modom) # define SLIDE_DELAY 20 // Vrijeme u milisekundama za efekat slajda po karakteru u režimu slajda. Učinite ovo višim za sporiji efekat #define cls clear_display // Obriši prikaz RTC_DS1307 ds1307; // Kreiraj RTC objekat Button buttonA = Button(2, BUTTON_PULLUP); // Dugme za podešavanje A (koristeći biblioteku dugmadi) Button buttonB = Button(3, BUTTON_PULLUP); // Dugme za podešavanje B (koristeći biblioteku dugmadi) void setup() ( digitalWrite(2, HIGH); // uključite pullup otpornik za dugme na pinu 2 digitalWrite(3, HIGH); // uključite pullup otpornik za dugme na pinu 3 digitalWrite(4, HIGH); // uključite pullup otpornik za dugme na pinu 4 Serial.begin(9600); //pokreni serijski //inicijalizujemo 4 matrična panela //već smo postavili broj uređaja kada smo kreirali the LedControl int devices = lc.getDeviceCount(); //moramo pokrenuti sve uređaje u petlji za (int address = 0; adresa< 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--) ( za (adresa bajta = 0; adresa< 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 >> red)) plot(x + col, y + row, 1); else plot(x + kolona, ​​y + red, 0); ) ) ) void putnormalchar(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 // } 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; // strelica za biranje načina rada sata ) else if (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 >> red)) ( // samo 7 redova. plot(x + col, y + red, 1); ) else ( plot(x + col, y + row, 0); ) //) ) ) ) //small_mode //prikaži vrijeme u malim 3x5 znakova sa sekundama display void small_mode() ( char textchar; // 16 znakova na ekranu bajt mins = 100; //mins bajt sekundi = rtc; //sekundi bajt old_secs = secs; / /drži staru vrijednost sekunde - od posljednjeg trenutka kada su sekunde ažurirane na prikaz - koristi se za provjeru da li su sekunde promijenjene cls(); //pokreni glavnu petlju sata sve dok run_mode vraća true while (run_mode()) ( get_time(); / /check for button press if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); return; ) //ako su se sekunde promijenjene, ažurirajte ih na zaslonu secs = rtc; if (secs != old_secs) ( //secs char bafer; itoa(secs, buffer, 10); //fix - u suprotnom, ako broj ima vodeću nulu, npr. "03" sec, itoa to pokriva znakovima s razmakom "3" ako (sek< 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 ->1:00 u 12-satnom režimu. //izvršimo konverziju 12/24 sata ako je ampm postavljen na 1 bajt sati = rtc; if (sati > 12) ( sati = sati - ampm * 12; ) if (sati< 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) ( sati = sati - ampm * 12; ) if (sati< 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) ( sati = sati - ampm * 12; ) if (sati< 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 ->Februar 01, tada se jedna cifra ne mijenja ako ((digits_old != digits_new) || (digits_old != digits_new)) ( //promijeni prikazani dan. Petlja ispod prolazi kroz svaki od 3 znaka zauzvrat, npr. "MON" za (bajt dan_znak = 0; dan_znak<=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--)( if (stare_cifre[i] != nove_cifre[i]) ( for (byte seq = 0; seq<=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" && || (trenutni_c >= "a" && trenutni_c<= "z")) { // current_c &= 0x1F; // A-Z maps to 1-26 // } if (current_c >= "A" && struja_c<= "Z") { current_c &= 0x1F; // A-Z maps to 1-26 } else if (current_c >= "a" && trenutni_c<= "z") { current_c = (current_c - "a") + 41; // A-Z maps to 41-67 } else if (current_c >= "0" && trenutni_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 == ">") ( current_c = 30; // clock_mode selektor strelica ) bajt curr_char_row_max = 7 - sekvenca; //maksimalni broj redova za crtanje je 6 - broj sekvence bajt start_y = sekvenca; //y pozicija za početak - je ista kao Uključujemo ovu svaku petlju // iscrtavamo svaki red do maksimuma reda (izračunato iz broja sekvence) za (bajt curr_char_row = 0; curr_char_row<= 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)) plot(x + col, y + start_y, 1); // grafički prikaz na else plot(x + col, y + start_y, 0); //drugo je dijagram ugašen ) start_y++;//dodaj jedan na y tako da povučemo sljedeći red jedan dolje ) ) //nacrtaj praznu liniju između znakova ako je niz između 1 i 7. Ako to ne učinimo, dobićemo ostaci trenutnih znakova posljednja pozicija koja je ostala na ekranu ako (sekvenca >= 1 && sekvenca<= 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) ( //razradi tačkice char bajtova; //if (new_c >= "A" && new_c<= "Z" || (new_c >= "a" && novi_c<= "z")) { // new_c &= 0x1F; // A-Z maps to 1-26 //} if (new_c >= "A" && new_c<= "Z") { new_c &= 0x1F; // A-Z maps to 1-26 } else if (new_c >= "a" && novi_c<= "z") { new_c = (new_c - "a") + 41; // A-Z maps to 41-67 } else if (new_c >= "0" && new_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; // clock_mode selektor strelica ) bajt newcharrowmin = 6 - (sekvenca - 2); //minimalni broj reda za crtanje za novi znak - ovo generiše izlaz od 6 do 0 kada se unose brojevi sekvence 2-8 Ovo je minimalni red za crtanje za novi bajt znaka start_y = 0; //y pozicija za početak - ista je kao broj sekvence. Uključujemo ga svaki red // iscrtavamo svaki red prema gore od minimuma reda (izračunato po redoslijedu ) do 6 for (bajt newcharrow = newcharrowmin; newcharrow<= 6; newcharrow++) { for (byte col = 0; col < 5; col++) { dots = pgm_read_byte_near(&myfont); if (dots & (64 >> newcharrow)) plot(x + col, y + start_y, 1); // grafički prikaz na else plot(x + col, y + start_y, 0); //drugo je dijagram ugašen ) start_y++;//dodaj jedan na y tako da crtamo sljedeći red dolje ) ) ) //ispis sata koristeći riječi umjesto brojeva void word_clock() ( cls(); char numbers = ( "jedan ", "dva", "tri", "četiri", "pet", "šest", "sedam", "osam", "devet", "deset", "jedanaest", "dvanaest", "trinaest", "četrnaest", "petnaest", "šesnaest", "sedamnaest", "osamnaest", "devetnaest"); char numberstens = ( "deset", "dvadeset", "trideset", "četrdeset", "pedeset"); //potencijalno 3 reda za prikaz char str_a; char str_b; char str_c; //bajt hours_y, mins_y; //sati i minute i pozicije za sate i minute linije bajt sati = rtc; if (sati > 12) ( sati = sati - ampm * 12; ) ako (sati< 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) ( sati = sati - 12; ) if (sati == 0) ( sati = 12; ) // podijeliti vrijednost min na dvije odvojene cifre int minsdigit = rtc % 10; bajt minsdigitten = (rtc / 10) % 10; //ako min<= 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 && min<= 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)( //provjera pritiska na dugme if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) delay(1); counter--; ) fade_down (); //ispis linije b len = 0; while (str_b) ( len++; ); //dobijemo dužinu poruke offset_top = (31 - ((len - 1) * 4)) / 2; i = 0; while (str_b[i]) ( puttinychar((i * 4) + offset_top, 1, str_b[i]); i++; ) //zadrži prikaz, ali provjeri pritisnuti tipke counter = 1000; while (counter > 0)( if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) delay(1); counter--; ) fade_down() ; //ispis reda c ako postoji. len = 0; while (str_c) (len++; ); //dobijemo dužinu poruke offset_top = (31 - ((len - 1) * 4)) / 2; i = 0; while (str_c[i]) ( puttinychar((i * 4) + offset_top, 1, str_c[i]); i++; ) brojač = 1000; while (counter > 0)( //provjera pritiska na dugme if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) delay(1); counter- -; ) fade_down(); // držite ekran prazan, ali provjerite da li su gumbi pritisnuti prije ponovnog pokretanja. brojač = 1000; while (counter > 0)( //provjera pritiska na dugme if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) delay(1); counter- -; ) ) fade_down(); ) /// poruka za pomicanje - trenutno se ne koristi - presporo. void scroll() ( char poruka = ​​("Zdravo "); cls(); bajt p = 6; //trenutni pos u stringu bajt chara = (0, 1, 2, 3, 4, 5); //chars iz niza int x = (0, 6, 12, 18, 24, 30); //xpos za svaki bajt znakova y = 0; //y pos // clear_buffer(); while (message[p] != "\ 0") ( //nacrtaj svih 6 znakova za (bajt 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+offset, 1, buffer); offset = 8; //pomak prema centru teksta ako 4 znaka) //ispis 2 znaka sufiksa puttinychar(suffixposx+offset, 1, sufiks[s ]); puttinychar(sufiksposx+4+offset, 1, sufiks[s]); kašnjenje (1000); fade_down(); //ispisati ime mjeseca //dobiti dužinu teksta u pikselima, na taj način možemo ga centrirati na displeju tako što ćemo podijeliti preostale piksele b2 i koristiti to kao pomak len = 0; while(imena mjeseci) (len++; ); pomak = (31 - ((len-1)*4)) / 2; //naš pomak za centriranje teksta i = 0; while(monthnames[i]) (puttinychar((i*4) +offset, 1, monthnames[i]); i++; ) delay(1000); fade_down(); ) //dislpay meni za promjenu načina rada sata void switch_mode() ( //zapamti način u kojem se nalazimo. Koristimo ovu vrijednost ako idemo u mod postavki, tako da se možemo vratiti iz moda postavki (6) u bilo koji način rada in. old_mode = clock_mode; char* modovi = ( "Basic", "Small", "Slide", "Words", "Setup"); bajt next_clock_mode; byte firstrun = 1; //petlja čeka na dugme (timeout nakon 35 petlje za povratak u način X) za (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; ) //ispis strelice i trenutnog naziva clock_mode na liniji jedan i ispis sljedećeg naziva clock_mode na liniji dva char str_top; //strcpy (str_top, "-"); strcpy(str_top, modovi); next_clock_mode = clock_mode + 1; if (sljedeći_clock_mode > NUM_DISPLAY_MODES + 1) ( sljedeći_clock_mode = 0; ) bajt i = 0; while (str_top[i]) ( putnormalchar(i * 6, 0, str_top[i]); i++; ) firstrun = 0; ) kašnjenje (50); ) ) //pokreni glavnu petlju sata sve dok run_mode vraća pravi bajt run_mode() ( //ako je nasumični način uključen... provjerite sat kada mijenjamo mod. if (random_mode) ( //ako vrijednost sata u modu promjene time = sati. zatim vraća false = tj. izlaz iz moda. if (change_mode_time == rtc) ( //podesite sljedeći nasumični način rada sata i vrijeme da ga promijenite set_next_random(); // izađite iz trenutnog moda. vratite 0; ) ) / /else return 1 - nastavi raditi u ovom načinu return 1; ) //postaviti sljedeći sat da će sat promijeniti način rada kada je nasumični način uključen void set_next_random() ( //postavi sljedeći sat mod sata će se promijeniti - trenutno vrijeme plus 1 - 4 sata get_time(); change_mode_time = rtc + random (1, 5); //ako je change_mode_time sada preko 23, onda ga postavite na između 1 i 3 ujutro ako (change_mode_time > 23) ( change_mode_time = random (1 , 4); ) //postavite novi način rada sata clock_mode = random(0, NUM_DISPLAY_MODES + 1); //odaberite novi nasumični režim sata ) //dislpay meni za promjenu postavki sata void setup_menu() ( char* set_modes = ( "Rndom", "24 sata", "Set", "Brght", "Exit"); if (ampm == 0) ( set_modes = ("12 sati"); ) bajt setting_mode = 0; bajt next_setting_mode; bajt prvo pokretanje = 1; //petlja čeka na dugme (timeout nakon 35 petlji za povratak u način X) 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) (setting_mode = 0; ) //ispis strelice i trenutnog naziva clock_modea na liniji jedan i ispis sljedećeg naziva clock_mode na liniji dva char str_top; strcpy(str_top, set_modes); next_setting_mode = setting_mode + 1; if (sljedeći_način_podešavanja > NUM_SETTINGS_MODES) (sljedeći_način_postavke = 0; ) bajt i = 0; while(str_top[i]) (putnormalchar(i*6, 0, str_top[i]); i++; ) firstrun = 0; ) kašnjenje (50); ) //odaberimo prekidač načina rada(setting_mode)( slučaj 0: set_random(); break; slučaj 1: set_ampm(); break; slučaj 2: set_time(); break; slučaj 3: set_intensity(); break; slučaj 4: //izlaz iz menija pauza; ) //promijeni sat iz moda 6 (postavke) nazad na onaj u kojem je bio prije clock_mode=old_mode; ) //prebacivanje nasumičnog načina rada - birajte drugačiji način sata svakih nekoliko sati void set_random())( cls(); char text_a = "Isključeno"; char text_b = "Uključeno"; bajt i = 0; //ako je nasumični način rada on , isključi ga if (random_mode)( //isključi nasumični način rada random_mode = 0; //ispiši poruku na displeju while(text_a[i]) ( putnormalchar((i*6), 0, text_a[i] ) ; i++; ) ) else ( //uključiti nasumični način rada. random_mode = 1; //podešavanje sata će promijeniti set_next_random(); //ispisati poruku na displeju while(text_b[i]) ( putnormalchar((i * 6), 0, text_b[i]); i++; ) ) delay(1500); //ostavite poruku na sekundu ili tako nešto ) //postavite sat na 12 ili 24 sata void set_ampm() ( // AM/ PM ili 24-satni način rada sata - okrenite bit (čini 0 u 1, ili 1 u 0 za ampm mod) ampm = (ampm ^ 1); cls(); ) //promijenite intenzitet ekrana intensity void set_intensity() ( cls() ; byte i = 0; char text = "Bright"; while(text[i]) ( puttinychar((i*4)+4, 0, text[i]); i++; ) //sačekajte unos gumba dok ( ! buttonA.uniquePress()) (traka nivoa (0,6,(intenzitet*2)+2,2); //prikazujemo nivo intenziteta kao traku while (buttonB.isPressed()) ( if(intensity == 15) ( intenzitet = 0; cls (); ) else ( intenzitet++; ) //ispis nove vrijednosti i = 0; while(text[i]) ( puttinychar((i*4)+4, 0, text[i]); i++; ) //prikaži nivo intenziteta kao traku nivoa (0,6,(intensity*2)+ 2,2); //promijenite postavku svjetline na displejima za (adresa bajta = 0; adresa< 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); */ }

Sada, da biste dovršili rad na uređaju, trebate izvršiti samo nekoliko jednostavnih operacija:


Sastavljanje programskog koda i njegovo dalje učitavanje u memoriju mikrokontrolera će potrajati neko vrijeme, obično ne više od jedne minute. Uspješan završetak operacije bit će prijavljen na Arduino IDE konzoli. Nakon čega ostaje samo da ponovo pokrenete Arduino pomoću tipke Reset na uređaju - jednostavan sat na LED matricama je spreman!

Spreman sat na Arduinu

Sat se podešava pomoću dva dugmeta. Uređaj podržava 12- i 24-časovne formate vremena, prikazuje datum i dan u sedmici i prikazuje vrijeme sa ili bez sekundi. Također je moguće promijeniti svjetlinu LED dioda.


Vjerovatno ćete u budućnosti poželjeti dodati još funkcija (na primjer, termometar) ili instalirati uređaj u kućište po vlastitom dizajnu - dobri rezultati se mogu postići proizvodnjom na mašinama za lasersko sečenje. Ali sada možete sa sigurnošću reći da ste vlastitim rukama sastavili punopravni elektronski sat!

Sat sa sedmosegmentnim LED indikatorom na K145IK1911 čipu

Istorija pojavljivanja ovih satova na sajtu malo se razlikuje od drugih dijagrama na sajtu.

Običan je slobodan dan, odem do pošte, preturam, i naiđe naš čitalac Fedorenko Evgeniy, poslao dijagram sata, sa opisom i svim fotografijama.

Ukratko o šemi kolo elektronskog sata njihov ruke završeno na čipu K145IK1911, a vrijeme je prikazano na sedmosegmentnim LED indikatorima. I njegov članak. Pogledajmo sve.

Dijagram sata:


Da biste uvećali sliku, jednostavno kliknite na nju da biste je uvećali i sačuvajte računar.

Nedavno sam se suočio sa zadatkom da ili kupim novi sat ili sam sastavim novi. Zahtjevi za sat bili su jednostavni - displej bi trebao prikazivati ​​sate i minute, trebao bi postojati budilnik, a kao uređaj za prikaz treba koristiti sedmosegmentne LED indikatore. Nisam želio da gomilam gomilu logičkih čipova, i nisam htio da se miješam u programiranje kontrolera. Izbor je napravljen na razvoju sovjetske elektronske industrije - čip K145IK1901.

U to vrijeme nije bio u trgovini, ali postojao je analog, u 40-pinskom paketu - K145IK1911. Naziv pinova ovog mikrokola se ne razlikuje od prethodnog, razlika je u numeraciji.



Loša strana ovih mikro kola je da rade samo sa vakuum fluorescentnim indikatorima. Da bi se osiguralo spajanje sa LED indikatorom, bilo je potrebno izgraditi odgovarajući krug pomoću poluvodičkih prekidača.

Kao string driveri – J1-J7 mogu se koristiti tranzistori KT3107 sa slovnim indeksom I, A, B. Za drajvere za odabir segmenata D1-D4, KT3102I, ili KT3117A, KT660A, kao i sve druge sa maksimalnim naponom kolektor-emiter od najmanje 35 V i kolektorskom strujom od koristit će se najmanje 100 mA. Struja segmenata indikatora regulirana je otpornicima u kolektorskim krugovima rednih drajvera.



Tačka koja treperi frekvencijom od 1 Hz koristi se za razdvajanje cifara sati i minuta.

Ova frekvencija je prisutna na Y4 pinu nakon početka mjerenja vremena. Ova šema takođe pruža mogućnost prikazivanja na displeju umesto sati i minuta – minuta i sekundi, respektivno. Prelazak na ovaj način rada vrši se pritiskom na tipku “Sec.” Povratak na prikaz sata i minuta vrši se nakon pritiska na tipku „Povratak“. Ovaj čip pruža mogućnost istovremenog postavljanja dva budilnika, ali se u ovoj šemi drugi budilnik ne koristi kao nepotreban. Kao emiter zvuka koristi se piezo visokotonac sa ugrađenim generatorom, napona napajanja od 12V. Signal budilnika se uklanja sa pina Y5 mikrokola. Da bi se dobio isprekidan zvuk, signal se modulira na frekvenciji od 1 Hz, koja se koristi za označavanje drugog ritma (tačka). Za detaljniju studiju funkcionalnosti mikrokola K145IK1901(11) možete pogledati dokumentaciju koja se nedavno lako može pronaći na Internetu. Mikrokolo mora biti napajano negativnim naponom od -27V±10%. Prema provedenim eksperimentima, mikrokolo ostaje u funkciji čak i pri naponu od -19V, a točnost sata uopće nije pogođena.

Dijagram sata je prikazan na gornjoj slici. U krugu su korišteni čip otpornici standardne veličine 1206, što omogućava značajno smanjenje dimenzija uređaja. Pogodni su bilo koji sedmosegmentni indikatori sa zajedničkom anodom.

E, to je za sada kraj priče. Biće dalje razvijana i dopunjavana. I izražavam svoju zahvalnost njenom autoru, Evgeniju Fedorenku, za sva pitanja i takođe dajem njegov e-mail. Pišite na Ova adresa el. pošte je zaštićena od spambotova. Morate imati omogućen JavaScript da biste ga vidjeli.

Sat sa LED pozadinskim osvetljenjem i pulsirajućom minutnom kazaljkom na Arduino mikrokontroleru
Ovaj jedinstveni sat sa LED pozadinskim osvetljenjem i pulsirajućom minutnom kazaljkom napravljen je pomoću TLC5940 PWM kontrolera. Njegov glavni zadatak je da proširi broj PWM modulacijskih kontakata. Još jedna karakteristika ovog sata je da je analogni voltmetar pretvorio u uređaj koji mjeri minute. Da biste to učinili, nova skala je odštampana na standardnom štampaču i zalijepljena na staru. Kao takav, 5. minuta se ne računa, već samo tokom petog minuta brojač vremena pokazuje strelicu koja pokazuje na kraj skale (van skale). Glavna kontrola je implementirana na Arduino Uno mikrokontroleru.

Kako bi se osiguralo da pozadinsko osvjetljenje sata ne svijetli previše jako u mračnoj prostoriji, implementirano je kolo za automatsko podešavanje svjetline ovisno o osvjetljenju (korišten je fotootpornik).

Korak 1: Potrebne komponente



Evo šta će vam trebati:

  • 5V DC analogni voltmetarski modul;
  • Arduino UNO mikrokontroler ili drugi odgovarajući Arduino;
  • Arduino ploča (proto ploča);
  • DS1307 Modul sata realnog vremena (RTC);
  • Modul sa PWM kontrolerom TLC5940;
  • Petal LED pozadinsko osvetljenje – 12 kom.;
  • Komponente za sklapanje kola za automatsku kontrolu svjetline (LDR).

Takođe, za izradu nekih drugih komponenti projekta poželjno je imati pristup 3D štampaču i mašini za lasersko sečenje. Pretpostavlja se da imate ovaj pristup, tako da će upute uključivati ​​proizvodne crteže u odgovarajućim fazama.

Korak 2: Birajte




Brojčanik se sastoji od tri dijela (sloja) izrezana na mašini za lasersko sečenje od MDF lima debljine 3 mm, koji su međusobno pričvršćeni vijcima. Ploča bez proreza (dolje desno na slici) se postavlja ispod druge ploče za postavljanje LED dioda (dolje lijevo). Zatim se pojedinačne LED diode postavljaju u odgovarajuće utore, a prednji panel se stavlja na vrh (gore na slici). Duž ruba brojčanika izbušene su četiri rupe kroz koje su sva tri dijela spojena vijcima.

  • Za testiranje performansi LED dioda u ovoj fazi, korištena je CR2032 dugmasta baterija;
  • Za pričvršćivanje LED dioda korištene su male trake ljepljive trake koje su zalijepljene na stražnju stranu LED dioda;
  • Sve LED noge su prethodno savijene u skladu s tim;
  • Ponovo su izbušene rupe duž ivica kroz koje je izvedeno zavrtnje. Ispostavilo se da je to mnogo zgodnije.

Tehnički crtež dijelova brojčanika dostupan je na:

Korak 3: Dizajnirajte krug



U ovoj fazi razvijeno je električno kolo. U tu svrhu korišteni su različiti udžbenici i vodiči. Nećemo se previše upuštati u ovaj proces; dvije datoteke ispod prikazuju gotov električni krug koji je korišten u ovom projektu.

Korak 4: Povezivanje Arduino ploče





  1. Prvi korak je da odlemite sve kontakte igle na ploči i sekcijskim pločama;
  2. Nadalje, zbog činjenice da 5V i GND napajanje koriste tolike ploče i periferni uređaji, radi pouzdanosti, dvije žice za 5V i GND su zalemljene na ploči;
  3. Zatim je pored korištenih kontakata instaliran TLC5940 PWM kontroler;
  4. Zatim se TLC5940 kontroler povezuje prema dijagramu povezivanja;
  5. Da bi se baterija mogla koristiti, RTC modul je instaliran na rubu ploče. Ako ga zalemite na sredini ploče, oznake pinova neće biti vidljive;
  6. RTC modul je spojen prema dijagramu povezivanja;
  7. Sastavljen je sklop za automatsku kontrolu svjetline (LDR), možete ga pogledati na linku
  8. Žice za voltmetar su povezane spajanjem žica na pin 6 i GND.
  9. Na kraju je zalemljeno 13 žica za LED diode (u praksi se pokazalo da je to bolje učiniti prije nego što pređete na korak 3).

Korak 5: Kod

Donji kod je kompajliran od različitih dijelova sata koji se nalaze na Internetu. U potpunosti je otklonjena greška i sada je potpuno funkcionalna, a dodani su i neki prilično detaljni komentari. Ali prije učitavanja u mikrokontroler, razmotrite sljedeće točke:

  • Prije flešovanja Arduino firmvera, morate dekomentirati red koji postavlja vrijeme:
    rtc.adjust(DateTime(__DATE__, __TIME__))
    Nakon bljeskanja kontrolera sa ovom linijom (vrijeme je podešeno), potrebno ga je ponovo prokomentirati i ponovo flešovati kontroler. Ovo omogućava RTC modulu da koristi bateriju kako bi zapamtio vrijeme ako se izgubi glavno napajanje.
  • Svaki put kada koristite "Tlc.set()" morate koristiti "Tlc.update"

Korak 6: Vanjski prsten

Vanjski prsten za sat je 3D štampan pomoću Replicator Z18 štampača. Pričvršćuje se na sat pomoću vijaka na prednjoj strani sata. Ispod je fajl sa 3D modelom prstena za štampanje na 3D štampaču.

Korak 7: Sastavljanje sata


Arduino mikrokontroler sa svom ostalom elektronikom bio je pričvršćen za stražnji dio sata pomoću vijaka i matica kao odstojnika. Zatim sam spojio sve LED diode, analogni voltmetar i LDR na žice koje su prethodno bile zalemljene na ploču. Sve LED diode su međusobno povezane jednom nogom i spojene na VCC pin na TLC5940 kontroleru (komad žice je jednostavno zalemljen u krug).

Sve ovo do sada nije dobro izolovano od kratkih spojeva, ali rad na tome će se nastaviti u budućim verzijama.