Orologi su matrici RGB - Sviluppo e modifica di circuiti. Vendita all'ingrosso di LED luminosi, per orologi fatti in casa su matrici LED Orologi Radiocat su matrici LED

Per quanto riguarda gli orologi fatti in casa, avevo promesso di continuare, quindi ecco qua. Orologio su matrici LED fatte in casa.
, E

Questo è stato fatto per provare a realizzare orologi a segmenti, al ritmo di tre LED per segmento 7*4*3=84+2=86 pezzi

È più o meno così:

Ho voluto provare colori diversi e decisamente accesi (come poteva essere altrimenti?)

Per questo motivo i lotti da 100 pezzi mi sono andati molto bene, soprattutto perché il prezzo è abbastanza ragionevole, e ho anche ordinato dallo stesso negozio di far realizzare i numeri in diversi colori in modo da poter confrontare i colori su un display - quale sarebbe più bello, e così via - sto scherzando... :)

Il prodotto è stato ordinato e pagato 20 agosto 2016, e arrivò 15 settembre 2016, secondo i nostri standard, abbastanza rapidamente. MA! LED rossi: non sono arrivati! Al termine del periodo di protezione dell'acquirente, è stata aperta una controversia e il venditore ha restituito il denaro. È stato un peccato sprecare il mio tempo...

Il prodotto è arrivato in una busta postale standard a bolle d'aria gialla, i LED stessi erano imballati in un sacchetto di plastica separato, il numero di pezzi in blu e verde era poco più di 100 (non ricordo esattamente ora, ma ricordo che lì erano 4-5 pezzi in più)

Tutto funzionante (cioè luminoso)

Quelli multicolori venivano confezionati in sacchetti separati, sui quali era segnato con un pennarello il colore R G B W Y - il colore corrispondeva ovunque, e anche 2-3 in più - si creava l'impressione che probabilmente fosse così per tutti, ma in seguito Ero convinto che non fosse sempre così, accade il contrario...

Se non fosse stato per lo stipite rosso, al venditore avrebbe potuto essere dato un bel A+ per la non avidità.

Invece i soldi sono stati restituiti, il problema è il tempo perso, e ha anche mandato una lettera in cui scriveva che mi restituiva i SUOI ​​soldi, e se arrivava la merce, mi chiedeva di restituirgli questa somma

Testualmente:

Ciao amico mio, ora ho un rimborso, quando ricevi un pacco, per favore restituisci i miei soldi, per favore dammi un elogio a cinque stelle.

Al che dovette buttare giù una lettera che non era quella IL SUO soldi, ma me li restituisce semplicemente a seguito di una controversia MIO soldi, perché Non ho mai ricevuto la sua merce e allo stesso tempo ho perso molto tempo nell'attesa della sua merce

A proposito, quando sono arrivati ​​tutti gli altri suoi ordini, 10 giorni dopo, gli ho scritto dicendo che ero preoccupato perché... è strano: sono venuti tutti, ma uno degli ordini non è arrivato

Al che lui ha risposto seccamente, senza nessun “ciao amico”, “non sono ancora passati 60 giorni”

E poi all'improvviso è diventato un “amico”, e sembrava che avesse preso i SUOI ​​soldi...

Ma in generale - il venditore adempie ai suoi doveri, risponde alle lettere, la merce inviata ha solo emozioni positive, ha restituito i soldi per ciò che non è stato inviato - tutto è secondo le REGOLE

Bene, ora parliamo del motivo per cui è stato acquistato

Orologi fatti in casa su matrici LED fatte in casa

Esistono molti modi per assemblare un orologio elettronico con le tue mani: i diagrammi sono ampiamente presentati in letteratura e su Internet. La maggior parte delle implementazioni moderne si basano su microcontrollori. L'implementazione di tali progetti richiede spesso ampie competenze pratiche e conoscenze teoriche nel campo dell'elettronica: la capacità di utilizzare software specializzati, creare a casa circuiti stampati mediante il metodo dell'attacco in cloruro ferrico, saldando bene. È inoltre necessario disporre di una varietà di strumenti e forniture.

Tuttavia, esiste un modo semplice ed economico per assemblare un orologio elettronico con le proprie mani a casa: utilizzare la piattaforma Arduino. Si tratta di un complesso software e hardware appositamente progettato per l'insegnamento delle basi della programmazione e dell'elettronica. C utilizzandoArduino chiunque, anche senza una speciale formazione preliminare, può costruire un orologio elettronico con le proprie mani: non sono necessari schemi elettrici, programmi di ingegneria e persino un saldatore!

La connessione di tutti i componenti elettronici viene effettuata su una breadboard a contatto speciale (“senza saldatura”), che elimina il rischio di ustioni, tagli e altre lesioni, quindi puoi lavorare con il progettista Arduino insieme ai bambini. Un modo visivo di presentare lo schema elettrico ti aiuterà a evitare di commettere errori durante l'assemblaggio del dispositivo.

Passaggio 1. Elenco dei componenti

Per assemblare un semplice orologio su matrici LED ti serviranno solo pochi componenti economici:

  • Piattaforma Arduino. Andranno bene i modelli più semplici - o Micro;
  • breadboard di contatto;
  • cavi di collegamento per breadboard;
  • Modulo orologio in tempo reale Adafruit DS3231;
  • Modulo matrice LED 32x8 MAX7219;
  • due pulsanti.

Avrai bisogno anche di un personal computer e di un cavo USB-mini-USB per caricare il programma di controllo in memoria. Questo è tutto: non sono necessari saldatore, spelafili, coltelli di montaggio e altri strumenti professionali: tutte le operazioni vengono eseguite manualmente. Forse in alcuni casi è più comodo usare le pinzette, ma puoi farne a meno.


Passaggio 2. Assemblaggio del circuito elettronico

Schema orologio elettronico con l'indicazione LED utilizzando Arduino, anche per i radioamatori inesperti sembrerà abbastanza semplice. Per il montaggio sono necessari solo pochi fili. Tabella di connessione:

Modulo Arduino → Matrice LED 32x8 MAX7219

Modulo Arduino → Orologio in tempo reale Adafruit DS3231

Modulo Arduino → pulsanti

D2 - pulsante 1

D3 - pulsante 2

Il secondo pin dei pulsanti è collegato a GND.

Devi solo prestare attenzione e ricordare come sono collegati tra loro i fori di contatto sulla breadboard. Lo schema seguente illustra il metodo di collegamento interno dei fori di contatto:


Due file (1 e 4) su entrambi i lati sono collegate orizzontalmente: vengono solitamente utilizzate come linea di alimentazione +5 V e terra GND. Tutti i contatti interni (2 e 3) sono chiusi verticalmente. In questo caso il circuito stampato è diviso sia verticalmente che orizzontalmente in due parti simmetriche indipendenti tra loro. Ciò consente, ad esempio, di assemblare due dispositivi diversi su una scheda.

Lo schema di un orologio elettronico con indicazione LED, nonché la disposizione degli elementi sul circuito stampato, è mostrato nell'illustrazione:

Controllare attentamente che tutti i collegamenti rispettino lo schema riportato. Assicurarsi inoltre che i conduttori siano ben fissati nei fori di contatto del circuito.


Passaggio 3. Firmware Arduino

Una volta completato l'assemblaggio e il test del circuito, puoi iniziare a caricare il programma di controllo (o "firmware") nella memoria di Arduino.


Per fare ciò, è necessario installare l'ambiente di sviluppo ufficiale gratuito - . Ti servirà anche il codice sorgente del progetto, che potrai scaricare qui sotto nell'archivio con tutte le librerie e uno sketch, e se ti serve solo uno sketch, potrai copiarlo a parte:

//include librerie: #include "LedControl.h" #include // Libreria di caratteri #include // Orologio DS1307 #include "RTClib.h" // Orologio DS1307 #include // Libreria di pulsanti di Alexander Brevig // Setup LED Matrix // il pin 12 è collegato a DataIn sul display // il pin 11 è collegato a CLK sul display // il pin 10 è collegato a LOAD sul display LedControl lc = Controllo Led(6, 5, 4, 4); //imposta i 3 pin come 12, 11 e 10 e quindi imposta 4 display (il massimo è 8 display) //variabili globali intensità byte = 7; // Intensità/luminosità predefinita (0-15) byte clock_mode = 0; // Modalità orologio predefinita. Valore predefinito = 0 (modalità_base) bool modalità_casuale = 0; // Definisci la modalità casuale: cambia il tipo di visualizzazione ogni poche ore. Default = 0 (off) byte old_mode = clock_mode; // Memorizza la modalità orologio precedente, quindi se andiamo alla data o altro, sappiamo a quale modalità tornare dopo. bool ampere = 0; // Definisce l'orario di 12 o 24 ore. 0 = 24 ore. 1 = byte di 12 ore change_mode_time = 0; // Mantiene l'ora in cui la modalità orologio cambierà successivamente se in modalità casuale. ritardo lungo senza segno = 500; // Aspettiamo sempre un po' tra gli aggiornamenti del display int rtc; // Mantiene l'output dell'orologio in tempo reale char days = ( "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"); //array dei giorni - utilizzato nelle modalità slide, basic_mode e jumble (il DS1307 restituisce da 1 a 7 valori per il giorno della settimana) char daysfull = ( "Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì" ", "Venerdì", "Sabato" ); suffisso char = ("st", "nd", "rd", "th"); //array dei suffissi della data, utilizzato nelle modalità slide, basic_mode e jumble. e,g, 1st 2nd ... //define costanti #define NUM_DISPLAY_MODES 3 // Modalità di visualizzazione dei numeri (contando zero come prima modalità) #define NUM_SETTINGS_MODES 4 // Modalità di impostazione dei numeri = 6 (contando zero come prima modalità) # define SLIDE_DELAY 20 // Il tempo in millisecondi per l'effetto diapositiva per carattere in modalità diapositiva. Aumenta questo valore per un effetto più lento #define cls clear_display // Cancella display RTC_DS1307 ds1307; // Crea oggetto RTC Button buttonA = Button(2, BUTTON_PULLUP); // Imposta il pulsante A (usando la libreria dei pulsanti) Pulsante pulsanteB = Pulsante(3, BUTTON_PULLUP); // Imposta il pulsante B (utilizzando la libreria dei pulsanti) void setup() ( digitalWrite(2, HIGH); // attiva la resistenza pullup per il pulsante sul pin 2 digitalWrite(3, HIGH); // attiva la resistenza pullup per il pulsante sul pin 3 digitalWrite(4, HIGH); // attiva la resistenza pullup per il pulsante sul pin 4 Serial.begin(9600); //avvia seriale //inizializza i 4 pannelli a matrice //abbiamo già impostato il numero di dispositivi al momento della creazione il LedControl int devices = lc.getDeviceCount(); //dobbiamo inizializzare tutti i dispositivi in ​​un ciclo for (int indirizzo = 0; indirizzo< 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--) ( for (indirizzo byte = 0; indirizzo< 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 >= "un" && 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 >> riga)) plot(x + col, y + riga, 1);<= "Z" || (c >= "un" && 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 >= "un" && 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 + riga, 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 punti; // if (c >= "A" && c<= 31) && (y >") ( c = 30; // freccia selettore modalità_orologio ) else if (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> riga)) ( // solo 7 righe. plot(x + col, y + riga, 1); ) else ( plot(x + col, y + riga, 0); ) //) ) ) ) //small_mode //mostra l'ora in piccoli caratteri 3x5 con display dei secondi void small_mode() ( char textchar; // i 16 caratteri sul display byte mins = 100; //mins byte secs = rtc; //seconds byte old_secs = secs; / /mantiene il vecchio valore dei secondi - dall'ultima volta che i secondi sono stati aggiornati o display - usato per verificare se i secondi sono cambiati cls( //esegui il ciclo principale dell'orologio finché run_mode restituisce true while (run_mode()) ( get_time(); / /controlla la pressione del pulsante if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); return; ) //se i secondi sono cambiati, aggiornali sul display secs = rtc; if (secs != old_secs) ( //secs char buffer; itoa(secs, buffer, 10); //fix - altrimenti se num ha zero iniziale, ad esempio "03" secs, itoa lo copre in caratteri con spazio "3".se(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 la sinistra lancetta "1" del display quando passiamo dalle 12:59 -> 1:00 in modalità 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 >//effettua la conversione a 12/24 ore se apm è impostato su 1 byte 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 ->if (ore > 12) ( ore = ore - amp * 12; ) if (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 >il nuovo<=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 >valori 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 >//regola le ore di amp impostate sulla modalità 12 ore se (ore > 12) ( ore = ore - amp * 12; ) se (ore<= "z") { current_c = (current_c - "a") + 41; // A-Z maps to 41-67 } else if (current_c >12) ( ore = ore - amp * 12; ) se (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 febbraio quindi la cifra non cambia se ((digits_old!= digits_new) || (digits_old!= digits_new)) ( //cambia il giorno mostrato. Il ciclo seguente attraversa ciascuno dei 3 caratteri a turno, ad esempio "MON" per (byte giorno_car = 0; giorno_car<= 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); //la trama ha portato su else plot(x + col, y + start_y, 0); //altrimenti la trama inizia ) start_y++;//aggiungi uno a y così disegniamo la riga successiva uno in basso ) ) //disegna una riga vuota tra i caratteri se la sequenza è compresa tra 1 e 7. Se non lo facciamo otteniamo i resti dei caratteri attuali ultima posizione rimasta sul display se (sequenza >= 1 && sequenza<= 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) ( //calcola i punti di char byte; //if (new_c >= "A" && new_c<= "Z" || (new_c >= "a" && nuovo_c<= "z")) { // new_c &= 0x1F; // A-Z maps to 1-26 //} if (new_c >= "A" && nuovo_c<= "Z") { new_c &= 0x1F; // A-Z maps to 1-26 } else if (new_c >= "a" && nuovo_c<= "z") { new_c = (new_c - "a") + 41; // A-Z maps to 41-67 } else if (new_c >= "0" && nuovo_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; // freccia di selezione clock_mode ) byte newcharrowmin = 6 - (sequenza - 2); // numero minimo di righe da disegnare per il nuovo carattere - questo genera un output da 6 a 0 quando vengono inseriti i numeri di sequenza 2-8 . Questa è la riga minima da disegnare per il nuovo char byte start_y = 0; //y posizione da cui iniziare - è uguale al numero di sequenza che inseriamo in ogni riga //tracciamo ogni riga a partire dal minimo della riga (calcolato in base al numero di sequenza ) ) fino a 6 per (byte 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); //la trama ha portato su else plot(x + col, y + start_y, 0); //altrimenti la trama inizia ) start_y++;//aggiungi uno a y così disegniamo la riga successiva uno in basso ) ) ) //stampa un orologio usando parole anziché numeri void word_clock() ( cls(); char numeri = ( "uno ", "due", "tre", "quattro", "cinque", "sei", "sette", "otto", "nove", "dieci", "undici", "dodici", "tredici", "quattordici", "quindici", "sedici", "diciassette", "diciotto", "diciannove" ; numeri chartens = ( "dieci", "venti", "trenta", "quaranta", "cinquanta" ); //potenzialmente 3 righe da visualizzare char str_a; //byte ore_y, mins_y; //ore e minuti e posizioni per ore e minuti ore = - amp * 12;< 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; ) //dividi il valore dei minuti in due 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 mindigitten = (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)( //controlla la pressione del pulsante if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) ritardo(1); contatore--; ) 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)( suffixposx = 8; puttinychar(4+offset, 1, buffer); offset = 8; //offset per centrare il testo se 4 caratteri ) //stampa i 2 caratteri del suffisso puttinychar(suffixposx+offset, 1, suffisso[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; ) //stampa la freccia e il nome della modalità clock corrente sulla prima riga e stampa il nome della modalità clock successiva sulla riga due 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; ) //stampa la freccia e il nome della modalità orologio corrente sulla prima riga e stampa il nome della modalità orologio successiva sulla riga due 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);


La compilazione del codice del programma e il successivo caricamento nella memoria del microcontrollore richiederà del tempo, solitamente non più di un minuto. Il buon esito dell'operazione verrà segnalato nella console IDE di Arduino. Dopodiché non resta che riavviare Arduino utilizzando il pulsante Reset sul dispositivo: un semplice orologio su matrici LED è pronto!

Orologio pronto su Arduino

L'orologio viene impostato utilizzando due pulsanti. Il dispositivo supporta i formati dell'ora a 12 e 24 ore, visualizza la data e il giorno della settimana e visualizza l'ora con o senza secondi. È anche possibile modificare la luminosità dei LED.


Probabilmente in futuro vorrai aggiungere altre funzionalità (ad esempio un termometro) o installare il dispositivo in un corpo di tua progettazione: è possibile ottenere buoni risultati producendo su macchine da taglio laser. Ma ora puoi tranquillamente dire di aver assemblato un orologio elettronico a tutti gli effetti con le tue mani!

Un semplice orologio su matrici LED. Molti radioamatori, principianti e altri, amano "reinventare la ruota": costruiscono i PROPRI orologi elettronici. Anche questo destino non ha risparmiato me. Oggi, ovviamente, ci sono molti modelli di orologi su Internet, ma per qualche motivo tra questi ci sono solo pochi orologi su matrici LED. Su Internet di lingua russa ho trovato solo un disegno completamente completato e descritto. Allo stesso tempo, le matrici LED sono diventate molto più economiche e il loro costo non è né superiore né inferiore rispetto agli indicatori a sette segmenti della stessa dimensione. Ad esempio, il GNM23881AD che ho utilizzato con una dimensione di 60x60 mm è stato acquistato per 1,5 euro (3 indicatori costano 4,5 euro), per questi soldi difficilmente si possono acquistare quattro indicatori a sette segmenti delle stesse dimensioni. Ma molte più informazioni possono essere inserite nell’indicatore a matrice. Oltre ai numeri, possono visualizzare lettere, segni e, con l'aiuto di una linea strisciante, anche testo.

Sulla base di ciò, c'era il desiderio di costruire un orologio su matrici LED, ma in modo che il circuito non fosse più complicato di quello a sette segmenti. Volevo anche che fosse abbastanza funzionale e non come gli altri. È nato così il seguente schema.

La funzionalità dell'orologio è la seguente:

  • Conto alla rovescia, calendario, giorno della settimana. (vengono presi in considerazione gli anni bisestili, il passaggio all'ora legale/solare non viene effettuato).
  • Conservazione dell'orologio in caso di perdita di alimentazione esterna (il consumo è di 15 micron).
  • Correzione della corsa + - 59,9 sec/giorno, con incrementi di 0,1 sec. 9 allarmi. Di cui 3 “una tantum” e 6 “permanenti”, personalizzabili individualmente per giorno della settimana.
  • Durata regolabile individualmente del segnale sonoro per ciascun allarme (1-15 minuti).
  • Conferma sonora della pressione dei pulsanti (può essere disabilitata).
  • Segnale acustico orario (può essere disabilitato).
  • Dalle 00:00 alle 08:00 non c'è segnale.
  • 1 o 2 sensori di temperatura (strada e casa).
  • Ticker personalizzabile, attraverso il quale vengono visualizzate tutte le informazioni (tranne l'ora)
  • Il valore di correzione della corsa e le impostazioni della “linea di corsa” vengono salvati anche in caso di interruzione dell'alimentazione di backup.

AtMega16A è stato scelto come il “cuore” dell'orologio, per la sua disponibilità, convenienza e “legalità”. Volevo semplificare il più possibile il circuito, quindi tutto ciò che era possibile è stato assegnato al controller. Di conseguenza, siamo riusciti a cavarcela con solo due microcircuiti, un controller e un registro TPIC6B595. Se TPIC6B595 non è disponibile per qualcuno, puoi sostituirlo con 74HC595 + ULN2803. Sono state provate entrambe le opzioni. Puoi anche provare a utilizzare TPIC6C595, è un po' debole e si è riscaldato un po', ma nel complesso ha funzionato stabilmente. Il tempo viene conteggiato utilizzando il tempo asincrono - T2. L'orologio continua a funzionare anche in caso di interruzione di corrente. In questo momento, la maggior parte del circuito è diseccitata e il controller è alimentato da una batteria, un accumulatore o uno ionistore. Ero interessato a "giocare" con lo ionistore, quindi l'ho usato. Il consumo attuale per ore in modalità standby è di 15 micron. Quando alimentato da uno ionistore 1F, l'orologio "durava" per quattro giorni. Questo è abbastanza per mantenere la velocità durante le interruzioni di corrente. Se si utilizza una batteria CR2032, in teoria, secondo i calcoli, la carica dovrebbe essere sufficiente per 1,5 anni. Il controller “ascolta” la presenza della tensione di rete attraverso il pin PB.3 Questo pin è l'ingresso invertente del comparatore. La tensione di alimentazione, attraverso il partitore R2-R3, viene fornita al pin PB.3 e nello stato normale è di circa 1,5 V. Se la tensione esterna scende al di sotto di 4,1 volt, la tensione sul pin RV.3 diventerà inferiore a 1,23 volt e verrà generato un interrupt dal comparatore e nel gestore di interrupt tutti i nodi "extra" del controller verranno attivati spento e il controller stesso verrà messo in modalità di sospensione. In questa modalità continua a funzionare solo il timer T2. Quando viene visualizzata l'alimentazione esterna, la tensione su RV.3 salirà nuovamente al di sopra di 1,23 V, il controller "vedendolo" metterà tutti i nodi in condizioni di lavoro. Se al posto dello ionitore viene utilizzata una batteria CR2032, è necessario collegarla tramite un diodo (preferibilmente un diodo Schottky). L'anodo del diodo è collegato alla batteria + e il catodo al catodo VD1. In modalità normale, lo schermo visualizza l'ora nel formato ore-minuti. Il ticker inizia a funzionare a intervalli di un minuto. La linea corrente visualizza il giorno della settimana, la data, l'anno, la temperatura. a casa e temp. sulla strada. Il ticker è personalizzabile, ad es. È possibile attivare/disattivare la visualizzazione di qualsiasi elemento. (ad esempio, disattivo sempre la visualizzazione dell'anno). Quando tutti gli elementi sono spenti, il ticker non si avvia e l'orologio visualizza costantemente l'ora corrente. 9 sveglie sono divise in 3 usa e getta e 6 riutilizzabili. Quando attivi le sveglie 1-3, suonano solo una volta. Affinché funzionino di nuovo, devono essere riattivati ​​manualmente. E le sveglie 4-9 sono riutilizzabili, ad es. opereranno quotidianamente all'orario prestabilito. Inoltre, è possibile impostare queste sveglie in modo che si attivino solo in determinati giorni della settimana. Questo è utile, ad esempio, se non vuoi che la sveglia ti svegli durante il fine settimana. Oppure, ad esempio, devi svegliarti nei giorni feriali alle 7:00 e il giovedì alle 8:00, e nei fine settimana non hai bisogno della sveglia. Quindi ne impostiamo uno riutilizzabile alle 7:00 dal lunedì al mercoledì e al venerdì, e il secondo alle 8:00 il giovedì..... Inoltre, tutte le sveglie hanno un'impostazione della durata del segnale e, se tu, in ordine per svegliarsi non avere segnale sufficiente per 1 minuto, poi è possibile aumentarlo per un tempo da 1 a 15 minuti. Il corso viene corretto una volta al giorno, alle 00-00. Se l'orologio è veloce, ad esempio, di 5 secondi al giorno, alle 00-00-00 l'ora verrà impostata su 23-59-55, ma se l'orologio è lento, alle 00-00-00 l'ora verrà impostata su 23-59-55. sarà impostato su 00-00-05. Passo di correzione – 0,1 sec. Correzione massima – 59,9 sec/giorno. Con un quarzo funzionante, difficilmente ne avrai bisogno di più. La correzione viene eseguita anche in modalità standby quando alimentato a batteria. Le matrici LED possono utilizzare qualsiasi LED 8*8 con un catodo comune. Come già detto ho utilizzato la GNM23881AD. In linea di principio, puoi “assemblare” una matrice da singoli LED. Il microcontrollore AtMega16a può essere sostituito con il “vecchio” AtMega16 con la lettera L. Allo stesso tempo, teoricamente, il consumo di corrente della batteria dovrebbe aumentare leggermente. Probabilmente funzionerà solo AtMega16, ma potrebbero verificarsi problemi durante il funzionamento a batteria. Diodo D1 - preferibilmente qualsiasi diodo Schottky. Funziona anche con un normale raddrizzatore, ma per proteggersi da vari inconvenienti legati al fatto che parte del circuito è alimentata dalla tensione "prima del diodo" e parte "dopo il diodo", è meglio cercare Tensione Schottky. Transistor VT1 – qualsiasi n-p-n. L'orologio è controllato da due pulsanti. Il loro numero poteva essere aumentato fino a 8 pezzi senza aggiungere altri componenti oltre ai bottoni stessi, ma ho voluto provare a “uscire” con solo due. I pulsanti sono convenzionalmente denominati “OK” e “STEP”. Il pulsante “STEP” solitamente passa alla voce di menu successiva e il pulsante “OK” modifica i parametri del menu corrente. Il segnale di un allarme attivato può anche essere disattivato utilizzando i pulsanti “OK” o “STEP”. Premendo qualsiasi pulsante mentre la sveglia suona si spegne. Lo schema di controllo è risultato così:

Video di come funziona il tutto!

Per quanto riguarda gli orologi fatti in casa, avevo promesso di continuare, quindi ecco qua. Orologio su matrici LED fatte in casa.

Questi LED sono stati ordinati PRIMA che decidessi di realizzare orologi su matrici
Ho ordinato tre diversi colori di LED da un venditore: , e
Questo è stato fatto per provare a realizzare orologi a segmenti, al ritmo di tre LED per segmento 7*4*3=84+2=86 pezzi
È più o meno così:

Ho voluto provare colori diversi e decisamente accesi (come poteva essere altrimenti?)
Per questo motivo i lotti da 100 pezzi mi sono andati molto bene, soprattutto perché il prezzo è abbastanza ragionevole, e ho anche ordinato dallo stesso negozio di far realizzare i numeri in diversi colori in modo da poter confrontare i colori su un display - quale sarebbe più bello, e così via - sto scherzando... :)

Il prodotto è stato ordinato e pagato 20 agosto 2016, e arrivò 15 settembre 2016, secondo i nostri standard, abbastanza rapidamente. MA! LED rossi: non sono arrivati! Al termine del periodo di protezione dell'acquirente, è stata aperta una controversia e il venditore ha restituito il denaro. È stato un peccato sprecare il mio tempo...

Il prodotto è arrivato in una busta postale standard a bolle d'aria gialla, i LED stessi erano imballati in un sacchetto di plastica separato, il numero di pezzi in blu e verde era poco più di 100 (non ricordo esattamente ora, ma ricordo che lì erano 4-5 pezzi in più)
Tutto funzionante (cioè luminoso)
Quelli multicolori venivano confezionati in sacchetti separati, sui quali era segnato con un pennarello il colore R G B W Y - il colore corrispondeva ovunque, e anche 2-3 in più - si creava l'impressione che probabilmente fosse così per tutti, ma in seguito Ero convinto che non fosse sempre così, accade il contrario...

Se non fosse stato per lo stipite rosso, il venditore avrebbe potuto ricevere un bel A+ per la generosità.

D'altra parte, i soldi sono stati restituiti: il problema è semplicemente perdita di tempo e aspettative deluse
E ha anche inviato una lettera in cui scriveva che mi avrebbe restituito i SUOI ​​soldi, e se la merce fosse arrivata, mi avrebbe chiesto di restituirgli tale importo
Testualmente:

Ciao amico mio, ora ho un rimborso, quando ricevi un pacco, per favore restituisci i miei soldi, per favore dammi un elogio a cinque stelle.
Al che dovette buttare giù una lettera che non era quella IL SUO soldi, ma me li restituisce semplicemente a seguito di una controversia MIO soldi, perché Non ho mai ricevuto la sua merce e allo stesso tempo ho perso molto tempo nell'attesa della sua merce

A proposito, quando sono arrivati ​​tutti gli altri suoi ordini, 10 giorni dopo, gli ho scritto dicendo che ero preoccupata, perché... è strano: sono venuti tutti, ma uno degli ordini non è arrivato
Al che lui ha risposto seccamente, senza nessun “ciao amico”, “non sono ancora passati 60 giorni”
E poi all'improvviso è diventato un “amico” e sembrava aver preso i SUOI ​​soldi...

Ma in generale - il venditore adempie ai suoi doveri, risponde alle lettere, la merce inviata ha solo emozioni positive, ha restituito i soldi per ciò che non è stato inviato - tutto è secondo le REGOLE

Bene, ora parliamo del motivo per cui è stato acquistato