Sommario:

Orologio con mappa della metropolitana di Londra: 9 passaggi (con immagini)
Orologio con mappa della metropolitana di Londra: 9 passaggi (con immagini)

Video: Orologio con mappa della metropolitana di Londra: 9 passaggi (con immagini)

Video: Orologio con mappa della metropolitana di Londra: 9 passaggi (con immagini)
Video: Questa purtroppo è Milano....😔 #ruzzaorologi #orologio #rapina 2024, Novembre
Anonim
Orologio della mappa della metropolitana di Londra
Orologio della mappa della metropolitana di Londra
Orologio della mappa della metropolitana di Londra
Orologio della mappa della metropolitana di Londra

Nel 2014, dopo uno stage presso una società di consulenza di stampa 3D a Londra e un esperimento con litofanie a colori utilizzando la loro macchina Stratasys, progetto il mio regalo di addio, una stampa 3D a colori di linee di tubi locali nei loro uffici. Ero determinato a ricavarne qualcosa. Solo 2 anni dopo, nel 2016, ho avuto la mia stampante 3D e mi sono messa al lavoro trasformandola in un orologio.

Da bambino pensavo che gli orologi digitali Tokyo Flash fossero le cose più belle di sempre e ho pensato che sarebbe stato il punto di ispirazione per il design.

E ora sono passati solo 4 anni di pausa prima di riuscire a scriverlo!

Anche se le istruzioni esatte saranno difficili da replicare e la riduzione dei costi nella produzione di PCB per hobby negli ultimi due anni potrebbe rendere obsoleto il mio metodo esatto per il posizionamento dei LED. Spero che le idee condivise possano portare altri a realizzare strani orologi da oggetti sottili!

Passaggio 1: strato anteriore

Strato anteriore
Strato anteriore
Strato anteriore
Strato anteriore
Strato anteriore
Strato anteriore

Come accennato nell'introduzione, questa era una stampa 3D a colori, credo una macchina Stratasys che utilizzava un letto di polvere e una cartuccia di inchiostro modificata per legante e pigmento.

Il file viene perso nella storia, ma questo livello potrebbe essere qualsiasi cosa, una foto o una litofania a un colore farebbero miracoli.

Questa parte è stata realizzata in 3DS max nel 2014, ma oggi ci sono strumenti online per trasformare un'immagine in un SLT in base alla luminosità

Passaggio 2: progettazione del livello guida

Progettare il livello guida
Progettare il livello guida
Progettare il livello guida
Progettare il livello guida
Progettare il livello guida
Progettare il livello guida
Progettare il livello guida
Progettare il livello guida

È qui che decidiamo la complessità del progetto e il metodo di lettura del tempo. Le immagini mostrano le 2 idee con cui stavo giocando.

Questi sono stati realizzati scansionando il design e disegnando linee su di esso in inkscape.

Questo non è un orologio molto leggibile, ma ho preferito l'idea di linee che si riempissero durante il giorno in modo che diventasse l'obiettivo del design.

Il conteggio binario è un metodo praticabile per ridurre il conteggio dei LED e migliorerebbe la leggibilità se il binario è la tua marmellata, ma ciò ha minato la mia idea di "linee di riempimento", quindi non era un'opzione per questo progetto

È comune sui Tokyo Flash Watch ridurre al minimo il conteggio dei LED, ma avendo una sezione che conta in 3 o 5 e poi un altro riempimento per ogni volta che la sezione si riempie, ho usato questa tecnica per i minuti, per ridurli da 60 a 20 più 2. I non era così preoccupato per la precisione questo per i secondi.

Passaggio 3: creazione del livello guida

Costruire il livello guida
Costruire il livello guida
Costruire il livello guida
Costruire il livello guida
Costruire il livello guida
Costruire il livello guida

Questo strato guida per i LED ha 2 scopi, mantiene i LED in posizione e impedisce la fuoriuscita tra di loro

È stato disegnato come un livello su Inkscape direttamente sopra la scansione che stavo usando per il layout del progetto. Lo spessore di 1 mm è stato aggiunto nel frullatore prima di inviarlo alla mia stampante.

Questa è stata una delle stampe più difficili che ho dovuto realizzare sul mio magro Makibox A6, la parte è stata stampata in abs, quindi è stata utilizzata una tonnellata di impasto liquido di acetone per tenerla attaccata alla piattaforma di costruzione con deformazioni minime. Fortunatamente questa parte non si vede sul prodotto finale

L'immagine finale lo mostra avvicinato a una lampada per verificare la spaziatura.

Col senno di poi, lo sversamento tra le luci lungo una linea potrebbe effettivamente essere preferibile per le immagini, non è più difficile da leggere, questo potrebbe essere ottenuto aggiungendo uno smusso alla guida sui lati corti di ogni luce

Passaggio 4: cablaggio dei LED

Cablaggio dei LED
Cablaggio dei LED
Cablaggio dei LED
Cablaggio dei LED
Cablaggio dei LED
Cablaggio dei LED

La prima immagine mostra la stampa di prova che ho fatto per controllare il dimensionamento dei fori, puntavo che il LED si adattasse perfettamente al pizzo con un po' di forza, la forma corretta è stata quindi posizionata a mano durante la stesura dello strato guida.

A causa della bassa tolleranza della mia stampante 3D, alcuni erano allentati e richiedevano una piccola quantità di supercolla per rimanere in posizione mentre altri erano troppo stretti, ma sono stati incoraggiati a posizionarsi premendo sul LED durante la saldatura, questo era in realtà un adattamento migliore di il foro di dimensioni corrette, che aveva una locazione da estrarre una volta collegato.

Per ridurre il numero di fili i LED sono stati saldati in una matrice di 7 per 8, il che significa che tutti i 55 LED potevano essere controllati da soli 13 pin, avevo una mappa disegnata a mano di ciascuna di queste connessioni che purtroppo è andata persa.

Il filo smaltato è stato utilizzato in modo che le sezioni potessero essere esposte in posizione riscaldando una sezione con il ferro e stagnando prima di effettuare il collegamento.

Questo processo richiedeva molto tempo, consiglio vivamente di progettare un PCB

Passaggio 5: progettazione dell'elettronica

Progettare l'elettronica
Progettare l'elettronica
Progettare l'elettronica
Progettare l'elettronica
Progettare l'elettronica
Progettare l'elettronica
Progettare l'elettronica
Progettare l'elettronica

Il mio piano iniziale era di utilizzare un microcontrollore Arduino con un RTC, ma ho optato per un ESP8266 sulla scheda Node MCU D1 in quanto consentiva l'ora legale automatica e il potenziale controllo tramite WIFI.

Per ridurre ulteriormente il numero di pin, avevo il numero perfetto di LED per poter utilizzare un MAX7219 (che può gestire fino a 64 LED).

Questo IC è comunemente usato per pilotare display LED a 7 segmenti, ma ha avuto un caso d'uso molto simile al mio, accendendo un numero arbitrario di LED con uno sfarfallio minimo, ha persino una luminosità controllabile.

Ho deciso di utilizzare la scheda prototipi per il cablaggio, ma eagle è stato utile per il posizionamento delle parti e la comprensione del cablaggio

Ho allegato i file della mia bacheca, ma questa era la prima volta che usavo eagle (e una versione obsoleta ormai) quindi sono solo di riferimento

Passaggio 6: cablaggio dell'elettronica

Cablaggio dell'elettronica
Cablaggio dell'elettronica
Cablaggio dell'elettronica
Cablaggio dell'elettronica
Cablaggio dell'elettronica
Cablaggio dell'elettronica
Cablaggio dell'elettronica
Cablaggio dell'elettronica

Questo è stato un semplice passaggio ripetitivo, seguendo lo schema Eagle, utilizzando le intestazioni per l'ESP e la matrice LED ha aiutato enormemente nell'assemblaggio.

Il pin 1 sulle intestazioni dei LED Anodo e Catodo era contrassegnato da un pennarello argentato, potevano essere differenziati tra come 7 e l'altro 8.

Passaggio 7: programmazione

Programmazione
Programmazione

Poiché il nostro display non è una matrice tradizionale, ho dovuto trovare un metodo per visualizzare quali bit attivare e inviare al MAX IC in HEX. Fortunatamente conosco abbastanza Excel per mettermi nei guai e ho creato un "mago esadecimale" per guidarmi attraverso il modello che volevo visualizzare, le caselle di controllo posizionate a mano e tutto.

Ciò è avvenuto con la rivalutazione che l'esadecimale per le mie ore, minuti e secondi potrebbe essere combinato utilizzando un OR bit per bit per produrre il comando esadecimale finale da inviare al max7219, inclusa una piccola animazione che ho aggiunto ai secondi in modo da poter essere sicuro che la scheda non era congelato.

Quindi, quasi alla fine. e tempo per un'altra decisione che non è invecchiata troppo bene.

Il codice per l'ESP è in LUA, oggi consiglierei di utilizzare l'IDE arduino per una migliore documentazione e una solida libreria di pacchetti, all'epoca la comunità ESP stava ancora maturando e ho scelto LUA come lingua per questo progetto.

Ho preso la discutibile decisione di eseguire regolarmente il ping dei server di Google per leggere l'ora. Questo ha evitato la necessità di un RTC per ridurre al minimo la deriva, funziona, ma faresti meglio a usare un'API in tempo reale.

mezzoSec = 0ora=0 minuto=0 secondo=0

bassaIntensità = 0

altaIntensità = 9

SSID locale ="Wifi"

locale SSID_PASSWORD ="Password"

function time() --connect to internet per ottenere l'ora e la data correnti

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

conn:on("connessione", function(conn, payload) conn:send("HEAD / HTTP/1.1\r\n".. "Host: time.is\r\n".. "Accetta: */*\r\n".. " Agente utente: Mozilla/4.0 (compatibile; esp8266 Lua;)".. "\r\n\r\n") fine)

conn:on("ricevere", function(conn, payload) --print(payload) conn:close() local p=string.find(payload, "GMT") -- trova la stringa di data e ora nel payload da internet, cambia per il fuso orario se p~ =nil then -- estrae i numeri corrispondenti all'ora, minuto, secondo, giorno, mese hour=toumber(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() --hard coded BST (ora legale britannica) ora legale print(hour, minute, second) halfSec = (second%6)*2 --print(halfSec) else print("aggiornamento web non riuscito!") end end --function) --end of on "ricevi" gestore di eventi

conn:on("disconnessione", function(conn, payload) conn=nil payload=nil end) end print("nessun wifi ancora") end

funzione borTable(a, b, …) --bitwise OR tabelle insieme

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)) fine ritorno z fine

funzione bxorTable(a, b, …) --tabelle OR bit per bit insieme

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)) fine ritorno z fine

funzione addSecond()

secondo=secondo+1 se secondo>=60 poi secondo=0 minuto=minuto+1 se minuto>=60 allora minuto=0 addHour() end end end

funzione addOra()

ora=ora+1 se ora>=24 quindi ora=0 termina se ora == 2 o ora == 16 quindi max7219.setIntensity(lowIntensity) termina se ora == 8 o ora == 18 quindi 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} }; locale 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} }; hor locale={ { 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, 0x0C, 0C,, 0x0C, 0x08}, { 0x04, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, 0, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x4C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x4C, 0xC, 0x4}, 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48}, { 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48}, { 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48} }; --print (ora, minuto, secondo)

--la tabella inizia da 0, quindi da 1 come attualmente sec[0] = nil)

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

fine --funzione

wifi.setmode(wifi. STATION)

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

--configura max7219

max7219 = require("max7219") max7219.setup({numberOfModules = 1, slaveSelectPin = 8, intensità = highIntensity })

--Programma principale

checkOnline = tmr.create()

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

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

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

funzione anima (ancora)

frame locali={ { 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, 0x }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; halfSec=halfSec+1 se halfSec >=12 then halfSec = 0 end --print(halfSec) return bxorTable(frames[halfSec+1], still) end

Passaggio 8: l'alloggio

L'alloggio
L'alloggio
L'alloggio
L'alloggio
L'alloggio
L'alloggio

Ora è il momento di mostrare la tua incredibile maestria e ospitare il progetto.

O quello o prendi un pacco amazon dal riciclaggio e costruisci un alloggio temporaneo che è ancora in uso oggi.

Il vantaggio di utilizzare questo approccio era che ogni strato del progetto corrispondeva quasi perfettamente allo spessore del cartone, quindi un sandwich poteva essere impilato e fissato insieme. Una versione premium simile potrebbe utilizzare l'acrilico

Passaggio 9: osservazioni di chiusura

Grazie per aver letto, come molti di voi sanno documentare un progetto può essere difficile quanto realizzarlo. ci sono frammenti di video con me che parlo che alla fine potrebbero vedere la luce del giorno.

Negli anni tra la realizzazione di questo progetto e la stesura, mi aspettavo di vedere più esempi di display a LED arbitrari utilizzando la stampa 3D, ma la riduzione delle strisce RGB ha per lo più rimosso la necessità di un'alternativa.

Spero che questo sia stato informativo e per favore poni domande poiché cercherò di fornire maggiori dettagli sulle sezioni che non soddisfano completamente.

Saluti

Consigliato: