Ceasuri pe matrice RGB - Dezvoltarea și modificarea circuitelor. LED-uri strălucitoare angro, pentru ceasuri de casă pe matrice LED Ceasuri Radiocat pe matrice LED

Pe tema ceasurilor de casă, am promis că voi continua, așa că iată. Ceas pe matrice LED de casă.
, Și

Acest lucru a fost făcut pentru a încerca să se realizeze ceasuri cu segmente, în ritmul a trei LED-uri pe segment 7*4*3=84+2=86 bucăți

Cam cam asa:

Am vrut să încerc culori diferite și cu siguranță luminoase (cum ar putea fi altfel?)

Din acest motiv, loturile de 100 de piese mi s-au potrivit destul de bine, mai ales ca pretul este destul de rezonabil si am mai comandat din acelasi magazin sa am numerele facute in culori diferite pentru a putea compara culorile pe un singur display - care ar fi mai frumos și așa mai departe - glumesc... :)

Produsul a fost comandat și plătit 20 august 2016, și a ajuns 15 septembrie 2016, după standardele noastre, destul de repede. DAR! LED-uri roșii - nu au ajuns! La sfârșitul perioadei de protecție a cumpărătorului s-a deschis un litigiu și vânzătorul a returnat banii. A fost doar păcat să-mi pierd timpul...

Produsul a sosit într-un plic de corespondență standard cu bule galbene, LED-urile în sine au fost ambalate într-o pungă de plastic separată, numărul de piese albastre și verzi a fost puțin mai mare de 100 (nu îmi amintesc exact acum, dar îmi amintesc că au existat încă 4-5 bucăți)

Toate funcționează (adică strălucitoare)

Cele care erau multicolore erau ambalate în pungi separate, pe care era marcată cu un marker culoarea R G B W Y - culoarea se potrivea peste tot și, de asemenea, 2-3 în plus - s-a creat impresia că probabil așa a fost pentru toată lumea, dar mai târziu Eram convins că nu a fost întotdeauna cazul, ci se întâmplă invers...

Dacă nu ar fi fost sticlă roșie, vânzătorului i s-ar fi putut da un A+ gras pentru non-lacomie.

Pe de altă parte, banii au fost returnați - problema este timpul pierdut și a trimis și o scrisoare în care scria că îmi returnează banii ȘI, iar dacă a ajuns mărfurile, mi-a cerut să-i returnez această sumă.

Verbatim:

Bună, prietene, acum sunt o rambursare, atunci când primiți un pachet, vă rog să-mi returnați banii, vă rog să-mi dați o laudă de cinci stele.

Către care a trebuit să trimită o scrisoare că aceasta nu era LUI bani, dar pur și simplu mi-i returnează în urma unei dispute MELE bani, pentru că Nu am primit niciodată bunurile lui și, în același timp, am pierdut mult timp în așteptarea bunurilor lui

Apropo, când au sosit toate celelalte comenzi de la el, 10 zile mai târziu, i-am scris spunându-i că sunt îngrijorat pentru că... este ciudat - toată lumea a venit, dar una dintre comenzi nu a sosit

La care a răspuns sec, fără niciun „bună prietene”, „încă nu au trecut 60 de zile”

Și apoi deodată a devenit „prieten” și părea că și-a luat banii...

Dar, în general - vânzătorul își îndeplinește îndatoririle, răspunde la scrisori, mărfurile trimise au doar emoții pozitive, a returnat banii pentru ceea ce nu a fost trimis - totul este conform REGULUI

Ei bine, acum despre motivul pentru care a fost achiziționat

Ceasuri de casă pe matrice LED de casă

Există multe modalități de a asambla un ceas electronic cu propriile mâini: diagramele sunt prezentate pe scară largă în literatură și pe Internet. Majoritatea implementărilor moderne se bazează pe microcontrolere. Implementarea unor astfel de proiecte necesită adesea abilități practice extinse și cunoștințe teoretice în domeniul electronicii: capacitatea de a utiliza software specializat, de a crea acasă plăci de circuite imprimate prin metoda de gravare în clorură ferică, lipire bună. De asemenea, trebuie să aveți o varietate de instrumente și consumabile.

Cu toate acestea, există o modalitate simplă și accesibilă de a asambla un ceas electronic cu propriile mâini acasă: utilizați platforma Arduino. Este un complex software și hardware special conceput pentru predarea elementelor de bază ale programării și electronicii. C folosind Arduino oricine, chiar și fără pregătire preliminară specială, poate construi un ceas electronic cu propriile mâini: nu sunt necesare scheme de circuit, programe de inginerie și chiar un fier de lipit!

Conexiunea tuturor componentelor electronice se realizează pe o placă specială de contact (fără lipire), care elimină riscul de arsuri, tăieturi și alte răni - prin urmare, puteți lucra cu designerul Arduino împreună cu copiii. O modalitate vizuală de prezentare a unei scheme de circuit vă va ajuta să evitați greșelile la asamblarea dispozitivului.

Pasul 1. Lista componentelor

Pentru a asambla un ceas simplu pe matrice LED, veți avea nevoie doar de câteva componente ieftine:

  • Platforma Arduino. Cele mai simple modele vor face - sau Micro;
  • contact breadboard;
  • fire de conectare pentru panou;
  • Modul de ceas în timp real Adafruit DS3231;
  • Modul matrice LED 32x8 MAX7219;
  • doi nasturi.

Veți avea nevoie, de asemenea, de un computer personal și de un cablu USB-mini-USB pentru a încărca programul de control în memorie. Asta este tot - nu sunt necesare un fier de lipit, decapatoare de izolare, cuțite de montare și alte instrumente profesionale: toate operațiunile sunt efectuate manual. Poate că în unele cazuri este mai convenabil să folosiți pensete, dar puteți face fără ea.


Pasul 2. Asamblarea circuitului electronic

Sistem ceas electronic cu indicarea LED folosind Arduino, chiar și pentru radioamatorii fără experiență va părea destul de simplu. Pentru asamblare sunt necesare doar câteva fire. Tabel de conectare:

Modul Arduino → matrice LED 32x8 MAX7219

Modul Arduino → Ceas în timp real Adafruit DS3231

Modul Arduino → butoane

D2 - butonul 1

D3 - butonul 2

Al doilea pin al butoanelor este conectat la GND.

Trebuie doar să acordați atenție și să vă amintiți modul în care găurile de contact de pe placa de breadboard sunt conectate între ele. Următoarea diagramă ilustrează metoda de conectare internă a găurilor de contact:


Două rânduri (1 și 4) de pe ambele părți sunt scurtcircuitate orizontal - sunt de obicei folosite ca linie de alimentare +5V și masă GND. Toate contactele interne (2 și 3) sunt închise vertical. În acest caz, placa de circuit este împărțită atât pe verticală, cât și pe orizontală în două părți simetrice independente una de cealaltă. Acest lucru permite, de exemplu, asamblarea a două dispozitive diferite pe o singură placă.

Schema unui ceas electronic cu indicație LED, precum și aranjarea elementelor pe placa de circuite, sunt prezentate în ilustrație:

Verificați cu atenție dacă toate conexiunile sunt conforme cu schema prezentată. De asemenea, asigurați-vă că conductorii sunt bine fixați în orificiile de contact ale plăcii de circuite.


Pasul 3. Firmware-ul Arduino

Odată ce asamblarea și testarea circuitului sunt finalizate, puteți începe să încărcați programul de control (sau „firmware”) în memoria Arduino.


Pentru a face acest lucru, trebuie să instalați mediul de dezvoltare oficial gratuit - . Veți avea nevoie și de codul sursă al proiectului, pe care îl puteți descărca mai jos în arhiva cu toate bibliotecile și o schiță, iar dacă aveți nevoie doar de o schiță, o puteți copia separat:

//include biblioteci: #include "LedControl.h" #include // Biblioteca de fonturi #include // Ceas DS1307 #include „RTClib.h” // Ceas DS1307 #include // Biblioteca de butoane de Alexander Brevig // Setup LED Matrix // pinul 12 este conectat la DataIn de pe afișaj // pinul 11 ​​este conectat la CLK de pe afișaj // pinul 10 este conectat la LOAD de pe afișaj LedControl lc = LedControl(6, 5, 4, 4); //setează cei 3 pini ca 12, 11 și 10 și apoi setează 4 afișaje (maximum este de 8 afișaje) //variabile globale intensitate octet = 7; // Intensitate/luminozitate implicită (0-15) byte clock_mode = 0; // Modul de ceas implicit. Implicit = 0 (mod_de bază) bool mod_aleatoriu = 0; // Definiți modul aleatoriu - schimbă tipul de afișare la fiecare câteva ore. Implicit = 0 (off) byte old_mode = clock_mode; // Stochează modul de ceas anterior, așa că dacă mergem la data sau orice altceva, știm la ce mod să ne întoarcem după. bool ampm = 0; // Definiți timpul de 12 sau 24 de ore. 0 = 24 de ore. 1 = 12 ore byte change_mode_time = 0; // Menține ora când modul ceas se va schimba următoarea dacă este în modul aleatoriu. timp de întârziere lung nesemnat = 500; // Așteptăm mereu puțin între actualizări ale afișajului int rtc; // Ține în timp real ceasul de ieșire char days = ( "Sun", "Lun", "Tue", "Wed", "Thu", "Fri", "Sat" ); //day array - folosit în modurile slide, basic_mode și jumble (DS1307 scoate 1-7 valori pentru ziua săptămânii) char daysfull = ( „duminică”, „luni”, „marți”, „miercuri”, „joi „, „Vineri”, „Sâmbătă” ); sufixul char = ("st", "nd", "rd", "th" ); //matrice de sufixe de dată, folosită în modurile slide, basic_mode și jumble. e,g, 1st 2nd ... //definiți constantele #define NUM_DISPLAY_MODES 3 // Moduri de afișare a numărului (contingent zero ca prim mod) #define NUM_SETTINGS_MODES 4 // Number settings modes = 6 (conting zero ca primul mod) # define SLIDE_DELAY 20 // Timpul în milisecunde pentru efectul de diapozitiv per caracter în modul de diapozitiv. Faceți acest lucru mai mare pentru un efect mai lent #define cls clear_display // Clear display RTC_DS1307 ds1307; // Creați obiect RTC Buton buttonA = Button(2, BUTTON_PULLUP); // Buton de configurare A (folosind biblioteca de butoane) Buton buttonB = Button(3, BUTTON_PULLUP); // Configurați butonul B (folosind biblioteca de butoane) void setup() ( digitalWrite(2, HIGH); // pornește rezistența de pullup pentru butonul de pe pinul 2 digitalWrite (3, HIGH); // pornește rezistența de pullup pentru butonul de pe pin 3 digitalWrite(4, HIGH // pornește rezistența de pullup pentru butonul de pe pinul 4 Serial.begin(9600) //start serial //inițializam cele 4 panouri matrice //am setat deja numărul de dispozitive; dispozitivele LedControl int = lc.getDeviceCount( //trebuie să inițiază toate dispozitivele într-o buclă pentru (int adresa = 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--) (pentru (adresa octet = 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 >> rând)) plot(x + col, y + rând, 1);<= "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 == ">else plot(x + col, y + rând, 0);<= -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 >) ) ) void putnormalchar(byte x, byte y, char c) (byte puncte; // dacă (c >= "A" && c<= 31) && (y >") ( c = 30; // săgeată selector mod_ceas ) altfel dacă (c >= -80 && c<= 7)){ if (dots & (64 >= 0) && (x< 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 = 0) && (y> rând)) ( // doar 7 rânduri. plot(x + col, y + row, 1); ) else ( plot(x + col, y + row, 0); ) //) ) ) ) //small_mode //afișează timpul în caractere mici de 3x5 cu secunde display void small_mode() ( char textchar; // cele 16 caractere de pe afișaj byte mins = 100; //mins byte secs = rtc; //secunde byte old_secs = secs; // / deține valoarea vechii secunde - de la ultima dată când secundele au fost actualizate o afișare - folosit pentru a verifica dacă secundele s-au schimbat cls( //run bucla principală a ceasului atâta timp cât run_mode returnează true while (run_mode()) ( get_time(); /); /verificați apăsarea butonului if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); return; ) //dacă secundele s-au schimbat, actualizați-le pe afișaj secs = rtc; if (secs != old_secs) ( //secs char buffer; itoa (secs, buffer, 10); //fix - ca altfel, dacă num are zero inițial, de exemplu "03" secs, itoa acoperă acest caracter cu spațiu "3". dacă (sec< 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 stânga mâna „1” a afișajului când rulăm de la 12:59 -> 1:00 am în modul 12 ore.< 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 >//efectuează o conversie de 12/24 de ore dacă ampm este setat la 1 octet ore = rtc;< 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 ->dacă (ore > 12) ( ore = ore - ampm * 12; ) dacă (ore<=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 >noul<=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 >valorile min = rtc;<= "z")) { // current_c &= 0x1F; // A-Z maps to 1-26 // } if (current_c >ore = rtc;<= "Z") { current_c &= 0x1F; // A-Z maps to 1-26 } else if (current_c >//ajustați orele de ampm setate la modul 12 ore dacă (ore > 12) ( ore = ore - ampm * 12; ) dacă (ore<= "z") { current_c = (current_c - "a") + 41; // A-Z maps to 41-67 } else if (current_c >12) ( ore = ore - ampm * 12; ) dacă (ore<= "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 == ">01 februarie, atunci cifra nu se schimbă dacă ((digits_old != digits_new) || (digits_old != digits_new)) ( //modifică ziua afișată. Bucla de mai jos parcurge pe rând fiecare dintre cele 3 caractere, de exemplu, „MON” pentru (octet day_char = 0; day_char<= 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); //plot condus pe else plot(x + col, y + start_y, 0); //altfel plotul este oprit ) start_y++;//adăugați unul la y, astfel încât să desenăm următorul rând unul în jos ) ) //desenați o linie goală între caractere dacă secvența este între 1 și 7. Dacă nu facem acest lucru, obținem rămășițele caracterelor curente ultima poziție rămasă pe afișaj dacă (secvență >= 1 && secvență<= 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) ( //elaborați punctele de octet de caractere; //dacă (new_c >= "A" && new_c<= "Z" || (new_c >= "a" && new_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" && new_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 selector arrow ) byte newcharrowmin = 6 - (secvență - 2); //minimumm row num to draw for new char - aceasta generează o ieșire de la 6 la 0 atunci când se furnizează numerele de secvență 2-8 . Acesta este rândul minim de desenat pentru noul octet de caractere start_y = 0 //y poziție pentru a începe - este același cu numărul de secvență ) ) până la 6 pentru (octet 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); //plot condus pe else plot(x + col, y + start_y, 0); //altfel plotul a fost oprit ) start_y++;//adăugați unul la y astfel încât să desenăm următorul rând unul în jos ) ) ) //printați un ceas folosind cuvinte mai degrabă decât numere void word_clock() ( cls(); char numbers = ( "unul) „, „doi”, „trei”, „patru”, „cinci”, „șase”, „șapte”, „opt”, „nouă”, „zece”, „unsprezece”, „doisprezece”, „treisprezece”, „paisprezece”, „cincisprezece”, „șaisprezece”, „șaptesprezece”, „optsprezece”, „nouăsprezece” ); //potențial 3 linii pentru a afișa char str_c //byte hours_y, mins_y și poziții pentru ore și min. ore = rtc;< 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) ( ore = ore - 12; ) if (ore == 0) ( ore = 12; ) //divizează valoarea minilor în două cifre separate int minsdigit = rtc % 10;<= 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 >byte minsdigitten = (rtc / 10) % 10;<= 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)( //verificați apăsarea butonului if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) delay(1); counter--; ) fade_down ();< 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)( sufixposx = 8; puttinychar(4+offset, 1, buffer); offset = 8; //offset la centrul textului dacă 4 caractere ) //printează cele 2 caractere sufix puttinychar(sufxposx+offset, 1, sufix[s ]);< 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; ) //printează săgeata și numele curent clock_mode pe linia unu și imprimă următorul clock_mode numele pe linia doi char str_top;< 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; ) //printează săgeata și numele curentului clock_mode pe linia unu și imprimă următorul clock_mode numele pe linia doi char str_top;< 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); */ }

strcpy(str_top, set_modes);


Compilarea codului programului și încărcarea în continuare a acestuia în memoria microcontrolerului va dura ceva timp, de obicei nu mai mult de un minut. Finalizarea cu succes a operațiunii va fi raportată în consola Arduino IDE. După care tot ce rămâne este să reporniți Arduino folosind butonul Reset de pe dispozitiv - un ceas simplu pe matrice LED este gata!

Ceas gata pe Arduino

Ceasul este reglat folosind două butoane. Dispozitivul acceptă formatele de oră de 12 și 24 de ore, afișează data și ziua săptămânii și afișează ora cu sau fără secunde. De asemenea, este posibilă modificarea luminozității LED-urilor.


Probabil că veți dori să adăugați mai multe funcții în viitor (de exemplu, un termometru) sau să instalați dispozitivul într-un corp de design propriu - rezultate bune pot fi obținute prin fabricarea pe mașini de tăiat cu laser. Dar acum puteți spune cu siguranță că ați asamblat un ceas electronic cu drepturi depline cu propriile mâini!

Un ceas simplu pe matrice LED. Mulți radioamatori, începători și alții, le place să „reinventeze roata” - își construiesc PROPRIILE ceasuri electronice. Nici această soartă nu m-a cruțat. Astăzi, desigur, există o mulțime de modele de ceasuri pe Internet, dar din anumite motive există doar câteva ceasuri pe matrice LED printre ele. Pe internetul vorbitor de limbă rusă am găsit doar un design complet completat și descris. În același timp, matricele LED au devenit acum mult mai ieftine, iar costul lor nu este mai mare sau chiar mai mic decât indicatorii cu șapte segmente de aceeași dimensiune. De exemplu, GNM23881AD pe care l-am folosit cu o dimensiune de 60x60 mm a fost achiziționat cu 1,5 euro (3 indicatoare costă 4,5 euro), la acești bani abia se pot cumpăra patru indicatoare cu șapte segmente de aceleași dimensiuni. Dar pe indicatorul matricei pot fi plasate mult mai multe informații. Pe lângă numere, pot afișa orice litere, semne și, cu ajutorul unei linii târâtoare, și text.

Pe baza acestui lucru, a existat dorința de a construi un ceas pe matrice LED, dar pentru ca circuitul să nu fie mai complicat decât pe cele cu șapte segmente. De asemenea, mi-am dorit să fie destul de funcțional și să nu fie ca alții. Astfel s-a născut următoarea schemă.

Funcționalitatea ceasului este următoarea:

  • Numărătoare inversă, calendar, zi a săptămânii. (se iau în considerare anii bisecți, nu se realizează trecerea la ora de vară/iarnă).
  • Conservarea ceasului în caz de pierdere a puterii externe (consumul este de 15 microni).
  • Corectarea cursei + - 59,9 sec/zi, în trepte de 0,1 sec. 9 alarme. Dintre care 3 sunt „o singură dată” și 6 „permanente”, personalizabile individual în funcție de ziua săptămânii.
  • Durată reglabilă individual a semnalului sonor pentru fiecare alarmă (1-15 minute).
  • Confirmare sonoră a apăsărilor butoanelor (poate fi dezactivată).
  • Bip orar (poate fi dezactivat).
  • De la 00-00 la 08-00 nu există semnal.
  • 1 sau 2 senzori de temperatura (strada si casa).
  • Ticker personalizabil, prin care sunt afișate toate informațiile (cu excepția orei)
  • Valoarea de corecție a cursei și setările pentru „linia de rulare” sunt salvate chiar dacă energia de rezervă este pierdută.

AtMega16A a fost ales drept „inima” ceasului, datorită disponibilității, ieftinității și „legalității”. Am vrut să simplific circuitul cât mai mult posibil, astfel încât tot ce era posibil a fost atribuit controlerului. Drept urmare, am reușit să ne descurcăm cu doar două microcircuite, un controler și un registru TPIC6B595. Dacă TPIC6B595 nu este disponibil pentru cineva, atunci îl puteți înlocui cu 74HC595 + ULN2803. Ambele variante au fost încercate. Puteți încerca și să utilizați TPIC6C595, este puțin slab și s-a cam cald, dar în general a funcționat stabil. Timpul este numărat folosind timpul asincron - T2. Ceasul continuă să funcționeze chiar dacă există o pană de curent. În acest moment, cea mai mare parte a circuitului este dezactivată, iar controlerul este alimentat de o baterie, un acumulator sau un ionistor. Eram interesat să mă „joc” cu ionistorul, așa că l-am folosit. Consumul de curent pentru ore în modul standby este de 15 microni. Când este alimentat de un ionistor 1F, ceasul a „durat” patru zile. Acest lucru este suficient pentru a menține viteza în timpul întreruperilor de curent. Dacă utilizați o baterie CR2032, atunci teoretic, conform calculelor, încărcarea ar trebui să fie suficientă pentru 1,5 ani. Controlerul „ascultă” prezența tensiunii de rețea prin pinul PB.3 Acest pin este intrarea inversoare a comparatorului. Tensiunea de alimentare, prin divizorul R2-R3, este alimentată pinului PB.3, iar în stare normală este de aproximativ 1,5 V. Dacă tensiunea externă scade sub 4,1 volți, atunci tensiunea la pinul RV.3 va deveni mai mică de 1,23 volți și va fi generată o întrerupere de la comparator, iar în manipulatorul de întreruperi toate nodurile „extra” ale controlerului vor fi rotite. oprit și controlerul în sine va fi pus în stare de adormire. În acest mod, doar temporizatorul T2 continuă să funcționeze. Când apare alimentarea externă, tensiunea de pe RV.3 va crește din nou peste 1,23 V, controlerul „văzând” acest lucru va pune toate nodurile în stare de funcționare. Dacă în locul unui ionistor se folosește o baterie CR2032, atunci aceasta trebuie conectată printr-o diodă (de preferință o diodă Schottky). Anodul diodei este conectat la bateria +, iar catodul la catodul VD1. În modul normal, ecranul afișează ora în format ore-minute. Tickerul începe să ruleze la intervale de un minut. Linia de rulare afișează ziua săptămânii, data, anul, temperatura. acasă, și temp. pe strada. Tickerul este personalizabil, adică Puteți activa/dezactiva afișarea oricăruia dintre elemente. (de exemplu, opresc întotdeauna afișarea anului). Când toate elementele sunt dezactivate, tickerul nu pornește și ceasul afișează în mod constant ora curentă. 9 ceasuri cu alarmă sunt împărțite în 3 de unică folosință și 6 reutilizabile. Când activați alarmele 1-3, acestea sună o singură dată. Pentru ca acestea să funcționeze din nou, trebuie să fie pornite din nou manual. Și ceasurile deșteptătoare 4-9 sunt reutilizabile, adică. vor funcționa zilnic la ora stabilită. În plus, aceste alarme pot fi setate să se declanșeze doar în anumite zile ale săptămânii. Acest lucru este convenabil, de exemplu, dacă nu doriți ca alarma să vă trezească în weekend. Sau, de exemplu, trebuie să te trezești în zilele lucrătoare la 7-00 și joi la 8-00, iar în weekend nu ai nevoie de ceas cu alarmă. Apoi am instalat unul reutilizabil la 7-00 luni-miercuri și vineri, iar al doilea la 8-00 joi..... În plus, toate ceasurile deșteptătoare au o setare a duratei semnalului, iar dacă tu, în ordine pentru a vă trezi, nu aveți suficient semnal pentru 1 minut, apoi îl puteți crește pentru un timp de la 1 la 15 minute. Cursul se corectează o dată pe zi, la 00-00. Dacă ceasul este rapid, de exemplu, cu 5 secunde pe zi, atunci la 00-00-00 ora va fi setată la 23-59-55, dar dacă ceasul este lent, atunci la 00-00-00 ora va fi setat la 00-00-05. Pas de corectare – 0,1 sec. Corecție maximă – 59,9 sec/zi. Cu un cuarț de lucru, este puțin probabil să aveți nevoie de mai mult. Corectarea se efectuează și în modul de așteptare atunci când este alimentat de la baterie. Matricele LED pot folosi orice LED-uri 8*8 cu un catod comun. După cum sa spus deja, am folosit GNM23881AD. În principiu, puteți „asambla” o matrice din LED-uri individuale. Microcontrolerul AtMega16a poate fi înlocuit cu „vechiul” AtMega16 cu litera L. În același timp, teoretic, consumul de curent din baterie ar trebui să crească ușor. Probabil că doar AtMega16 va funcționa, dar pot apărea probleme atunci când funcționează pe baterie. Dioda D1 - de preferință orice diodă Schottky. De asemenea, funcționează cu un redresor obișnuit, dar pentru a vă proteja de diverse erori legate de faptul că o parte a circuitului este alimentată de tensiune „înainte de diodă”, iar partea „după diodă”, este mai bine să căutați Tensiunea Schottky. Tranzistorul VT1 – orice n-p-n. Ceasul este controlat de două butoane. Numărul lor ar putea fi mărit la 8 bucăți fără a adăuga alte componente, cu excepția butoanelor în sine, dar am vrut să încerc să „ieși” cu doar două. Butoanele sunt denumite în mod convențional „OK” și „PAS”. Butonul „STEP” trece de obicei la următorul element de meniu, iar butonul „OK” modifică parametrii meniului curent. Semnalul unei alarme declanșate poate fi, de asemenea, oprit folosind butoanele „OK” sau „STEP”. Apăsând orice buton în timp ce alarma sună, aceasta se oprește. Schema de control s-a dovedit astfel:

Video despre cum funcționează totul!

Pe tema ceasurilor de casă, am promis că voi continua, așa că iată. Ceas pe matrice LED de casă.

Aceste LED-uri au fost comandate ÎNAINTE să mă hotărăsc să fac ceasuri pe matrice
Am comandat trei culori diferite de LED-uri de la un vânzător: , și
Acest lucru a fost făcut pentru a încerca să se realizeze ceasuri cu segmente, în ritmul a trei LED-uri pe segment 7*4*3=84+2=86 bucăți
Cam cam asa:

Am vrut să încerc culori diferite și cu siguranță luminoase (cum ar putea fi altfel?)
Din acest motiv, loturile de 100 de piese mi s-au potrivit destul de bine, mai ales ca pretul este destul de rezonabil si am mai comandat din acelasi magazin sa am numerele facute in culori diferite pentru a putea compara culorile pe un singur display - care ar fi mai frumos și așa mai departe - glumesc... :)

Produsul a fost comandat și plătit 20 august 2016, și a ajuns 15 septembrie 2016, după standardele noastre, destul de repede. DAR! LED-uri roșii - nu au ajuns! La sfârșitul perioadei de protecție a cumpărătorului s-a deschis un litigiu și vânzătorul a returnat banii. A fost doar păcat să-mi pierd timpul...

Produsul a sosit într-un plic de corespondență standard cu bule galbene, LED-urile în sine au fost ambalate într-o pungă de plastic separată, numărul de piese albastre și verzi a fost puțin mai mare de 100 (nu îmi amintesc exact acum, dar îmi amintesc că au existat încă 4-5 bucăți)
Toate funcționează (adică strălucitoare)
Cele care erau multicolore erau ambalate în pungi separate, pe care era marcată cu un marker culoarea R G B W Y - culoarea se potrivea peste tot și, de asemenea, 2-3 în plus - s-a creat impresia că probabil așa a fost pentru toată lumea, dar mai târziu Eram convins că nu a fost întotdeauna cazul, ci se întâmplă invers...

Dacă n-ar fi fost sticlă roșie, vânzătorului i s-ar fi putut da un A+ gras pentru generozitate.

Pe de altă parte, banii au fost returnați - problema este pur și simplu timpul pierdut și așteptările dezamăgite
Si a mai trimis o scrisoare in care scria ca imi returneaza banii LUI, iar daca ajungea marfa mi-a cerut sa ii returnez aceasta suma.
Verbatim:

Bună, prietene, acum sunt o rambursare, atunci când primiți un pachet, vă rog să-mi returnați banii, vă rog să-mi dați o laudă de cinci stele.
Către care a trebuit să trimită o scrisoare că aceasta nu era LUI bani, dar pur și simplu mi-i returnează în urma unei dispute MELE bani, pentru că Nu am primit niciodată bunurile lui și, în același timp, am pierdut mult timp în așteptarea bunurilor lui

Apropo, când au sosit toate celelalte comenzi de la el, 10 zile mai târziu, i-am scris spunându-i că sunt îngrijorat pentru că... este ciudat - toată lumea a venit, dar una dintre comenzi nu a sosit
La care a răspuns sec, fără niciun „bună prietene”, „încă nu au trecut 60 de zile”
Și apoi deodată a devenit „prieten” și părea că-și luase banii...

Dar, în general - vânzătorul își îndeplinește îndatoririle, răspunde la scrisori, mărfurile trimise au doar emoții pozitive, a returnat banii pentru ceea ce nu a fost trimis - totul este conform REGULUI

Ei bine, acum despre motivul pentru care a fost achiziționat