Cuprins:

Ceas LED din lemn - Stil analogic: 11 pași (cu imagini)
Ceas LED din lemn - Stil analogic: 11 pași (cu imagini)

Video: Ceas LED din lemn - Stil analogic: 11 pași (cu imagini)

Video: Ceas LED din lemn - Stil analogic: 11 pași (cu imagini)
Video: I-am luat Rolex in Dubai si tot nu ma suporta... 2024, Noiembrie
Anonim
Ceas LED din lemn - stil analogic
Ceas LED din lemn - stil analogic

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:

Imagine
Imagine
Imagine
Imagine

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

Proiecta
Proiecta
Proiecta
Proiecta

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

CNCing
CNCing
CNCing
CNCing
CNCing
CNCing
CNCing
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ă

Electronică
Electronică
Electronică
Electronică
Electronică
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ă

Asamblare electronică
Asamblare electronică
Asamblare electronică
Asamblare electronică
Asamblare electronică
Asamblare electronică
Asamblare electronică
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

Alergare uscată
Alergare uscată
Alergare uscată
Alergare uscată
Alergare uscată
Alergare uscată
Alergare uscată
Alergare uscată

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

Epoxidic
Epoxidic
Epoxidic
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ă

Punând totul împreună
Punând totul împreună
Punând totul împreună
Punând totul împreună
Punând totul împreună
Punând totul împreună
Punând totul împreună
Punând 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

Cod
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

Viziune computerizată - Calibrare
Viziune computerizată - Calibrare
Viziune computerizată - Calibrare
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: