Índice:

Relógio do mapa do metrô de Londres: 9 etapas (com fotos)
Relógio do mapa do metrô de Londres: 9 etapas (com fotos)

Vídeo: Relógio do mapa do metrô de Londres: 9 etapas (com fotos)

Vídeo: Relógio do mapa do metrô de Londres: 9 etapas (com fotos)
Vídeo: BATE VOLTA PARIS LONDRES! O GUIA COMPLETO! #dicasdeparis #batevoltaparislondres #londres #london 2024, Dezembro
Anonim
Relógio de mapa do metrô de Londres
Relógio de mapa do metrô de Londres
Relógio de mapa do metrô de Londres
Relógio de mapa do metrô de Londres

Em 2014, depois de um estágio em uma consultoria de impressão 3D em Londres e de um experimento com litofanos coloridos usando sua máquina Stratasys, projetei meu próprio presente de despedida, uma impressão 3D colorida de linhas de tubos em seus escritórios. Eu estava determinado a fazer algo com isso. Dois anos depois, em 2016, eu tinha minha própria impressora 3D e comecei a trabalhar para transformá-la em um relógio.

Quando criança, eu achava que os relógios digitais Tokyo Flash eram as melhores coisas de todos os tempos, e descobri que isso seria o ponto de inspiração para o design.

E agora foi apenas uma pequena pausa de 4 anos até que eu comecei a escrever isso!

Embora as instruções exatas sejam difíceis de replicar, e a redução de custo na fabricação de PCB por hobby nos últimos anos pode tornar meu método exato de colocação de LED obsoleto. Espero que as ideias compartilhadas possam levar a outros fazerem relógios estranhos a partir de objetos finos!

Etapa 1: Camada frontal

Camada Frontal
Camada Frontal
Camada Frontal
Camada Frontal
Camada Frontal
Camada Frontal

Como mencionado na introdução, esta era uma impressão 3D colorida, acredito que uma máquina Stratasys que usava uma cama de pó e um cartucho de tinta modificado para aglutinante e pigmento.

O arquivo se perdeu na história, mas essa camada poderia ser qualquer coisa, uma foto ou um litofano de uma única cor faria maravilhas.

Esta parte foi feita no 3DS max em 2014, mas hoje existem ferramentas online para transformar uma imagem em um SLT baseado no brilho

Etapa 2: Projetando a Camada Guia

Projetando a Camada Guia
Projetando a Camada Guia
Projetando a Camada Guia
Projetando a Camada Guia
Projetando a Camada Guia
Projetando a Camada Guia
Projetando a Camada Guia
Projetando a Camada Guia

É aqui que decidimos a complexidade do projeto e o método de leitura do tempo. As imagens mostram as 2 ideias com as quais estava brincando.

Eles foram feitos escaneando o design e desenhando linhas no Inkscape.

Este não é um relógio muito legível, mas eu preferia a ideia de linhas que se preenchiam ao longo do dia para que isso se tornasse o objetivo do design.

A contagem binária é um método viável para reduzir a contagem de LED e melhoraria a legibilidade se o binário fosse o seu congestionamento, mas isso prejudicou minha ideia de 'linhas de preenchimento', portanto, não era uma opção para este projeto

É comum nos relógios Tokyo Flash minimizar a contagem de LED, mas tendo uma seção contando em 3 ou 5 e depois outro preenchimento para cada vez que a seção é preenchida, usei essa técnica para os minutos, para reduzi-los de 60 para 20 mais 2. I não estava tão preocupado com a precisão pelos segundos.

Etapa 3: Construindo a Camada Guia

Construindo a Camada Guia
Construindo a Camada Guia
Construindo a Camada Guia
Construindo a Camada Guia
Construindo a Camada Guia
Construindo a Camada Guia

Esta camada de guia para os LEDs tem 2 finalidades, mantém os LEDs no lugar e evita respingos entre eles

Ele foi desenhado como uma camada no Inkscape diretamente em cima da digitalização que eu estava usando para o layout do design. 1 mm de espessura foi adicionado no liquidificador antes de enviar para minha impressora.

Esta foi uma das impressões mais difíceis que tive que fazer no meu magro Makibox A6, a peça foi impressa em abs, então uma tonelada de pasta de acetona foi usada para mantê-la presa à plataforma de construção com o mínimo de empenamento. Felizmente, essa parte não é vista no produto final

A imagem final mostra que ele é sustentado por uma lâmpada para verificar o espaçamento.

Em retrospectiva, o derramamento entre as luzes ao longo de uma linha pode realmente ser preferível para os visuais, não é mais difícil de ler, isso pode ser conseguido adicionando um chanfro ao guia nos lados curtos de cada luz

Etapa 4: conectando os LEDs

Fiação dos LEDs
Fiação dos LEDs
Fiação dos LEDs
Fiação dos LEDs
Fiação dos LEDs
Fiação dos LEDs

A primeira imagem mostra a impressão de teste que fiz para verificar o tamanho do orifício, eu queria que o LED se encaixasse perfeitamente na renda com um pouco de força, a forma correta foi então colocada à mão ao colocar a camada guia.

Devido à baixa tolerância da minha impressora 3D, algumas estavam soltas e exigiam um pouco de supercola para ficar no lugar, enquanto outras estavam muito apertadas, mas foram incentivadas a encaixar pressionando o LED durante a soldagem. Na verdade, foi um ajuste melhor do que o furado de tamanho correto, que tinha um locatário para retirar depois de conectado.

Para reduzir a contagem de fios, os LEDs foram soldados em uma matriz de 7 por 8, o que significa que todos os 55 LEDs poderiam ser controlados por apenas 13 pinos, eu tinha um mapa desenhado à mão de cada uma dessas conexões que infelizmente foi perdida.

Fio de esmalte foi usado para que as seções pudessem ser expostas no lugar, aquecendo uma seção com o ferro e estanhando antes de fazer a conexão.

Este processo consumia muito tempo, eu recomendo altamente projetar um PCB

Etapa 5: projetando os eletrônicos

Projetando a Eletrônica
Projetando a Eletrônica
Projetando a Eletrônica
Projetando a Eletrônica
Projetando a Eletrônica
Projetando a Eletrônica
Projetando a Eletrônica
Projetando a Eletrônica

Meu plano inicial era usar um microcontrolador Arduino com um RTC, mas optei por um ESP8266 na placa Node MCU D1, pois permitia o horário de verão automático e o potencial de controle sobre WIFI.

Para reduzir ainda mais a contagem de pinos, eu tinha o número perfeito de LEDs para poder usar um MAX7219 (que pode lidar com até 64 LEDs).

Este IC é comumente usado para acionar telas de LED de 7 segmentos, mas tinha um caso de uso muito semelhante ao meu, iluminando um número arbitrário de LEDs com oscilação mínima, e até mesmo brilho controlável.

Decidi usar protoboard para a fiação, mas o eagle foi útil para a colocação de peças e compreensão da fiação

Anexei meus arquivos de placa, mas esta foi minha primeira vez usando o eagle (e uma versão desatualizada agora), então eles são apenas para referência

Etapa 6: Fiação da Eletrônica

Fiação da Eletrônica
Fiação da Eletrônica
Fiação da Eletrônica
Fiação da Eletrônica
Fiação da Eletrônica
Fiação da Eletrônica
Fiação da Eletrônica
Fiação da Eletrônica

Este foi um passo simples e repetitivo, seguindo o esquema Eagle, usando cabeçalhos para o ESP e a matriz de LEDs ajudou enormemente na montagem.

O pino 1 nos conectores de LED ânodo e cátodo foi marcado com uma ponta de prata, eles podem ser diferenciados entre os 7 e os outros 8.

Etapa 7: Programação

Programação
Programação

Como nosso display não é uma matriz tradicional, tive que encontrar um método para visualizar quais bits ligar e enviar para o MAX IC em HEX. Felizmente, eu sei que o Excel o suficiente para ter problemas e fiz um 'assistente Hex' para me guiar através do padrão que eu queria exibir, caixas de seleção colocadas à mão e tudo.

Isso veio com a reavaliação de que o hex para minha hora, minuto e segundos poderiam ser combinados usando um OR bit a bit para produzir o comando hexadecimal final para enviar para o max7219, incluindo uma pequena animação que adicionei aos segundos para que eu pudesse ter certeza de que o tabuleiro não tinha; t congelado.

Então, quase no fim. e tempo para outra decisão que não envelheceu muito bem.

O código para o ESP está em LUA, hoje eu recomendo usar o IDE arduino por sua melhor documentação e biblioteca de pacotes robusta, na época a comunidade ESP ainda estava amadurecendo e eu escolhi LUA como a linguagem para este projeto.

Tomei a decisão questionável de fazer ping regularmente nos servidores do Google para ler as horas. Isso evitou a necessidade de um RTC para minimizar o desvio, isso funciona, mas seria melhor usar uma API de tempo real.

meioSeg = 0 hora = 0 minuto = 0 segundo = 0

lowIntensity = 0

highIntensity = 9

SSID local = "Wifi"

SSID_PASSWORD local = "Senha"

function time () - conecte-se à internet para obter a hora e data atuais

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

conn: on ("conexão", function (conn, payload) conn: send ("HEAD / HTTP / 1.1 / r / n".. "Host: time.is / r / n".. "Aceitar: * / * / r / n".. " Agente do usuário: Mozilla / 4.0 (compatível; esp8266 Lua;) ".." / r / n / r / n ") fim)

conn: on ("receber", function (conn, payload) --print (payload) conn: close () local p = string.find (payload, "GMT") - encontre a string de hora e data na carga útil da Internet, altere o fuso horário se p ~ = nulo então - extrair números correspondentes à hora, minuto, segundo, dia, mês hora = tonumber (string.sub (carga útil, p-9, p-8)) minuto = tonumber (string.sub (carga útil, p- 6, p-5)) segundo = tonumber (string.sub (payload, p-3, p-2)) addHour () - hard coded BST (horário de verão britânico) impressão de salvamento de luz do dia (hora, minuto, segundo) halfSec = (segundo% 6) * 2 --print (halfSec) else print ("falha na atualização da web!") end end - função) - fim do manipulador de eventos "receber"

conn: on ("desconexão", função (conexão, carga útil) conexão = carga útil nula = fim nulo) fim impressão ("sem wi-fi ainda") fim

function borTable (a, b, …) - tabelas OR bitwise juntas

se arg [1] then b = borTable (b, unpack (arg)) end local z = {} para i, v em ipairs (a) faça table.insert (z, bit.bor (v, b )) end return z end

function bxorTable (a, b, …) - tabelas OR bit a bit juntas

if arg [1] then b = bxorTable (b, unpack (arg)) end local z = {} para i, v in ipairs (a) faça table.insert (z, bit.bxor (v, b )) end return z end

função addSecond ()

segundo = segundo + 1 se segundo> = 60 então segundo = 0 minuto = minuto + 1 se minuto> = 60 então minuto = 0 addHour () fim fim fim

function addHour ()

hour = hour + 1 if hour> = 24 then hour = 0 end if hour == 2 or hour == 16 then max7219.setIntensity (lowIntensity) end if hour == 8 or hour == 18 then 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, 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}}; mínimo local = {{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, 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 local = {{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, 0x08 }, {0x04, 0x04, 0x04, 0x04, 0x0C, 0x0C, 0x0C, 0x08}, {0x04, 0x04, 0x04, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, {0x04, 0x04, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, {0x04, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, {0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, {0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x48}, {0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x4C, 0x48}, {0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x4C, 0x4C, 0x48}, {0x0C, 0x0C, 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x48}, {0x0C, 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48}, {0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48}, {0x0C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48}, {0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48}}; --print (hora, minuto, segundo)

- a tabela começa em 0, então em 1 como atualmente seg [0] = nulo)

max7219.write ({animate (borTable (sec [1+ (segundo / secGap)], min [1+ (minuto / minGap)], hor [1+ (hora / horGap)]))})

fim - função

wifi.setmode (wifi. STATION)

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

--configure max7219

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

--Programa principal

checkOnline = tmr.create ()

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

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

tmr.alarm (2, 500, 1, atualização)

função animar (ainda)

frames locais = {{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, 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 = halfSeg + 1 se halfSec> = 12 então halfSec = 0 end --print (halfSec) return bxorTable (frames [halfSec + 1], ainda) end

Etapa 8: a habitação

O alojamento
O alojamento
O alojamento
O alojamento
O alojamento
O alojamento

Agora é a sua hora de mostrar sua habilidade incrível e abrigar o projeto.

Ou isso ou pegar um pacote amazon da reciclagem e fazer uma caixa temporária que ainda está em uso hoje.

A vantagem de usar essa abordagem era que cada camada do projeto combinava quase perfeitamente com a espessura do papelão, de modo que um sanduíche poderia ser empilhado e colado com fita adesiva. Uma versão premium semelhante pode usar acrílico

Etapa 9: Discurso de encerramento

Obrigado por ler, Como muitos de vocês sabem, documentar um projeto pode ser tão difícil quanto fazê-lo. há pedaços de vídeo comigo falando que podem eventualmente ver a luz do dia.

Nos anos entre fazer este projeto e escrevê-lo, esperava ver mais exemplos de displays de LED arbitrários usando impressão 3D, mas a redução nas faixas RGB eliminou principalmente a necessidade de uma alternativa.

Espero que tenha sido informativo e faça perguntas, pois tentarei fornecer mais detalhes nas seções que não satisfazem totalmente.

Saúde

Recomendado: