Kazalo:

Lesena LED ura - analogni slog: 11 korakov (s slikami)
Lesena LED ura - analogni slog: 11 korakov (s slikami)

Video: Lesena LED ura - analogni slog: 11 korakov (s slikami)

Video: Lesena LED ura - analogni slog: 11 korakov (s slikami)
Video: Я работаю в Страшном музее для Богатых и Знаменитых. Страшные истории. Ужасы. 2024, November
Anonim
Lesena LED ura - analogni slog
Lesena LED ura - analogni slog

To je lesena LED ura v analognem slogu. Ne vem, zakaj še nisem videl enega od teh … čeprav so digitalni tipi zelo pogosti. Kakorkoli, gremo!

Korak 1:

Slika
Slika
Slika
Slika

Projekt ure iz vezanega lesa se je začel kot preprost začetni projekt za CNC usmerjevalnik. Na spletu sem iskal preproste projekte in našel to svetilko (slika zgoraj). Videl sem tudi digitalne ure, ki svetijo skozi leseni furnir (slika zgoraj). Torej je bila kombinacija obeh projektov očitna ideja. Ker sem se želel izzvati, sem se odločil, da za ta projekt ne bom uporabil furnirja, ampak le kos lesa.

2. korak: Oblikovanje

Oblikovanje
Oblikovanje
Oblikovanje
Oblikovanje

Uro sem oblikoval v Inkscapeu (slika zgoraj). Oblikovanje je po izbiri zelo preprosto. Odločil sem se, da ne bom usmerjal sledi za žice, ker na tej točki nisem bil prepričan, ali bi šel z radialnim ali obodnim ožičenjem. (Odločil sem se, da bom končno uporabil ožičenje po obodu.) V vsako od majhnih krožnih lukenj gre po en neopiksel za prikaz minute in ure s petminutno natančnostjo. Krog na sredini bo razporejen za namestitev elektronike.

3. korak: CNCing

CNCing
CNCing
CNCing
CNCing
CNCing
CNCing
CNCing
CNCing

Oblikoval sem poti orodja na MasterCAM -u in uporabil technoRouter za rezkanje ure iz 3/4 palčne vezane plošče. Za to uporabljam kos velikosti 15 "x15" z minimalno izgubo. Trik je v tem, da odstranite čim več lesa, ne da bi se prebili skozi les. Puščanje 0,05 "-0,1" je dobra izbira za svetel les. Če niste prepričani, je bolje, da pustite več lesa, saj lahko drugo stran vedno brušite. Na koncu sem z nekaterih delov odstranil malo preveč lesa, a na srečo rezultati zaradi tega ne trpijo preveč.

Opomba za uporabnike brez dostopa do CNC:

Ta projekt lahko enostavno izvedete z vrtalno stiskalnico. Ustaviti morate le na mestu, kjer pustite približno 0,1 palca lesa na dnu. Morate biti natančni, vendar ne preveč natančni. Navsezadnje v idealnem primeru nihče ne bo videl, da svetijo svetleče diode pri ob istem času, tako da se lahko izognete z malo poživitve.

4. korak: Elektronika

Elektronika
Elektronika
Elektronika
Elektronika
Elektronika
Elektronika

Elektronika je dokaj preprosta. Obstaja 24 neopikslov, dvanajst za prikaz ur in dvanajst za prikaz minut s petminutno natančnostjo. Arduino pro mini nadzoruje neopiksne pike in dobi natančen čas z modulom ure realnega časa DS3231 (RTC). Modul RTC ima rezervno celico v obliki kovanca, zato ne izgubi časa niti, ko je napajanje izklopljeno.

Material:

Arduino pro mini (ali kateri koli drug Arduino glede tega)

Odklopna plošča DS3231

Neopiksli v posameznih odmičnih deskah

5. korak: Montaža elektronike

Sestava elektronike
Sestava elektronike
Sestava elektronike
Sestava elektronike
Sestava elektronike
Sestava elektronike
Sestava elektronike
Sestava elektronike

Neopixele sem povezal v niz, pri čemer sem uporabil 2,5-palčne žice za prvih dvanajst LED in štiri palčne žice za naslednjih dvanajst. Lahko bi uporabil nekoliko manjše dolžine žic. Po izdelavi vrvice sem jo preizkusil in se prepričal, da je spajka sklepi so bili dobri. Dodal sem kratko stikalo, da vklopim vse LED diode, samo da se pokažem.

6. korak: Suhi tek

Suhi tek
Suhi tek
Suhi tek
Suhi tek
Suhi tek
Suhi tek
Suhi tek
Suhi tek

Po eksperimentiranju, vstavitvi LED v luknje in vklopu vseh, sem bil zadovoljen z rezultati. Tako sem sprednjo stran malo brusila in nanesla PU premaz. Na koncu sem pozneje brusila plašč, vendar je dobro, da ga pustite, če se vam ne zdi estetsko neprijeten.

7. korak: epoksi

Epoksi
Epoksi
Epoksi
Epoksi

Po nekaj testiranjih z vodilnim položajem v luknjah sem ugotovil, da je najboljša razprava dosežena, ko so LED diode oddaljene približno 0,2 palca od konca luknje. Ko to poskusite sami, bo svetlost LED zelo drugačna Vsaka luknja. Ne skrbite za to; popravili bomo v kodi. To je zaradi vrste svedra, ki sem ga uporabil. Če bi to ponovil, bi za luknje uporabil kroglični sveder Vsekakor pa sem, da sem dosegel razdaljo, zmešal nekaj epoksida in v vsako luknjo vstavil malo.

8. korak: Združite vse skupaj

Vse skupaj
Vse skupaj
Vse skupaj
Vse skupaj
Vse skupaj
Vse skupaj
Vse skupaj
Vse skupaj

Svetleče diode bodo nameščene od položaja 12-urne urne kazalke, ki se premika v nasprotni smeri urinega kazalca, skozi vse položaje urne ure, nato pa do minutne kazalke, spet od 60-minutne oznake, ki se premika v nasprotni smeri urinega kazalca. To je tako, da se na sprednji strani LED vzorec prikaže v smeri urinega kazalca.

Ko se je epoksid strjeval eno uro, sem dal še nekaj epoksida. Tokrat sem LED -diode postavil v luknje, pri tem pa žice in spajkalne spoje prekril z epoksidom. To omogoča dobro razpršitev svetlobe in pritrdi žice.

9. korak: Koda

Koda
Koda

Koda je na GitHubu, zato jo lahko spremenite za uporabo. Ko vklopite vse LED diode na isto raven, bo jakost svetlobe, ki sije skozi, v vsaki luknji zelo različna. To je posledica različne debeline lesa v luknjah in razlike v senci lesa. Kot vidite, se barva lesa v mojem kosu precej razlikuje. Da bi odpravili to razliko v svetlosti, sem naredil matriko ravni svetlosti LED. In zmanjšala svetlost svetlejših LED. To je postopek poskusov in napak in lahko traja nekaj minut, vendar so rezultati vredni tega.

plywoodClock.ino

// Ura iz vezanega lesa
// Avtor: tinkrmind
// Atribucija 4.0 International (CC BY 4.0). Prosto lahko:
// Skupna raba - kopirajte in distribuirajte gradivo v katerem koli mediju ali obliki
// Prilagodite - premešajte, preoblikujte in nadgradite material za kateri koli namen, tudi komercialni.
// Ura!
#vključi
#include "RTClib.h"
RTC_DS3231 rtc;
#include "Adafruit_NeoPixel.h"
#ifdef _AVR_
#vključi
#endif
#definePIN6
Adafruit_NeoPixel strip = Adafruit_NeoPixel (60, PIN, NEO_GRB + NEO_KHZ800);
int hourPixel = 0;
int minutePixel = 0;
unsignedlong lastRtcCheck;
Niz inputString = ""; // niz za shranjevanje dohodnih podatkov
logični nizComplete = false; // ali je niz popoln
int raven [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 (! Serijski); // za Leonardo/Micro/Zero
#endif
// To je za Trinket 5V 16MHz, te tri vrstice lahko odstranite, če ne uporabljate Trinket
#if definirano (_AVR_ATtiny85_)
if (F_CPU == 16000000) clock_prescale_set (clock_div_1);
#endif
// Koda posebne drobtinice
Serial.begin (9600);
strip.begin ();
strip.show (); // Inicializirajte vse slikovne pike na "off"
if (! rtc.begin ()) {
Serial.println ("RTC ni mogoče najti");
medtem ko (1);
}
pinMode (2, INPUT_PULLUP);
// rtc.adjust (DateTime (F (_ DATE_), F (_ TIME_))));
if (rtc.lostPower ()) {
Serial.println ("RTC je izgubil moč, nastavimo čas!");
// naslednja vrstica nastavi RTC na datum in čas, ko je bila skica sestavljena
rtc.adjust (DateTime (F (_ DATE_), F (_ TIME_))));
// Ta vrstica nastavi RTC z izrecnim datumom in časom, na primer za nastavitev
// 21. januarja 2014 ob 3. uri bi poklicali:
// rtc.adjust (DateTime (2017, 11, 06, 2, 49, 0));
}
// rtc.adjust (DateTime (2017, 11, 06, 2, 49, 0));
// lightUpEven ();
// medtem ko (1);
lastRtcCheck = 0;
}
voidloop () {
if (millis () - lastRtcCheck> 2000) {
DateTime zdaj = rtc.now ();
Serial.print (now.hour (), DEC);
Serial.print (':');
Serial.print (zdaj.minute (), DEC);
Serial.print (':');
Serial.print (now.second (), DEC);
Serial.println ();
čas za predstavo();
lastRtcCheck = millis ();
}
if (! digitalRead (2)) {
lightUpEven ();
}
if (stringComplete) {
Serial.println (inputString);
if (inputString [0] == 'l') {
Serial.println ("Raven");
lightUpEven ();
}
if (inputString [0] == 'c') {
Serial.println ("Prikaz časa");
čas za predstavo();
strip.show ();
}
if (inputString [0] == '1') {
Serial.println ("Vklop vseh LED");
lightUp (barvni trak (255, 255, 255));
strip.show ();
}
if (inputString [0] == '0') {
Serial.println ("Čistilni trak");
clear ();
strip.show ();
}
// #3, 255 bi postavilo vodilno številko 3 na raven 255, 255, 255
if (inputString [0] == '#') {
Nizna temp;
temp = inputString.substring (1);
int pixNum = temp.toInt ();
temp = inputString.substring (inputString.indexOf (',') + 1);
int intenzivnost = temp.toInt ();
Serial.print ("Nastavitev");
Serial.print (pixNum);
Serial.print ("na raven");
Serial.println (intenzivnost);
strip.setPixelColor (pixNum, strip. Color (intenzivnost, intenzivnost, intenzivnost));
strip.show ();
}
// #3, 255, 0, 125 bi postavilo vodilno številko 3 na raven 255, 0, 125
if (inputString [0] == '$') {
Nizna 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 bIntensity = temp.toInt ();
Serial.print ("Nastavitev");
Serial.print (pixNum);
Serial.print ("R do");
Serial.print (rIntensity);
Serial.print ("G do");
Serial.print (gIntensity);
Serial.print ("B do");
Serial.println (bIntensity);
strip.setPixelColor (pixNum, strip. Color (rIntensity, gIntensity, bIntensity));
strip.show ();
}
if (inputString [0] == 's') {
Nizna temp;
int ura, minuta;
temp = inputString.substring (1);
ura = temp.toInt ();
int rIndex = inputString.indexOf (',') + 1;
temp = inputString.substring (rIndex);
minuta = temp.toInt ();
Serial.print ("Prikaz časa:");
Serijski.tisk (ura);
Serial.print (":");
Serijski.tisk (minuta);
showTime (ura, minuta);
zamuda (1000);
}
inputString = "";
stringComplete = false;
}
// zakasnitev (1000);
}
voidserialEvent () {
medtem ko (Serial.available ()) {
char inChar = (char) Serial.read ();
inputString += inChar;
if (inChar == '\ n') {
stringComplete = true;
}
zamuda (1);
}
}
voidclear () {
for (uint16_t i = 0; i <strip.numPixels (); i ++) {
strip.setPixelColor (i, strip. Color (0, 0, 0));
}
}
voidshowTime () {
DateTime zdaj = rtc.now ();
hourPixel = now.hour () % 12;
minutePixel = (zdaj.minute () / 5) % 12 + 12;
clear ();
// strip.setPixelColor (hourPixel, strip. Color (40 + 40 * raven [hourPixel], 30 + 30 * raven [hourPixel], 20 + 20 * raven [hourPixel]));
// strip.setPixelColor (minutePixel, strip. Color (40 + 40 * raven [minutePixel], 30 + 30 * raven [minutePixel], 20 + 20 * raven [minutePixel]));
strip.setPixelColor (hourPixel, strip. Color (raven [hourPixel], raven [hourPixel], raven [hourPixel]));
strip.setPixelColor (minutePixel, strip. Color (raven [minutePixel], raven [minutePixel], raven [minutePixel]));
// lightUp (strip. Color (255, 255, 255));
strip.show ();
}
voidshowTime (int ura, int minuta) {
hourPixel = ura % 12;
minutePixel = (minuta / 5) % 12 + 12;
clear ();
// strip.setPixelColor (hourPixel, strip. Color (40 + 40 * raven [hourPixel], 30 + 30 * raven [hourPixel], 20 + 20 * raven [hourPixel]));
// strip.setPixelColor (minutePixel, strip. Color (40 + 40 * raven [minutePixel], 30 + 30 * raven [minutePixel], 20 + 20 * raven [minutePixel]));
strip.setPixelColor (hourPixel, strip. Color (raven [hourPixel], raven [hourPixel], raven [hourPixel]));
strip.setPixelColor (minutePixel, strip. Color (raven [minutePixel], raven [minutePixel], raven [minutePixel]));
// lightUp (strip. Color (255, 255, 255));
strip.show ();
}
voidlightUp (barva uint32_t) {
for (uint16_t i = 0; i <strip.numPixels (); i ++) {
strip.setPixelColor (i, barvno);
}
strip.show ();
}
voidlightUpEven () {
for (uint16_t i = 0; i <strip.numPixels (); i ++) {
strip.setPixelColor (i, strip. Color (raven , raven , raven ));
}
strip.show ();
}

oglejte si rawplywoodClock.ino, ki ga gosti ❤ GitHub

10. korak: Računalniški vid - kalibracija

Računalniški vid - kalibracija
Računalniški vid - kalibracija
Računalniški vid - kalibracija
Računalniški vid - kalibracija

Zavestno sem se odločil, da v tem projektu ne bom uporabljal furnirja. Če bi imel, bi bila debelina lesa enaka pred vsemi LED. Ker pa imam pred vsako LED drugačno debelino lesa in ker se tudi barva lesa zelo razlikuje, je svetlost LED za vsako LED drugačna. Da bi bile vse LED diode enake svetlosti, sem si izmislil odličen trik.

Napisal sem nekaj procesne kode (na GitHubu), ki fotografira uro in po vrsti analizira svetlost vsake LED. Nato spreminja moč vsake LED, da bi poskušala doseči, da imajo vsi enako svetlost kot najtemnejša LED. Vem, da je to pretirano, toda obdelava slik je zelo zabavna! Upam, da bom kalibracijsko kodo razvil kot knjižnico.

Svetlost LED pred kalibracijo in po njej lahko vidite na zgornjih fotografijah.

calibrateDispllay.pde

importprocessing.video.*;
importprocessing.serial.*;
Serijski myPort;
Snemanje videa;
finalint numLed = 24;
int ledNum = 0;
// Če želite uporabljati PxPGetPixelDark (), morate imeti te globalne spremenljivke
int rDark, gDark, bDark, aDark;
int rLed, gLed, bLed, aLed;
int rOrg, gOrg, bOrg, aOrg;
int rTemp, gTemp, bTemp, aTemp;
PImage ourImage;
int runNumber = 0;
int sprejemljivaError = 3;
int končano;
int numPixelsInLed;
long ledIntensity;
int ledPower;
long targetIntensity = 99999999;
voidsetup () {
dokončano = newint [numLed];
numPixelsInLed = newint [numLed];
ledIntensity = newlong [numLed];
ledPower = newint [numLed];
for (int i = 0; i <numLed; i ++) {
ledPower = 255;
}
printArray (Serial.list ());
Niz portName = Serial.list () [31];
myPort = newSerial (this, portName, 9600);
velikost (640, 480);
video = newCapture (to, širina, višina);
video.start ();
noStroke ();
gladko ();
zamuda (1000); // Počakajte, da se serijska vrata odprejo
}
voiddraw () {
if (video.available ()) {
if (končano [ledNum] == 0) {
clearDisplay ();
zamuda (1000);
video.read ();
slika (video, 0, 0, širina, višina); // Narišite video posnetek s spletne kamere na zaslon
saveFrame ("data/no_leds.jpg");
if (runNumber! = 0) {
if ((ledIntensity [ledNum] - targetIntensity)*100/targetIntensity> sprejemljiva napaka) {
ledPower [ledNum] -= pow (0.75, runNumber)*100+1;
}
if ((targetIntensity - ledIntensity [ledNum])*100/targetIntensity> sprejemljiva napaka) {
ledPower [ledNum] += pow (0.75, runNumber)*100 +1;
}
if (abs (targetIntensity - ledIntensity [ledNum])*100/targetIntensity <= sprejemljiva napaka) {
opravljeno [ledNum] = 1;
print ("Led");
tiskanje (ledNum);
print ("končano");
}
if (ledPower [ledNum]> 255) {
ledPower [ledNum] = 255;
}
if (ledPower [ledNum] <0) {
ledPower [ledNum] = 0;
}
}
setLedPower (ledNum, ledPower [ledNum]);
zamuda (1000);
video.read ();
slika (video, 0, 0, širina, višina); // Narišite video posnetek s spletne kamere na zaslon
zamuda (10);
medtem ko (myPort.available ()> 0) {
int inByte = myPort.read ();
// tiskanje (char (inByte));
}
Niz imageName = "podatki/";
imageName+= str (ledNum);
imageName += "_ led.jpg";
saveFrame (imageName);
Niz originalImageName = "podatki/organizacija";
originalImageName+= str (ledNum);
originalImageName += ". jpg";
if (runNumber == 0) {
saveFrame (originalImageName);
}
PImage noLedImg = loadImage ("podatki/no_leds.jpg");
PImage ledImg = loadImage (imageName);
PImage originalImg = loadImage (originalImageName);
noLedImg.loadPixels ();
ledImg.loadPixels ();
originalImg.loadPixels ();
ozadje (0);
loadPixels ();
ledIntensity [ledNum] = 0;
numPixelsInLed [ledNum] = 0;
for (int x = 0; x <širina; x ++) {
for (int y = 0; y <višina; y ++) {
PxPGetPixelDark (x, y, noLedImg.pixel, width);
PxPGetPixelLed (x, y, ledImg.pixel, width);
PxPGetPixelOrg (x, y, originalImg.pixel, width);
če ((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] ++;
} drugo {
rTemp = 0;
gTemp = 0;
bTemp = 0;
}
PxPSetPixel (x, y, rTemp, gTemp, bTemp, 255, slikovnih pik, širina);
}
}
ledIntensity [ledNum] /= numPixelsInLed [ledNum];
if (targetIntensity> ledIntensity [ledNum] && runNumber == 0) {
targetIntensity = ledIntensity [ledNum];
}
updatePixels ();
}
tiskanje (ledNum);
print (',');
tiskanje (ledPower [ledNum]);
print (',');
println (ledIntensity [ledNum]);
ledNum ++;
if (ledNum == numLed) {
int donezo = 0;
for (int i = 0; i <numLed; i ++) {
donezo += končano ;
}
če (donezo == numLed) {
println ("KONČANO");
for (int i = 0; i <numLed; i ++) {
tiskanje (i);
print ("\ t");
println (ledPower );
}
print ("int level [");
tiskanje (ledNum);
print ("] = {");
for (int i = 0; i <numLed-1; i ++) {
tiskanje (ledPower );
print (',');
}
tiskanje (ledPower [numLed -1]);
println ("};");
lightUpEven ();
medtem ko (res);
}
print ("Ciljna intenzivnost:");
if (runNumber == 0) {
targetIntensity -= 1;
}
println (targetIntensity);
ledNum = 0;
runNumber ++;
}
}
}
voidPxPGetPixelOrg (intx, inty, int pixelArray, intpixelsWidth) {
int thisPixel = pixelArray [x+y*pixelsWidth]; // pridobivanje barv kot int iz slikovnih pik
aOrg = (thisPixel >> 24) & 0xFF; // moramo prestaviti in prikriti, da dobimo vsako komponento posebej
rOrg = (thisPixel >> 16) & 0xFF; // to je hitreje kot klicanje red (), green (), blue ()
gOrg = (thisPixel >> 8) & 0xFF;
bOrg = thisPixel & 0xFF;
}
voidPxPGetPixelDark (intx, inty, int pixelArray, intpixelsWidth) {
int thisPixel = pixelArray [x+y*pixelsWidth]; // pridobivanje barv kot int iz slikovnih pik
aDark = (thisPixel >> 24) & 0xFF; // moramo premakniti in prikriti, da dobimo vsako komponento posebej
rDark = (thisPixel >> 16) & 0xFF; // to je hitreje kot klicanje red (), green (), blue ()
gDark = (thisPixel >> 8) & 0xFF;
bDark = thisPixel & 0xFF;
}
voidPxPGetPixelLed (intx, inty, int pixelArray, intpixelsWidth) {
int thisPixel = pixelArray [x+y*pixelsWidth]; // pridobivanje barv kot int iz slikovnih pik
aLed = (thisPixel >> 24) & 0xFF; // moramo premakniti in prikriti, da dobimo vsako komponento posebej
rLed = (thisPixel >> 16) & 0xFF; // to je hitreje kot klicanje red (), green (), blue ()
gLed = (thisPixel >> 8) & 0xFF;
bLed = thisPixel & 0xFF;
}
voidPxPSetPixel (intx, inty, intr, intg, intb, inta, int pixelArray, intpixelsWidth) {
a = (a << 24);
r = r << 16; // Vse 4 sestavine pakiramo v eno int
g = g << 8; // zato jih moramo premakniti na svoja mesta
barva argb = a | r | g | b; // binarna operacija "ali" jih vse doda v en int
pixelArray [x+y*pixelsWidth] = argb; // končno nastavimo int z barvami te v slikovne pike
}

oglejte si rawcalibrateDispllay.pde, ki ga gosti ❤ GitHub

11. korak: Opombe pri ločitvi

Pasti, ki se jim je treba izogniti:

* Z lesom dobite tisto, za kar plačate. Torej, dobite kakovosten les. Vezan les iz breze je dobra izbira; lepo se bo obnesel tudi vsak lahek masiven les. Pocenil sem les in obžalujem svojo odločitev.

* Bolje je vrtati manj kot več. Nekaj lukenj je bilo preveč globokih za moj kos. In epoksid se prikaže skozi sprednjo stran. To je zelo opazno, ko ga opazite.

* Namesto ravnega konca uporabite kroglični sveder. Nisem eksperimentiral s konico kroglice, vendar sem prepričan, da bodo rezultati veliko boljši.

Spogledujem se z idejo, da bi jih prodajal na Etsyju ali tindieju. Res bi bil hvaležen, če bi spodaj komentirali, če se vam zdi smiselno:)

Priporočena: