Sommario:
- Passo 1:
- Passaggio 2: progettazione
- Passaggio 3: lavorazione CNC
- Passaggio 4: elettronica
- Passaggio 5: assemblaggio dell'elettronica
- Passaggio 6: funzionamento a secco
- Passaggio 7: resina epossidica
- Passaggio 8: mettere tutto insieme
- Passaggio 9: codice
- Passaggio 10: Visione artificiale - Calibrazione
- Passaggio 11: osservazioni di separazione
Video: Orologio LED in Legno - Stile Analogico: 11 Passi (con Immagini)
2024 Autore: John Day | [email protected]. Ultima modifica: 2024-01-30 10:04
È un orologio a LED in legno in stile analogico. Non so perché non ne ho mai visto uno prima..anche se i tipi digitali sono molto comuni. Comunque, ci siamo!
Passo 1:
Il progetto dell'orologio in compensato è iniziato come un semplice progetto di partenza per il router CNC. Stavo guardando semplici progetti online e ho trovato questa lampada (immagine sopra). Avevo anche visto orologi digitali che brillano attraverso l'impiallacciatura di legno (immagine sopra). Quindi, combinare i due progetti era un'idea ovvia. Cercando di mettermi alla prova, ho deciso di non utilizzare l'impiallacciatura ma solo un pezzo di legno per questo progetto.
Passaggio 2: progettazione
Ho progettato l'orologio in Inkscape (immagine sopra). Il design è molto semplice per scelta. Ho deciso di non instradare le tracce per i fili perché a questo punto non ero sicuro di voler utilizzare un cablaggio radiale o perimetrale. (Ho deciso di utilizzare il cablaggio perimetrale alla fine.) Un neopixel va in ciascuno dei piccoli fori circolari per mostrare l'ora e i minuti, con una precisione di cinque minuti. Il cerchio al centro verrà instradato per ospitare l'elettronica.
Passaggio 3: lavorazione CNC
Ho progettato i percorsi utensile su MasterCAM e ho utilizzato un technoRouter per fresare l'orologio da compensato da 3/4 di pollice. Io uso un pezzo 15 "x 15" per questo, con uno spreco minimo. Il trucco è far uscire quanto più legno possibile senza rompere il legno. Lasciare 0,05 "-0,1" è una buona scelta per il legno chiaro. Se non sei sicuro, è meglio lasciare più legno, perché puoi sempre carteggiare l'altra faccia. Ho finito per rimuovere un po' troppo legno da alcune parti, ma per fortuna i risultati non ne risentono troppo.
Nota per gli utenti senza accesso a un CNC:
Questo progetto può essere fatto facilmente con un trapano a colonna. Hai solo bisogno di impostare l'arresto in un punto in cui lasci circa 0,1 di legno rimanente alla base. Dovrai essere preciso, ma non troppo preciso. Dopotutto, idealmente nessuno vedrà accendersi tutti i LED a allo stesso tempo, così puoi farla franca con un po 'di sbavatura.
Passaggio 4: elettronica
L'elettronica è abbastanza semplice. Ci sono 24 neopixel, dodici per mostrare le ore e dodici per mostrare i minuti, con una precisione di cinque minuti. Un Arduino pro mini controlla i neopixel e ottiene l'ora precisa tramite un modulo orologio in tempo reale (RTC) DS3231. Il modulo RTC ha una cella a bottone come backup, quindi non perde tempo anche quando l'alimentazione è spenta.
Materiale:
Arduino pro mini (o qualsiasi altro Arduino per quella materia)
Scheda breakout DS3231
Neopixel in singole schede breakout
Passaggio 5: assemblaggio dell'elettronica
Ho collegato i neopixel in una stringa, usando fili da 2,5 per i primi dodici led e un filo da quattro pollici per i successivi dodici. Avrei potuto usare cavi di lunghezza leggermente inferiore. Dopo aver realizzato la stringa, l'ho testata, assicurandomi che la saldatura le giunture erano buone, ho aggiunto un interruttore momentaneo per accendere tutti i led, tanto per mettersi in mostra.
Passaggio 6: funzionamento a secco
Dopo aver sperimentato, mettendo i LED nei fori e accendendoli tutti, sono rimasto soddisfatto dei risultati. Quindi ho carteggiato un po' la faccia anteriore e applicato uno strato di PU. Ho finito per carteggiare il cappotto in seguito, ma è una buona idea lasciarlo acceso se non lo trovi esteticamente sgradevole.
Passaggio 7: resina epossidica
Dopo alcuni test con la posizione del led all'interno dei fori, ho pensato che la migliore discussione si ottiene quando i LED si trovano a circa 0,2 di distanza dall'estremità del foro. Quando lo provi tu stesso, la luminosità dei LED sarà molto diversa in ogni foro. Non preoccuparti di questo; lo sistemeremo nel codice. Questo è dovuto al tipo di punta da trapano che ho usato. Se dovessi farlo di nuovo, userei una punta da trapano con estremità sferica per i fori Ma, in ogni caso, per ottenere la distanza ho mescolato un po' di resina epossidica e ne ho messo un po' in ogni foro.
Passaggio 8: mettere tutto insieme
I LED verranno posizionati a partire dalla posizione della lancetta delle ore 12 spostandosi in senso antiorario attraverso tutte le posizioni della lancetta delle ore e poi fino alla lancetta dei minuti, spostandosi nuovamente dal segno dei 60 minuti in senso antiorario. Questo è così che quando osserviamo di fronte il modello LED appare in senso orario.
Dopo che la resina epossidica si è indurita per un'ora, ho aggiunto dell'altra resina epossidica. Questa volta, ho posizionato i LED nei fori, assicurandomi di coprire i fili e i giunti di saldatura con la resina epossidica. Ciò consente una buona diffusione della luce e protegge i fili.
Passaggio 9: codice
Il codice è su GitHub, sentiti libero di modificarlo per il tuo uso. Quando accendi tutti i LED allo stesso livello, la luminosità della luce che attraversa sarà molto diversa in ogni foro. Ciò è dovuto al diverso spessore del legno nei fori e alla differenza nella tonalità del legno, come puoi vedere il colore del legno varia un po' nel mio pezzo. Per rimediare a questa differenza di luminosità, ho realizzato una matrice di livelli di luminosità dei led. E ha diminuito la luminosità dei LED più luminosi. È un processo per tentativi ed errori e può richiedere diversi minuti, ma i risultati ne valgono la pena.
compensatoClock.ino
// Orologio in compensato |
// Autore: tinkrmind |
// Attribuzione 4.0 Internazionale (CC BY 4.0). Sei libero di: |
// Condividi: copia e ridistribuisci il materiale in qualsiasi supporto o formato |
// Adatta - remixa, trasforma e costruisci sul materiale per qualsiasi scopo, anche commerciale. |
// Evviva! |
#includere |
#include"RTClib.h" |
RTC_DS3231 rtc; |
#include"Adafruit_NeoPixel.h" |
#ifdef _AVR_ |
#includere |
#finisci se |
#definePIN6 |
Striscia Adafruit_NeoPixel = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800); |
int hourPixel = 0; |
int minutePixel = 0; |
unsignedlong lastRtcCheck; |
stringa inputString = ""; // una stringa per contenere i dati in arrivo |
stringa booleanaComplete = false; // se la stringa è completa |
livello int[24] = {31, 51, 37, 64, 50, 224, 64, 102, 95, 255, 49, 44, 65, 230, 80, 77, 102, 87, 149, 192, 67, 109, 68, 77}; |
voidsetup() { |
#ifndef ESP8266 |
mentre (!Seriale); // per Leonardo/Micro/Zero |
#finisci se |
// Questo è per Trinket 5V 16MHz, puoi rimuovere queste tre linee se non stai usando un Trinket |
#se definito (_AVR_ATtiny85_) |
if (F_CPU == 16000000) clock_prescale_set(clock_div_1); |
#finisci se |
// Codice speciale di fine gingillo |
Serial.begin(9600); |
strip.begin(); |
strip.show(); // Inizializza tutti i pixel su 'off' |
if (! rtc.begin()) { |
Serial.println("Impossibile trovare RTC"); |
mentre (1); |
} |
pinMode(, INPUT_PULLUP); |
// rtc.adjust(DateTime(F(_DATE_), F(_TIME_))); |
if (rtc.lostPower()) { |
Serial.println("RTC ha perso potenza, impostiamo l'ora!"); |
// la riga seguente imposta l'RTC sulla data e l'ora in cui questo sketch è stato compilato |
rtc.adjust(DateTime(F(_DATE_), F(_TIME_))); |
// Questa riga imposta l'RTC con una data e un'ora esplicite, ad esempio per impostare |
// 21 gennaio 2014 alle 3 del mattino chiameresti: |
// rtc.adjust(DateTime(2017, 11, 06, 2, 49, 0)); |
} |
// rtc.adjust(DateTime(2017, 11, 06, 2, 49, 0)); |
// lightUpEven(); |
// mentre (1); |
lastRtcCheck = 0; |
} |
voidloop() { |
if (millis() - lastRtcCheck >2000) { |
DateTime now = rtc.now(); |
Serial.print(now.hour(), DEC); |
Serial.print(':'); |
Serial.print(now.minute(), DEC); |
Serial.print(':'); |
Serial.print(now.second(), DEC); |
Serial.println(); |
orario dello spettacolo(); |
lastRtcCheck = millis(); |
} |
if (!digitalRead(2)) { |
lightUpEven(); |
} |
if (stringComplete) { |
Serial.println(inputString); |
if (inputString[0] == 'l') { |
Serial.println("Livello"); |
lightUpEven(); |
} |
if (inputString[0] == 'c') { |
Serial.println("Mostra l'ora"); |
orario dello spettacolo(); |
strip.show(); |
} |
if (inputString[0] == '1') { |
Serial.println("Accensione di tutti i LED"); |
lightUp(strip. Color(255, 255, 255)); |
strip.show(); |
} |
if (inputString[0] == '0') { |
Serial.println("Striscia di cancellazione"); |
chiaro(); |
strip.show(); |
} |
// #3, 255 imposterebbe il led numero 3 al livello 255, 255, 255 |
if (inputString[0] == '#') { |
Temp. stringa; |
temp = inputString.substring(1); |
int pixNum = temp.toInt(); |
temp = inputString.substring(inputString.indexOf(', ') + 1); |
int intensità = temp.toInt(); |
Serial.print("Impostazione"); |
Serial.print(pixNum); |
Serial.print(" al livello "); |
Serial.println(intensità); |
strip.setPixelColor(pixNum, strip. Color(intensità, intensità, intensità)); |
strip.show(); |
} |
// #3, 255, 0, 125 imposterebbe il led numero 3 al livello 255, 0, 125 |
if (inputString[0] == '$') { |
Temp. stringa; |
temp = inputString.substring(1); |
int pixNum = temp.toInt(); |
int rIndex = inputString.indexOf(', ') + 1; |
temp = inputString.substring(rIndex); |
int rIntensity = temp.toInt(); |
intgIndex = inputString.indexOf(', ', rIndex + 1) + 1; |
temp = inputString.substring(gIndex); |
intgIntensity = temp.toInt(); |
int bIndex = inputString.indexOf(', ', gIndex + 1) + 1; |
temp = inputString.substring(bIndex); |
int bIntensity = temp.toInt(); |
Serial.print("Impostazione"); |
Serial.print(pixNum); |
Serial.print ("da R a "); |
Serial.print(rIntensity); |
Serial.print ("da G a "); |
Serial.print(gIntensity); |
Serial.print ("da B a "); |
Serial.println(bIntensity); |
strip.setPixelColor(pixNum, strip. Color(rIntensity, gIntensity, bIntensity)); |
strip.show(); |
} |
if (inputString[0] == 's') { |
Temp. stringa; |
int ora, minuto; |
temp = inputString.substring(1); |
ora = temp.toInt(); |
int rIndex = inputString.indexOf(', ') + 1; |
temp = inputString.substring(rIndex); |
minuto = temp.toInt(); |
Serial.print("Ora di visualizzazione: "); |
Serial.print(ora); |
Serial.print(":"); |
Serial.print(minuto); |
showTime (ora, minuto); |
ritardo(1000); |
} |
inputString = ""; |
stringaCompleta = falso; |
} |
// ritardo(1000); |
} |
voidserialEvent() { |
while (Serial.available()) { |
char inChar = (char)Serial.read(); |
inputString += inChar; |
if (inChar == '\n') { |
stringaCompleta = vero; |
} |
ritardo(1); |
} |
} |
voidclear() { |
for (uint16_t i = 0; i < strip.numPixels(); i++) { |
strip.setPixelColor(i, strip. Color(0, 0, 0)); |
} |
} |
voidshowTime() { |
DateTime now = rtc.now(); |
hourPixel = now.hour() % 12; |
minutePixel = (now.minute() / 5) % 12 + 12; |
chiaro(); |
// strip.setPixelColor(hourPixel, strip. Color(40 + 40 * level[hourPixel], 30 + 30 * level[hourPixel], 20 + 20 * level[hourPixel])); |
// strip.setPixelColor(minutePixel, strip. Color(40 + 40 * level[minutePixel], 30 + 30 * level[minutePixel], 20 + 20 * level[minutePixel])); |
strip.setPixelColor(hourPixel, strip. Color(level[hourPixel], level[hourPixel], level[hourPixel])); |
strip.setPixelColor(minutePixel, strip. Color(level[minutePixel], level[minutePixel], level[minutePixel])); |
// lightUp(strip. Color(255, 255, 255)); |
strip.show(); |
} |
voidshowTime(int ora, int minuto) { |
hourPixel = ora % 12; |
minutePixel = (minuti / 5) % 12 + 12; |
chiaro(); |
// strip.setPixelColor(hourPixel, strip. Color(40 + 40 * level[hourPixel], 30 + 30 * level[hourPixel], 20 + 20 * level[hourPixel])); |
// strip.setPixelColor(minutePixel, strip. Color(40 + 40 * level[minutePixel], 30 + 30 * level[minutePixel], 20 + 20 * level[minutePixel])); |
strip.setPixelColor(hourPixel, strip. Color(level[hourPixel], level[hourPixel], level[hourPixel])); |
strip.setPixelColor(minutePixel, strip. Color(level[minutePixel], level[minutePixel], level[minutePixel])); |
// lightUp(strip. Color(255, 255, 255)); |
strip.show(); |
} |
voidlightUp(uint32_t color) { |
for (uint16_t i = 0; i < strip.numPixels(); i++) { |
strip.setPixelColor(i, colore); |
} |
strip.show(); |
} |
voidlightUpEven() { |
for (uint16_t i = 0; i < strip.numPixels(); i++) { |
strip.setPixelColor(i, strip. Color(livello, livello, livello)); |
} |
strip.show(); |
} |
visualizza rawplywoodClock.ino ospitato con ❤ da GitHub
Passaggio 10: Visione artificiale - Calibrazione
Ho fatto una scelta consapevole di non usare l'impiallacciatura in questo progetto. Se lo avessi fatto, lo spessore del legno sarebbe stato lo stesso davanti a tutti i LED. Ma, poiché ho uno spessore di legno diverso davanti a ciascun LED e poiché anche il colore del legno varia molto, la luminosità del LED è diversa per ciascun LED. Per far sembrare che tutti i LED abbiano la stessa luminosità, ho escogitato un trucco intelligente.
Ho scritto un codice di elaborazione (su GitHub) che scatta una foto dell'orologio e analizza a turno la luminosità di ciascun LED. Quindi varia la potenza di ciascun LED per cercare di far sì che tutti abbiano la stessa luminosità del LED più fioco. Ora, so che è eccessivo, ma l'elaborazione delle immagini è molto divertente! E spero di sviluppare il codice di calibrazione come una libreria.
Puoi vedere la luminosità del LED prima e dopo la calibrazione nelle foto sopra.
calibrateDisplay.pde
importprocessing.video.*; |
importprocessing.serial.*; |
myPort seriale; |
Cattura video; |
finalent numLed =24; |
int ledNum =0; |
// devi avere queste variabili globali per usare PxPGetPixelDark() |
int rScuro, gScuro, bScuro, aScuro; |
int rLed, gLed, bLed, aLed; |
int rOrg, gOrg, bOrg, aOrg; |
int rTemp, gTemp, bTemp, aTemp; |
PImage nostraImmagine; |
int runNumber =0; |
int accettabileError =3; |
int fatto; |
int numPixelsInLed; |
lungo ledIntensità; |
int ledPower; |
lungo targetIntensity =99999999; |
voidsetup() { |
done =newint[numLed]; |
numPixelsInLed =newint[numLed]; |
ledIntensity =newlong[numLed]; |
ledPower =newint[numLed]; |
for (int i=0; i<numLed; i++) { |
ledPower =255; |
} |
printArray(Serial.list()); |
String nomeporta =Serial.list()[31]; |
myPort =newSerial(this, portName, 9600); |
dimensione (640, 480); |
video =newCapture(questo, larghezza, altezza); |
video.start(); |
noStroke(); |
liscio(); |
ritardo(1000); // Attendi l'apertura della porta seriale |
} |
voiddraw() { |
if (video.disponibile()) { |
if (fatto[num.led] ==0) { |
clearDisplay(); |
ritardo(1000); |
video.leggi(); |
immagine(video, 0, 0, larghezza, altezza); // Disegna il video della webcam sullo schermo |
saveFrame("data/no_leds.jpg"); |
if (runNumber !=0) { |
if ((ledIntensity[ledNum] - targetIntensity)*100/targetIntensity > accettabileErrore) { |
ledPower[ledNum] -=pow(0.75, runNumber)*100+1; |
} |
if ((targetIntensity - ledIntensity[ledNum])*100/targetIntensity > accettabileError) { |
ledPower[ledNum] +=pow(0.75, runNumber)*100+1; |
} |
if (abs(targetIntensity - ledIntensity[ledNum])*100/targetIntensity <= errore accettabile) { |
done[ledNum] =1; |
print("Led"); |
print(numero led); |
print("fatto"); |
} |
if (ledPower[ledNum] >255) { |
ledPower[ledNum] =255; |
} |
if (ledPower[ledNum] <0) { |
ledPower[ledNum]=0; |
} |
} |
setLedPower(ledNum, ledPower[ledNum]); |
ritardo(1000); |
video.leggi(); |
immagine(video, 0, 0, larghezza, altezza); // Disegna il video della webcam sullo schermo |
ritardo(10); |
while (myPort.available() >0) { |
int inByte = myPort.read(); |
//print(char(inByte)); |
} |
String imageName ="dati/"; |
nomeimmagine+=str(ledNum); |
nomeimmagine +="_led.jpg"; |
saveFrame(nomeimmagine); |
String originalImageName ="data/org"; |
originalImageName+=str(ledNum); |
nomeImmagineoriginale +=".jpg"; |
if (runNumber ==0) { |
saveFrame(nomeImmagineoriginale); |
} |
PImage noLedImg =loadImage("data/no_leds.jpg"); |
PImage ledImg =loadImage(imageName); |
PImage originalImg =loadImage(originalImageName); |
noLedImg.loadPixels(); |
ledImg.loadPixels(); |
originalImg.loadPixels(); |
sfondo (0); |
loadPixel(); |
ledIntensity[ledNum] =0; |
numPixelsInLed[ledNum] =0; |
for (int x =0; x<larghezza; x++) { |
for (int y =0; y<altezza; y++) { |
PxPGetPixelDark(x, y, noLedImg.pixel, larghezza); |
PxPGetPixelLed(x, y, ledImg.pixel, larghezza); |
PxPGetPixelOrg(x, y, originalImg.pixels, width); |
if ((rOrg+gOrg/2+bOrg/3)-(rDark+gDark/2+bDark/3) >75) { |
ledIntensity[ledNum] = ledIntensity[ledNum] +(rLed+gLed/2+bLed/3) -(rDark+gDark/2+bDark/3); |
rTemp=255; |
gTemp=255; |
bTemp=255; |
numPixelsInLed[ledNum]++; |
} altro { |
rTemp=0; |
gTemp=0; |
bTemp=0; |
} |
PxPSetPixel(x, y, rTemp, gTemp, bTemp, 255, pixel, larghezza); |
} |
} |
ledIntensity[ledNum] /= numPixelsInLed[ledNum]; |
if (targetIntensity > ledIntensity[ledNum] && runNumber ==0) { |
targetIntensity = ledIntensity[ledNum]; |
} |
updatePixel(); |
} |
print(numero led); |
stampa(', '); |
print(ledPower[ledNum]); |
stampa(', '); |
println(ledIntensity[ledNum]); |
ledNum++; |
if (ledNum == numLed) { |
int donezo =0; |
for (int i=0; i<numLed; i++) { |
donezo += fatto; |
} |
if (donezo == numLed) { |
println("FATTO"); |
for (int i=0; i<numLed; i++) { |
stampa(i); |
print("\t"); |
println(ledPower); |
} |
print("livello int["); |
print(numero led); |
print("] = {"); |
for (int i=0; i<numLed-1; i++) { |
print(ledPower); |
stampa(', '); |
} |
print(ledPower[numLed -1]); |
println("};"); |
lightUpEven(); |
mentre (vero); |
} |
print("Intensità obiettivo: "); |
if (runNumber ==0) { |
targetIntensity -=1; |
} |
println(targetIntensity); |
ledNum =0; |
runNumber++; |
} |
} |
} |
voidPxPGetPixelOrg(intx, inty, int pixelArray, intpixelsWidth) { |
int thisPixel=pixelArray[x+y*pixelsWidth]; // ottengo i colori come int dai pixels |
aOrg = (thisPixel >>24) &0xFF; // dobbiamo spostare e mascherare per ottenere ogni componente da solo |
rOrg = (thisPixel >>16) &0xFF; // questo è più veloce che chiamare red(), green(), blue() |
gOrg = (thisPixel >>8) &0xFF; |
bOrg = thisPixel &0xFF; |
} |
voidPxPGetPixelDark(intx, inty, int pixelArray, intpixelsWidth) { |
int thisPixel=pixelArray[x+y*pixelsWidth]; // ottengo i colori come int dai pixels |
aDark = (thisPixel >>24) &0xFF; // dobbiamo spostare e mascherare per ottenere ogni componente da solo |
rDark = (thisPixel >>16) &0xFF; // questo è più veloce che chiamare red(), green(), blue() |
gDark = (thisPixel >>8) &0xFF; |
bDark = thisPixel &0xFF; |
} |
voidPxPGetPixelLed(intx, inty, int pixelArray, intpixelsWidth) { |
int thisPixel=pixelArray[x+y*pixelsWidth]; // ottengo i colori come int dai pixels |
aLed = (thisPixel >>24) &0xFF; // dobbiamo spostare e mascherare per ottenere ogni componente da solo |
rLed = (questoPixel >>16) &0xFF; // questo è più veloce che chiamare red(), green(), blue() |
gLed = (thisPixel >>8) &0xFF; |
bLed = questoPixel &0xFF; |
} |
voidPxPSetPixel(intx, inty, intr, intg, intb, inta, int pixelArray, intpixelsWidth) { |
a =(a<24); |
r = r<16; // Stiamo impacchettando tutti e 4 i componenti in un unico int |
g = g<8; // quindi dobbiamo spostarli al loro posto |
colore argb = a | r | g | B; // operazione binaria "or" li aggiunge tutti in un int |
pixelArray[x+y*pixelsWidth]= argb; // finalmente impostiamo l'int con i colori nei pixel |
} |
visualizza rawcalibrateDispllay.pde ospitato con ❤ da GitHub
Passaggio 11: osservazioni di separazione
Insidie da evitare:
* Con il legno, ottieni quello per cui paghi. Quindi, procurati un legno di buona qualità. Il compensato di betulla è una buona scelta; anche qualsiasi legno massello chiaro andrà bene. Ho perso il legno e mi pento della mia decisione.
* È meglio perforare di meno che di più. Un paio di buchi sono andati troppo in profondità per il mio pezzo. E la resina epossidica si vede attraverso la faccia anteriore. È molto evidente una volta che lo noti.
* Utilizzare una punta da trapano con estremità sferica invece di un'estremità diritta. Non ho sperimentato la punta a sfera, ma sono abbastanza sicuro che i risultati saranno molto migliori.
Sto flirtando con l'idea di venderli su Etsy o tindie. Ti sarei davvero grato se potessi commentare qui sotto se pensi che abbia senso:)
Consigliato:
LEDura - Orologio LED analogico: 12 passi (con immagini)
LEDura - Orologio analogico a LED: dopo tanto tempo dedicato alla realizzazione di vari progetti, ho deciso di creare io stesso un istruibile. Per il primo, ti guiderò attraverso il processo di creazione del tuo orologio analogico realizzato con un fantastico anello LED indirizzabile. L'anello interno mostra le ore, ou
Come creare un orologio analogico e un orologio digitale con una striscia LED usando Arduino: 3 passaggi
Come creare un orologio analogico e un orologio digitale con una striscia LED usando Arduino: oggi realizzeremo un orologio analogico e un orologio Orologio digitale con Led Strip e modulo MAX7219 Dot con Arduino. Correggerà l'ora con il fuso orario locale. L'orologio analogico può utilizzare una striscia LED più lunga, quindi può essere appeso al muro per diventare un'opera d'arte
C51 Orologio elettronico a 4 bit - Orologio in legno: 15 passi (con immagini)
C51 Orologio elettronico a 4 bit - Orologio in legno: ho avuto un po' di tempo libero questo fine settimana, quindi sono andato avanti e ho assemblato questo orologio digitale elettronico fai-da-te a 4 bit da AU $ 2,40 che ho acquistato da AliExpress qualche tempo fa
Orologio digitale analogico: 4 passi (con immagini)
Orologio digitale analogico: il motivo per cui ho realizzato questo orologio è stato perché il mio orologio IKEA originale non funzionava più e mi è piaciuto molto l'alloggiamento di questo orologio. Ho trovato uno spreco buttare via l'orologio e ho deciso di riutilizzarlo per un orologio analogico/digitale. Avrei potuto arrabbiarmi
Orologio digitale in legno massello: 11 passi (con immagini)
Orologio digitale in legno massello: come costruire un orologio digitale in legno alimentato da un atmega168 (arduino) con sveglia e giochi integrati. Ho pensato di realizzarlo per la prima volta quando ho visto un orologio a LED ricoperto da un'impiallacciatura di legno. Mi è piaciuto quando l'ho visto, finché non ho visto il prezzo. Questo è dove