Inhoudsopgave:

London Underground Map Clock: 9 stappen (met afbeeldingen)
London Underground Map Clock: 9 stappen (met afbeeldingen)

Video: London Underground Map Clock: 9 stappen (met afbeeldingen)

Video: London Underground Map Clock: 9 stappen (met afbeeldingen)
Video: A Show of Scrutiny | Critical Role: THE MIGHTY NEIN | Episode 2 2024, November
Anonim
London Underground Kaart Klok
London Underground Kaart Klok
London Underground Kaart Klok
London Underground Kaart Klok

In 2014, na mijn stage bij een 3D-printadviesbureau in Londen en een experiment met kleurenlithofanen met behulp van hun Stratasys-machine, ontwerp ik mijn eigen afscheidscadeau, een 3D-kleurenprint van buisleidingen in de buurt van hun kantoren. Ik was vastbesloten er iets van te maken. Een kleine 2 jaar later, in 2016, had ik mijn eigen 3D-printer en ging aan de slag om er een klok van te maken.

Als kind dacht ik dat de Tokyo Flash digitale horloges de beste dingen ooit waren, en ik dacht dat dat het inspiratiepunt voor het ontwerp zou zijn.

En nu is het slechts een kleine pauze van 4 jaar geweest voordat ik eraan toe ben gekomen om het op te schrijven!

Hoewel de exacte instructies moeilijk te repliceren zijn, en de verlaging van de kosten bij de fabricage van PCB's voor hobbyisten in de afgelopen jaren, zou mijn exacte methode voor het plaatsen van LED's overbodig kunnen worden. Ik hoop dat de gedeelde ideeën ertoe kunnen leiden dat anderen rare klokken maken van dunne voorwerpen!

Stap 1: Voorste laag

Voorste laag
Voorste laag
Voorste laag
Voorste laag
Voorste laag
Voorste laag

Zoals vermeld in de intro, was dit een 3D-print in kleur, ik geloof een Stratasys-machine die een poederbed en een gemodificeerde inktcartridge voor bindmiddel en pigment gebruikte.

Het bestand is verloren gegaan aan de geschiedenis, maar deze laag kan van alles zijn, een foto of een litofaan in één kleur zou wonderen doen.

Dit onderdeel is gemaakt in 3DS max in 2014, maar tegenwoordig zijn er online tools om een afbeelding om te zetten in een SLT op basis van helderheid

Stap 2: De gidslaag ontwerpen

De hulplaag ontwerpen
De hulplaag ontwerpen
De hulplaag ontwerpen
De hulplaag ontwerpen
De hulplaag ontwerpen
De hulplaag ontwerpen
De hulplaag ontwerpen
De hulplaag ontwerpen

Hier bepalen we de complexiteit van het project en de methode voor het aflezen van de tijd. De afbeeldingen tonen de 2 ideeën waarmee ik aan het spelen was.

Deze zijn gemaakt door het ontwerp in te scannen en er in inkscape lijnen over te tekenen.

Dit is geen erg leesbare klok, maar ik gaf de voorkeur aan het idee van lijnen die de hele dag vullen, dus dat werd het ontwerpdoel.

Binair tellen is een haalbare methode om het aantal LED's te verminderen, en het zou de leesbaarheid verbeteren als binair je probleem is, maar dat ondermijnde mijn idee van 'vullijnen', dus was geen optie voor dit project

Het is gebruikelijk op de Tokyo Flash-horloges om het aantal LED's te minimaliseren, maar met een sectie die in 3 of 5 telt en dan een andere vulling voor elke keer dat die sectie wordt gevuld, heb ik deze techniek voor de minuten gebruikt om ze te verminderen van 60 naar 20 plus 2. I was niet zo bezorgd over precisie dit voor de seconden.

Stap 3: De gidslaag bouwen

De gidslaag bouwen
De gidslaag bouwen
De gidslaag bouwen
De gidslaag bouwen
De gidslaag bouwen
De gidslaag bouwen

Deze geleidingslaag voor de LED's heeft 2 doelen, het houdt de LED's op hun plaats en voorkomt morsen tussen de LED's

Het werd als een laag op Inkscape getekend, direct bovenop de scan die ik gebruikte voor de ontwerplay-out. 1 mm dikte werd in de blender toegevoegd voordat het naar mijn printer werd gestuurd.

Dit was een van de moeilijkste afdrukken die ik op mijn magere Makibox A6 moest maken, het onderdeel was in abs gedrukt, dus een ton acetonsuspensie werd gebruikt om het met minimale kromming aan het bouwplatform vast te houden. Gelukkig is dit onderdeel niet te zien op het eindproduct

De laatste afbeelding laat zien dat het tegen een lamp werd gehouden om te controleren op afstand.

Achteraf bezien zou verspilling tussen lichten langs een lijn eigenlijk de voorkeur kunnen hebben voor de beelden, is niet moeilijker te lezen, dit kan worden bereikt door een afschuining toe te voegen aan de gids aan de korte zijden van elk licht

Stap 4: Bedrading van de LED's

Bedrading van de LED's
Bedrading van de LED's
Bedrading van de LED's
Bedrading van de LED's
Bedrading van de LED's
Bedrading van de LED's

De eerste afbeelding toont de testafdruk die ik heb gemaakt om de grootte van de gaten te controleren, ik streefde ernaar dat de LED met een beetje kracht goed in het kant zou passen, de juiste vorm werd vervolgens met de hand geplaatst bij het leggen van de geleidelaag.

Vanwege de lage tolerantie van mijn 3D-printer, zaten sommige los en hadden ze een beetje superlijm nodig om op hun plaats te blijven, terwijl andere te strak waren, maar werden aangemoedigd om op hun plaats te blijven door tijdens het solderen op de LED te drukken, dit was eigenlijk een betere pasvorm dan de gaten met de juiste maat, die een huurovereenkomst hadden om eruit te trekken zodra ze waren aangesloten.

Om het aantal draden te verminderen, werden de LED's gesoldeerd in een matrix van 7 bij 8, wat betekent dat alle 55 LED's met slechts 13 pinnen konden worden bestuurd. Ik had een met de hand getekende kaart van elk van deze verbindingen die helaas verloren is gegaan.

Emaille draad werd gebruikt zodat secties op hun plaats konden worden blootgesteld door een sectie met het ijzer te verwarmen en te vertinnen voordat de verbinding werd gemaakt.

Dit proces was erg tijdrovend, ik zou het ten zeerste aanbevelen om een PCB te ontwerpen

Stap 5: De elektronica ontwerpen

De elektronica ontwerpen
De elektronica ontwerpen
De elektronica ontwerpen
De elektronica ontwerpen
De elektronica ontwerpen
De elektronica ontwerpen
De elektronica ontwerpen
De elektronica ontwerpen

Mijn oorspronkelijke plan was om een Arduino-microcontroller met een RTC te gebruiken, maar ik koos voor een ESP8266 op het Node MCU D1-bord omdat dit automatische daglichtbesparing mogelijk maakte en controle over WIFI mogelijk maakte.

Om het aantal pinnen verder te verminderen, had ik het perfecte aantal LED's om een MAX7219 te kunnen gebruiken (die tot 64 LED's aankan).

Dit IC wordt vaak gebruikt om LED 7 Segment-displays aan te sturen, maar het had een zeer vergelijkbare use-case als de mijne, het verlichten van een willekeurig aantal LED's met minimaal flikkeren, het heeft zelfs een regelbare helderheid.

Ik besloot om protoboard te gebruiken voor de bedrading, maar eagle was nuttig voor het plaatsen van onderdelen en het begrijpen van bedrading

Ik heb mijn bordbestanden bijgevoegd, maar dit was de eerste keer dat ik eagle gebruikte (en inmiddels een verouderde versie), dus ze zijn alleen ter referentie

Stap 6: bedrading van de elektronica

De elektronica bedraden
De elektronica bedraden
De elektronica bedraden
De elektronica bedraden
De elektronica bedraden
De elektronica bedraden
De elektronica bedraden
De elektronica bedraden

Dit was een repetitieve eenvoudige stap, volgens het Eagle-schema, waarbij headers voor de ESP en de LED-matrix enorm hielpen bij de montage.

Pin 1 op de Anode & Cathode LED-headers was gemarkeerd met een zilveren sharpie, ze konden worden onderscheiden zoals op 7 de andere 8.

Stap 7: Programmeren

Programmeren
Programmeren

Omdat ons display geen traditionele matrix is, moest ik een methode vinden om te visualiseren welke bits ik moest inschakelen en naar de MAX IC in HEX stuurde. Gelukkig ken ik net genoeg Excel om in de problemen te komen en heb ik een 'Hex wizard' gemaakt om me door het patroon te leiden dat ik wilde laten zien, met de hand geplaatste selectievakjes en alles.

Dit kwam met de herwaardering dat de hex voor mijn uur, minuut en seconden kon worden gecombineerd met behulp van een bitsgewijze OR om het laatste hex-commando te produceren om naar de max7219 te sturen, inclusief een kleine animatie die ik aan de seconden heb toegevoegd, zodat ik ervoor kon zorgen dat het bord was niet bevroren.

Dus bijna ten einde. en tijd voor een andere beslissing die niet al te oud is geworden.

De code voor de ESP is in LUA. Vandaag zou ik aanraden om de arduino IDE te gebruiken voor zijn betere documentatie en robuuste pakketbibliotheek, op het moment dat de ESP-gemeenschap nog volwassener werd en ik LUA koos als de taal voor dit project.

Ik nam de twijfelachtige beslissing om de Google-servers regelmatig te pingen om de tijd te lezen. Dit kwam er omheen dat je een RTC nodig had om drift te minimaliseren, dit werkt, maar je kunt beter een echte tijd-API gebruiken.

halfSec = 0uur=0 minuut=0 seconde=0

lage intensiteit = 0

hoge intensiteit = 9

lokale SSID = "Wifi"

lokaal SSID_PASSWORD ="Wachtwoord"

functietijd() -- verbinding maken met internet om de huidige tijd en datum te krijgen

if wifi.sta.getip() dan lokaal conn=net.createConnection(net. TCP, 0) conn:connect(80, "google.com")

conn:on("verbinding", function(conn, payload) conn:send("HEAD / HTTP/1.1\r\n".. "Host: time.is\r\n".. "Accepteren: */*\r\n".. " User-Agent: Mozilla/4.0 (compatibel; esp8266 Lua;)".. "\r\n\r\n") einde)

conn:on("ontvangen", function(conn, payload) --print(payload) conn:close() local p=string.find(payload, "GMT") -- zoek de tijd- en datumreeks in de payload van internet, verander voor tijdzone als p~ = nul dan -- haal getallen op die overeenkomen met het uur, de minuut, de seconde, de dag, de maand hour=tonumber(string.sub(payload, p-9, p-8)) minute=tonumber(string.sub(payload, p-) 6, p-5)) second=tonumber(string.sub(payload, p-3, p-2)) addHour() --hardcoded BST (Britse zomertijd) zomertijd print (uur, minuut, seconde) halfSec = (second%6)*2 --print(halfSec) else print("webupdate mislukt!") end end --function) --end of on "receive" event handler

conn:on("verbinding verbroken", functie(conn, payload) conn=nil payload=nil end) end print("nog geen wifi") end

functie borTable(a, b, …) --bitsgewijze OF tabellen samen

if arg[1] then b = borTable(b, unpack(arg)) end local z = {} for i, v in ipairs(a) do table.insert(z, bit.bor(v, b)) einde retour z einde

functie bxorTable(a, b, …) --bitsgewijze OF tabellen samen

if arg[1] then b = bxorTable(b, unpack(arg)) end local z = {} for i, v in ipairs(a) do table.insert(z, bit.bxor(v, b)) einde retour z einde

functie addSecond()

second=second+1 if second>=60 then second=0 minute=minute+1 if minute>=60 then minute=0 addHour() end end end

functie addHour()

hour=hour+1 if hour>=24 then hour=0 end if hour == 2 of hour == 16 dan max7219.setIntensity(lowIntensity) end if hour == 8 of hour == 18 dan max7219.setIntensity(highIntensity) end end function update() local secGap = 6 local minGap = 3 local horGap = 1 local sec={ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x03}, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x03}, { 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x01, 0x03}, { 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x01, 0x03}, { 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x03 }, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x03} }; lokaal min={ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00}, { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00}, { 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x00}, { 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x02, 0x00}, { 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x00}, { 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x00}, { 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x10}, { 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x12, 0x10}, { 0x02, 0x02, 0x02, 0x02, 0x02, 0x10, 0x12, 0x10}, { 0x02, 0x02, 0x02, 0x02, 0x12, 0x10, 0x12, 0x10 }, { 0x02, 0x02, 0x02, 0x12, 0x12, 0x10, 0x12, 0x10}, { 0x02, 0x02, 0x12, 0x12, 0x12, 0x10, 0x12, 0x10}, { 0x02, 0x12, 0x12, 0x12, 0x12, 0x10, 0x12, 0x10}, { 0x12, 0x12, 0x12, 0x12, 0x12, 0x10, 0x12, 0x10}, { 0x12, 0x12, 0x12, 0x12, 0x12, 0x30, 0x12, 0x10}, { 0x12, 0x12, 0x12, 0x12, 0x32, 0x30, 0x12, 0x10}, { 0x12, 0x12, 0x12, 0x32, 0x32, 0x30, 0x12, 0x10}, { 0x12, 0x12, 0x32, 0x32, 0x32, 0x30, 0x12, 0x10}, { 0x12, 0x32, 0x32, 0x32, 0x32, 0x30, 0x12, 0x10}, { 0x32, 0x32, 0x32, 0x32, 0x32, 0x30, 0x12, 0x10} }; lokaal hor={ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00}, { 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00}, { 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00}, { 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00}, { 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00}, { 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00}, { 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08}, { 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0C, 0x08}, { 0x04, 0x04, 0x04, 0x04, 0x04, 0x0C, 0x 0x0C, 0x 0x0C }, { 0x04, 0x04, 0x04, 0x04, 0x0C, 0x0C, 0x0C, 0x08}, { 0x04, 0x04, 0x04, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, { 0x04, 0x04, 0x0C, 0x0C,x 0x0C, 0x0C, 0x0C, 0x08}, { 0x04, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, 0x 0x0C, 0x0C, 0x0C, 0x0C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x4C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x4C, 0x4}, 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48}, { 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x4C,x 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48}, { 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48} }; --print (uur, minuut, seconde)

--de tabel begint op 0, dus op 1 aangezien momenteel sec[0] = nihil)

max7219.write({animate(borTable(sec[1+(second/secGap)], min[1+(minute/minGap)], hor[1+(hour/horGap)]))})

einde --functie

wifi.setmode(wifi. STATION)

wifi.sta.config(SSID, SSID_PASSWORD) wifi.sta.autoconnect(1)

--configureer max7219

max7219 = required("max7219") max7219.setup({numberOfModules = 1, slaveSelectPin = 8, intensity = highIntensity })

--Hoofdprogramma

checkOnline = tmr.create()

tmr.alarm(0, 180000, 1, tijd)

tmr.alarm(1, 1000, 1, addSecond)

tmr.alarm(2, 500, 1, update)

functie animeren (nog steeds)

lokale frames={ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, { 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; halfSec=halfSec+1 als halfSec >=12 dan halfSec = 0 end --print(halfSec) return bxorTable(frames[halfSec+1], still) end

Stap 8: De behuizing

De huisvesting
De huisvesting
De huisvesting
De huisvesting
De huisvesting
De huisvesting

Dit is jouw tijd om te pronken met je ongelooflijke vakmanschap en het project te huisvesten.

Ofwel dat of een amazon-pakket uit de recycling halen en een tijdelijke behuizing maken die nog steeds in gebruik is.

Het voordeel van deze aanpak was dat elke laag van het project bijna perfect overeenkwam met de dikte van het karton, zodat een sandwich kon worden gestapeld en aan elkaar geplakt. Een vergelijkbare premium-versie zou acryl kunnen gebruiken

Stap 9: Slotopmerkingen

Bedankt voor het lezen. Zoals velen van jullie weten, kan het documenteren van een project net zo moeilijk zijn als het maken ervan. er zijn stukjes video met mij aan het praten die uiteindelijk het daglicht kunnen zien.

In de jaren tussen het maken van dit project en het schrijven ervan verwachtte ik meer voorbeelden te zien van willekeurige LED-schermen die 3D-printen gebruiken, maar de vermindering van RGB-strips heeft de behoefte aan een alternatief grotendeels weggenomen.

Ik hoop dat dit informatief is geweest, en stel alsjeblieft vragen, want ik zal proberen meer details te geven over secties die niet volledig voldoen.

Proost

Aanbevolen: