Inhaltsverzeichnis:

Londoner U-Bahn-Karte Uhr - Gunook
Londoner U-Bahn-Karte Uhr - Gunook

Video: Londoner U-Bahn-Karte Uhr - Gunook

Video: Londoner U-Bahn-Karte Uhr - Gunook
Video: Peppa-Wutz-Geschichten | Die Londoner U-Bahn | Videos für Kinder 2024, November
Anonim
Londoner U-Bahn-Karte Uhr
Londoner U-Bahn-Karte Uhr
Londoner U-Bahn-Karte Uhr
Londoner U-Bahn-Karte Uhr

Im Jahr 2014 entwerfe ich nach einem Praktikum bei einer 3D-Druckberatung in London und einem Experiment mit Farblithophanen mit ihrer Stratasys-Maschine mein eigenes Abschiedsgeschenk, einen farbigen 3D-Druck von Rohrleitungen vor Ort in ihren Büros. Ich war fest entschlossen, daraus etwas zu machen. Kurze 2 Jahre später, im Jahr 2016, hatte ich meinen eigenen 3D-Drucker und machte mich daran, ihn zu einer Uhr zu machen.

Als Kind dachte ich, die Digitaluhren von Tokyo Flash seien die großartigsten Dinge aller Zeiten, und ich entschied, dass dies der Inspirationspunkt für das Design sein würde.

Und jetzt war es nur eine kleine 4-jährige Pause, bis ich dazu gekommen bin, es aufzuschreiben!

Während die genauen Anweisungen schwer zu replizieren sein werden, und die Kostensenkung bei der Herstellung von Hobby-PCBs in den letzten Jahren könnte meine genaue Methode zur LED-Platzierung obsolet machen. Ich hoffe, die geteilten Ideen könnten dazu führen, dass andere seltsame Uhren aus dünnen Objekten herstellen!

Schritt 1: Vordere Schicht

Vordere Schicht
Vordere Schicht
Vordere Schicht
Vordere Schicht
Vordere Schicht
Vordere Schicht

Wie im Intro erwähnt, war dies ein 3D-Farbdruck, ich glaube, eine Stratasys-Maschine, die ein Pulverbett und eine modifizierte Tintenpatrone für Bindemittel und Pigment verwendet.

Die Datei ist in der Geschichte verloren, aber diese Ebene könnte alles sein, ein Foto oder eine einfarbige Lithophan würde Wunder bewirken.

Dieser Teil wurde 2014 in 3DS max erstellt, aber heute gibt es Online-Tools, um ein Bild basierend auf der Helligkeit in ein SLT umzuwandeln

Schritt 2: Entwerfen der Führungsebene

Entwerfen der Führungsebene
Entwerfen der Führungsebene
Entwerfen der Führungsebene
Entwerfen der Führungsebene
Entwerfen der Führungsebene
Entwerfen der Führungsebene
Entwerfen der Führungsebene
Entwerfen der Führungsebene

Hier entscheiden wir über die Komplexität des Projekts und die Methode zum Ablesen der Zeit. Die Bilder zeigen die 2 Ideen, mit denen ich gespielt habe.

Diese wurden durch Einscannen des Designs und Zeichnen von Linien in Inkscape erstellt.

Dies ist keine sehr lesbare Uhr, aber ich bevorzugte die Idee, dass sich die Linien den ganzen Tag füllen, so dass dies das Designziel wurde.

Binäres Zählen ist eine praktikable Methode zum Reduzieren der LED-Anzahl, und es würde die Lesbarkeit verbessern, wenn Binär Ihr Jam ist, aber das hat meine Idee des "Füllens von Zeilen" untergraben und war daher keine Option für dieses Projekt

Es ist bei den Tokyo Flash Watches üblich, die LED-Anzahl zu minimieren, aber mit einem Abschnitt, der in 3 oder 5 zählt und dann für jedes Mal, wenn dieser Abschnitt gefüllt wird, eine weitere Füllung hat, habe ich diese Technik für die Minuten verwendet, um sie von 60 auf 20 plus 2 zu reduzieren war für die Sekunden nicht so besorgt um die Präzision.

Schritt 3: Erstellen der Führungsebene

Aufbau der Führungsebene
Aufbau der Führungsebene
Aufbau der Führungsebene
Aufbau der Führungsebene
Aufbau der Führungsebene
Aufbau der Führungsebene

Diese Führungsschicht für die LEDs hat 2 Zwecke, sie hält die LEDs an Ort und Stelle und verhindert ein Verschütten zwischen ihnen

Es wurde als Ebene auf Inkscape direkt auf den Scan gezeichnet, den ich für das Design-Layout verwendet habe. 1 mm Dicke wurde vor dem Senden an meinen Drucker in einen Mixer gegeben.

Dies war einer der härtesten Drucke, die ich auf meiner mageren Makibox A6 machen musste. Das Teil wurde in ABS gedruckt, sodass eine Tonne Acetonaufschlämmung verwendet wurde, um es mit minimalem Verzug an der Bauplattform zu halten. Glücklicherweise ist dieser Teil auf dem Endprodukt nicht zu sehen

Das letzte Bild zeigt, wie es an eine Lampe gehalten wird, um den Abstand zu überprüfen.

Im Nachhinein betrachtet, könnte ein Streuen zwischen Lichtern entlang einer Linie für die Optik tatsächlich vorzuziehen sein, ist nicht schwerer zu lesen, dies könnte durch Hinzufügen einer Fase an der Führung an den kurzen Seiten jedes Lichts erreicht werden

Schritt 4: Verdrahtung der LEDs

Verdrahtung der LEDs
Verdrahtung der LEDs
Verdrahtung der LEDs
Verdrahtung der LEDs
Verdrahtung der LEDs
Verdrahtung der LEDs

Das erste Bild zeigt den Testdruck, den ich zur Überprüfung der Lochgröße gemacht habe, ich wollte, dass die LED mit etwas Kraft fest in die Spitze passt, die richtige Form wurde dann beim Auslegen der Führungsschicht von Hand platziert.

Aufgrund der geringen Toleranz meines 3D-Druckers waren einige locker und erforderten einen Klecks Sekundenkleber, um an Ort und Stelle zu bleiben, während andere zu fest waren, aber durch Drücken auf die LED während des Lötens in Position gebracht wurden, war dies tatsächlich eine bessere Passform als das Loch mit der richtigen Größe, das nach dem Verdrahten eine Ausziehbarkeit hatte.

Um die Anzahl der Drähte zu reduzieren, wurden die LEDs in einer Matrix von 7 x 8 gelötet, dh alle 55 LEDs konnten mit nur 13 Pins angesteuert werden, ich hatte von jedem dieser Anschlüsse eine handgezeichnete Karte, die leider verloren gegangen ist.

Es wurde Emailledraht verwendet, so dass Abschnitte durch Erhitzen eines Abschnitts mit dem Eisen und Verzinnen vor dem Herstellen der Verbindung freigelegt werden konnten.

Dieser Prozess war sehr zeitaufwändig, ich würde dringend empfehlen, eine Leiterplatte zu entwerfen

Schritt 5: Entwerfen der Elektronik

Entwerfen der Elektronik
Entwerfen der Elektronik
Entwerfen der Elektronik
Entwerfen der Elektronik
Entwerfen der Elektronik
Entwerfen der Elektronik
Entwerfen der Elektronik
Entwerfen der Elektronik

Mein ursprünglicher Plan war es, einen Arduino-Mikrocontroller mit einer RTC zu verwenden, entschied mich jedoch für einen ESP8266 auf der Node MCU D1-Platine, da er eine automatische Sommerzeit und die Möglichkeit der Kontrolle über WIFI ermöglichte.

Um die Pinanzahl weiter zu reduzieren, hatte ich die perfekte Anzahl von LEDs, um einen MAX7219 (der bis zu 64 LEDs verarbeiten kann) verwenden zu können.

Dieser IC wird häufig zum Ansteuern von LED-7-Segment-Displays verwendet, hatte jedoch einen sehr ähnlichen Anwendungsfall wie bei mir, er beleuchtete eine beliebige Anzahl von LEDs mit minimalem Flackern und hat sogar eine steuerbare Helligkeit.

Ich entschied mich, Protoboard für die Verkabelung zu verwenden, aber Eagle war hilfreich für die Teileplatzierung und das Verständnis der Verkabelung

Ich habe meine Board-Dateien angehängt, aber dies war mein erstes Mal, dass ich Eagle (und eine veraltete Version) verwendet habe, also dienen sie nur als Referenz

Schritt 6: Verdrahtung der Elektronik

Verkabelung der Elektronik
Verkabelung der Elektronik
Verkabelung der Elektronik
Verkabelung der Elektronik
Verkabelung der Elektronik
Verkabelung der Elektronik
Verkabelung der Elektronik
Verkabelung der Elektronik

Dies war ein sich wiederholender einfacher Schritt, der dem Eagle-Schema folgte, wobei Header für das ESP und die LED-Matrix verwendet wurden, was bei der Montage enorm half.

Pin 1 auf den Anoden- und Kathoden-LED-Headern war mit einem silbernen Sharpie markiert, sie konnten zwischen 7 und den anderen 8 unterschieden werden.

Schritt 7: Programmierung

Programmierung
Programmierung

Da es sich bei unserem Display nicht um eine traditionelle Matrix handelt, musste ich eine Methode finden, um zu visualisieren, welche Bits eingeschaltet und an den MAX-IC in HEX gesendet werden. Glücklicherweise kenne ich gerade genug Excel, um in Schwierigkeiten zu geraten, und habe einen "Hex-Assistenten" erstellt, der mich durch das Muster führt, das ich anzeigen wollte, von Hand platzierte Kontrollkästchen und alle.

Dies kam mit der Neubewertung, dass der Hex für meine Stunde, Minute und Sekunde mit einem bitweisen ODER kombiniert werden konnte, um den endgültigen Hex-Befehl zum Senden an den max7219 zu erzeugen, einschließlich einer kleinen Animation, die ich den Sekunden hinzugefügt habe, damit ich sicherstellen kann, dass das Board war nicht gefroren.

Also fast am Ende. und Zeit für eine andere Entscheidung, die nicht allzu gut gealtert ist.

Der Code für das ESP ist in LUA. Heute würde ich empfehlen, die Arduino-IDE für eine bessere Dokumentation und robuste Paketbibliothek zu verwenden, zu der Zeit, als die ESP-Community noch reifte und ich LUA als Sprache für dieses Projekt wählte.

Ich habe die fragwürdige Entscheidung getroffen, die Google-Server regelmäßig anzupingen, um die Uhrzeit abzulesen. Dies hat sich herumgesprochen, dass eine RTC benötigt wird, um die Drift zu minimieren, dies funktioniert, aber Sie sollten besser eine Echtzeit-API verwenden.

halbe Sek = 0Stunde=0 Minute=0 Sekunde=0

niedrige Intensität = 0

hohe Intensität = 9

lokale SSID ="Wifi"

local SSID_PASSWORD ="Passwort"

function time() --Verbindung zum Internet herstellen, um die aktuelle Uhrzeit und das aktuelle Datum abzurufen

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

conn:on("Verbindung", function(conn, payload) conn:send("HEAD / HTTP/1.1\r\n".. "Host: time.is\r\n".. "Akzeptieren: */*\r\n".. " User-Agent: Mozilla/4.0 (kompatibel; esp8266 Lua;)".. "\r\n\r\n") end)

conn:on("empfangen", function(conn, payload) --print(payload) conn:close() local p=string.find(payload, "GMT") -- Finde die Zeit- und Datumszeichenfolge in der Nutzlast aus dem Internet, ändere die Zeitzone, wenn p~ =nil then -- Extrahiere Zahlen, die der Stunde, Minute, Sekunde, Tag, Monat entsprechen. 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() --hardcodierte BST (Britische Sommerzeit) Sommerzeit print(Stunde, Minute, Sekunde) halfSec = (second%6)*2 --print(halfSec) else print("Web-Update fehlgeschlagen!") end end --function) --end of on "receive" Eventhandler

conn:on("Verbindung trennen", function(conn, payload) conn=nil payload=nil end) end print("Noch kein WLAN") end

Funktion borTable(a, b, …) --bitweise ODER-Tabellen zusammen

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)) Ende zurück z Ende

Funktion bxorTable(a, b, …) --bitweise ODER-Tabellen zusammen

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)) Ende zurück z Ende

Funktion addSecond()

Sekunde=Sekunde+1 wenn Sekunde>=60 dann Sekunde=0 Minute=Minute+1 wenn Minute>=60 dann Minute=0 addHour() end end end

Funktion addHour()

Stunde=Stunde+1 wenn Stunde>=24 dann Stunde=0 Ende wenn Stunde == 2 oder Stunde == 16 dann max7219.setIntensity(lowIntensity) Ende wenn Stunde == 8 oder Stunde == 18 dann 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} }; lokale 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} }; lokales 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, 0x0C, }, { 0x04, 0x04, 0x04, 0x04, 0x0C, 0x0C, 0x0C, 0x08}, { 0x04, 0x04, 0x04, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, { 0x04, 0x04, 0x0C 0x 0x0C, 0x0C, 0x, 0x0C, 0x08}, { 0x04, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, 0C, 0x, 0x0x, 0x0x,, 0x0C, 0x0C, 0x0C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x4C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x4C, 0x48x,, 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48}, { 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x4, 0x, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48}, { 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48} }; --print (Stunde, Minute, Sekunde)

--die Tabelle beginnt bei 0, also bei 1 wie aktuell sec[0] = nil)

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

Ende --Funktion

wifi.setmode(wifi. STATION)

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

--konfiguriere max7219

max7219 = require("max7219") max7219.setup({numberOfModules = 1, slaveSelectPin = 8, Intensität = highIntensity})

--Hauptprogramm

checkOnline = tmr.create()

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

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

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

Funktion animieren (noch)

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 if halfSec >=12 then halfSec = 0 end --print(halfSec) return bxorTable(frames[halfSec+1], still) end

Schritt 8: Das Gehäuse

Das Gehäuse
Das Gehäuse
Das Gehäuse
Das Gehäuse
Das Gehäuse
Das Gehäuse

Jetzt ist es an der Zeit, Ihre unglaubliche Handwerkskunst zu zeigen und das Projekt zu beherbergen.

Entweder das oder schnapp dir ein Amazon-Paket aus dem Recycling und baue ein temporäres Gehäuse, das noch heute genutzt wird.

Der Vorteil dieses Ansatzes bestand darin, dass jede Schicht des Projekts fast perfekt zur Dicke des Kartons passte, sodass ein Sandwich gestapelt und zusammengeklebt werden konnte. Eine ähnliche Premium-Version könnte Acryl verwenden

Schritt 9: Schlussbemerkung

Vielen Dank fürs Lesen. Wie viele von Ihnen wissen, kann die Dokumentation eines Projekts genauso schwierig sein wie die Durchführung. es gibt Videofetzen mit mir im Gespräch, die vielleicht irgendwann das Licht der Welt erblicken.

In den Jahren zwischen der Erstellung dieses Projekts und dem Schreiben habe ich erwartet, mehr Beispiele für beliebige LED-Displays mit 3D-Druck zu sehen, aber die Reduzierung der RGB-Streifen hat die Notwendigkeit einer Alternative größtenteils beseitigt.

Ich hoffe, dies war informativ und bitte stellen Sie Fragen, da ich versuchen werde, mehr Details zu Abschnitten zu geben, die nicht vollständig zufriedenstellend sind.

Danke schön

Empfohlen: