Índice:
- Passo 1:
- Etapa 2: Design
- Etapa 3: CNC
- Etapa 4: Eletrônica
- Etapa 5: Montagem de eletrônicos
- Etapa 6: Operação a seco
- Etapa 7: epóxi
- Etapa 8: juntando tudo
- Etapa 9: Código
- Etapa 10: Visão por Computador - Calibração
- Etapa 11: observações de despedida
Vídeo: Relógio LED de madeira - Estilo analógico: 11 etapas (com imagens)
2024 Autor: John Day | [email protected]. Última modificação: 2024-01-30 11:39
É um relógio LED de madeira de estilo analógico. Não sei por que não vi um desses antes … embora os tipos digitais sejam muito comuns. Anyhoo, vamos lá!
Passo 1:
O projeto do relógio de madeira compensada começou como um projeto inicial simples para a fresadora CNC. Eu estava procurando projetos simples online e encontrei esta lâmpada (imagem acima). Também tinha visto relógios digitais que brilham através do folheado de madeira (imagem acima). Portanto, combinar os dois projetos foi uma ideia óbvia. Procurando me desafiar, decidi não usar folheado, mas apenas um pedaço de madeira para este projeto.
Etapa 2: Design
Eu projetei o relógio no Inkscape (imagem acima). O design é muito simples por escolha. Decidi não rotear os rastreamentos para os fios porque, a essa altura, eu não tinha certeza se queria usar fiação radial ou de perímetro. (Decidi finalmente ir com a fiação de perímetro.) Um neopixel vai em cada um dos pequenos orifícios circulares para mostrar o tempo de minuto e hora, com precisão de cinco minutos. O círculo no meio será direcionado para acomodar os componentes eletrônicos.
Etapa 3: CNC
Eu projetei os caminhos da ferramenta no MasterCAM e usei um technoRouter para fresar o relógio em compensado de 3/4 de polegada. Eu uso uma peça de 15 "x 15" para isso, com desperdício mínimo. O truque é rotear o máximo possível da madeira sem quebrar a madeira. Deixar 0,05 "-0,1" é uma boa escolha para madeira leve. Se você não tiver certeza, é melhor deixar mais madeira, porque você sempre pode lixar a outra face. Acabei removendo um pouco demais de madeira de algumas peças, mas felizmente os resultados não sofreram muito com isso.
Nota para usuários sem acesso a um CNC:
Este projeto pode ser feito facilmente com uma furadeira. Você só precisa definir o limite em um ponto em que deixa cerca de 0,1 de madeira restante na base. Você terá que ser preciso, mas não muito preciso. Afinal, o ideal é que ninguém veja todos os LEDs acendendo em ao mesmo tempo, para que você possa se safar com um pouco de sujeira.
Etapa 4: Eletrônica
A eletrônica é bastante simples. São 24 neopixels, doze para mostrar as horas e doze para mostrar os minutos, com precisão de cinco minutos. Um mini Arduino pro controla os neopixels e obtém o tempo preciso por meio de um módulo de relógio em tempo real (RTC) DS3231. O módulo RTC possui uma célula tipo moeda como reserva, de forma que não perde tempo mesmo com a alimentação desligada.
Material:
Arduino pro mini (ou qualquer outro Arduino)
Placa de breakout DS3231
Neopixels em placas de breakout individuais
Etapa 5: Montagem de eletrônicos
Eu conectei os neopixels em uma corda, usando fios de 2,5 para os primeiros doze leds e fio de quatro polegadas para os doze seguintes. Eu poderia ter usado comprimentos de fio um pouco menores. Depois de fazer a corda, testei, verificando a solda juntas estavam boas. Eu adicionei um interruptor momentâneo para ligar todos os leds, apenas para mostrar.
Etapa 6: Operação a seco
Depois de experimentar, colocar LEDs nos orifícios e ligá-los todos, fiquei satisfeito com os resultados. Então, lixei um pouco a face frontal e apliquei uma camada de PU. Acabei lixando o casaco mais tarde, mas é uma boa ideia deixá-lo colocado se você não achar desagradável esteticamente.
Etapa 7: epóxi
Após alguns testes com a posição do led dentro dos orifícios, descobri que a melhor discussão é alcançada quando os LEDs estão a cerca de 0,2 de distância do final do orifício. Quando você tentar fazer isso, o brilho dos LEDs será muito diferente em cada furo. Não se preocupe com isso; vamos corrigi-lo no código. Isso se deve ao tipo de broca que usei. Se eu fizesse isso novamente, usaria uma broca de ponta esférica para os furos. Mas, em todo caso, para pegar a distância misturei um pouco de epóxi e coloquei um pouquinho em cada furo.
Etapa 8: juntando tudo
Os LEDs serão colocados a partir da posição do ponteiro das 12 horas, movendo-se no sentido anti-horário, passando por todas as posições dos ponteiros das horas e, em seguida, para o ponteiro dos minutos, novamente movendo-se a partir da marca de 60 minutos movendo-se no sentido anti-horário. Isso ocorre para que, quando observamos de frente, o padrão de LED apareça no sentido horário.
Depois que o epóxi curou por uma hora, coloquei um pouco mais de epóxi. Desta vez, coloquei os LEDs nos orifícios, certificando-se de cobrir os fios e as juntas de solda com o epóxi. Isso contribui para uma boa difusão de luz e protege os fios.
Etapa 9: Código
O código está no GitHub, fique à vontade para modificá-lo para seu uso. Quando você liga todos os LEDs no mesmo nível, o brilho da luz que brilha será muito diferente em cada orifício. Isso se deve às diferentes espessuras de madeira nos furos e à diferença de tonalidade da madeira, como você pode ver a cor da madeira varia bastante na minha peça. Para remediar essa diferença de brilho, fiz uma matriz de níveis de brilho do led. E diminuiu o brilho dos LEDs mais brilhantes. É um processo de tentativa e erro e pode levar vários minutos, mas os resultados valem a pena.
plywoodClock.ino
// Plywood Clock |
// Autor: tinkrmind |
// Atribuição 4.0 Internacional (CC BY 4.0). Você é livre para: |
// Compartilhar - copia e redistribui o material em qualquer meio ou formato |
// Adaptar - remixar, transformar e construir sobre o material para qualquer propósito, mesmo comercialmente. |
// Viva! |
#incluir |
#include "RTClib.h" |
RTC_DS3231 rtc; |
#include "Adafruit_NeoPixel.h" |
#ifdef _AVR_ |
#incluir |
#fim se |
# definePIN6 |
Tira Adafruit_NeoPixel = Adafruit_NeoPixel (60, PIN, NEO_GRB + NEO_KHZ800); |
int hourPixel = 0; |
int minutePixel = 0; |
unsignedlong lastRtcCheck; |
String inputString = ""; // uma string para conter os dados de entrada |
boolean stringComplete = false; // se a string está completa |
nível interno [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); // para Leonardo / Micro / Zero |
#fim se |
// Isso é para Trinket 5V 16MHz, você pode remover essas três linhas se não estiver usando um Trinket |
#if definido (_AVR_ATtiny85_) |
if (F_CPU == 16000000) clock_prescale_set (clock_div_1); |
#fim se |
// Fim do código especial do trinket |
Serial.begin (9600); |
strip.begin (); |
strip.show (); // Inicializa todos os pixels para 'desligado' |
if (! rtc.begin ()) { |
Serial.println ("Não foi possível encontrar RTC"); |
enquanto (1); |
} |
pinMode (2, INPUT_PULLUP); |
// rtc.adjust (DateTime (F (_ DATE_), F (_ TIME_))); |
if (rtc.lostPower ()) { |
Serial.println ("RTC perdeu energia, vamos definir a hora!"); |
// a linha seguinte define o RTC para a data e hora em que este esboço foi compilado |
rtc.adjust (DateTime (F (_ DATE_), F (_ TIME_))); |
// Esta linha define o RTC com uma data e hora explícitas, por exemplo, para definir |
// 21 de janeiro de 2014 às 3h, você ligaria: |
// rtc.adjust (DateTime (2017, 11, 06, 2, 49, 0)); |
} |
// rtc.adjust (DateTime (2017, 11, 06, 2, 49, 0)); |
// lightUpEven (); |
// enquanto (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 (); |
altura de começar(); |
lastRtcCheck = millis (); |
} |
if (! digitalRead (2)) { |
lightUpEven (); |
} |
if (stringComplete) { |
Serial.println (inputString); |
if (inputString [0] == 'l') { |
Serial.println ("Nível"); |
lightUpEven (); |
} |
if (inputString [0] == 'c') { |
Serial.println ("Mostrar tempo"); |
altura de começar(); |
strip.show (); |
} |
if (inputString [0] == '1') { |
Serial.println ("Ligar todos os LEDs"); |
lightUp (strip. Color (255, 255, 255)); |
strip.show (); |
} |
if (inputString [0] == '0') { |
Serial.println ("Faixa de limpeza"); |
Claro(); |
strip.show (); |
} |
// # 3, 255 definiria o led número 3 para o nível 255, 255, 255 |
if (inputString [0] == '#') { |
String temp; |
temp = inputString.substring (1); |
int pixNum = temp.toInt (); |
temp = inputString.substring (inputString.indexOf (',') + 1); |
intensidade int = temp.toInt (); |
Serial.print ("Configuração"); |
Serial.print (pixNum); |
Serial.print ("para o nível"); |
Serial.println (intensidade); |
strip.setPixelColor (pixNum, strip. Color (intensidade, intensidade, intensidade)); |
strip.show (); |
} |
// # 3, 255, 0, 125 definiria o led número 3 para o nível 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 b Intensidade = temp.toInt (); |
Serial.print ("Configuração"); |
Serial.print (pixNum); |
Serial.print ("R para"); |
Serial.print (rIntensity); |
Serial.print ("G para"); |
Serial.print (gIntensity); |
Serial.print ("B para"); |
Serial.println (bIntensity); |
strip.setPixelColor (pixNum, strip. Color (rIntensity, gIntensity, bIntensity)); |
strip.show (); |
} |
if (inputString [0] == 's') { |
String temp; |
hora, minuto int; |
temp = inputString.substring (1); |
hora = temp.toInt (); |
int rIndex = inputString.indexOf (',') + 1; |
temp = inputString.substring (rIndex); |
minuto = temp.toInt (); |
Serial.print ("Mostrar tempo:"); |
Serial.print (hora); |
Serial.print (":"); |
Serial.print (minuto); |
showTime (hora, minuto); |
atraso (1000); |
} |
inputString = ""; |
stringComplete = false; |
} |
// delay (1000); |
} |
voidserialEvent () { |
while (Serial.available ()) { |
char inChar = (char) Serial.read (); |
inputString + = inChar; |
if (inChar == '\ n') { |
stringComplete = true; |
} |
atraso (1); |
} |
} |
voidclear () { |
para (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; |
Claro(); |
// strip.setPixelColor (hourPixel, strip. Color (40 + 40 * nível [hourPixel], 30 + 30 * nível [hourPixel], 20 + 20 * nível [hourPixel])); |
// strip.setPixelColor (minutePixel, strip. Color (40 + 40 * nível [minutePixel], 30 + 30 * nível [minutePixel], 20 + 20 * nível [minutePixel])); |
strip.setPixelColor (hourPixel, strip. Color (nível [hourPixel], nível [hourPixel], nível [hourPixel])); |
strip.setPixelColor (minutePixel, strip. Color (nível [minutePixel], nível [minutePixel], nível [minutePixel])); |
// lightUp (strip. Color (255, 255, 255)); |
strip.show (); |
} |
voidshowTime (int hora, int minuto) { |
hourPixel = hora% 12; |
minutePixel = (minuto / 5)% 12 + 12; |
Claro(); |
// strip.setPixelColor (hourPixel, strip. Color (40 + 40 * nível [hourPixel], 30 + 30 * nível [hourPixel], 20 + 20 * nível [hourPixel])); |
// strip.setPixelColor (minutePixel, strip. Color (40 + 40 * nível [minutePixel], 30 + 30 * nível [minutePixel], 20 + 20 * nível [minutePixel])); |
strip.setPixelColor (hourPixel, strip. Color (nível [hourPixel], nível [hourPixel], nível [hourPixel])); |
strip.setPixelColor (minutePixel, strip. Color (nível [minutePixel], nível [minutePixel], nível [minutePixel])); |
// lightUp (strip. Color (255, 255, 255)); |
strip.show (); |
} |
voidlightUp (uint32_t color) { |
para (uint16_t i = 0; i <strip.numPixels (); i ++) { |
strip.setPixelColor (i, color); |
} |
strip.show (); |
} |
voidlightUpEven () { |
para (uint16_t i = 0; i <strip.numPixels (); i ++) { |
strip.setPixelColor (i, strip. Color (nível , nível , nível )); |
} |
strip.show (); |
} |
veja rawplywoodClock.ino hospedado com ❤ por GitHub
Etapa 10: Visão por Computador - Calibração
Fiz uma escolha consciente de não usar verniz neste projeto. Se tivesse, a espessura da madeira seria a mesma na frente de todos os LEDs. Mas, como eu tenho uma espessura de madeira diferente na frente de cada LED e porque a cor da madeira também varia muito, o brilho do LED é diferente para cada LED. Para fazer todos os LEDs parecerem ter o mesmo brilho, inventei um truque bacana.
Eu escrevi um código de processamento (no GitHub) que tira uma foto do relógio e analisa o brilho de cada LED por vez. Em seguida, varia a potência de cada LED para tentar fazer com que todos tenham o mesmo brilho que o LED mais escuro. Bem, eu sei que isso é um exagero, mas o processamento de imagens é muito divertido! E espero desenvolver o código de calibração como uma biblioteca.
Você pode ver o brilho do LED antes e depois da calibração nas fotos acima.
calibrateDispllay.pde
importprocessing.video. *; |
importprocessing.serial. *; |
Serial myPort; |
Capturar vídeo; |
finalint numLed = 24; |
int ledNum = 0; |
// você deve ter essas variáveis globais para usar o PxPGetPixelDark () |
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 aceitávelError = 3; |
int feito; |
int numPixelsInLed; |
long ledIntensity; |
int ledPower; |
long targetIntensity = 99999999; |
voidsetup () { |
feito = newint [numLed]; |
numPixelsInLed = newint [numLed]; |
ledIntensity = newlong [numLed]; |
ledPower = newint [numLed]; |
para (int i = 0; i <numLed; i ++) { |
ledPower = 255; |
} |
printArray (Serial.list ()); |
String portName = Serial.list () [31]; |
myPort = newSerial (this, portName, 9600); |
tamanho (640, 480); |
video = newCapture (this, width, height); |
video.start (); |
noStroke (); |
suave(); |
atraso (1000); // Aguarde a porta serial abrir |
} |
voiddraw () { |
if (video.available ()) { |
if (feito [ledNum] == 0) { |
clearDisplay (); |
atraso (1000); |
video.read (); |
imagem (vídeo, 0, 0, largura, altura); // Desenhe o vídeo da webcam na tela |
saveFrame ("data / no_leds.jpg"); |
if (runNumber! = 0) { |
if ((ledIntensity [ledNum] - targetIntensity) * 100 / targetIntensity> aceitávelError) { |
ledPower [ledNum] - = pow (0,75, runNumber) * 100 + 1; |
} |
if ((targetIntensity - ledIntensity [ledNum]) * 100 / targetIntensity> aceitávelError) { |
ledPower [ledNum] + = pow (0,75, runNumber) * 100 + 1; |
} |
if (abs (targetIntensity - ledIntensity [ledNum]) * 100 / targetIntensity <= aceitávelError) { |
concluído [ledNum] = 1; |
imprimir ("Led"); |
imprimir (ledNum); |
imprimir ("pronto"); |
} |
if (ledPower [ledNum]> 255) { |
ledPower [ledNum] = 255; |
} |
if (ledPower [ledNum] <0) { |
ledPower [ledNum] = 0; |
} |
} |
setLedPower (ledNum, ledPower [ledNum]); |
atraso (1000); |
video.read (); |
imagem (vídeo, 0, 0, largura, altura); // Desenhe o vídeo da webcam na tela |
atraso (10); |
while (myPort.available ()> 0) { |
int inByte = myPort.read (); |
// print (char (inByte)); |
} |
String imageName = "dados /"; |
imageName + = str (ledNum); |
imageName + = "_ led.jpg"; |
saveFrame (imageName); |
String originalImageName = "data / org"; |
originalImageName + = str (ledNum); |
originalImageName + = ". jpg"; |
if (runNumber == 0) { |
saveFrame (originalImageName); |
} |
PImage noLedImg = loadImage ("data / no_leds.jpg"); |
PImage ledImg = loadImage (imageName); |
PImage originalImg = loadImage (originalImageName); |
noLedImg.loadPixels (); |
ledImg.loadPixels (); |
originalImg.loadPixels (); |
fundo (0); |
loadPixels (); |
ledIntensity [ledNum] = 0; |
numPixelsInLed [ledNum] = 0; |
para (int x = 0; x <largura; x ++) { |
para (int y = 0; y <altura; y ++) { |
PxPGetPixelDark (x, y, noLedImg.pixels, largura); |
PxPGetPixelLed (x, y, ledImg.pixels, largura); |
PxPGetPixelOrg (x, y, originalImg.pixels, largura); |
if ((rOrg + gOrg / 2 + bOrg / 3) - (rOrg + 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] ++; |
} outro { |
rTemp = 0; |
gTemp = 0; |
bTemp = 0; |
} |
PxPSetPixel (x, y, rTemp, gTemp, bTemp, 255, pixels, largura); |
} |
} |
ledIntensity [ledNum] / = numPixelsInLed [ledNum]; |
if (targetIntensity> ledIntensity [ledNum] && runNumber == 0) { |
targetIntensity = ledIntensity [ledNum]; |
} |
updatePixels (); |
} |
imprimir (ledNum); |
imprimir(', '); |
imprimir (ledPower [ledNum]); |
imprimir(', '); |
println (ledIntensity [ledNum]); |
ledNum ++; |
if (ledNum == numLed) { |
int donezo = 0; |
para (int i = 0; i <numLed; i ++) { |
donezo + = feito ; |
} |
if (donezo == numLed) { |
println ("FEITO"); |
para (int i = 0; i <numLed; i ++) { |
imprimir (i); |
imprimir ("\ t"); |
println (ledPower ); |
} |
imprimir ("nível interno ["); |
imprimir (ledNum); |
imprimir ("] = {"); |
para (int i = 0; i <numLed-1; i ++) { |
imprimir (ledPower ); |
imprimir(', '); |
} |
imprimir (ledPower [numLed -1]); |
println ("};"); |
lightUpEven (); |
enquanto (verdadeiro); |
} |
imprimir ("Intensidade alvo:"); |
if (runNumber == 0) { |
targetIntensity - = 1; |
} |
println (targetIntensity); |
ledNum = 0; |
runNumber ++; |
} |
} |
} |
voidPxPGetPixelOrg (intx, inty, int pixelArray, intpixelsWidth) { |
int thisPixel = pixelArray [x + y * pixelsWidth]; // obtendo as cores como um inteiro dos pixels |
aOrg = (thisPixel >> 24) & 0xFF; // precisamos mudar e mascarar para obter cada componente sozinho |
rOrg = (thisPixel >> 16) & 0xFF; // isso é mais rápido do que chamar red (), green (), blue () |
gOrg = (thisPixel >> 8) & 0xFF; |
bOrg = thisPixel & 0xFF; |
} |
voidPxPGetPixelDark (intx, inty, int pixelArray, intpixelsWidth) { |
int thisPixel = pixelArray [x + y * pixelsWidth]; // obtendo as cores como um inteiro dos pixels |
aDark = (thisPixel >> 24) & 0xFF; // precisamos mudar e mascarar para obter cada componente sozinho |
rDark = (thisPixel >> 16) & 0xFF; // isso é mais rápido do que chamar red (), green (), blue () |
gDark = (thisPixel >> 8) & 0xFF; |
bDark = thisPixel & 0xFF; |
} |
voidPxPGetPixelLed (intx, inty, int pixelArray, intpixelsWidth) { |
int thisPixel = pixelArray [x + y * pixelsWidth]; // obtendo as cores como um inteiro dos pixels |
aLed = (thisPixel >> 24) & 0xFF; // precisamos mudar e mascarar para obter cada componente sozinho |
rLed = (thisPixel >> 16) & 0xFF; // isso é mais rápido do que chamar 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; // Estamos empacotando todos os 4 compostos em um único |
g = g << 8; // então precisamos mudá-los para seus lugares |
cor argb = a | r | g | b; // operação binária "ou" adiciona todos eles em um único int |
pixelArray [x + y * pixelsWidth] = argb; // finalmente definimos o int com as cores nos pixels |
} |
veja rawcalibrateDispllay.pde hospedado com ❤ por GitHub
Etapa 11: observações de despedida
Armadilhas a evitar:
* Com madeira, você obtém o que pagou. Portanto, obtenha madeira de boa qualidade. Contraplacado de bétula é uma boa escolha; qualquer madeira leve e sólida também serve. Eu roubei da madeira e lamento minha decisão.
* É melhor perfurar menos do que mais. Alguns buracos foram muito profundos para a minha peça. E o epóxi fica visível na face frontal. É muito perceptível quando você percebe.
* Use uma broca de ponta esférica em vez de uma ponta reta. Não experimentei a ponta da bola, mas tenho quase certeza de que os resultados serão muito melhores.
Estou flertando com a ideia de vendê-los no Etsy ou no Tindie. Eu realmente apreciaria se você pudesse comentar abaixo se você acha que faz sentido:)
Recomendado:
Como fazer relógio analógico e relógio digital com faixa LED usando o Arduino: 3 etapas
Como fazer relógio analógico e relógio digital com faixa de LED usando o Arduino: Hoje faremos um relógio analógico e relógio digital com faixa de LED. Relógio digital com Led Strip e módulo MAX7219 Dot com Arduino. Corrigirá a hora com o fuso horário local. O relógio analógico pode usar uma faixa de LED mais longa, então pode ser pendurado na parede para se tornar uma arte
C51 Relógio Eletrônico de 4 Bits - Relógio de Madeira: 15 Passos (com Imagens)
C51 Relógio Eletrônico de 4 Bits - Relógio de Madeira: Tive algum tempo livre neste fim de semana, então fui em frente e montei este Relógio Digital Eletrônico 4-Bits DIY de AU $ 2,40 que comprei no AliExpress um tempo atrás
Relógio de mesa "de madeira" * aparência moderna *: 9 etapas (com imagens)
Relógio de mesa "de madeira" * de aparência moderna *: Olá a todos, este é meu segundo instrutível! Desta vez vamos construir um relógio de madeira com indicador de temperatura e umidade. Como mostrado na imagem, nosso tempo será exibido através da " madeira ". Visto que a luz não é forte o suficiente
Como usar alguns pedaços de madeira para montar em um braço robótico de madeira bonito e poderoso: 10 etapas
Como usar alguns pedaços de madeira para montar em um braço robótico de madeira bonito e poderoso: O nome do braço do robô é WoodenArm. Parece muito fofo! Se você quiser mais detalhes sobre o WoodenArm, consulte www.lewansoul.com. Agora podemos fazer uma introdução sobre o WoodenArm, vamos prosseguir
Gravador alimentado por USB! Este projeto pode queimar plásticos / madeira / papel (o projeto divertido também deve ser uma madeira muito fina): 3 etapas
Gravador alimentado por USB! Este projeto pode queimar através de plástico / madeira / papel (projeto divertido também deve ser madeira muito fina): NÃO FAÇA ISSO USANDO USB !!!! Eu descobri que isso pode danificar seu computador com todos os comentários. meu computador está bem tho. Use um carregador de telefone 600ma 5v. Eu usei isso e funciona bem e nada pode ser danificado se você usar um plugue de segurança para interromper a alimentação