Table des matières:

Horloge de la carte du métro de Londres : 9 étapes (avec photos)
Horloge de la carte du métro de Londres : 9 étapes (avec photos)

Vidéo: Horloge de la carte du métro de Londres : 9 étapes (avec photos)

Vidéo: Horloge de la carte du métro de Londres : 9 étapes (avec photos)
Vidéo: 7 STATUES QUI ONT ÉTÉ FILMÉES EN TRAIN DE BOUGER (ʘ_ʘ) 2024, Novembre
Anonim
Horloge de carte du métro de Londres
Horloge de carte du métro de Londres
Horloge de carte du métro de Londres
Horloge de carte du métro de Londres

En 2014, à la suite d'un stage dans un cabinet de conseil en impression 3D à Londres et d'une expérience avec des lithophanes couleur à l'aide de leur machine Stratasys, je conçois mon propre cadeau de départ, une impression 3D couleur de lignes de tubes locales dans leurs bureaux. J'étais déterminé à en faire quelque chose. Deux ans plus tard, en 2016, j'avais ma propre imprimante 3D et je me suis mise au travail pour en faire une horloge.

Enfant, je pensais que les montres numériques Tokyo Flash étaient les meilleures choses de tous les temps, et j'ai pensé que ce serait le point d'inspiration pour le design.

Et maintenant, ce n'est qu'une petite pause de 4 ans jusqu'à ce que je me sois mis à l'écrire !

Bien que les instructions exactes soient difficiles à reproduire, et la réduction des coûts de fabrication de circuits imprimés par les amateurs au cours des deux dernières années pourrait rendre ma méthode exacte de placement des LED obsolète. J'espère que les idées partagées pourraient amener d'autres à fabriquer des horloges étranges à partir d'objets minces !

Étape 1: couche avant

Couche avant
Couche avant
Couche avant
Couche avant
Couche avant
Couche avant

Comme mentionné dans l'intro, il s'agissait d'une impression 3D couleur, je crois une machine Stratasys qui utilisait un lit de poudre et une cartouche d'encre modifiée pour le liant et le pigment.

Le fichier est perdu pour l'histoire, mais cette couche pourrait être n'importe quoi, une photo ou un lithophane unicolore ferait des merveilles.

Cette partie a été réalisée en 3DS max en 2014, mais il existe aujourd'hui des outils en ligne pour transformer une image en SLT en fonction de la luminosité

Étape 2: Conception du calque de guidage

Conception de la couche de guidage
Conception de la couche de guidage
Conception de la couche de guidage
Conception de la couche de guidage
Conception de la couche de guidage
Conception de la couche de guidage
Conception de la couche de guidage
Conception de la couche de guidage

C'est là que nous décidons de la complexité du projet et de la méthode de lecture de l'heure. Les images montrent les 2 idées avec lesquelles je jouais.

Ceux-ci ont été réalisés en scannant le dessin et en traçant des lignes dans inkscape.

Ce n'est pas une horloge très lisible, mais j'ai préféré l'idée que les lignes se remplissent tout au long de la journée, ce qui est devenu l'objectif du design.

Le comptage binaire est une méthode viable pour réduire le nombre de LED, et cela améliorerait la lisibilité si le binaire est votre confiture, mais cela a sapé mon idée de « lignes de remplissage », donc ce n'était pas une option pour ce projet

Il est courant sur les montres Tokyo Flash de minimiser le nombre de LED mais d'avoir une section comptant par 3 ou 5, puis un autre remplissage pour chaque fois que cette section se remplit, j'ai utilisé cette technique pour les minutes, pour les réduire de 60 à 20 plus 2. Je n'était pas si inquiet de la précision pendant les secondes.

Étape 3: Créer le calque de guidage

Création de la couche de guidage
Création de la couche de guidage
Construire la couche de guidage
Construire la couche de guidage
Construire la couche de guidage
Construire la couche de guidage

Cette couche de guidage pour les LED a 2 objectifs, elle maintient les LED en place et empêche les déversements entre elles

Il a été dessiné en tant que couche sur Inkscape directement au-dessus du scan que j'utilisais pour la mise en page de la conception. Une épaisseur de 1 mm a été ajoutée au mélangeur avant d'être envoyée à mon imprimante.

Ce fut l'une des impressions les plus difficiles que j'aie à faire sur ma maigre Makibox A6, la pièce a été imprimée en abs, donc une tonne de suspension d'acétone a été utilisée pour la maintenir attachée à la plate-forme de construction avec un gauchissement minimal. Heureusement cette partie ne se voit pas sur le produit final

L'image finale le montre tenu à une lampe pour vérifier l'espacement.

Avec le recul, le déversement entre les lumières le long d'une ligne pourrait en fait être préférable pour les visuels, n'est pas plus difficile à lire, cela pourrait être réalisé en ajoutant un chanfrein au guide sur les côtés courts de chaque lumière

Étape 4: Câblage des LED

Câblage des LED
Câblage des LED
Câblage des LED
Câblage des LED
Câblage des LED
Câblage des LED

La première image montre l'impression de test que j'ai faite pour vérifier la taille des trous, je visais que la LED s'adapte parfaitement à la dentelle avec un peu de force, la forme correcte a ensuite été placée à la main lors de la pose de la couche de guidage.

En raison de la faible tolérance de mon imprimante 3D, certains étaient lâches et nécessitaient un peu de superglue pour rester en place tandis que d'autres étaient trop serrés, mais ont été encouragés à se mettre en place en appuyant sur la LED pendant le soudage, c'était en fait un meilleur ajustement que le trou correctement dimensionné, qui avait une location à retirer une fois câblé.

Pour réduire le nombre de fils, les LED ont été soudées dans une matrice de 7 par 8, ce qui signifie que les 55 LED ne pouvaient être contrôlées que par 13 broches, j'avais une carte dessinée à la main de chacune de ces connexions qui a malheureusement été perdue.

Du fil émaillé a été utilisé pour que les sections puissent être exposées en place en chauffant une section avec le fer et l'étamage avant de faire la connexion.

Ce processus prenait beaucoup de temps, je recommande fortement de concevoir un PCB

Étape 5: Conception de l'électronique

Conception de l'électronique
Conception de l'électronique
Conception de l'électronique
Conception de l'électronique
Conception de l'électronique
Conception de l'électronique
Conception de l'électronique
Conception de l'électronique

Mon plan initial était d'utiliser un microcontrôleur Arduino avec un RTC, mais j'ai opté pour un ESP8266 sur la carte Node MCU D1 car il permettait l'heure d'été automatique et le potentiel de contrôle du WIFI.

Pour réduire davantage le nombre de broches, j'avais le nombre parfait de LED pour pouvoir utiliser un MAX7219 (qui peut gérer jusqu'à 64 LED).

Ce circuit intégré est couramment utilisé pour piloter des écrans LED 7 segments, mais il avait un cas d'utilisation très similaire au mien, allumant un nombre arbitraire de LED avec un scintillement minimal, il a même une luminosité contrôlable.

J'ai décidé d'utiliser protoboard pour le câblage, mais eagle a été utile pour le placement des pièces et la compréhension du câblage

J'ai joint les fichiers de mon tableau, mais c'était la première fois que j'utilisais eagle (et une version obsolète maintenant), ils sont donc à titre indicatif uniquement

Étape 6: Câblage de l'électronique

Câblage de l'électronique
Câblage de l'électronique
Câblage de l'électronique
Câblage de l'électronique
Câblage de l'électronique
Câblage de l'électronique
Câblage de l'électronique
Câblage de l'électronique

Il s'agissait d'une étape simple et répétitive, suivant le schéma Eagle, l'utilisation d'en-têtes pour l'ESP et la matrice LED a énormément aidé à l'assemblage.

La broche 1 sur les en-têtes des LED d'anode et de cathode était marquée d'un sharpie argenté, ils pouvaient être différenciés car le 7 était l'autre 8.

Étape 7: Programmation

La programmation
La programmation

Comme notre affichage n'est pas une matrice traditionnelle, j'ai dû trouver une méthode pour visualiser les bits à activer qu'il envoyait au MAX IC en HEX. Heureusement, je connais juste assez Excel pour avoir des ennuis et j'ai créé un «assistant hexadécimal» pour me guider à travers le modèle que je voulais afficher, des cases à cocher placées à la main et tout.

Cela est venu avec la réévaluation que l'hex de mes heures, minutes et secondes pouvait être combiné à l'aide d'un OR au niveau du bit pour produire la commande hexadécimale finale à envoyer au max7219, y compris une petite animation que j'ai ajoutée aux secondes pour que je puisse m'assurer que le tableau n'avait pas gelé.

Donc, presque à la fin. et le temps d'une autre décision qui n'a pas trop bien vieilli.

Le code de l'ESP est en LUA. Aujourd'hui, je recommanderais d'utiliser l'IDE arduino pour sa meilleure documentation et sa bibliothèque de packages robuste, à l'époque où la communauté ESP était encore en train de mûrir et j'ai choisi LUA comme langage pour ce projet.

J'ai pris la décision discutable de pinger régulièrement les serveurs de Google pour lire l'heure. Cela a eu besoin d'un RTC pour minimiser la dérive, cela fonctionne, mais vous feriez mieux d'utiliser une API en temps réel.

demiSec = 0heure=0 minute=0 seconde=0

faible intensité = 0

hauteIntensité = 9

SSID local ="Wifi"

local SSID_PASSWORD = "Mot de passe"

fonction time() --connectez-vous à Internet pour obtenir l'heure et la date actuelles

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

conn:on("connexion", function(conn, payload) conn:send("HEAD / HTTP/1.1\r\n".. "Host: time.is\r\n".. "Accept: */*\r\n".. " User-Agent: Mozilla/4.0 (compatible; esp8266 Lua;)".. "\r\n\r\n") fin)

conn:on("recevoir", function(conn, payload) --print(payload) conn:close() local p=string.find(payload, "GMT") -- trouver la chaîne d'heure et de date dans la charge utile à partir d'Internet, changer le fuseau horaire si p~ =nil then -- extrait les nombres correspondant à l'heure, la minute, la seconde, le jour, le mois 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() --code en dur BST (heure d'été britannique) print (heure, minute, seconde) demi-sec = (second%6)*2 --print(halfSec) else print("la mise à jour Web a échoué !") end end --function) --end of on "receive" gestionnaire d'événements

conn:on("déconnexion", function(conn, payload) conn=nil payload=nil end) end print("pas encore de wifi") end

fonction borTable(a, b, …) -- tables OR au niveau du bit ensemble

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)) fin retour z fin

fonction bxorTable(a, b, …) -- tables OR au niveau du bit ensemble

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)) fin retour z fin

fonction addSecond()

seconde=seconde+1 si seconde>=60 then seconde=0 minute=minute+1 si minute>=60 alors minute=0 addHour() end end end

fonction 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, 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} }; local 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} }; local 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, 0x0x0C,, 0x0C, 0x08}, { 0x04, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08}, 0x0, 0x0C, 0x0C, 0x0C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x4C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0,4C, 0x0}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0,4C, 0x0}, 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48}, { 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x},4x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48}, { 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48} }; --print(heure, minute, seconde)

--la table commence à 0, donc à 1 comme actuellement sec[0] = nil)

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

fin --fonction

wifi.setmode(wifi. STATION)

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

--configurer max7219

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

--Programme principal

checkOnline = tmr.create()

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

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

tmr.alarm(2, 500, 1, mise à jour)

fonction animer (encore)

trames locales={ { 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 si halfSec >=12 alors halfSec = 0 end --print(halfSec) return bxorTable(frames[halfSec+1], still) end

Étape 8: Le logement

Le logement
Le logement
Le logement
Le logement
Le logement
Le logement

C'est maintenant le moment de montrer votre incroyable savoir-faire et d'héberger le projet.

Soit ça, soit sortez un paquet Amazon du recyclage et fabriquez un logement temporaire qui est toujours utilisé aujourd'hui.

L'avantage d'utiliser cette approche était que chaque couche du projet correspondait presque parfaitement à l'épaisseur du carton, de sorte qu'un sandwich pouvait être empilé et scotché ensemble. Une version premium similaire pourrait utiliser de l'acrylique

Étape 9: Remarques de clôture

Merci d'avoir lu, Comme beaucoup d'entre vous le savent, documenter un projet peut être aussi difficile que de le réaliser. il y a des bribes de vidéo avec moi en train de parler qui pourraient éventuellement voir le jour.

Au cours des années entre la réalisation de ce projet et sa rédaction, je m'attendais à voir plus d'exemples d'affichages LED arbitraires utilisant l'impression 3D, mais la réduction des bandes RVB a largement supprimé le besoin d'une alternative.

J'espère que cela a été instructif, et veuillez poser des questions car j'essaierai de donner plus de détails sur les sections qui ne satisfont pas pleinement.

À votre santé

Conseillé: