Słów kilka o projektowaniu mojego pierwszego ambitniejszego obiektu 3D – stojaka na bity do śrubokręta Xiaomi Wowstick 1F
Table of Contents
Moja przygoda z drukiem 3D zaczęła się jeszcze na studiach, kiedy to w Kole Studentów Informatyki UJ zacząłem korzystać z drukarki SLA (Prusa i3 mk1). Stworzyłem wówczas kilka prostych obiektów w webowym Tinkercadzie. Korzystałem głównie z konwersji grafiki wektorowej na obiekty 3D poprzez prymitywnie “wyciąganie” ich, by uzyskały wysokość oraz sklejania takich elementów ze sobą. Kilka lat później kupiłem swoją drukarkę DLP (Anycubic Photon S) i stanął przede mną problem praktyczny, którego tak łatwo nie można było rozwiązać w prymitywnych narzędziach - stojak na bity do śrubokręta elektrycznego Xiaomi Wowstick 1F. Oczywiście żaden ze znalezionych w internecie projektów nie odpowiadał moim potrzebom, a generyczne stojaki czy organizery nie były zbyt dobrze dopasowane, mimo iż tytułowy śrubokręt używa standardowych 4mm bitów. Ponadto chciałem, aby bity były uporządkowane według typu - poza zamiłowaniem do porządku chciałem po prostu szybko znajdować konkretny typ, co nie jest aż tak proste, mając kilka podobnych końcówek w małym rozmiarze.
Idea ogólna i planowanie #
Pierwszym etapem projektowania była ogólna idea, którą od samego początku miałem w głowie - kształt schodkowy z przeznaczeniem do postawienia na biurku. Z mojego doświadczenia stojaki, czy bardziej etui, gdzie wszystkie bity są na tym samym poziomie, a ich końcówki widoczne jedynie z góry są mało praktyczne do wyjmowania.
Kolejny etap to zbadanie potrzeb szczegółowych, czyli posortowanie bitów wedle typów, opisanie ich oraz zaprojektowanie ich przestrzennego ułożenia. Mało ambitnie użyłem w tym celu MS Excela, ale zadziałało.
Przy okazji spędziłem nieco za dużo czasu, wędrując po stronach Wikipedii o śrubokrętach…
Wiedząc już, co chciałbym osiągnąć, nadszedł czas, żeby znaleźć narzędzie do realizacji. Wybór padł na otwartoźródłowy program OpenSCAD ( https://openscad.org/), który zdaje się dość popularny w środowisku hobbystycznych projektantów 3D, a także jest używany przez portal ThingVerse do personalizowania projektów poprzez ich narzędzie Customizer. Nauka podstaw nie jest trudna - wystarczy jakikolwiek zmysł geometryczny i można już szukać w internecie jak budować konkretne bloki składowe naszego projektu - za pomocą kodu. Poza tym jest cała masa tutoriali, więc szybko można poznać bardziej zaawansowane sposoby opisywania naszego obiektu 3D.
Rozbicie na elementy składowe #
Po oswojeniu się z narzędziem wydzieliłem trzy elementy składowe obiektu wymienione poniżej. Pod listą pokazuję przykładowy obiekt (używa on finalnego kodu, zmodyfikowanego do celów demonstracyjnych).
- Prostopadłościan z wgłębieniem na bit od góry, najlepiej z miejscem na dwie litery identyfikujące rodzaj bitu od przodu (wedle planu w Excelu); stałe rozmiary; kolor żółty
- Pełny prostopadłościan bez wgłębienia na bit umożliwiający tworzenie odstępów między różnymi typami bitów; również stałe rozmiary; kolor różowy
- Prostopadłościan o szerokości i głębokości segmentu na bit, ale o wysokości będącej wielokrotnością wysokości segmentu na bit - znajdującego się pomiędzy segmentem na bit a podłożem; kolor zielony
Ze względu na naturę obiektów 3D nie widać wszystkich granic między elementami składowymi. Żółtych jest co widać 10, różowych 2, a zielonych 8 (lub licząc także elementy o zerowej wysokości - 12). Te ostatnie występują w czwórkach: dwu-, jedno- i zerowo- krotnie wysokich względem obiektów żółtych i różowych.
Mając wizję całości, czas było przystąpić do tworzenia kodu opisującego elementy składowe. Dla uproszczenia będę nazywał elementy kolorami z wizualizacji idei ogólnej w poprzednim akapicie. Elementy różowe i zielone to po prostu prostopadłościany (sześciany foremne przekształcone parametrami funkcji cube()
).
Zasadnicze wyzwanie to elementy żółte, czyli te, które mają trzymać pojedynczy bit i mieć wytłoczone oznaczenie. Punktem wyjścia znowu będzie cube()
, lecz będziemy chcieli od niego “odjąć” (poprzez operację difference()
) wgłębienie na bit i kształt liter.
Wgłębienie na bit to graniastosłup o podstawie sześciokąta foremnego - tak jak sam bit. Hexagon nie jest kształtem podstawowym, do jego generowania pozwoliłem sobie pożyczyć kod z https://www.youtube.com/watch?v=KAKEk1falNg, choć później znalazłem nieco inne podejście do tego tematu.
module fhex(wid,height){
hull(){
cube([wid/1.7,wid,height],center = true);
rotate([0,0,120])
cube([wid/1.7,wid,height],center = true);
rotate([0,0,240])
cube([wid/1.7,wid,height],center = true);
}
}
Same napisy to połączenie generowanych z fontów dostępnych w systemie obiektów dwuwymiarowych przy pomocy text()
, uwypuklania takich obiektów przez nadanie im wysokości używając linear_extrude()
, obrotów powstałym obiektem by znajdował się na ścianie prostopadłościanu przy pomocy rotate()
oraz finalnie pozycjonowania w przestrzeni poprzez translate()
.
Kod segmentu poniżej:
module segment(txt=""){
difference(){
cube([$segment_width,$segment_width,$segment_height]);
translate([$segment_width/2,$segment_width/2,$segment_height-$hole_height/2])
fhex($hole_width,$hole_height);
extrusion=1;
translate([0,extrusion,0])
rotate([90,0,0])
linear_extrude(extrusion){
divider=3.0*len(txt);
translate([$segment_width/divider,$segment_height-$segment_width/2,0]){
text(txt, size=$segment_width/2, font="Ubuntu Mono:style=Bold");
}
}
}
}
Składanie w całość #
Cały taki element można upakować jeszcze w module
, czyli coś na kształt funkcji i można brać się za generowanie ich docelowych instancji oraz rozmieszczanie ich w przestrzeni.
Za rozmieszczenie przestrzenne odpowiada tablica tablic zawierających etykiety segmentów (bądź puste stringi gdzie element ma być bez otworu) - przeniesiona 1:1 z planu w Excelu.
$plan=[
["PH","PH","" ,"" ,"" ,"PH","PH","PH","PH","PH","PH"],
["SL","" ,"" ,"" ,"SL","SL","SL","SL","SL","SL","SL"],
["H" ,"" ,"" ,"H" ,"H" ,"H" ,"H" ,"H" ,"H" ,"H" ,"H" ],
["T" ,"T" ,"T" ,"T" ,"T" ,"T" ,"T" ,"T" ,"T" ,"T" ,"T" ],
["TR","TR","TR","TR","" ,"" ,"Y" ,"Y" ,"Y" ,"Y" ,"Y" ],
["S" ,"S" ,"S" ,"" ,"" ,"" ,"" ,"" ,"P" ,"P" ,"P" ],
["U" ,"U" ,"U" ,"" ,"" ,"" ,"" ,"" ,"W" ,"" ,"C" ],
];
Po całości możemy przemieszczać się pętlą for
zagnieżdżoną w pętli for
. Kod takiego przebiegu wraz z wyodrębnioną dla czytelności funkcją segment_in_grid
zamieszczam poniżej, a całość oczywiście znajduje się w zalinkowanym na końcu artykułu repozytorium Githuba i na Thingverse.
module segment_in_grid(x,y,txt=""){
translate([x*$segment_width, y*$segment_width, y*$segment_height]){
if (len(txt)>0) segment(txt); //segment żółty
else cube([$segment_width,$segment_width,$segment_height]); //segment różowy
}
translate([x*$segment_width, y*$segment_width, 0]){
cube([$segment_width, $segment_width, y*$segment_height]); //segment zielony
}
}
yl=len($plan)-1;
for (y=[0:yl]){
for (x=[0:len($plan[yl-y])-1]){
segment_in_grid(x,y,txt=$plan[yl-y][x]);
}
}
Zachowanie segment_in_grid
jest takie samo w każdym wierszu, a więc na najniższym “schodku” tworzy segment zielony o wysokości 0.
Dostrajanie parametrów #
Żeby całość stojaka pasowała do rzeczywistości, wymiary elementów składowych należy odpowiednio dobrać - łącząc znane wartości z pomiarów samych bitów i ogólnego pomysłu z testowymi wydrukami, tak by uwzględnić dokładność druku oraz oczywiście z testami UX - żeby wygodnie się tego używało 🙂
Dzięki opracowanemu systemowi znakowania slotów na bity przy okazji udało mi się dość łatwo otrzymać system znakowania prototypów, by nie pogubić się, jakie mają parametry zadane (rzeczywiste jednak mogą się różnić).
Prototypy na zdjęciach poniżej nie mają docelowej czytelności znakowania - nie zostały idealnie utwardzone ani oczyszczone, a kąpiel zaliczyły w izopropanolu wymagającym filtracji lub wręcz wymiany. Finalna wersja jest dużo ładniejsza.
Zakończenie #
Na sam koniec należy już tylko złożyć kod w całość, wygenerować obiekt STL i wrzucić do slicera. Do mojej drukarki DLP używam płatnej wersji LycheeSlicer ( https://mango3d.io/lychee-slicer-for-sla-3d-printers/).
Obiekt, wraz z kodem źródłowym opublikowałem na Thingversie i Githubie.
Obiekt został pozbawiony wnętrza (hollow) z wypełnieniem w trybie lattice 20%, dodałem dwa kwadratowe otwory odpływowe na nieutwardzoną żywicę z wnętrza (drain holes) z tyłu: kilka milimetrów od dołu i boków, po jednym z każdej strony. Żadne supporty nie były wymagane.
Od rozpoczęcia prac do gotowego wydruku minęło kilka wieczorów kodowania, cięcia i testowania wydruków, a efekt bardzo mnie cieszy, bo stojak w 100% odpowiada moim oczekiwaniom i jeśli kiedyś będę potrzebował podobnego, ale dla innego zestawu bitów - wystarczy kilka zmian w parametrach kodu, render i obiekt będzie gotowy do wydruku. Zabawę polecam każdemu.