The Smell of Molten Projects in the Morning

Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.

The New Hotness

  • 3D Printed 20×102mm Cartridge

    Having accumulated a box of empty 12 gram CO₂ capsules and having already done Too Many bomb fins:

    20x102mm cartridges
    20x102mm cartridges

    The capsule is obviously the wrong shape, too short, and only 19 mm diameter, but it’s the thought that counts.

    Apply the contour gauge to a genuine slightly battered 20×102mm cartridge:

    20x102mm cartridge tracing
    20x102mm cartridge tracing

    Scan the sketch, import into Inkscape, rotate the image to correct the case taper angle vs. the page, lay lines & curves around the perimeter, align half of it at the page origin to work with OpenSCAD, export as SVG:

    Cartridge - 20x102mm outline - Inkscape layout
    Cartridge – 20x102mm outline – Inkscape layout

    Import into OpenSCAD, let rotate_extrude do the heavy lifting, and remove some pieces:

    Cartridge Case - build view solid model
    Cartridge Case – build view solid model

    The little disk represents a fired primer you’d print separately in a different color and glue into the pocket shown in this cutaway view:

    Cartridge Case - cutaway solid model
    Cartridge Case – cutaway solid model

    The interior void could hold sand for additional heft, as the whole thing is obviously nose-heavy; that’s certainly in the nature of fine tuning. Obviously, we are not dealing with anything that could go bang.

    It builds just like you’d expect:

    20x102mm cartridge - printing
    20x102mm cartridge – printing

    Dab some adhesive on the capsule tip, ditto for the primer, stick them in place, and it’s all good.

    I like the gray PETG-CF version:

    20x102mm cartridges - blue gray PETG-CF
    20x102mm cartridges – blue gray PETG-CF

    Maybe not such a good idea in this day & age. Print responsibly, as they say.

    Update

    Print a sabot to fit a CO₂ capsule into a genuine steel cartridge.

    The solid model:

    Cartridge Case - sabot solid model
    Cartridge Case – sabot solid model

    The OpenSCAD making it happen:

    module Sabot() {
    tube(SabotOA[LENGTH],id=SabotOA[ID],od=SabotOA[OD],anchor=BOTTOM)
        position(BOTTOM)
          tube(SabotOA[LENGTH]/2,id=SabotOA[ID],od=CartridgeOA[ID],anchor=BOTTOM);
    }
    

    The result:

    20x102mm cartridges
    20x102mm cartridges

    The OpenSCAD source code (minus the sabot) and outline as a GitHub Gist:

    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    // 20x102mm cartridge
    // Ed Nisley – KE4ZNU
    // 2025-05-18
    include <BOSL2/std.scad>
    Layout = "Show"; // [Show,Build]
    Powder = true; // build internal void
    /* [Hidden] */
    ID = 0;
    OD = 1;
    LENGTH = 2;
    HoleWindage = 0.2;
    Protrusion = 0.1;
    NumSides = 3*3*4;
    $fn = NumSides;
    CartridgeOA = [21.0,29.5,101.4]; // must match SVG pretty closely
    PrimerOA = [2.0,8.0,2.0];
    CapsuleTip = [7.5,7.5,5.0];
    Capsule = [7.5,18.8 + HoleWindage,83];
    SeatingDepth = 25.0;
    Void = [CartridgeOA[ID]- 4.0,CartridgeOA[OD]- 4.0,CartridgeOA[LENGTH] – SeatingDepth – 4*PrimerOA[LENGTH]];
    //———-
    // Define shapes
    module Cartridge() {
    difference() {
    rotate_extrude()
    import("Cartridge – 20x102mm outline.svg",layer="Cartridge Aligned Half");
    up(PrimerOA[LENGTH])
    cyl(PrimerOA[LENGTH] + Protrusion,d=PrimerOA[OD],anchor=TOP);
    up(CartridgeOA[LENGTH] + CapsuleTip[LENGTH])
    cyl(SeatingDepth,d=Capsule[OD],anchor=TOP);
    up(CartridgeOA[LENGTH] – SeatingDepth)
    cyl(Void[LENGTH],d=CapsuleTip[OD],anchor=BOTTOM);
    if (Powder) {
    up(Void[LENGTH]/2)
    cyl(Void[LENGTH],d=CapsuleTip[OD],anchor=BOTTOM);
    up(2*PrimerOA[LENGTH])
    cyl(Void[LENGTH],d=Void[OD],rounding=Void[OD]/2,anchor=BOTTOM);
    down(Protrusion)
    cyl(Void[LENGTH],d=PrimerOA[ID],anchor=BOTTOM);
    }
    }
    }
    module Primer() {
    difference() {
    cyl(PrimerOA[LENGTH] – Protrusion,d=PrimerOA[OD] – HoleWindage,anchor=BOTTOM);
    up(PrimerOA[LENGTH])
    spheroid(d=PrimerOA[ID]);
    }
    }
    //———-
    // Build things
    if (Layout == "Show")
    //render()
    difference() {
    Cartridge();
    cuboid(3*CartridgeOA[LENGTH],anchor=LEFT+BACK);
    }
    if (Layout == "Build") {
    Cartridge();
    right(CartridgeOA[OD])
    Primer();
    }