Inhoudsopgave:
- Stap 1:
- Stap 2: Ontwerp
- Stap 3: CNCen
- Stap 4: Elektronica
- Stap 5: Elektronica Montage
- Stap 6: Drooglopen
- Stap 7: Epoxy
- Stap 8: Alles samenbrengen
- Stap 9: Coderen
- Stap 10: Computer Vision - Kalibratie
- Stap 11: Opmerkingen bij afscheid
Video: Houten LED-klok - analoge stijl - Ajarnpa
2024 Auteur: John Day | [email protected]. Laatst gewijzigd: 2024-01-30 11:19
Het is een houten LED-klok in analoge stijl. Ik weet niet waarom ik er nog nooit een heb gezien… hoewel de digitale typen heel gewoon zijn. Hoe dan ook, hier gaan we!
Stap 1:
Het multiplex klokproject begon als een eenvoudig startproject voor de CNC-router. Ik keek online naar eenvoudige projecten en vond deze lamp (afbeelding hierboven). Ik had ook digitale klokken gezien die door houtfineer schijnen (afbeelding hierboven). Het was dus een voor de hand liggend idee om de twee projecten te combineren. Om mezelf uit te dagen, besloot ik voor dit project geen fineer te gebruiken, maar alleen een stuk hout.
Stap 2: Ontwerp
Ik ontwierp de klok in Inkscape (afbeelding hierboven). Het ontwerp is naar keuze heel eenvoudig. Ik besloot om geen sporen voor de draden te routeren, omdat ik op dit moment niet zeker wist of ik met radiale of perimeterbedrading wilde gaan. (Ik besloot uiteindelijk om met perimeterbedrading te gaan.) Een neopixel gaat in elk van de kleine ronde gaatjes om de minuten- en uurtijd weer te geven, met een precisie van vijf minuten. De cirkel in het midden wordt naar buiten geleid om plaats te bieden aan de elektronica.
Stap 3: CNCen
Ik ontwierp de toolpaths op MasterCAM, en gebruikte een technoRouter om de klok uit 3/4 inch multiplex te frezen. Ik gebruik hiervoor een stuk van 15 "x15", met minimale verspilling. De truc is om zoveel mogelijk van het hout weg te werken zonder door het hout te breken. Het laten van 0,05"-0,1" is een goede keuze voor licht hout. Als je het niet zeker weet, kun je er beter meer hout in laten, omdat je de andere kant altijd kunt schuren. Ik heb uiteindelijk iets te veel hout uit sommige delen verwijderd, maar gelukkig hebben de resultaten hier niet al te veel onder te lijden.
Opmerking voor gebruikers zonder toegang tot een CNC:
Dit project kan eenvoudig worden gedaan met een kolomboormachine. Je hoeft alleen maar de stop in te stellen op een punt waar je ongeveer 0,1 hout aan de basis achterlaat. Je moet precies zijn, maar niet te precies. In het ideale geval ziet niemand alle LED's oplichten op tegelijkertijd, dus je kunt wegkomen met een beetje slop.
Stap 4: Elektronica
De elektronica is vrij eenvoudig. Er zijn 24 neopixels, twaalf voor het weergeven van de uren en twaalf voor het weergeven van de minuten, met een precisie van vijf minuten. Een Arduino pro mini bestuurt de neopixels en krijgt nauwkeurige tijd via een DS3231 realtime clock (RTC) -module. De RTC-module heeft een knoopcel als back-up, zodat hij geen tijd verliest, zelfs niet als de stroom is uitgeschakeld.
Materiaal:
Arduino pro mini (of welke andere Arduino dan ook)
DS3231 breakout-bord
Neopixels in afzonderlijke breakout-borden
Stap 5: Elektronica Montage
Ik verbond de neopixels in een string, met 2,5 draden voor de eerste twaalf leds en vier-inch draad voor de volgende twaalf. Ik had iets kleinere draadlengtes kunnen gebruiken. Nadat ik de string had gemaakt, testte ik hem uit en zorgde ervoor dat het soldeer verbindingen waren goed. Ik voegde een tijdelijke schakelaar toe om alle leds in te schakelen, gewoon om te pronken.
Stap 6: Drooglopen
Na wat geëxperimenteerd te hebben, LED's in de gaten te hebben gestoken en ze allemaal aan te zetten, was ik tevreden met het resultaat. Dus heb ik de voorkant een beetje geschuurd en een PU-laag aangebracht. Uiteindelijk heb ik de vacht er later afgeschuurd, maar het is een goed idee om het aan te laten als je het esthetisch niet onaangenaam vindt.
Stap 7: Epoxy
Na wat testen met de led-positie in de gaten, kwam ik tot de conclusie dat de beste discussie wordt bereikt wanneer de LED's ongeveer 0,2 verwijderd zijn van het einde van het gat. Als je dit zelf probeert, zal de helderheid van de LED's heel anders zijn in elk gat. Maak je hier geen zorgen over; we lossen het in code op. Dit komt door het type boor dat ik heb gebruikt. Als ik dit opnieuw zou doen, zou ik een kogelboor gebruiken voor de gaten Maar in ieder geval om de afstand te krijgen heb ik wat epoxy gemengd en een klein beetje in elk gaatje gedaan.
Stap 8: Alles samenbrengen
De LED's worden geplaatst vanaf de 12-uurwijzerpositie tegen de klok in door alle uurwijzerposities en vervolgens naar de minutenwijzer, opnieuw bewegend vanaf de 60-minutenmarkering tegen de klok in. Dit is zo dat wanneer we vanaf de voorkant kijken, het LED-patroon met de klok mee lijkt te gaan.
Nadat de epoxy een uur was uitgehard, heb ik wat meer epoxy aangebracht. Deze keer plaatste ik de LED's in de gaten, waarbij ik ervoor zorgde dat de draden en soldeerverbindingen met de epoxy werden bedekt. Dit zorgt voor een goede lichtverspreiding en borgt de draden.
Stap 9: Coderen
De code staat op GitHub, voel je vrij om deze aan te passen voor jouw gebruik. Wanneer je alle LED's op hetzelfde niveau inschakelt, zal de helderheid van het licht dat er doorheen schijnt in elk gat heel anders zijn. Dit komt door de verschillende diktes van het hout in de gaten en het verschil in de schaduw van het hout. Zoals je kunt zien varieert de houtkleur nogal in mijn stuk. Om dit verschil in helderheid te verhelpen, heb ik een matrix gemaakt van led-helderheidsniveaus. En verminderde de helderheid van de helderdere LED's. Het is een proces van vallen en opstaan en kan enkele minuten duren, maar de resultaten zijn het zeker waard.
multiplexClock.ino
// Multiplex klok |
// Auteur: tinkrmind |
// Naamsvermelding 4.0 Internationaal (CC BY 4.0). U bent vrij om: |
// Delen - kopieer en distribueer het materiaal in elk medium of formaat |
// Aanpassen - remix, transformeer en bouw voort op het materiaal voor elk doel, zelfs commercieel. |
// Hoera! |
#erbij betrekken |
#include"RTClib.h" |
RTC_DS3231 rtc; |
#include"Adafruit_NeoPixel.h" |
#ifdef _AVR_ |
#erbij betrekken |
#stop als |
#definePIN6 |
Adafruit_NeoPixel-strip = Adafruit_NeoPixel (60, PIN, NEO_GRB + NEO_KHZ800); |
int uurPixel = 0; |
int minuutPixel = 0; |
niet ondertekend lang laatsteRtcCheck; |
String inputString = ""; // een string om inkomende gegevens vast te houden |
boolean stringComplete = false; // of de string compleet is |
int-niveau [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 |
terwijl (!Serial); // voor Leonardo/Micro/Zero |
#stop als |
// Dit is voor Trinket 5V 16MHz, u kunt deze drie lijnen verwijderen als u geen Trinket gebruikt |
#indien gedefinieerd (_AVR_ATtiny85_) |
if (F_CPU == 16000000) clock_prescale_set(clock_div_1); |
#stop als |
// Einde van speciale code voor trinket |
Serieel.begin(9600); |
strip.begin(); |
strip.show(); // Initialiseer alle pixels op 'uit' |
if (! rtc.begin()) { |
Serial.println ("Kon RTC niet vinden"); |
terwijl (1); |
} |
pinMode (2, INPUT_PULLUP); |
// rtc.adjust(DateTime(F(_DATE_), F(_TIME_))); |
if (rtc.lostPower()) { |
Serial.println("RTC heeft geen stroom meer, laten we de tijd instellen!"); |
// volgende regel stelt de RTC in op de datum en tijd waarop deze schets is gecompileerd |
rtc.adjust(DateTime(F(_DATE_), F(_TIME_))); |
// Deze regel stelt de RTC in met een expliciete datum en tijd, bijvoorbeeld om in te stellen |
// 21 januari 2014 om 3 uur zou je bellen: |
// rtc.adjust(DateTime(2017, 11, 06, 2, 49, 0)); |
} |
// rtc.adjust(DateTime(2017, 11, 06, 2, 49, 0)); |
// lightUpEven(); |
// terwijl (1); |
lastRtcCheck = 0; |
} |
leegteloop () { |
if (millis() - lastRtcCheck >2000) { |
DateTime nu = rtc.now(); |
Serial.print(nu.uur(), DEC); |
Serieel.print(':'); |
Serial.print(nu.minute(), DEC); |
Serieel.print(':'); |
Serial.print(nu.second(), DEC); |
Serieel.println(); |
show Time(); |
lastRtcCheck = millis(); |
} |
if (!digitalRead(2)) { |
lightUpEven(); |
} |
if (stringCompleet) { |
Serial.println(inputString); |
if (inputString[0] == 'l') { |
Serieel.println("Niveau"); |
lightUpEven(); |
} |
if (inputString[0] == 'c') { |
Serial.println ("Toon tijd"); |
show Time(); |
strip.show(); |
} |
if (inputString[0] == '1') { |
Serial.println ("Alle LED's inschakelen"); |
lightUp(strip. Color(255, 255, 255)); |
strip.show(); |
} |
if (inputString[0] == '0') { |
Serial.println("Clearing strip"); |
Doorzichtig(); |
strip.show(); |
} |
// #3, 255 zou led nummer 3 instellen op niveau 255, 255, 255 |
if (inputString[0] == '#') { |
Stringtemperatuur; |
temp = inputString.substring(1); |
int pixNum = temp.toInt(); |
temp = inputString.substring(inputString.indexOf(', ') + 1); |
int intensiteit = temp.toInt(); |
Serial.print("Instelling "); |
Serial.print(pixNum); |
Serial.print(" naar niveau "); |
Serial.println(intensiteit); |
strip.setPixelColor(pixNum, strip. Color(intensiteit, intensiteit, intensiteit)); |
strip.show(); |
} |
// #3, 255, 0, 125 zou led nummer 3 instellen op niveau 255, 0, 125 |
if (inputString[0] == '$') { |
Stringtemperatuur; |
temp = inputString.substring(1); |
int pixNum = temp.toInt(); |
int rIndex = inputString.indexOf(', ') + 1; |
temp = inputString.substring(rIndex); |
int rIntensiteit = 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 bIntensiteit = temp.toInt(); |
Serial.print("Instelling "); |
Serial.print(pixNum); |
Serial.print(" R naar "); |
Serial.print(rIntensiteit); |
Serial.print(" G naar "); |
Serial.print(gIntensity); |
Serial.print(" B tot "); |
Serial.println(bIntensiteit); |
strip.setPixelColor(pixNum, strip. Color(rIntensity, gIntensity, bIntensity)); |
strip.show(); |
} |
if (inputString[0] == 's') { |
Stringtemperatuur; |
int uur, minuut; |
temp = inputString.substring(1); |
uur = temp.toInt(); |
int rIndex = inputString.indexOf(', ') + 1; |
temp = inputString.substring(rIndex); |
minuut = temp.toInt(); |
Serial.print("Toon tijd: "); |
Seriële.afdruk(uur); |
Serial.print(":"); |
Serieafdruk(minuut); |
showTime (uur, minuut); |
vertraging (1000); |
} |
invoerString = ""; |
stringComplete = onwaar; |
} |
// vertraging (1000); |
} |
voidserialEvent() { |
while (Serial.available()) { |
char inChar = (char)Serial.read(); |
inputString += inChar; |
if (inChar == '\n') { |
stringComplete = waar; |
} |
vertraging(1); |
} |
} |
leegte wissen() { |
voor (uint16_t ik = 0; ik <strip.numPixels(); i++) { |
strip.setPixelColor(i, strip. Color(0, 0, 0)); |
} |
} |
voidshowTime() { |
DateTime nu = rtc.now(); |
hourPixel = nu.uur() % 12; |
minutePixel = (now.minute() / 5) % 12 + 12; |
Doorzichtig(); |
// strip.setPixelColor (hourPixel, strip. Color (40 + 40 * niveau [uurPixel], 30 + 30 * niveau [uurPixel], 20 + 20 * niveau [uurPixel])); |
// strip.setPixelColor (minutePixel, strip. Color (40 + 40 * niveau [minutePixel], 30 + 30 * niveau [minutePixel], 20 + 20 * niveau [minutePixel])); |
strip.setPixelColor(hourPixel, strip. Color(level[hourPixel], level[hourPixel], level[hourPixel])); |
strip.setPixelColor(minutePixel, strip. Color(level[minutePixel], level[minutePixel], level[minutePixel])); |
// lightUp (strip. Color (255, 255, 255)); |
strip.show(); |
} |
voidshowTime(int uur, int minuut) { |
uurPixel = uur % 12; |
minuutPixel = (minuut / 5) % 12 + 12; |
Doorzichtig(); |
// strip.setPixelColor (hourPixel, strip. Color (40 + 40 * niveau [uurPixel], 30 + 30 * niveau [uurPixel], 20 + 20 * niveau [uurPixel])); |
// strip.setPixelColor (minutePixel, strip. Color (40 + 40 * niveau [minutePixel], 30 + 30 * niveau [minutePixel], 20 + 20 * niveau [minutePixel])); |
strip.setPixelColor(hourPixel, strip. Color(level[hourPixel], level[hourPixel], level[hourPixel])); |
strip.setPixelColor(minutePixel, strip. Color(level[minutePixel], level[minutePixel], level[minutePixel])); |
// lightUp (strip. Color (255, 255, 255)); |
strip.show(); |
} |
voidlightUp(uint32_t kleur) { |
voor (uint16_t ik = 0; ik <strip.numPixels(); i++) { |
strip.setPixelColor(i, kleur); |
} |
strip.show(); |
} |
voidlightUpEven() { |
voor (uint16_t ik = 0; ik <strip.numPixels(); i++) { |
strip.setPixelColor(i, strip. Color(niveau, niveau, niveau)); |
} |
strip.show(); |
} |
bekijk rawplywoodClock.ino gehost met ❤ door GitHub
Stap 10: Computer Vision - Kalibratie
Ik heb er bewust voor gekozen om geen fineer te gebruiken in dit project. Als ik dat had gedaan, zou de houtdikte voor alle LED's hetzelfde zijn geweest. Maar omdat ik voor elke LED een andere houtdikte heb en omdat de houtkleur ook erg varieert, is de helderheid van de LED per LED anders. Om ervoor te zorgen dat alle LED's dezelfde helderheid hebben, bedacht ik een handige truc.
Ik heb een verwerkingscode geschreven (op GitHub) die een foto van de klok maakt en om de beurt de helderheid van elke LED analyseert. Het varieert vervolgens het vermogen naar elke LED om te proberen ze allemaal dezelfde helderheid te geven als de zwakste LED. Ik weet dat dit overdreven is, maar beeldverwerking is erg leuk! En ik hoop de kalibratiecode als bibliotheek te ontwikkelen.
U kunt de LED-helderheid voor en na de kalibratie zien op de bovenstaande foto's.
calibrerenDispllay.pde
importprocessing.video.*; |
importprocessing.serial.*; |
Seriële myPort; |
Video opnemen; |
finalint numLed =24; |
int ledNum =0; |
// je moet deze globale variabelen hebben om de PxPGetPixelDark() te gebruiken |
int rDonker, gDonker, bDonker, aDonker; |
int rLed, gLed, bLed, aLed; |
int rOrg, gOrg, bOrg, aOrg; |
int rTemp, gTemp, bTemp, aTemp; |
PImage onzeImage; |
int runNumber =0; |
int acceptabelError =3; |
int gedaan; |
int numPixelsInLed; |
lang ledIntensiteit; |
int ledPower; |
lange doelintensiteit =99999999; |
voidsetup() { |
gedaan =newint[numLed]; |
numPixelsInLed =newint[numLed]; |
ledIntensity =nieuwlang[numLed]; |
ledPower =newint[numLed]; |
voor (int i=0; i<numLed; i++) { |
ledPower =255; |
} |
printArray(Serial.list()); |
String portName =Serial.list()[31]; |
myPort =newSerial(this, portName, 9600); |
grootte (640, 480); |
video =newCapture(deze, breedte, hoogte); |
video.start(); |
geen slag(); |
zacht(); |
vertraging (1000); // Wacht tot de seriële poort opengaat |
} |
leegteken() { |
if (video.beschikbaar()) { |
if (klaar[ledNum] ==0) { |
clearDisplay(); |
vertraging (1000); |
video.lezen(); |
afbeelding (video, 0, 0, breedte, hoogte); // Teken de webcamvideo op het scherm |
saveFrame("data/geen_leds.jpg"); |
if (runNumber !=0) { |
if ((ledIntensity[ledNum] - targetIntensity)*100/targetIntensity > acceptabele fout) { |
ledPower[ledNum] -=pow(0.75, runNumber)*100+1; |
} |
if ((targetIntensity - ledIntensity[ledNum])*100/targetIntensity > acceptabele fout) { |
ledPower[ledNum] +=pow(0.75, runNumber)*100+1; |
} |
if (abs(targetIntensity - ledIntensity[ledNum])*100/targetIntensity <= acceptabele fout) { |
klaar[ledNum] =1; |
print("Led"); |
print(ledNum); |
print("klaar"); |
} |
if (ledPower[ledNum] >255) { |
ledPower[ledNum] =255; |
} |
if (ledPower[ledNum] <0) { |
ledPower[ledNum]=0; |
} |
} |
setLedPower (ledNum, ledPower [ledNum]); |
vertraging (1000); |
video.lezen(); |
afbeelding (video, 0, 0, breedte, hoogte); // Teken de webcamvideo op het scherm |
vertraging(10); |
while (myPort.available() >0) { |
int inByte = myPort.read(); |
//print(char(inByte)); |
} |
Tekenreeks afbeeldingsnaam = "data/"; |
imageName+=str(ledNum); |
afbeeldingNaam +="_led.jpg"; |
saveFrame(afbeeldingNaam); |
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(); |
achtergrond (0); |
loadPixels(); |
ledIntensity[ledNum] =0; |
aantalPixelsInLed[ledNum] =0; |
voor (int x =0; x<breedte; x++) { |
voor (int y =0; y<hoogte; y++) { |
PxPGetPixelDark(x, y, noLedImg.pixels, breedte); |
PxPGetPixelLed(x, y, ledImg.pixels, breedte); |
PxPGetPixelOrg(x, y, originalImg.pixels, breedte); |
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]++; |
} anders { |
rTemp=0; |
gTemp=0; |
bTemp=0; |
} |
PxPSetPixel(x, y, rTemp, gTemp, bTemp, 255, pixels, breedte); |
} |
} |
ledIntensity[ledNum] /= numPixelsInLed[ledNum]; |
if (targetIntensity > ledIntensity[ledNum] && runNumber ==0) { |
targetIntensity = ledIntensity[ledNum]; |
} |
updatePixels(); |
} |
print(ledNum); |
afdrukken(', '); |
print(ledPower[ledNum]); |
afdrukken(', '); |
println(ledIntensity[ledNum]); |
ledNum++; |
if (ledNum == numLed) { |
int donezo =0; |
voor (int i=0; i<numLed; i++) { |
donezo += klaar; |
} |
if (donezo == numLed) { |
println("KLAAR"); |
voor (int i=0; i<numLed; i++) { |
afdrukken (ik); |
print("\t"); |
println(ledPower); |
} |
print("int niveau["); |
print(ledNum); |
print("] = {"); |
voor (int i=0; i<numLed-1; i++) { |
print(ledPower); |
afdrukken(', '); |
} |
print(ledPower[numLed -1]); |
println("};"); |
lightUpEven(); |
terwijl (waar); |
} |
print("Doelintensiteit: "); |
if (runNumber ==0) { |
targetIntensity -=1; |
} |
println(targetIntensity); |
ledNum =0; |
runNumber++; |
} |
} |
} |
voidPxPGetPixelOrg(intx, inty, int pixelArray, intpixelsWidth) { |
int thisPixel=pixelArray[x+y*pixelsBreedte]; // de kleuren krijgen als een int van de pixels |
aOrg = (dit pixel >>24) &0xFF; // we moeten verschuiven en maskeren om elk onderdeel alleen te krijgen |
rOrg = (dit pixel >>16) &0xFF; // dit is sneller dan het aanroepen van red(), green(), blue() |
gOrg = (dit pixel >>8) &0xFF; |
bOrg = thisPixel &0xFF; |
} |
voidPxPGetPixelDark(intx, inty, int pixelArray, intpixelsWidth) { |
int thisPixel=pixelArray[x+y*pixelsBreedte]; // de kleuren krijgen als een int van de pixels |
aDark = (dit pixel >>24) &0xFF; // we moeten verschuiven en maskeren om elk onderdeel alleen te krijgen |
rDark = (dit pixel >>16) &0xFF; // dit is sneller dan het aanroepen van red(), green(), blue() |
gDark = (dit pixel >>8) &0xFF; |
bDonker = ditPixel &0xFF; |
} |
voidPxPGetPixelLed(intx, inty, int pixelArray, intpixelsWidth) { |
int thisPixel=pixelArray[x+y*pixelsBreedte]; // de kleuren krijgen als een int van de pixels |
aLed = (dit pixel >>24) &0xFF; // we moeten verschuiven en maskeren om elk onderdeel alleen te krijgen |
rLed = (dit pixel >>16) &0xFF; // dit is sneller dan het aanroepen van red(), green(), blue() |
gLed = (dit pixel >>8) &0xFF; |
bLed = ditPixel &0xFF; |
} |
voidPxPSetPixel(intx, inty, intr, intg, intb, inta, int pixelArray, intpixelsWidth) { |
een =(a <<24); |
r = r <<16; // We verpakken alle 4 componenten in één int |
g = g <<8; // dus we moeten ze naar hun plaats verplaatsen |
kleur argb = een | r | g | B; // binaire "of"-bewerking voegt ze allemaal toe aan één int |
pixelArray[x+y*pixelsWidth]= argb; // eindelijk zetten we de int met de kleuren in de pixels |
} |
bekijk rawcalibrateDispllay.pde gehost met ❤ door GitHub
Stap 11: Opmerkingen bij afscheid
Te vermijden valkuilen:
* Met hout krijgt u waar u voor betaalt. Koop dus hout van goede kwaliteit. Berken multiplex is een goede keuze; elk licht massief hout zal het ook goed doen. Ik heb bezuinigd op het hout en heb spijt van mijn beslissing.
* Het is beter om minder te boren dan meer. Een paar van de gaten gingen te diep voor mijn stuk. En de epoxy is zichtbaar aan de voorkant. Het valt erg op als je het eenmaal opmerkt.
* Gebruik een kogelkopboor in plaats van een recht uiteinde. Ik heb niet geëxperimenteerd met het kogeleindstuk, maar ik ben er vrij zeker van dat de resultaten veel beter zullen zijn.
Ik flirt met het idee om deze op Etsy of Tindie te verkopen. Ik zou het erg op prijs stellen als je hieronder een reactie zou plaatsen als je denkt dat het logisch is:)
Aanbevolen:
Houten schijfspeler: 20 stappen (met afbeeldingen)
Houten schijfspeler: ik wilde demonstreren hoe apparaten voor informatieopslag werken door een grootschalige schijfafspeelmachine te bouwen. In plaats van te zijn gebaseerd op lichtinterferentie zoals cd-spelers, speelt het apparaat dat ik heb gebouwd houten schijven met gaten en "niet-gaten" af. (als
Een geodetische koepel in Temcor-stijl maken in Autodesk Inventor: 8 stappen
Een geodetische koepel in Temcor-stijl maken in Autodesk Inventor: deze tutorial laat je zien hoe je een koepel in Temcor-stijl maakt met slechts een klein beetje wiskunde. De meeste informatie in deze tutorial is verkregen uit TaffGoch's reverse-engineering van de onderverdelingsmethode van het oude Amundsen-Scott South Pole Station, s
Muziekinstrument in DDR-stijl: 3 stappen
Muziekinstrument in DDR-stijl: dit is een snel gebouwd muziekinstrument dat ik heb gemaakt met behulp van de "gratis" promotionele dans-dans-revolutie-dansmatten die Kraft uitdeelt
Een DIY-stijl voor een wifi-booster bouwen: 4 stappen
Een wifi-booster bouwen DIY-stijl: leer hoe u uw wifi-signaal voor een prikkie kunt versterken met deze eenvoudige doe-het-zelfgidsOrigineel artikel: een wifi-booster bouwen
Een opvallend display maken (LED-stijl): 9 stappen (met afbeeldingen)
Een opvallend display maken (LED-stijl): dit is niet zozeer een instructie als een verslag van hoe ik een schoolproject heb gemaakt. Hoewel precies herhalen wat ik heb gedaan, je waarschijnlijk niet zal helpen, kan dit project worden aangepast om bijna elk scherm opvallender te maken