Spisu treści:
- Krok 1: Przednia warstwa
- Krok 2: Projektowanie warstwy pomocniczej
- Krok 3: Budowanie warstwy przewodnika
- Krok 4: Okablowanie diod LED
- Krok 5: Projektowanie elektroniki
- Krok 6: Okablowanie elektroniki
- Krok 7: Programowanie
- Krok 8: Obudowa
- Krok 9: Uwagi końcowe
Wideo: Zegar na mapie metra w Londynie: 9 kroków (ze zdjęciami)
2024 Autor: John Day | [email protected]. Ostatnio zmodyfikowany: 2024-01-30 11:26
W 2014 roku, po stażu w firmie doradczej zajmującej się drukowaniem 3D w Londynie i eksperymencie z kolorowymi litofanami przy użyciu ich maszyny Stratasys, zaprojektowałem własny prezent wyjazdowy, kolorowy wydruk 3D linii rur w ich biurach. Byłem zdeterminowany, żeby coś z tego zrobić. Niedługo 2 lata później, w 2016 roku, miałem własną drukarkę 3D i zabrałem się do robienia z niej zegara.
Jako dziecko myślałem, że cyfrowe zegarki Tokyo Flash były najwspanialszymi rzeczami w historii i odmrożone, które byłyby punktem inspiracji dla projektu.
A teraz to była tylko niewielka 4-letnia przerwa, zanim zabrałem się do pisania!
Chociaż dokładne instrukcje będą trudne do odtworzenia, a obniżenie kosztów produkcji PCB przez hobbystów w ciągu ostatnich kilku lat może sprawić, że moja dokładna metoda rozmieszczenia diod LED stanie się przestarzała. Mam nadzieję, że wspólne pomysły mogą sprawić, że inni zrobią dziwne zegary z cienkich przedmiotów!
Krok 1: Przednia warstwa
Jak wspomniano we wstępie, był to kolorowy druk 3D, wydaje mi się, że maszyna Stratasys używała łoża proszkowego i zmodyfikowanego wkładu atramentowego do spoiwa i pigmentu.
Plik ginie w historii, ale ta warstwa może być cokolwiek, zdjęcie lub jednokolorowa litofan zdziałałyby cuda.
Ta część została wykonana w 3DS max w 2014 roku, ale dziś istnieją narzędzia online do przekształcania obrazu w SLT w oparciu o jasność
Krok 2: Projektowanie warstwy pomocniczej
To tutaj decydujemy o złożoności projektu i sposobie odczytywania czasu. Obrazy pokazują 2 pomysły, z którymi się bawiłem.
Zostały one wykonane przez skanowanie projektu i rysowanie linii w inkscape.
Nie jest to zbyt czytelny zegar, ale wolałem pomysł wypełniania linii przez cały dzień, więc stało się to celem projektu.
Liczenie binarne jest realną metodą zmniejszenia liczby diod LED i poprawiłoby czytelność, jeśli binarny jest twoim zacięciem, ale to podważyło mój pomysł na „linie wypełniające”, więc nie było opcji dla tego projektu
W zegarkach Tokyo Flash zwykle minimalizuje się liczbę diod LED, ale mając jedną sekcję liczącą się w 3 lub 5, a następnie kolejne wypełnienie za każdym razem, gdy ta sekcja zostanie wypełniona, użyłem tej techniki przez minuty, aby zmniejszyć je z 60 do 20 plus 2. przez kilka sekund nie martwił się tak bardzo o precyzję.
Krok 3: Budowanie warstwy przewodnika
Ta warstwa prowadząca dla diod LED ma 2 cele, utrzymuje diody LED na miejscu i zapobiega rozlewaniu się między nimi
Został narysowany jako warstwa w Inkscape bezpośrednio nad skanem, którego używałem do projektowania układu. Przed wysłaniem do mojej drukarki w blenderze dodano 1 mm grubości.
To był jeden z najtrudniejszych wydruków, jakie muszę wykonać na moim skromnym Makibox A6, część została wydrukowana w abs, więc użyto tony zawiesiny acetonu, aby utrzymać ją przyłączoną do platformy roboczej z minimalnym wypaczeniem. Na szczęście ta część nie jest widoczna na produkcie końcowym
Ostateczny obraz pokazuje, że trzymany jest przy lampie, aby sprawdzić odstępy.
Z perspektywy czasu rozlanie między światłami wzdłuż linii może być w rzeczywistości lepsze dla efektów wizualnych, nie jest trudniejsze do odczytania, można to osiągnąć poprzez dodanie fazki do prowadnicy na krótszych bokach każdego światła
Krok 4: Okablowanie diod LED
Pierwszy obraz przedstawia wydruk testowy, który wykonałem w celu sprawdzenia rozmiaru otworu. Chciałem, aby dioda LED ściśle przylegała do koronki z niewielką siłą, a następnie podczas układania warstwy prowadzącej ręcznie ułożono prawidłowy kształt.
Ze względu na niską tolerancję mojej drukarki 3D, niektóre były luźne i wymagały odrobiny superkleju, aby pozostać na miejscu, podczas gdy inne były zbyt ciasne, ale zachęcano ich do umieszczenia na miejscu poprzez naciśnięcie diody LED podczas lutowania, było to właściwie lepsze dopasowanie niż otwór o odpowiedniej wielkości, który miał dzierżawę do wyciągnięcia po podłączeniu.
Aby zmniejszyć ilość drutów diody LED zostały wlutowane w matrycę 7 na 8, co oznacza, że wszystkie 55 diod LED można było sterować tylko 13 pinami, miałem ręcznie narysowaną mapę każdego z tych połączeń, która niestety została utracona.
Użyto drutu emaliowanego, aby sekcje można było odsłonić na miejscu przez podgrzanie sekcji żelazkiem i cynowanie przed wykonaniem połączenia.
Ten proces był bardzo czasochłonny, gorąco polecam zaprojektowanie płytki drukowanej
Krok 5: Projektowanie elektroniki
Moim początkowym planem było użycie mikrokontrolera Arduino z zegarem czasu rzeczywistego, ale zdecydowałem się na ESP8266 na płycie Node MCU D1, ponieważ pozwalało to na automatyczne oszczędzanie światła dziennego i możliwość kontroli nad WIFI.
Aby jeszcze bardziej zredukować liczbę pinów, miałem idealną liczbę diod LED, aby móc użyć MAX7219 (który może obsłużyć do 64 diod LED).
Ten układ scalony jest powszechnie używany do sterowania 7-segmentowymi wyświetlaczami LED, ale miał bardzo podobny przypadek użycia do mojego, oświetlając dowolną liczbę diod LED z minimalnym migotaniem, a nawet ma regulowaną jasność.
Zdecydowałem się użyć płyty prototypowej do okablowania, ale eagle był pomocny w umieszczeniu części i zrozumieniu okablowania
Załączyłem pliki planszy, ale to był mój pierwszy raz, kiedy używałem eagle (i nieaktualna wersja do tej pory), więc są tylko w celach informacyjnych
Krok 6: Okablowanie elektroniki
Był to powtarzalny, prosty krok, zgodnie ze schematem Eagle, użycie nagłówków dla ESP i matrycy LED ogromnie pomogło w montażu.
Pin 1 na głowicach LED Anode i Cathode został oznaczony srebrnym sharpie, można je rozróżnić, tak jak na 7 pozostałych 8.
Krok 7: Programowanie
Ponieważ nasz wyświetlacz nie jest tradycyjną matrycą, musiałem znaleźć sposób na wizualizację, które bity włączyć, które wysłał do MAX IC w HEX. Na szczęście znam wystarczająco dużo excela, aby wpaść w kłopoty i stworzyłem „czarodzieja szesnastków”, który poprowadził mnie przez wzór, który chciałem wyświetlić, ręcznie umieszczane pola wyboru i wszystko.
Przyszło to wraz z przewartościowaniem, że hex dla mojej godziny, minuty i sekund można połączyć za pomocą bitowego OR, aby utworzyć ostateczne polecenie hex do wysłania do max7219, w tym małą animację, którą dodałem do sekund, abym mógł upewnić się, że tablica nie zamarzł.
A więc prawie na końcu. i czas na kolejną decyzję, która nie postarzała się zbyt dobrze.
Kod dla ESP jest w LUA. Dzisiaj polecam używanie arduino IDE ze względu na lepszą dokumentację i solidną bibliotekę pakietów, w tym czasie społeczność ESP wciąż dojrzewała i wybrałem LUA jako język dla tego projektu.
Podjąłem wątpliwą decyzję, aby regularnie pingować serwery Google, aby odczytać godzinę. To ominęło potrzebę RTC, aby zminimalizować dryf, to działa, ale lepiej byłoby użyć API czasu rzeczywistego.
halfSec = 0godzina=0 minuta=0 sekunda=0
niska intensywność = 0
wysoka intensywność = 9
lokalny identyfikator SSID ="Wi-Fi"
lokalne SSID_PASSWORD ="Hasło"
funkcja time() -- połącz się z internetem, aby uzyskać aktualną godzinę i datę
jeśli wifi.sta.getip() to local conn=net.createConnection(net. TCP, 0) conn:connect(80, "google.com")
conn:on("połączenie", function(conn, payload) conn:send("HEAD / HTTP/1.1\r\n".. "Host: time.is\r\n".. "Accept: */*\r\n".. " User-Agent: Mozilla/4.0 (kompatybilny; esp8266 Lua;)".. Koniec "\r\n\r\n"))
conn:on("odbierz", function(conn, payload) --print(payload) conn:close() local p=string.find(payload, "GMT") -- znajdź ciąg czasu i daty w ładunku z Internetu, zmień na strefę czasową, jeśli p~ =nil then -- wyodrębnij liczby odpowiadające godzinie, minucie, sekundzie, dniu, miesiącowi hour=tonumber(string.sub(payload, p-9, p-8)) minute=tonumber(string.sub(payload, p- 6, p-5)) sekunda=tonumber(string.sub(payload, p-3, p-2)) addHour() --kodowany na stałe BST (czas letni brytyjski) oszczędzanie światła dziennego print(godzina, minuta, sekunda) halfSec = (second%6)*2 --print(halfSec) else print("aktualizacja sieciowa nie powiodła się!") end end --function) --end of on obsługi zdarzenia "odbierz"
conn:on("rozłączenie", function(conn, payload) conn=nil payload=nil end) end print("jeszcze nie ma wifi") end
function borTable(a, b, …) --bitowe OR tabele razem
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)) koniec powrót z koniec
function bxorTable(a, b, …) --bitowe OR tabele razem
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)) koniec powrót z koniec
funkcja addSecond()
sekunda=sekunda+1 jeśli sekunda>=60 to sekunda=0 minuta=minuta+1 jeśli minuta>=60 to minuta=0 addHour() end end end
funkcja dodajGodzinę()
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 funkcja update() lokalna secGap = 6 lokalna minGap = 3 lokalna horGap = 1 lokalna 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} }; lokalne 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} }; lokalny poziom = { { 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, 0x08x0C }, { 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, 0x08}, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x4C, 0x48}, { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x4, 0x0x4}, 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, 0x48}, { 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x48} }; --print(godzina, minuta, sekunda)
--tabela zaczyna się od 0, więc od 1, ponieważ obecnie sec[0] = zero)
max7219.write({animate(borTable(s[1+(sekunda/sek.przerwy)], min[1+(minuta/min.przerwy)], hor[1+(godzina/horGap)]))})
koniec --funkcja
wifi.setmode(wifi. STACJA)
wifi.sta.config(SSID, SSID_PASSWORD) wifi.sta.autoconnect(1)
--skonfiguruj max7219
max7219 = require("max7219") max7219.setup({numberOfModules = 1, slaveSelectPin = 8, intensywność = highIntensity })
--Główny program
checkOnline = tmr.create()
alarm.tmr(0, 180000, 1, czas)
tmr.alarm(1, 1000, 1, dod.druga)
tmr.alarm(2, 500, 1, aktualizacja)
animacja funkcji (wciąż)
ramki lokalne = { { 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 jeśli halfSec >=12 to halfSec = 0 end --print(halfSec) return bxorTable(frames[halfSec+1], still) end
Krok 8: Obudowa
Teraz nadszedł czas, aby pochwalić się niesamowitym kunsztem i umieścić projekt.
Albo weź paczkę Amazon z recyklingu i zbuduj tymczasową obudowę, która nadal jest w użyciu.
Zaletą takiego podejścia było to, że każda warstwa projektu prawie idealnie pasowała do grubości tektury, dzięki czemu kanapkę można było ułożyć w stos i skleić razem. Podobna wersja premium może używać akrylu
Krok 9: Uwagi końcowe
Dziękuję za przeczytanie. Jak wielu z was wie, dokumentowanie projektu może być równie trudne, jak jego wykonanie. są skrawki wideo, na których rozmawiam, które mogą w końcu ujrzeć światło dzienne.
W latach między stworzeniem tego projektu a jego napisaniem spodziewałem się zobaczyć więcej przykładów dowolnych wyświetlaczy LED wykorzystujących druk 3D, ale redukcja pasków RGB w większości wyeliminowała potrzebę alternatywy.
Mam nadzieję, że było to pouczające i proszę zadawać pytania, ponieważ postaram się podać więcej szczegółów w sekcjach, które nie są w pełni satysfakcjonujące.
Pozdrawiam
Zalecana:
Pulpit nawigacyjny COVID19 na mapie świata (przy użyciu Pythona): 16 kroków
Pulpit nawigacyjny COVID19 na mapie świata (przy użyciu Pythona): Wiem, że prawie każdy z nas zna większość informacji o COVID19. A ta instrukcja dotyczy tworzenia mapy bąbelkowej, aby wykreślić dane w czasie rzeczywistym (przypadków) na mapie świata. Dla większej wygody , dodałem program do repozytorium Github: https://github.co
Zegar WiFi, zegar i stacja pogodowa, sterowanie Blynk: 5 kroków (ze zdjęciami)
Zegar WiFi, timer i stacja pogodowa, sterowanie Blynk: jest to zegar cyfrowy Morphing (dzięki Hari Wiguna za koncepcję i kod morfingu), jest to również zegar analogowy, stacja raportowania pogody i minutnik kuchenny. Jest kontrolowany w całości przez Aplikacja Blynk na smartfonie przez Wi-Fi.Aplikacja umożliwia
ESP8266 Zegar sieciowy bez zegara RTC - Nodemcu NTP Zegar bez RTC - PROJEKT ZEGAR INTERNETOWY: 4 kroki
ESP8266 Zegar sieciowy bez zegara RTC | Nodemcu NTP Zegar bez RTC | PROJEKT ZEGARA INTERNETOWEGO: W projekcie będzie wykonywany projekt zegara bez RTC, będzie pobierał czas z internetu za pomocą wifi i wyświetli go na wyświetlaczu st7735
Zegar elektroniczny C51 4 bity - Drewniany zegar: 15 kroków (ze zdjęciami)
C51 4-bitowy zegar elektroniczny - drewniany zegar: W ten weekend miałem trochę wolnego czasu, więc poszedłem dalej i zmontowałem ten 4-bitowy elektroniczny zegar cyfrowy DIY o wartości 2,40 USD, który kupiłem jakiś czas temu od AliExpress
Konwertuj zwykły zegar domowy na samoświecący zegar: 8 kroków (ze zdjęciami)
Konwertuj zwykły zegar domowy na świecący zegar: NAJPIERW SERDECZNIE DZIĘKUJĘ ZESPÓŁ INSTRUKCJI, ABY MOJE DNI ODZYSKANIA ZDROWIA BARDZIEJ ODPOWIEDZIALNE ….. W tej instrukcji chcę podzielić się z wami, jak przekonwertować zwykły zegar w domu w samoświecący się zegar.>> Za to