Cuprins:
- Pasul 1:
- Pasul 2: Proiectare
- Pasul 3: CNCing
- Pasul 4: Electronică
- Pasul 5: Asamblare electronică
- Pasul 6: Run Dry
- Pasul 7: Epoxidic
- Pasul 8: Puneți totul împreună
- Pasul 9: Cod
- Pasul 10: Viziune computerizată - Calibrare
- Pasul 11: Remarci de despărțire
Video: Ceas LED din lemn - Stil analogic: 11 pași (cu imagini)
2024 Autor: John Day | [email protected]. Modificat ultima dată: 2024-01-30 11:46
Este un ceas LED din lemn în stil analogic. Nu știu de ce nu am mai văzut una dintre acestea până acum.. chiar dacă tipurile digitale sunt foarte frecvente. Oricum, iată-ne!
Pasul 1:
Proiectul de ceas din placaj a început ca un simplu proiect de pornire pentru routerul CNC. Mă uitam la proiecte simple online și am găsit această lampă (imaginea de mai sus). Văzusem și ceasuri digitale care străluceau prin furnir de lemn (imaginea de mai sus). Așadar, combinarea celor două proiecte a fost o idee evidentă. Căutând să mă provoc, am decis să nu folosesc furnir, ci doar o bucată de lemn pentru acest proiect.
Pasul 2: Proiectare
Am proiectat ceasul în Inkscape (imaginea de mai sus). Designul este foarte simplu la alegere. Am decis să nu urmăresc traseele pentru fire, deoarece în acest moment nu eram sigur dacă voiam să merg cu cabluri radiale sau perimetrale. (Am decis să merg cu cablajul perimetral în cele din urmă.) Un neopixel intră în fiecare dintre găurile mici circulare pentru a arăta minutul și ora, cu o precizie de cinci minute. Cercul din mijloc va fi direcționat pentru a găzdui componentele electronice.
Pasul 3: CNCing
Am proiectat traseele de instrumente de pe MasterCAM și am folosit un technoRouter pentru a măcina ceasul din placaj de 3/4 inch. Folosesc o piesă de 15 "x15" pentru aceasta, cu risipa minimă. Trucul este de a direcționa cât mai mult din lemn posibil fără a sparge lemnul. Lăsarea de 0,05 "-0,1" este o alegere bună pentru lemnul ușor. Dacă nu sunteți sigur, este mai bine să lăsați mai mult lemn, deoarece puteți oricând șlefui cealaltă față. Am ajuns să scot puțin prea mult lemn din unele părți, dar din fericire rezultatele nu suferă prea mult din această cauză.
Notă pentru utilizatorii fără acces la un CNC:
Acest proiect poate fi realizat cu ușurință cu o presă de burghiu. Trebuie doar să setați opritorul într-un punct în care lăsați aproximativ 0,1 de lemn rămas la bază. Va trebui să fiți preciși, dar nu prea preciși. La urma urmei, în mod ideal, nimeni nu va vedea toate LED-urile aprinse la în același timp, astfel încât să puteți scăpa cu o mică înclinație.
Pasul 4: Electronică
Electronica este destul de simplă. Există 24 de neopixeli, doisprezece pentru afișarea orelor și doisprezece pentru afișarea minutelor, cu o precizie de cinci minute. Un Arduino pro mini controlează neopixeli și obține timp precis printr-un modul DS3231 în timp real (RTC). Modulul RTC are o celulă monedă ca rezervă, deci nu pierde timp chiar și atunci când alimentarea este oprită.
Material:
Arduino pro mini (sau orice alt Arduino de altfel)
Placă DS3231
Neopixeli în plăci individuale
Pasul 5: Asamblare electronică
Am conectat neopixelii într-un șir, folosind fire de 2,5 pentru primele douăsprezece leduri și sârmă de patru inci pentru următorii doisprezece. Aș fi putut folosi lungimi de sârmă puțin mai mici. După ce am făcut șirul, l-am testat, asigurându-mă că lipirea îmbinările au fost bune. Am adăugat un comutator momentan pentru a porni toate ledurile, doar pentru a arăta.
Pasul 6: Run Dry
După ce am experimentat, am pus LED-uri în găuri și le-am aprins pe toate, am fost mulțumit de rezultate. Așa că am șlefuit puțin fața frontală și am aplicat un strat de PU. Am ajuns să șlefuiesc haina mai târziu, dar este o idee bună să o las pe ea dacă nu vi se pare neplăcută din punct de vedere estetic.
Pasul 7: Epoxidic
După câteva testări cu poziția led în interiorul orificiilor, m-am gândit că cea mai bună discuție se realizează atunci când LED-urile sunt la aproximativ 0,2 distanță de capătul găurii. Când încercați singur, luminozitatea LED-urilor va fi foarte diferită în fiecare gaură. Nu vă faceți griji în legătură cu acest lucru; o vom rezolva în cod. Acest lucru se datorează tipului de burghiu pe care l-am folosit. Dacă ar fi să fac asta din nou, aș folosi un burghie cu bile pentru găuri Dar, în orice caz, pentru a obține distanța, am amestecat ceva epoxidic și am pus puțin în fiecare gaură.
Pasul 8: Puneți totul împreună
LED-urile vor fi plasate începând de la poziția mâinii orelor de la ora 12, deplasându-se în sens invers acelor de ceasornic prin toate pozițiile mâinii orelor și apoi la axa minutelor, deplasându-se din nou de la semnul de 60 de minute care se deplasează în sens invers acelor de ceasornic. Acest lucru se întâmplă astfel încât atunci când privim din față, modelul LED apare în sensul acelor de ceasornic.
După ce epoxidul s-a vindecat timp de o oră, am mai pus ceva epoxidic. De data aceasta, am plasat LED-urile în găuri, asigurându-mă că acoperiți firele și îmbinările de lipit cu epoxidic. Acest lucru asigură o bună difuzie a luminii și asigură firele.
Pasul 9: Cod
Codul este pe GitHub, nu ezitați să îl modificați pentru utilizarea dvs. Când porniți toate LED-urile la același nivel, luminozitatea luminii care strălucește va fi foarte diferită în fiecare gaură. Acest lucru se datorează grosimii diferite a lemnului în găuri și diferenței de nuanță a lemnului. După cum puteți vedea, culoarea lemnului variază destul de mult în piesa mea. Pentru a remedia această diferență de luminozitate, am realizat o matrice de niveluri de luminozitate led. Și a scăzut luminozitatea LED-urilor mai luminoase. Este un proces de încercare și eroare și poate dura câteva minute, dar rezultatele merită.
placajClock.ino
// Ceas din placaj |
// Autor: tinkrmind |
// Atribuire 4.0 internațională (CC BY 4.0). Ești liber să: |
// Partajare - copiați și redistribuiți materialul în orice mediu sau format |
// Adaptează - remixează, transformă și construiește pe material pentru orice scop, chiar și din punct de vedere comercial. |
// Ura! |
#include |
#include "RTClib.h" |
RTC_DS3231 rtc; |
#include "Adafruit_NeoPixel.h" |
#ifdef _AVR_ |
#include |
#endif |
# definePIN6 |
Adafruit_NeoPixel strip = Adafruit_NeoPixel (60, PIN, NEO_GRB + NEO_KHZ800); |
int hourPixel = 0; |
int minutePixel = 0; |
unsignedlong lastRtcCheck; |
String inputString = ""; // un șir pentru a păstra datele primite |
șir boolean Complet = fals; // dacă șirul este complet |
nivel 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 |
while (! Serial); // pentru Leonardo / Micro / Zero |
#endif |
// Aceasta este pentru Trinket 5V 16MHz, puteți elimina aceste trei linii dacă nu utilizați un Trinket |
#if definit (_AVR_ATtiny85_) |
if (F_CPU == 16000000) clock_prescale_set (clock_div_1); |
#endif |
// Sfârșitul codului special bibelou |
Serial.begin (9600); |
strip.begin (); |
strip.show (); // Inițializați toți pixelii la „dezactivat” |
if (! rtc.begin ()) { |
Serial.println („Nu s-a putut găsi RTC”); |
în timp ce (1); |
} |
pinMode (2, INPUT_PULLUP); |
// rtc.adjust (DateTime (F (_ DATE_), F (_ TIME_))); |
if (rtc.lostPower ()) { |
Serial.println ("RTC a pierdut puterea, permite să setăm ora!"); |
// următoarea linie setează RTC la data și ora la care a fost compilată această schiță |
rtc.adjust (DateTime (F (_ DATE_), F (_ TIME_)))); |
// Această linie setează RTC cu o dată și o oră explicite, de exemplu pentru a seta |
// 21 ianuarie 2014 la ora 03:00 sunați la: |
// rtc.adjust (DateTime (2017, 11, 06, 2, 49, 0)); |
} |
// rtc.adjust (DateTime (2017, 11, 06, 2, 49, 0)); |
// lightUpEven (); |
// while (1); |
lastRtcCheck = 0; |
} |
voidloop () { |
if (millis () - lastRtcCheck> 2000) { |
DateTime acum = rtc.now (); |
Serial.print (now.hour (), DEC); |
Serial.print (':'); |
Serial.print (now.minute (), DEC); |
Serial.print (':'); |
Serial.print (now.second (), DEC); |
Serial.println (); |
arată timpul(); |
lastRtcCheck = millis (); |
} |
if (! digitalRead (2)) { |
lightUpEven (); |
} |
if (stringComplete) { |
Serial.println (inputString); |
if (inputString [0] == 'l') { |
Serial.println ("Nivel"); |
lightUpEven (); |
} |
if (inputString [0] == 'c') { |
Serial.println („Afișarea timpului”); |
arată timpul(); |
strip.show (); |
} |
if (inputString [0] == '1') { |
Serial.println („Pornirea tuturor LED-urilor”); |
lightUp (strip. Color (255, 255, 255)); |
strip.show (); |
} |
if (inputString [0] == '0') { |
Serial.println („Banda de compensare”); |
clar(); |
strip.show (); |
} |
// # 3, 255 ar seta numărul led 3 la nivelul 255, 255, 255 |
if (inputString [0] == '#') { |
String temp; |
temp = inputString.substring (1); |
int pixNum = temp.toInt (); |
temp = inputString.substring (inputString.indexOf (',') + 1); |
int intensitate = temp.toInt (); |
Serial.print („Setare”); |
Serial.print (pixNum); |
Serial.print („la nivel”); |
Serial.println (intensitate); |
strip.setPixelColor (pixNum, strip. Color (intensitate, intensitate, intensitate)); |
strip.show (); |
} |
// # 3, 255, 0, 125 ar seta ledul numărul 3 la nivelul 255, 0, 125 |
if (inputString [0] == '$') { |
String temp; |
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 bIntensitate = temp.toInt (); |
Serial.print („Setare”); |
Serial.print (pixNum); |
Serial.print ("de la R la"); |
Serial.print (rIntensity); |
Serial.print ("G la"); |
Serial.print (gIntensity); |
Serial.print ("de la B la"); |
Serial.println (bIntensity); |
strip.setPixelColor (pixNum, strip. Color (rIntensity, gIntensity, bIntensity)); |
strip.show (); |
} |
if (inputString [0] == 's') { |
String temp; |
oră, minut; |
temp = inputString.substring (1); |
ora = temp.toInt (); |
int rIndex = inputString.indexOf (',') + 1; |
temp = inputString.substring (rIndex); |
minute = temp.toInt (); |
Serial.print („Se afișează timpul:”); |
Serial.print (oră); |
Serial.print (":"); |
Serial.print (minut); |
showTime (oră, minut); |
întârziere (1000); |
} |
inputString = ""; |
stringComplete = false; |
} |
// întârziere (1000); |
} |
voidserialEvent () { |
while (Serial.available ()) { |
char inChar = (char) Serial.read (); |
inputString + = inChar; |
if (inChar == '\ n') { |
stringComplete = adevărat; |
} |
întârziere (1); |
} |
} |
voidclear () { |
pentru (uint16_t i = 0; i <strip.numPixels (); i ++) { |
strip.setPixelColor (i, strip. Color (0, 0, 0)); |
} |
} |
voidshowTime () { |
DateTime acum = rtc.now (); |
hourPixel = now.hour ()% 12; |
minutePixel = (now.minute () / 5)% 12 + 12; |
clar(); |
// strip.setPixelColor (hourPixel, strip. Color (40 + 40 * nivel [hourPixel], 30 + 30 * level [hourPixel], 20 + 20 * level [hourPixel])); |
// strip.setPixelColor (minutePixel, strip. Color (40 + 40 * nivel [minutePixel], 30 + 30 * nivel [minutePixel], 20 + 20 * nivel [minutePixel])); |
strip.setPixelColor (hourPixel, strip. Color (nivel [hourPixel], level [hourPixel], level [hourPixel])); |
strip.setPixelColor (minutePixel, strip. Color (nivel [minutePixel], nivel [minutePixel], nivel [minutePixel])); |
// lightUp (strip. Color (255, 255, 255)); |
strip.show (); |
} |
voidshowTime (oră int, minut int) { |
hourPixel = ora% 12; |
minute Pixel = (minut / 5)% 12 + 12; |
clar(); |
// strip.setPixelColor (hourPixel, strip. Color (40 + 40 * nivel [hourPixel], 30 + 30 * level [hourPixel], 20 + 20 * level [hourPixel])); |
// strip.setPixelColor (minutePixel, strip. Color (40 + 40 * nivel [minutePixel], 30 + 30 * nivel [minutePixel], 20 + 20 * nivel [minutePixel])); |
strip.setPixelColor (hourPixel, strip. Color (nivel [hourPixel], level [hourPixel], level [hourPixel])); |
strip.setPixelColor (minutePixel, strip. Color (nivel [minutePixel], nivel [minutePixel], nivel [minutePixel])); |
// lightUp (strip. Color (255, 255, 255)); |
strip.show (); |
} |
voidlightUp (uint32_t color) { |
pentru (uint16_t i = 0; i <strip.numPixels (); i ++) { |
strip.setPixelColor (i, culoare); |
} |
strip.show (); |
} |
voidlightUpEven () { |
pentru (uint16_t i = 0; i <strip.numPixels (); i ++) { |
strip.setPixelColor (i, strip. Color (nivel , nivel , nivel )); |
} |
strip.show (); |
} |
vizualizați rawplywoodClock.ino găzduit cu ❤ de GitHub
Pasul 10: Viziune computerizată - Calibrare
Am făcut o alegere conștientă de a nu folosi furnir în acest proiect. Dacă aș fi avut, grosimea lemnului ar fi fost aceeași în fața tuturor LED-urilor. Dar, pentru că am o grosime diferită de lemn în fața fiecărui LED și pentru că și culoarea lemnului variază foarte mult, luminozitatea LED-ului este diferită pentru fiecare LED. Pentru ca toate LED-urile să pară de aceeași luminozitate, am conceput un truc ingenios.
Am scris un cod de procesare (pe GitHub) care face o fotografie a ceasului și analizează la rândul său luminozitatea fiecărui LED. Apoi, variază puterea fiecărui LED pentru a încerca să-i facă pe toți să aibă aceeași luminozitate ca cel mai slab LED. Acum, știu că acest lucru este excesiv, dar procesarea imaginilor este foarte distractivă! Și sper să dezvolt codul de calibrare ca bibliotecă.
Puteți vedea luminozitatea LED-ului înainte și după calibrare în fotografiile de mai sus.
calibrateDispllay.pde
importprocessing.video. *; |
importprocessing.serial. *; |
Serial myPort; |
Captura video; |
finalint numLed = 24; |
int ledNum = 0; |
// trebuie să aveți aceste variabile globale pentru a utiliza PxPGetPixelDark () |
int rDark, gDark, bDark, aDark; |
int rLed, gLed, bLed, aLed; |
int rOrg, gOrg, bOrg, aOrg; |
int rTemp, gTemp, bTemp, aTemp; |
PImage imaginea noastră; |
int runNumber = 0; |
int acceptableError = 3; |
int făcut; |
int numPixelsInLed; |
long ledIntensity; |
int ledPower; |
long 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 portName = Serial.list () [31]; |
MyPort = newSerial (this, portName, 9600); |
dimensiune (640, 480); |
video = newCapture (aceasta, lățime, înălțime); |
video.start (); |
noStroke (); |
neted(); |
întârziere (1000); // Așteptați deschiderea portului serial |
} |
voiddraw () { |
if (video.available ()) { |
if (gata [ledNum] == 0) { |
clearDisplay (); |
întârziere (1000); |
video.read (); |
imagine (video, 0, 0, lățime, înălțime); // Desenați videoclipul camerei web pe ecran |
saveFrame („date / no_leds.jpg”); |
if (runNumber! = 0) { |
if ((ledIntensity [ledNum] - targetIntensity) * 100 / targetIntensity> acceptableError) { |
ledPower [ledNum] - = pow (0,75, runNumber) * 100 + 1; |
} |
if ((targetIntensity - ledIntensity [ledNum]) * 100 / targetIntensity> acceptableError) { |
ledPower [ledNum] + = pow (0,75, runNumber) * 100 + 1; |
} |
if (abs (targetIntensity - ledIntensity [ledNum]) * 100 / targetIntensity <= acceptableError) { |
done [ledNum] = 1; |
print ("Led"); |
print (ledNum); |
print („gata”); |
} |
if (ledPower [ledNum]> 255) { |
ledPower [ledNum] = 255; |
} |
if (ledPower [ledNum] <0) { |
ledPower [ledNum] = 0; |
} |
} |
setLedPower (ledNum, ledPower [ledNum]); |
întârziere (1000); |
video.read (); |
imagine (video, 0, 0, lățime, înălțime); // Desenați videoclipul camerei web pe ecran |
întârziere (10); |
while (myPort.available ()> 0) { |
int inByte = MyPort.read (); |
// print (char (inByte)); |
} |
String imageName = "date /"; |
imageName + = str (ledNum); |
imageName + = "_ led.jpg"; |
saveFrame (imageName); |
String originalImageName = "date / org"; |
OriginalImageName + = str (ledNum); |
originalImageName + = ". jpg"; |
if (runNumber == 0) { |
saveFrame (originalImageName); |
} |
PImage noLedImg = loadImage ("date / no_leds.jpg"); |
PImage ledImg = loadImage (imageName); |
PImage originalImg = loadImage (originalImageName); |
noLedImg.loadPixels (); |
ledImg.loadPixels (); |
originalImg.loadPixels (); |
fundal (0); |
loadPixels (); |
ledIntensity [ledNum] = 0; |
numPixelsInLed [ledNum] = 0; |
for (int x = 0; x <width; x ++) { |
for (int y = 0; y <înălțime; y ++) { |
PxPGetPixelDark (x, y, noLedImg.pixels, lățime); |
PxPGetPixelLed (x, y, ledImg.pixels, lățime); |
PxPGetPixelOrg (x, y, OriginalImg.pixels, lățime); |
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] ++; |
} altceva { |
rTemp = 0; |
gTemp = 0; |
bTemp = 0; |
} |
PxPSetPixel (x, y, rTemp, gTemp, bTemp, 255, pixeli, lățime); |
} |
} |
ledIntensity [ledNum] / = numPixelsInLed [ledNum]; |
if (targetIntensity> ledIntensity [ledNum] && runNumber == 0) { |
targetIntensity = ledIntensity [ledNum]; |
} |
updatePixels (); |
} |
print (ledNum); |
imprimare(', '); |
print (ledPower [ledNum]); |
imprimare(', '); |
println (ledIntensity [ledNum]); |
ledNum ++; |
if (ledNum == numLed) { |
int donezo = 0; |
for (int i = 0; i <numLed; i ++) { |
donezo + = done ; |
} |
if (donezo == numLed) { |
println ("GĂSIT"); |
for (int i = 0; i <numLed; i ++) { |
print (i); |
print ("\ t"); |
println (ledPower ); |
} |
print ("nivel int ["); |
print (ledNum); |
print ("] = {"); |
for (int i = 0; i <numLed-1; i ++) { |
print (ledPower ); |
imprimare(', '); |
} |
print (ledPower [numLed -1]); |
println ("};"); |
lightUpEven (); |
while (adevărat); |
} |
print ("Intensitatea țintei:"); |
if (runNumber == 0) { |
targetIntensity - = 1; |
} |
println (targetIntensity); |
ledNum = 0; |
runNumber ++; |
} |
} |
} |
voidPxPGetPixelOrg (intx, inty, int pixelArray, intpixelsWidth) { |
int thisPixel = pixelArray [x + y * pixelsWidth]; // obținerea culorilor ca int din pixeli |
aOrg = (thisPixel >> 24) & 0xFF; // trebuie să schimbăm și să mascăm pentru a obține fiecare componentă singură |
rOrg = (thisPixel >> 16) & 0xFF; // acest lucru este mai rapid decât apelarea roșu (), verde (), albastru () |
gOrg = (thisPixel >> 8) & 0xFF; |
bOrg = thisPixel & 0xFF; |
} |
voidPxPGetPixelDark (intx, inty, int pixelArray, intpixelsWidth) { |
int thisPixel = pixelArray [x + y * pixelsWidth]; // obținerea culorilor ca int din pixeli |
aDark = (thisPixel >> 24) & 0xFF; // trebuie să schimbăm și să mascăm pentru a obține fiecare componentă singură |
rDark = (thisPixel >> 16) & 0xFF; // acest lucru este mai rapid decât apelarea roșu (), verde (), albastru () |
gDark = (thisPixel >> 8) & 0xFF; |
bDark = thisPixel & 0xFF; |
} |
voidPxPGetPixelLed (intx, inty, int pixelArray, intpixelsWidth) { |
int thisPixel = pixelArray [x + y * pixelsWidth]; // obținerea culorilor ca int din pixeli |
aLed = (thisPixel >> 24) & 0xFF; // trebuie să schimbăm și să mascăm pentru a obține fiecare componentă singură |
rLed = (thisPixel >> 16) & 0xFF; // acest lucru este mai rapid decât apelarea roșu (), verde (), albastru () |
gLed = (thisPixel >> 8) & 0xFF; |
bLed = thisPixel & 0xFF; |
} |
voidPxPSetPixel (intx, inty, intr, intg, intb, inta, int pixelArray, intpixelsWidth) { |
a = (a << 24); |
r = r << 16; // Am ambalat toate cele 4 componente într-un singur int |
g = g << 8; // deci trebuie să le mutăm la locurile lor |
culoare argb = a | r | g | b; // operația "binară" sau "le adaugă pe toate într-un singur int |
pixelArray [x + y * pixelsWidth] = argb; // în cele din urmă am setat int cu te culori în pixeli |
} |
vizualizați rawcalibrateDispllay.pde găzduit cu ❤ de GitHub
Pasul 11: Remarci de despărțire
Capcanele de evitat:
* Cu lemnul, primești ceea ce plătești. Deci, obțineți lemn de bună calitate. Placajul de mesteacăn este o alegere bună; orice lemn masiv ușor se va descurca frumos. Am ieftinit lemnul și regret decizia mea.
* Este mai bine să găuriți mai puțin decât mai mult. Câteva găuri au mers prea adânc pentru piesa mea. Și epoxidul arată pe fața frontală. Este foarte vizibil odată ce îl observi.
* Folosiți un burghiu cu bile în locul unui capăt drept. Nu am experimentat bitul final al mingii, dar sunt destul de sigur că rezultatele vor fi mult mai bune.
Cochetez cu ideea de a le vinde pe Etsy sau tindie. Aș aprecia foarte mult dacă ați putea comenta mai jos dacă credeți că are sens:)
Recomandat:
Cum să faci ceas analogic și ceas digital cu bandă LED folosind Arduino: 3 pași
Cum să faci ceas analogic și ceas digital cu bandă led folosind Arduino: Astăzi vom face un ceas analogic & Ceas digital cu Led Strip și modul MAX7219 Dot cu Arduino. Acesta va corecta ora cu fusul orar local. Ceasul analogic poate folosi o bandă cu LED mai lungă, deci poate fi agățat pe perete pentru a deveni un artist
Ceas de nuntă din lemn luminat cu LED: 8 pași (cu imagini)
Ceas de nuntă din lemn luminat cu LED: am început acest proiect pentru a crea un ceas de nuntă unic, unic pentru sora și cumnatul meu. A vrut să facă ceva ce ar putea să se lumineze și să arate un aspect al zilei nunții lor pentru mult timp. Am trecut prin multe modele
Ceas LED din lemn: 5 pași (cu imagini)
Ceas LED din lemn: Ceasul LED din lemn arată ca o cutie plictisitoare din lemn, cu excepția faptului că timpul strălucește prin partea din față a acestuia. În loc să vă uitați la o bucată de plastic gri, aveți o bucată de lemn mai frumoasă. Păstrează în continuare toate funcțiile sale, inclusiv
C51 Ceas electronic cu 4 biți - Ceas din lemn: 15 pași (cu imagini)
C51 Ceas electronic cu 4 biți - Ceas din lemn: a avut ceva timp liber în acest weekend, așa că am mers mai departe și am asamblat acest 2,40 USD Ceas digital digital cu 4 biți, pe care l-am cumpărat de la AliExpress acum ceva timp
Cum se utilizează câteva bucăți de lemn pentru a se asambla într-un braț de robot din lemn drăguț și puternic: 10 pași
Cum se utilizează câteva bucăți de lemn pentru a se asambla într-un braț de roboți din lemn drăguț și puternic: numele brațului robot este WoodenArm. Arată foarte drăguț! Dacă doriți mai multe detalii despre WoodenArm, vă rugăm să consultați www.lewansoul.com Acum putem face o introducere despre WoodenArm, să mergem mai departe