Spisu treści:

Drewniany zegar LED - styl analogowy: 11 kroków (ze zdjęciami)
Drewniany zegar LED - styl analogowy: 11 kroków (ze zdjęciami)

Wideo: Drewniany zegar LED - styl analogowy: 11 kroków (ze zdjęciami)

Wideo: Drewniany zegar LED - styl analogowy: 11 kroków (ze zdjęciami)
Wideo: ZLOT MŁODZIEŻY GRYPSUJĄCEJ 2024, Lipiec
Anonim
Drewniany zegar LED - styl analogowy
Drewniany zegar LED - styl analogowy

Jest to drewniany zegar LED w stylu analogowym. Nie wiem, dlaczego nie widziałem wcześniej żadnego z nich… mimo że typy cyfrowe są bardzo powszechne. W każdym razie, zaczynamy!

Krok 1:

Obraz
Obraz
Obraz
Obraz

Projekt zegara ze sklejki rozpoczął się jako prosty projekt startowy dla routera CNC. Przeglądałem proste projekty online i znalazłem tę lampę (obrazek powyżej). Widziałem również zegary cyfrowe, które prześwitują przez okleinę drewnianą (obrazek powyżej). Połączenie obu projektów było więc oczywistym pomysłem. Chcąc rzucić sobie wyzwanie, postanowiłem nie używać do tego projektu forniru, a jedynie kawałek drewna.

Krok 2: Projekt

Projekt
Projekt
Projekt
Projekt

Zaprojektowałem zegar w Inkscape (obrazek powyżej). Projekt jest bardzo prosty z wyboru. Zrezygnowałem z prowadzenia ścieżek dla przewodów, ponieważ w tym momencie nie byłem pewien, czy chcę okablowanie promieniowe, czy obwodowe. (W końcu zdecydowałem się na okablowanie obwodowe.) Jeden neopiksel jest umieszczany w każdym z małych okrągłych otworów, aby pokazać godzinę i godzinę z dokładnością do pięciu minut. Okrąg pośrodku zostanie poprowadzony, aby pomieścić elektronikę.

Krok 3: Obróbka CNC

Obróbka CNC
Obróbka CNC
Obróbka CNC
Obróbka CNC
Obróbka CNC
Obróbka CNC
Obróbka CNC
Obróbka CNC

Zaprojektowałem ścieżki narzędzia w MasterCAM i użyłem technoRoutera do wyfrezowania zegara ze sklejki 3/4 cala. Używam do tego kawałka 15"x15", z minimalnym marnotrawstwem. Sztuczka polega na tym, aby wyprowadzić jak najwięcej drewna bez przebijania się przez drewno. Pozostawienie 0,05"-0,1" to dobry wybór w przypadku jasnego drewna. Jeśli nie masz pewności, lepiej zostawić więcej drewna, ponieważ zawsze możesz przeszlifować drugą powierzchnię. Skończyło się na usunięciu trochę za dużo drewna z niektórych części, ale na szczęście wyniki nie są z tego powodu zbytnio cierpiące.

Uwaga dla użytkowników bez dostępu do CNC:

Ten projekt można łatwo wykonać za pomocą wiertarki. Wystarczy ustawić ogranicznik w punkcie, w którym zostawisz około 0,1 cala drewna pozostałego u podstawy. Musisz być precyzyjny, ale nie zbyt precyzyjny. W końcu idealnie nikt nie zobaczy, że wszystkie diody świecą w tym samym czasie, więc możesz ujść trochę na sucho.

Krok 4: Elektronika

Elektronika
Elektronika
Elektronika
Elektronika
Elektronika
Elektronika

Elektronika jest dość prosta. Są 24 neopiksele, dwanaście do pokazywania godzin i dwanaście do pokazywania minut z pięciominutową precyzją. Arduino pro mini kontroluje neopiksele i uzyskuje dokładny czas za pomocą modułu zegara czasu rzeczywistego DS3231 (RTC). Moduł RTC ma zapasową baterię monetową, dzięki czemu nie traci czasu nawet przy wyłączonym zasilaniu.

Materiał:

Arduino pro mini (lub dowolny inny Arduino)

DS3231 tabliczka zaciskowa

Neopiksele w poszczególnych tablicach typu breakout

Krok 5: Montaż elektroniki

Montaż elektroniki
Montaż elektroniki
Montaż elektroniki
Montaż elektroniki
Montaż elektroniki
Montaż elektroniki
Montaż elektroniki
Montaż elektroniki

Połączyłem neopiksele w ciąg, używając przewodów 2,5 dla pierwszych dwunastu diod led i czterocalowego drutu dla następnych dwunastu. Mogłem użyć nieco mniejszych długości przewodów. Po zrobieniu sznurka przetestowałem go, upewniając się, że lut stawy były dobre. Dodałem chwilowy włącznik, aby włączyć wszystkie diody, tylko po to, żeby się popisać.

Krok 6: Bieg na sucho

Próba
Próba
Próba
Próba
Próba
Próba
Próba
Próba

Po eksperymentach, włożeniu diod LED do otworów i włączeniu ich wszystkich, byłem zadowolony z wyników. Więc trochę oszlifowałem przednią powierzchnię i nałożyłem powłokę PU. Skończyło się na zeszlifowaniu płaszcza później, ale dobrym pomysłem jest pozostawienie go na sobie, jeśli nie uważasz go za nieprzyjemny pod względem estetycznym.

Krok 7: Epoksyd

epoksydowe
epoksydowe
epoksydowe
epoksydowe

Po kilku testach z pozycją diody LED w otworach stwierdziłem, że najlepszą dyskusję osiąga się, gdy diody LED znajdują się w odległości około 0,2 cala od końca otworu. Gdy spróbujesz tego samodzielnie, jasność diod LED będzie bardzo różna w każdy otwór. Nie martw się o to; naprawimy to w kodzie. Wynika to z rodzaju użytego wiertła. Gdybym miał to zrobić ponownie, użyłbym wiertła z końcówką kulkową do otworów Ale w każdym razie, aby uzyskać odległość, zmieszałem trochę żywicy epoksydowej i włożyłem trochę w każdy otwór.

Krok 8: Składanie wszystkiego razem

Kładąc wszystko razem
Kładąc wszystko razem
Kładąc wszystko razem
Kładąc wszystko razem
Kładąc wszystko razem
Kładąc wszystko razem
Kładąc wszystko razem
Kładąc wszystko razem

Diody LED zostaną umieszczone, zaczynając od pozycji wskazówki na godzinie 12 poruszającej się w kierunku przeciwnym do ruchu wskazówek zegara przez wszystkie pozycje wskazówki godzinowej, a następnie do wskazówki minutowej, ponownie przechodząc od znaku 60 minut poruszającego się w kierunku przeciwnym do ruchu wskazówek zegara. Dzieje się tak, że gdy patrzymy od przodu, wzór diody wydaje się iść w kierunku zgodnym z ruchem wskazówek zegara.

Po utwardzeniu żywicy epoksydowej przez godzinę dodałem trochę więcej żywicy epoksydowej. Tym razem diody LED umieściłem w otworach, upewniając się, że przewody i złącza lutowane pokryłem żywicą epoksydową. Zapewnia to dobre rozproszenie światła i zabezpiecza przewody.

Krok 9: Kod

Kod
Kod

Kod znajduje się na GitHub, możesz go modyfikować do własnego użytku. Gdy włączysz wszystkie diody LED na tym samym poziomie, jasność wpadającego światła będzie bardzo różna w każdym otworze. Wynika to z różnej grubości drewna w otworach i różnicy w odcieniu drewna. Jak widać kolor drewna w moim kawałku jest dość różny. Aby zniwelować tę różnicę w jasności, wykonałem matrycę poziomów jasności led. I zmniejszono jasność jaśniejszych diod LED. Jest to proces prób i błędów, który może potrwać kilka minut, ale wyniki są tego warte.

sklejkaClock.ino

// Zegar ze sklejki
// Autor: tinkrmind
// Uznanie autorstwa 4.0 Międzynarodowe (CC BY 4.0). Możesz:
// Udostępnij - kopiuj i rozpowszechniaj materiał na dowolnym nośniku lub formacie
// Dostosuj - remiksuj, przekształcaj i buduj na materiale w dowolnym celu, nawet komercyjnym.
// Hurra!
#włączać
#include"RTClib.h"
RTC_DS3231 RTC;
#include"Adafruit_NeoPixel.h"
#ifdef _AVR_
#włączać
#endif
#definiuj PIN6
Pasek Adafruit_NeoPixel = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
int godzinaPixel = 0;
int minutaPiksel = 0;
unsignedlong lastRtcCheck;
String inputString = ""; // ciąg do przechowywania przychodzących danych
boolean stringComplete = false; // czy napis jest kompletny
poziom wewnętrzny[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};
pustka () {
#ifndef ESP8266
podczas (!Serial); // dla Leonarda/Mikro/Zero
#endif
// To jest dla Trinket 5V 16MHz, możesz usunąć te trzy linie, jeśli nie używasz Trinket
#jeśli zdefiniowano (_AVR_ATtiny85_)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
// Koniec kodu specjalnego drobiazgu
Serial.początek(9600);
strip.początek();
strip.pokaż(); // Zainicjuj wszystkie piksele na „wyłączone”
if (! rtc.begin()) {
Serial.println("Nie można znaleźć RTC");
natomiast (1);
}
pinMode(2, INPUT_PULLUP);
// rtc.adjust(DataCzas(F(_DATA_), F(_CZAS_)));
if (rtc.lostPower()) {
Serial.println("RTC stracił zasilanie, ustawmy czas!");
// kolejna linia ustawia RTC na datę i godzinę skompilowania tego szkicu
rtc.adjust(DataCzas(F(_DATA_), F(_CZAS_)));
// Ta linia ustawia RTC z wyraźną datą i godziną, na przykład, aby ustawić
// 21 stycznia 2014 o 3 nad ranem zadzwoniłbyś:
// rtc.adjust(DateTime(2017, 11, 06, 2, 49, 0));
}
// rtc.adjust(DateTime(2017, 11, 06, 2, 49, 0));
//EvenEven();
// gdy (1);
lastRtcCheck = 0;
}
pusta pętla () {
if (millis() - lastRtcCheck >2000) {
DataCzas teraz = rtc.now();
Serial.print(teraz.godzina(), DEC);
Serial.print(':');
Serial.print(teraz.minuta(), DEC);
Serial.print(':');
Serial.print(teraz.second(), DEC);
Serial.println();
czas na przedstawienie();
lastRtcCheck = millis();
}
jeśli (!digitalRead(2)) {
lightUpEven();
}
if (stringComplete) {
Serial.println(ciąg wejściowy);
if (inputString[0] == 'l') {
Serial.println("Poziom");
lightUpEven();
}
if (inputString[0] == 'c') {
Serial.println("Pokazuje czas");
czas na przedstawienie();
strip.pokaż();
}
if (inputString[0] == '1') {
Serial.println("Włączanie wszystkich diod LED");
lightUp(strip. Color(255, 255, 255));
strip.pokaż();
}
if (inputString[0] == '0') {
Serial.println("Pasek kasujący");
jasne();
strip.pokaż();
}
// #3, 255 ustawi diodę numer 3 na poziom 255, 255, 255
if (inputString[0] == '#') {
Temp. struny;
temp = inputString.substring(1);
int pixNum = temp.toInt();
temp = inputString.substring(inputString.indexOf(', ') + 1);
int intensywność = temp.toInt();
Serial.print("Ustawienie ");
Serial.print(PixNum);
Serial.print("do poziomu");
Serial.println(intensywność);
strip.setPixelColor(pixNum, strip. Color(intensywność, intensywność, intensywność));
strip.pokaż();
}
// #3, 255, 0, 125 ustawi diodę numer 3 na 255, 0, 125
if (inputString[0] == '$') {
Temp. struny;
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("Ustawienie ");
Serial.print(PixNum);
Serial.print("R do");
Serial.print(rIntensywność);
Serial.print("G do");
Serial.print(gIntensywność);
Serial.print(" B do ");
Serial.println(bIntensywność);
strip.setPixelColor(pixNum, strip. Color(rIntensity, gIntensity, bIntensity));
strip.pokaż();
}
if (inputString[0] == 's') {
Temp. struny;
int godzina, minuta;
temp = inputString.substring(1);
godzina = temp.doInt();
int rIndex = inputString.indexOf(', ') + 1;
temp = inputString.substring(rIndex);
minuta = temp.doInt();
Serial.print("Pokazuje czas: ");
Serial.print(godzina);
Serial.print(":");
Serial.print(minuta);
showTime (godzina, minuta);
opóźnienie (1000);
}
inputString = "";
stringComplete = fałsz;
}
// opóźnienie(1000);
}
voidserialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '\n') {
stringComplete = prawda;
}
opóźnienie(1);
}
}
voidclear() {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, strip. Color(0, 0, 0));
}
}
voidshowTime() {
DataCzas teraz = rtc.now();
hourPixel = now.hour() % 12;
minutaPixel = (teraz.minuta() / 5) % 12 + 12;
jasne();
// 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(minutaPixel, strip. Color(poziom[minutaPixel], poziom[minutaPixel], poziom[minutaPixel]));
// lightUp(strip. Color(255, 255, 255));
strip.pokaż();
}
voidshowTime(int godzina,int minuta) {
hourPixel = godzina % 12;
minutaPiksel = (minuta / 5) % 12 + 12;
jasne();
// 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(minutaPixel, strip. Color(poziom[minutaPixel], poziom[minutaPixel], poziom[minutaPixel]));
// lightUp(strip. Color(255, 255, 255));
strip.pokaż();
}
voidlightUp(uint32_t kolor) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, kolor);
}
strip.pokaż();
}
voidlightUpEven() {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, strip. Color(poziom, poziom, poziom));
}
strip.pokaż();
}

zobacz rawplywoodClock.ino hostowane z ❤ przez GitHub

Krok 10: Widzenie komputerowe - kalibracja

Widzenie komputerowe - kalibracja
Widzenie komputerowe - kalibracja
Widzenie komputerowe - kalibracja
Widzenie komputerowe - kalibracja

Świadomie zdecydowałem się nie używać w tym projekcie forniru. Gdybym miał, grubość drewna byłaby taka sama przed wszystkimi diodami LED. Ale ponieważ mam różną grubość drewna przed każdą diodą LED i ponieważ kolor drewna również bardzo się różni, jasność diody LED jest inna dla każdej diody LED. Aby wszystkie diody LED wydawały się mieć tę samą jasność, wymyśliłem sprytną sztuczkę.

Napisałem kod przetwarzania (na GitHubie), który robi zdjęcie zegara i analizuje kolejno jasność każdej diody LED. Następnie zmienia moc każdej diody LED, aby spróbować uzyskać tę samą jasność, co najciemniejsza dioda LED. Teraz wiem, że to przesada, ale przetwarzanie obrazu to świetna zabawa! I mam nadzieję, że opracuję kod kalibracyjny jako bibliotekę.

Na powyższych zdjęciach widać jasność diod LED przed i po kalibracji.

kalibracjaDispllay.pde

importprzetwarzanie.wideo.*;
importprocessing.serial.*;
port szeregowy myPort;
Przechwytywanie wideo;
ostateczna liczba =24;
int ledNum =0;
// musisz mieć te globalne zmienne, aby użyć PxPGetPixelDark()
int rCiemny, gCiemny, bCiemny, aCiemny;
int rLed, gLed, bled, aLed;
int rOrg, gOrg, bOrg, aOrg;
int rTemp, gTemp, bTemp, aTemp;
PObraz naszObraz;
int runNumber =0;
int akceptowalnyBłąd =3;
int zrobione;
int numPixelsInLed;
long ledIntensywność;
int ledPower;
długi targetIntensity =99999999;
voidsetup() {
gotowe = newint[liczbaLed];
numPixelsInLed =newint[numLed];
ledIntensity =newlong[numLed];
ledPower =newint[liczbaLed];
for (int i=0; i<liczba; i++) {
moc diody =255;
}
printArray(Serial.list());
Ciąg nazwa_portu =Serial.list()[31];
mójPort =nowySeryjny(ten, nazwa_portu, 9600);
rozmiar (640, 480);
video = newCapture(to, szerokość, wysokość);
wideo.start();
noStroke();
gładki();
opóźnienie (1000); // Poczekaj na otwarcie portu szeregowego
}
nieważne rysowanie () {
jeśli (wideo.dostępne()) {
if (done[ledNum] ==0) {
wyczyśćWyświetlacz();
opóźnienie (1000);
wideo.odczyt();
obraz(wideo, 0, 0, szerokość, wysokość); // Narysuj wideo z kamery internetowej na ekran
saveFrame("dane/no_leds.jpg");
if (runNumber !=0) {
if ((ledIntensity[ledNum] - targetIntensity)*100/targetIntensity > acceptError) {
ledPower[ledNum] -=pow(0.75, runNum)*100+1;
}
if ((targetIntensity - ledIntensity[ledNum])*100/targetIntensity > acceptError) {
ledPower[ledNum] +=pow(0.75, runNum)*100+1;
}
if (abs(targetIntensity - ledIntensity[ledNum])*100/targetIntensity <= acceptError) {
gotowe[liczba_zad] =1;
print("Dioda ");
print(ledNum);
print("gotowe");
}
if (ledPower[ledNum] >255) {
mocled[liczbaled] =255;
}
if (moc diody[liczba diod] <0) {
mocled[liczbaled]=0;
}
}
setLedPower(ledNum, ledPower[ledNum]);
opóźnienie (1000);
wideo.odczyt();
obraz(wideo, 0, 0, szerokość, wysokość); // Narysuj wideo z kamery internetowej na ekran
opóźnienie(10);
while (mójPort.dostępny() >0) {
int inByte = myPort.read();
//print(char(inByte));
}
Ciąg nazwa obrazu ="dane/";
imageName+=str(ledNum);
imageName +="_led.jpg";
saveFrame(nazwaobrazu);
String originalImageName ="data/org";
originalImageName+=str(ledNum);
oryginalna nazwa obrazu +=".jpg";
if (runNumber ==0) {
saveFrame(oryginalnaNazwaObrazu);
}
PImage noLedImg =loadImage("dane/brak_led.jpg");
PImage ledImg =loadImage(imageName);
PImage originalImg =loadImage(oryginalnaNazwaObrazu);
noLedImg.loadPixels();
ledImg.loadPixels();
oryginalnyImg.loadPixels();
tło (0);
wczytaj piksele();
ledIntensity[ledNum] =0;
numPixelsInLed[ledNum] =0;
for (int x =0; x<szerokość; x++) {
for (int y =0; y<wysokość; y++) {
PxPGetPixelDark(x, y, noLedImg.piksele, szerokość);
PxPGetPixelLed(x, y, ledImg.piksele, szerokość);
PxPGetPixelOrg(x, y, oryginalnyImg.piksele, szerokość);
jeśli ((rOrg+gOrg/2+bOrg/3)-(rDark+gDark/2+bDark/3) >75) {
ledIntensity[ledNum] = ledIntensity[ledNum] +(rLed+gLed/2+bLed/3) -(rCiemny+gCiemny/2+bCiemny/3);
rTemp=255;
gTemp=255;
bTemp=255;
numPixelsInLed[ledNum]++;
} w przeciwnym razie {
rTemp=0;
gTemp=0;
bTemp=0;
}
PxPSetPixel(x, y, rTemp, gTemp, bTemp, 255, piksele, szerokość);
}
}
ledIntensity[ledNum] /= numPixelsInLed[ledNum];
if (targetIntensity > ledIntensity[ledNum] && runNumber ==0) {
targetIntensity = ledIntensity[ledNum];
}
zaktualizuj piksele();
}
print(ledNum);
print(', ');
print(ledPower[ledNum]);
print(', ');
println(ledIntensity[ledNum]);
ledNum++;
if (ledNum == numLed) {
int donezo =0;
for (int i=0; i<liczba; i++) {
donezo += gotowe;
}
if (donezo == liczba) {
println("GOTOWE");
for (int i=0; i<liczba; i++) {
drukuj(i);
print("\t");
println(ledPower);
}
print("int poziom[");
print(ledNum);
print("] = {");
for (int i=0; i<numLed-1; i++) {
print(ledPower);
print(', ');
}
print(ledPower[numLed -1]);
println("};");
lightUpEven();
podczas (prawda);
}
print("Intensywność docelowa: ");
if (runNumber ==0) {
celIntensywność -=1;
}
println(intensywność docelowa);
liczba led =0;
runNumer++;
}
}
}
voidPxPGetPixelOrg(intx, inty, int pixelArray, intpixelsWidth) {
int thisPixel=pixelArray[x+y*pixelsWidth]; // pobieranie kolorów jako int z pikseli
aOrg = (ten piksel >>24) &0xFF; // musimy przesunąć i zamaskować, aby uzyskać każdy komponent osobno
rOrg = (ten piksel >>16) &0xFF; // to jest szybsze niż wywołanie red(), green(), blue()
gOrg = (ten piksel >>8) &0xFF;
bOrg = tenPixel &0xFF;
}
voidPxPGetPixelDark(intx, inty, int pixelArray, intpixelsWidth) {
int thisPixel=pixelArray[x+y*pixelsWidth]; // pobieranie kolorów jako int z pikseli
aCiemny = (ten piksel >>24) &0xFF; // musimy przesunąć i zamaskować, aby uzyskać każdy komponent osobno
rCiemny = (ten piksel >>16) &0xFF; // to jest szybsze niż wywołanie red(), green(), blue()
gDark = (ten piksel >>8) &0xFF;
bDark = tenPixel &0xFF;
}
voidPxPGetPixelLed(intx, inty, int pixelArray, intpixelsWidth) {
int thisPixel=pixelArray[x+y*pixelsWidth]; // pobieranie kolorów jako int z pikseli
aLed = (tenPixel >>24) &0xFF; // musimy przesunąć i zamaskować, aby uzyskać każdy komponent osobno
rLed = (ten piksel >>16) &0xFF; // to jest szybsze niż wywołanie red(), green(), blue()
gLed = (ten piksel >>8) &0xFF;
bLed = tenPixel &0xFF;
}
voidPxPSetPixel(intx, inty, intr, intg, intb, inta, int pixelArray, intpixelsWidth) {
a =(a <<24);
r = r <<16; // Pakujemy wszystkie 4 komponenty w jeden int
g = g <<8; // więc musimy je przenieść na swoje miejsca
kolor argb = a | r | g | b; // binarna operacja "lub" dodaje je wszystkie do jednego int
pixelArray[x+y*pixelsWidth]= argb; // w końcu ustawiamy int z kolorami te w pikselach
}

zobacz rawscaleDispllay.pde hostowany z ❤ przez GitHub

Krok 11: Pożegnalne uwagi

Pułapki, których należy unikać:

* Z drewnem dostajesz to, za co płacisz. Więc zdobądź drewno dobrej jakości. Sklejka brzozowa to dobry wybór; każde lekkie lite drewno również się sprawdzi. Opuściłem drewno i żałuję swojej decyzji.

* Lepiej wiercić mniej niż więcej. Kilka dziur poszło zbyt głęboko dla mojego kawałka. A żywica epoksydowa prześwituje na przedniej powierzchni. Jest to bardzo zauważalne, gdy to zauważysz.

* Użyj wiertła z końcówką kulistą zamiast prostego końca. Nie eksperymentowałem z końcówką kulkową, ale jestem pewien, że wyniki będą znacznie lepsze.

Flirtuję z pomysłem sprzedawania ich na Etsy lub Tindie. Byłbym bardzo wdzięczny, gdybyś mógł skomentować poniżej, jeśli uważasz, że ma to sens:)

Zalecana: