Jako většinu národa mne zasáhla moudrost naší vlády, která nejdřív občanům zakázala koupit si účinnou ochranu před šířením koronaviru a poté jim přikázala nosit aspoň tu neúčinnou. Protože mne štve zavazování čehokoliv a zejména když na to nevidím, rozhodl jsem se, že na tkaničky od roušky potřebuji nějakou inteligentní sponu. Výsledkem je model univerzální parametrické spony v OpenSCADu, který vám dávám k dispozici. Zároveň popíšu celý proces vzniku modelu, jako jakýsi doplněk svého nedávného online školení o modelování v OpenSCADu.

Zadání

Při návrhu je třeba nejprve definovat problém a požadované řešení. Moje zadání je následující:

Existující řešení

Samozřejmě nejjednodušší je použít nějaké existující řešení, než vytvářet vlastní. Jako první se nabízí použít klasické "trojzubce", plastové spony, které se běžně používají u batohů a všude možně. Nicméně ty v rozměru 20 mm nemám a nejsem schopen je v tomto okamžiku rychle koupit. Kromě toho nesplňují podmínku snadného zapínání za hlavou, alespoň pro mne.

Dále jsem se podíval na Thingiverse a PrusaPrinters.org, jestli tam nenajdu něco použitelného. Bohužel jsem nebyl úspěšný. Asi nejvíc se mému zadání blížil model Clasp 50mm od uživatele Nys1, ale z mého pohledu má řadu nevýhod:

Moje vlastní řešení

Napadlo mne pro sponu použít neodymové magnety. S magnety při návrhu pracuji často a rád, protože se snadno dají zalepit nebo zatisknout do modelu a lze je použít pro relativně pevné a přitom opakovaně použitelné spojení. Navíc se magnety umí samy "slícovat", což usnadňuje použití.

Ukázkové modely v tomto článku jsou záměrně tištěné z částečně průhledného materiálu, takže jsou magnety vidět. To samozřejmě není podmínkou.

Moje první řešení spoléhalo čistě na přídržnou funkci magnetů. Ty jsem zatiskl do jednoduchého plastového držáku, který se navlékne na tkanici. Toto řešení bohužel nefungovalo, protože magnety neměly pro tento účel dostatečnou sílu, masku nebylo možné dostatečně utáhnout.

Druhá verze proto přidala ještě výčnělek, který zapadá do otvoru v protikusu. To drží sponu zavřenou ve směru tahu tkanice. Magnety pak působí ve směru kolmém, drží jenom dvě části spony u sebe. V tomto směru je jejich síla větší a zároveň je spona v tomto směru namáhána minimálně. Zapínání na podobném principu jsem už v minulosti viděl, takže jsem ho jenom upravil pro své potřeby.

Výsledný model vypadá takto:

Modelování v OpenSCADu

Pro modelování jsem využil samozřejmě svůj oblíbený OpenSCAD. Pro zjednodušení jsem navrhl sponu tak, že oba dva díly jsou zcela identické, liší se jenom orientací vložených magnetů. Pro zapínání klasické masky se dvěma páry tkalounů tedy potřebujete vytisknout čtyři kusy (dva páry).

Výsledný kód vypadá takto:

Pojďme si nyní probrat jeho konstrukci a techniky, které jsem v OpenSCADu využil. Základní princip je jednoduchý: jde v podstatě o 2D tvar vytažený do výšky, ve kterém je jedna část "vykousnutá" a dá se do ní vložit protikus.

Při návrhu jsem využil svou knihovnu A2D, protože mi umožňuje snadno dělat tvary se zaoblenými rohy. Zaoblené rohy vypadají lépe, jsou příjemnější na omak a také se snáze tisknou, protože tiskárna může jet plynule a nemusí se na rohu zastavit při náhlé změně směru o 90°.

Tu tedy referencuji na začátku souboru a ověřím si, že má správnou verzi:

include <A2D.scad>; // https://github.com/ridercz/A2D
assert(a2d_required([1, 5, 0]), "Please upgrade A2D library to version 1.5.0 or higher.");

Parametrický návrh

Prakticky při každém návrhu začínám definicí proměnných. Mám pevně dané některé rozměry (zde magnetu a tkanice) a od nich je pak odvozeno všechno ostatní. Proměnné jsou zároveň opatřeny komentáři pro použití rozhraní Customizer, protože mne to v zásadě nic nestojí.

/* [General] */
// Render two parts clasped together
render_preview = false;
// Add holding peg and corresponding hole
use_peg = true;

Je-li hodnota render_preview nastavena na false, což je výchozí hodnota, vykreslí se jeden model, který lze vyexportovat a poslat na tiskárnu. Je-li nastavena na true, tak se vykreslí modely dva, napozicované proti sobě tak, jak budou v zapnutém stavu. To umožní vizuálně zkontrolovat, že všechno sedí.

Proměnná use_peg umožňuje zapnout (true, výchozí nastavení) nebo vypnout (false) generování kolíku a odpovídajícího otvoru. Pokud bude generování vypnuto, vytvoří se první verze spony, která spoléhá jenom na přídržnou sílu magnetů. To se může hodit pro jiné scénáře použití, silnější magnety a podobně.

Parametrizace nemusí spočívat pouze ve změně rozměru, ale i v chování modelu.

/* [Ribbon] */
// Width of ribbon tape
ribbon_width = 20;      // [20:50]
// Thickness of ribbon (width of hole)
ribbon_thickness = 3;   // [2:10]
// Number of holes
ribbon_holes = 2;       // [1, 2, 3]

Proměnné v sekci Ribbon nastavují šířku tkalounu (ribbon_width, 20 mm), tloušťku otvorů pro něj (ribbon_thickness, aby se dal otvorem provléknout, případně i dvakrát vedle sebe), tu jsem odhadl na 3 mm. Proměnná ribbon_holes pak určuje počet otvorů. Může být třeba jeden (pokud bude tkaloun pevně přišitý), dva (pro provléknutí tkalounu a držení frikcí) nebo tři (pevnější uchycení, vhodné třeba pro hladké materiály, ale zvětšuje sponu).

/* [Magnet] */
// Diameter of magnet hole
magnet_diameter = 11;
// Height of magnet hole
magnet_height = 1.8;
// Amount of material under and over magnet, should be 2-4 layers
magnet_cover = .4;

Proměnné v sekci Magnet určují rozměry magnetu. Přesněji rozměr díry pro něj. Mnou použité magnety mají průměr 10 mm a tloušťku 1,7 mm.

Průměr díry jsem udělal o milimetr větší. V 3D tisku jsou díry vždy ve skutečnosti o něco menší, než v modelu. Je to dáno tím, že průměr otvoru je ve skutečnosti průměr kružnice opsané pravidelnému mnohoúhelníku a z tohoto titulu je skutečný otvor o maličko menší. Navíc roztavený plast má tendenci se maličko "slévat", což otvor dále zmenšuje. V praxi je tedy třeba otvory navrhovat o něco větší, řádově o 0,5 až 1 mm, podle průměru, nastavení tiskárny, materiálu... Další variantou je otvory po tisku protáhnout vrtákem o přesném průměru, ale to zde nelze použít, protože magnet bude zatisknutý uvnitř modelu a budu ho vkládat v průběhu tisku. Navíc i kdyby magnet v otvoru trochu "plaval", při této konstrukci to vadit nebude.

Výška díry je o 0,1 mm větší, než výška magnetu. Je tomu tak opět ze dvou důvodů. První je, že počítám s tiskem s výškou vrstvy 0,2 mm a tedy je žádoucí, aby všechny horizontální plochy měly výšku v násobcích výšky vrstvy. Druhý je, že při zatiskávání čehokoliv do modelu nesmí zatiskávaný předmět (magnet, matice, ložisko...) vůbec přečnívat, protože by do něj mohla narazit tisková hlava a výtisk zkazit.

Proměnná magnet_cover určuje, kolik materiálu bude pod a nad zatisknutým magnetem. Chci aby byla spona co možná nejtenčí, ale zároveň aby držela. Zkušenost říká, že pro tento účel jsou vhodné nejméně dvě vrstvy materiálu, tedy 0,4 mm. Pokud bych zatiskával matici, bylo by patrně nutné použít vrstev více, aby ji bylo možné přitáhnout, ale tady mi dvě vrstvy stačí.

/* [Other] */
// Minimal wall thickness, should be 4 perimeters
wall_thickness = 1.67;
// Radius of rounded corners
corner_radius = 3;
// Clearance of pegs
part_clearance = 1;

Sekce Other obsahuje proměnné, které se jinam nehodily:

/* [Hidden] */
$fudge = 1;
total_width = ribbon_width + 2 * wall_thickness;
module_length = ribbon_width / 2 + (wall_thickness + ribbon_thickness) * (ribbon_holes + 1);
module_height = magnet_height + 2 * magnet_cover;
polygon_sides = 6;
polygon_angle = 180 / polygon_sides;

Sekce Hidden se v customizeru nezobrazuje. Obsahuje hodnoty, které nepředpokládám, že by uživatel měnil, nebo které jsou vypočítané z těch zadaných.

Tohle je koncept, který u svých modelů používám často. Zadám jenom minimální nutné hodnoty a zbytek dynamicky vypočítám z nich tím, že použiju jednu hodnotu pro víc účelů (zde např. šířku díry na tkaloun pro výpočet vzdálenosti díry od šestiúhelníku) nebo použiju nějaký koeficient, kterým hodnoty vynásobím. Zjednodušuje to parametrizovatelnost modelu. Na druhou stranu, ta není neomezená. Když se zadají extrémní hodnoty, nebo hodnoty ve vzájemném nesouladu, model nebude fungovat. Například tento design počítá s tím, že průměr magnetu bude nejvýše zhruba polovina šířky tkalounu. Pokud bu byl větší, bude magnet zasahovat do díry pro kolík.

Základní 2D návrh

Model je definován v modulu part. To mi umožňuje s ním jednoduše manipulovat, jako třeba udělat více kopií a napozicovat je vůči sobě a podobně.

Základem je tento 2D tvar:

V levé části je obdélník se zaoblenými rohy, v pravé pak šestiúhelník se zaoblenými rohy. Ty jsou spojeny do jednoho celku funkcí hull (je to jednodušší, než počítat rozměr obdélníku tak, aby se přesně potkal).

Do tohoto tvaru pak jsou udělány díry pro tkaloun a díra pro kolík. Kód, který to všechno zařizuje, vypadá takto:

difference() {
    // Main shape
    hull() {
        r_regpoly(od = total_width, vertices = polygon_sides, radius = corner_radius, $fn = 16);
        translate([-module_length, -total_width / 2]) r_square([corner_radius * 2, total_width], corner_radius, $fn = 16);
    }

    // Ribbon holes
    hole_xpos = [ for(i = [0:ribbon_holes - 1]) -module_length + wall_thickness * (i + 1) + ribbon_thickness * i ];
    for(x = hole_xpos) translate([x, -ribbon_width / 2]) r_square([ribbon_thickness, ribbon_width], ribbon_thickness / 2, $fn = 16);

    // Peg hole
    if(use_peg) translate([-corner_radius / 2, 0]) hull() 
        for(a = [-180 + polygon_angle, +180 - polygon_angle]) translate(vector_point(alpha = a, delta = total_width / 2 - corner_radius))
            circle(d = corner_radius + part_clearance, $fn = 16);
}

Odečtení otvoru pro druhou část

Tento tvar je pak příkazem linear_extrude(module_height * 2) vytažen do výšky. Je od něj ale nutné odečíst tvar o polovině výšky, aby se daly dva díly dát do sebe.

Nejjednodušší řešení by bylo udělat tvar "společné" části prostě obdélníkový a odečíst kvádr. Já jsem se rozhodl pro tvar šestiúhelníku. Dílem z důvodů estetických, ale také protože "vede" dvě části k sobě a mírně omezuje namáhání ve směru osy Y.

Odečtený tvar je o něco větší (šestiúhelník má větší průměr o 1 mm tolerance). Je tomu tak jednak kvůli prevenci vzniku stěny o nulové šířce a jednak kvůli toleranci tisku.

V této fázi také vytvořím válcovou díru pro magnet. Ta není na modelu vidět, protože je ze všech stran zakryta, ale uvidíme ji ve sliceru.

Kód pro vytvoření téměř celé části vypadá takto:

difference() {
    // Extruded base 2D shape
    linear_extrude(module_height * 2) difference() {
        // Main shape
        hull() {
            r_regpoly(od = total_width, vertices = polygon_sides, radius = corner_radius, $fn = 16);
            translate([-module_length, -total_width / 2]) r_square([corner_radius * 2, total_width], corner_radius, $fn = 16);
        }

        // Ribbon holes
        hole_xpos = [ for(i = [0:ribbon_holes - 1]) -module_length + wall_thickness * (i + 1) + ribbon_thickness * i ];
        for(x = hole_xpos) translate([x, -ribbon_width / 2]) r_square([ribbon_thickness, ribbon_width], ribbon_thickness / 2, $fn = 16);

        // Peg hole
        if(use_peg) translate([-corner_radius / 2, 0]) hull() 
            for(a = [-180 + polygon_angle, +180 - polygon_angle]) translate(vector_point(alpha = a, delta = total_width / 2 - corner_radius))
                circle(d = corner_radius + part_clearance, $fn = 16);
    }

    // Other half cutout
    translate([0, 0, module_height]) linear_extrude(module_height + $fudge) r_regpoly(od = total_width + part_clearance, vertices = polygon_sides, radius = corner_radius, $fn = 16);   

    // Magnet hole
    translate([0, 0, magnet_cover]) cylinder(d = magnet_diameter, h = magnet_height, $fn = 32);
}

Jistící kolík

Zbývá jenom vytvořit jistící kolík, umístěný tak, aby zapadl do otvoru na symetrickém místě v druhém dílu. Může mít jakýkoliv tvar, jenom musí odpovídat otvoru.

Já jsem se rozhodl udělat ho ve tvaru oválu, jsou to dva válce na vrcholech šestiúhelníku, průměr odpovídající poloměru zaoblení rohů. Přes ně pak natáhnu opět hull.

module part() {
    difference() {
        // Extruded base 2D shape
        linear_extrude(module_height * 2) difference() {
            // Main shape
            hull() {
                r_regpoly(od = total_width, vertices = polygon_sides, radius = corner_radius, $fn = 16);
                translate([-module_length, -total_width / 2]) r_square([corner_radius * 2, total_width], corner_radius, $fn = 16);
            }

            // Ribbon holes
            hole_xpos = [ for(i = [0:ribbon_holes - 1]) -module_length + wall_thickness * (i + 1) + ribbon_thickness * i ];
            for(x = hole_xpos) translate([x, -ribbon_width / 2]) r_square([ribbon_thickness, ribbon_width], ribbon_thickness / 2, $fn = 16);

            // Peg hole
            if(use_peg) translate([-corner_radius / 2, 0]) hull() 
                for(a = [-180 + polygon_angle, +180 - polygon_angle]) translate(vector_point(alpha = a, delta = total_width / 2 - corner_radius))
                    circle(d = corner_radius + part_clearance, $fn = 16);
        }

        // Other half cutout
        translate([0, 0, module_height]) linear_extrude(module_height + $fudge) r_regpoly(od = total_width + part_clearance, vertices = polygon_sides, radius = corner_radius, $fn = 16);   

        // Magnet hole
        translate([0, 0, magnet_cover]) cylinder(d = magnet_diameter, h = magnet_height, $fn = 32);
    }

    // Peg
    if(use_peg) translate([corner_radius / 2, 0]) hull() 
        for(a = [-polygon_angle, +polygon_angle]) translate(vector_point(alpha = a, delta = total_width / 2 - corner_radius))
            cylinder(d = corner_radius, h = module_height * 2, $fn = 16);
}

Tuto konstrukci jsme již viděli, v zrcadlovém provedení, při vytváření otvoru. Používám zde funkci vector_point, která vypočítá bod (střed podstavy válce) na základě úhlu a vzdálenosti od originu.

Zobrazení náhledu a jednoho dílu

Následující kód zobrazí buďto jeden díl pro tisk nebo dva díly, jeden červený a modrý, napozicované nad sebe tak, jak budou při složení obou dílů dohromady.

// Main render
if(render_preview) {
    // Render two parts together, to show how it works and also check if it fits
    color("#cc0000") part();
    color("#000099") translate([0, 0, module_height * 2 + part_clearance / 2]) rotate([0, 180, 0]) part();
} else {
    // Render single part, for export and printing
    part();
}

3D tisk

Model je navržen tak, aby byl 3D tisk pokud možno co nejjednodušší. Jediná zákeřnost se skrývá v nutnosti ve správné výšce přerušit tisk a vložit magnety.

Tisk je nutné přerušit před tiskem 12. vrstvy ve výšce 2,4 mm. Při této vrstvě začne tiskárna zakrývat díru novým materiálem.

Pro přípravu modelu k tisku používám program PrusaSlicer. Ve starších verzích bylo nutné tisk přerušit buďto ručně nebo použít funkci výměna filamentu. Nejnovější verze 2.2.0 ale obsahuje funkci pozastavení tisku, kdy není nutné vyjímat a znovu zavádět tiskovou strunu.

V nastavení tisku jsem ještě nastavil čtyři perimetry (výchozí jsou dva), protože to tomuto modelu lépe sedí.

Po přerušení tisku odjede tisková hlava stranou a lze vložit magnety.

Dejte si pozor na jejich správnou orientaci! Jeden pár (jedno který, všechny díly jsou stejné) musí mít nahoru severní pól, druhý jižní, aby zapadly do sebe.

Poté lze pokračovat v tisku. Tisk kompletní sady čtyř dílů trvá cca. hodinu. Jako tiskový materiál jsem použil PLA, ale lze použít cokoliv.

Soubory ke stažení