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.

Tag: Improvements

Making the world a better place, one piece at a time

  • Kenmore 158 Sewing Machine: Glare Reduction

    The additional LEDs around the needle on (one of) Mary’s Kenmore Model 158 sewing machines provide plenty of light for normal sewing, but produced too much glare on the polished steel “hand hole cover plate” (their nomenclature) for small-scale work. A matte surface seemed in order, which came from some translucent mailing labels left over from our Christmas card effort:

    Kenmore 158 - non-glare cover plate
    Kenmore 158 – non-glare cover plate

    Mailing labels probably aren’t a permanent solution, but they certainly solved the problem without delay. We’re loathe to etch the steel, as increasing the surface roughness definitely isn’t what you want, nor blacken it, for obvious reasons.

    Too much light is definitely better than too little, though.

  • Merry Christmas

    Moonrise, as seen through the pines in our yard:

    Pixel 3a Night Vision - moonrise
    Pixel 3a Night Vision – moonrise

    The Pixel 3a produces exceedingly useful low-light images, mostly by having Google’s software compensate for its tiny lens and minimal light-capture area, with the downside of turning a peaceful night scene into harsh daylight.

    Take the rest of the day off, OK?

  • Google Pixel 3a Microscope Adapter

    Hand-holding my Google Pixel 3a phone over the microscope eyepiece worked well enough to justify building Yet Another Camera Adapter:

    Pixel 3a Microscope Adapter - in action
    Pixel 3a Microscope Adapter – in action

    The solid model looks about like you’d expect:

    Google Pixel 3a Zoom Microscope Mount - solid model - top
    Google Pixel 3a Zoom Microscope Mount – solid model – top

    The “camera” actually has the outside dimensions of a Spigen case, rather than the bare phone, because dropping a bare phone is never a good idea.

    The base plate pretty much fills the M2’s platform:

    Pixel 3a Microscope Adapter - M2 platform
    Pixel 3a Microscope Adapter – M2 platform

    I originally arranged the four corners around the plate to print everything in one go, but an estimated six hours of print time suggested doing the corners separately would maximize local happiness. Which it did, whew, even if the plate ran for a bit over 4-1/2 hours.

    The snout is a loose fit around the 5× widefield microscope eyepiece, with the difference made up in a wrap of black tape; it’s much easier to adjust the fit upward than to bore out the snout. An overwrap of tape secures the snout to the eyepiece, which I’ve dedicated to the cause; the scope normally rocks 10× widefield glass.

    The tapered hole exposes the phone’s fingerprint reader to simplify unlocking, should it shut down while I’m fiddling with something else.

    The microscope doesn’t fully illuminate the camera’s entrance pupil at minimum zoom, with 4.5× filling the screen and (mostly) eliminating the vignette. The corner blocks have oversize holes to allow aligning the camera lens axis over the microscope optical axis. The solid model incorporates Lessons Learned from the version you see here, because you (well, I) can’t measure the camera axis with respect to the outside dimensions accurately enough:

    Pixel 3a Microscope Adapter - installed - front
    Pixel 3a Microscope Adapter – installed – front

    Although it’s less unsteady than it looks, microscopy requires a gentle touch at the best of times. The adapter doesn’t add much wobble to the outcome:

    Pixel 3a Microscope Adapter - installed - side
    Pixel 3a Microscope Adapter – installed – side

    The field is about 14×19 mm with the camera at 4.5× and the microscope at minimum zoom:

    Pixel 3a Microscope Adapter - test image - min mag
    Pixel 3a Microscope Adapter – test image – min mag

    You can see a little darkening on the upper and lower right corners, so the phone’s still minutely leftward.

    The field is about 1.5×2 mm at full throttle:

    Pixel 3a Microscope Adapter - test image - max mag
    Pixel 3a Microscope Adapter – test image – max mag

    Color balance with the cold white LED ring isn’t the best, but it’s survivable. Mad props to OpenCamera for exposing All. The. Controls. you might possibly need.

    The OpenSCAD source code as a GitHub Gist:

    // Google Pixel 3a mount for stereo zoom microscope
    // Ed Nisley – KE4ZNU – 2019-12
    Layout = "Show"; // [Show,BuildAll,BuildBumpers,BuildPlate,DrillGuide,Phone,Plate,Bumper]
    /* [Hidden] */
    ThreadThick = 0.25;
    ThreadWidth = 0.40;
    HoleWindage = 0.2;
    Protrusion = 0.1; // make holes end cleanly
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    ID = 0;
    OD = 1;
    LENGTH = 2;
    inch = 25.4;
    //———————-
    // Dimensions
    Phone = [74.5,156.0,12.0]; // inside Spigen case
    PhoneRadii = [10.0,10.0,3.0]; // corner rounding, likewise
    LensOffset = [-17.0,-18.5,0]; // looking at phone screen, (-) sign = from right/top edge
    PrintReader = [0,Phone.y/2 – 44.0,0]; // fingerprint reader from center
    PrintReaderDia = [20.0,30.0,0]; // … hole for access
    Eyepiece = [11.5,28.0 + 0.50,27.0]; // ID = lens, OD includes clearance
    Insert = [3.0,4.5,4.0]; // M3 threaded brass insert
    Screw = [3.0,7.0,3.5]; // OD = washer, LENGTH = washer + head height
    WallThick = 3.0; // minimum wall thickness
    Bumper = [2*Screw[OD],20.0,Phone.z]; // bumper edge piece
    BumperOAL = Bumper.y + Bumper.x; // outside length for corner piece
    BumperRadius = 2.0;
    MinMargin = 1.2*Bumper.x; // at least this much extra plate for bumpers
    echo(str("MinMargin: ",MinMargin));
    Plate = [IntegerMultiple(Phone.x + 2*MinMargin,5.0),
    IntegerMultiple(Phone.y + 2*MinMargin,5.0),
    false ? 3*ThreadThick : max(Insert[LENGTH] + 2*ThreadThick,WallThick)];
    PlateRadius = 5.0;
    echo(str("Plate: ",Plate," radius: ",PlateRadius));
    EmbossDepth = 2*ThreadThick + Protrusion;
    DebossHeight = EmbossDepth;
    ScrewOffset = Bumper.x/2;
    ScrewAdjust = 1.5*Screw[ID];
    NumSides = 2*3*4;
    Gap = 2.0; // between build layout parts
    //———————-
    // Useful routines
    module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes
    Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
    FixDia = Dia / cos(180/Sides);
    cylinder(r=(FixDia + HoleWindage)/2,
    h=Height,
    $fn=Sides);
    }
    // Basic shapes
    // Overall phone outline
    module Phone() {
    hull()
    for (i=[-1,1], j=[-1,1], k=[-1,1])
    translate([i*(Phone.x/2 – PhoneRadii.x),j*(Phone.y/2 – PhoneRadii.y),k*(Phone.z/2 – PhoneRadii.z)])
    resize(2*PhoneRadii)
    sphere(r=1,$fn=NumSides);
    }
    module Plate() {
    union() {
    difference() {
    union() {
    hull()
    for (i=[-1,1], j=[-1,1])
    translate([i*(Plate.x/2 – PlateRadius),j*(Plate.y/2 – PlateRadius),0])
    cylinder(r=PlateRadius,h=Plate.z,center=true,$fn=NumSides);
    translate([Phone.x/2,Phone.y/2,-Eyepiece[LENGTH]/3 + Plate.z/2] + LensOffset)
    cylinder(d=Eyepiece[OD] + 2*WallThick,h=Eyepiece[LENGTH]/3,
    center=false,$fn=NumSides);
    translate([Phone.x/2,Phone.y/2,-2*Eyepiece[LENGTH]/3 + Plate.z/2 + Protrusion] + LensOffset)
    cylinder(d1=Eyepiece[OD] + 10*ThreadThick,
    d2=Eyepiece[OD] + 2*WallThick,
    h=Eyepiece[LENGTH]/3,
    center=false,$fn=NumSides);
    }
    translate([Phone.x/2,Phone.y/2,-2*Eyepiece[LENGTH] + Plate.z/2 + Protrusion] + LensOffset)
    PolyCyl(Eyepiece[OD],2*Eyepiece[LENGTH],NumSides);
    translate(PrintReader + [0,0,-Plate.z/2 – Protrusion])
    cylinder(d1=PrintReaderDia[OD],d2=PrintReaderDia[ID],h=Plate.z + 2*Protrusion,$fn=NumSides);
    for (i=[-1,1], j=[-1,1])
    translate([i*(Phone.x/2 + Bumper.x/2),j*(Phone.y/2 – Bumper.y/2),-Plate.z])
    PolyCyl(Insert[OD],2*Plate.z,8);
    for (i=[-1,1], j=[-1,1])
    translate([i*(Phone.x/2 – Bumper.y/2),j*(Phone.y/2 + Bumper.x/2),-Plate.z])
    PolyCyl(Insert[OD],2*Plate.z,8);
    translate([0,-12,Plate.z/2]) // recess for legend
    cube([55,40,EmbossDepth],center=true);
    }
    translate([0,0,Plate.z/2 – EmbossDepth])
    linear_extrude(height=DebossHeight,convexity=20)
    text(text="Pixel 3a",size=6,spacing=1.20,
    font="Arial:style:Bold",halign="center",valign="center");
    translate([0,-15,Plate.z/2 – EmbossDepth])
    linear_extrude(height=DebossHeight,convexity=20)
    text(text="Ed Nisley",size=6,spacing=1.20,
    font="Arial:style:Bold",halign="center",valign="center");
    translate([0,-25,Plate.z/2 – EmbossDepth])
    linear_extrude(height=DebossHeight,convexity=20)
    text(text="softsolder.com",size=4,spacing=1.20,
    font="Arial:style:Bold",halign="center",valign="center");
    }
    }
    module BumperPiece() {
    difference() {
    translate([0,-BumperOAL/2 + Bumper.x,0])
    hull()
    for (i=[-1,1], j=[-1,1])
    translate([i*(Bumper.x/2 – BumperRadius),j*(BumperOAL/2 – BumperRadius),0])
    cylinder(r=BumperRadius,h=Bumper.z,center=true,$fn=NumSides);
    translate([0,-Bumper.y/2,-Bumper.z])
    PolyCyl(ScrewAdjust,2*Bumper.z,8);
    }
    }
    // Side bumpers, XY origin at inner corner
    module BumperCorner() {
    union() {
    translate([Bumper.x/2,0,0])
    BumperPiece();
    translate([0,Bumper.x/2,0])
    rotate(-90)
    BumperPiece();
    }
    }
    //- Build things
    if (Layout == "Phone")
    Phone();
    if (Layout == "Plate")
    Plate();
    if (Layout == "Bumper")
    BumperCorner();
    if (Layout == "Show") {
    color("LightBlue") Plate();
    for (i=[-1,1], j=[-1,1]) {
    a =
    i > 0 && j > 0 ? 0 :
    i < 0 && j > 0 ? 90 :
    i > 0 && j < 0 ? -90 :
    180
    ;
    translate([i*Phone.x/2,j*Phone.y/2,Plate.z/2 + Bumper.z/2])
    rotate(a)
    color("LightGreen") BumperCorner();
    translate([0,0,Phone.z/2 + Plate.z/2 + Protrusion])
    color("DarkGray",0.5) Phone();
    }
    }
    if (Layout == "BuildAll") {
    translate([0,0,Plate.z/2])
    rotate([0,180,0])
    Plate();
    for (i=[-1,1], j=[-1,1]) {
    a =
    i > 0 && j > 0 ? 0 :
    i < 0 && j > 0 ? 90 :
    i > 0 && j < 0 ? -90 :
    180
    ;
    translate([i*(Plate.x/2 + Gap),j*(Plate.y/2 + Gap),Bumper.z/2])
    rotate(a)
    BumperCorner();
    }
    }
    if (Layout == "BuildPlate") {
    translate([0,0,Plate.z/2])
    rotate([0,180,0])
    Plate();
    }
    if (Layout == "BuildBumpers") {
    for (i=[-1,1], j=[-1,1]) {
    a =
    i > 0 && j > 0 ? 180 :
    i < 0 && j > 0 ? -90 :
    i > 0 && j < 0 ? 90 :
    0
    ;
    translate([i*(Bumper.x + Gap),j*(Bumper.x + Gap),Bumper.z/2])
    rotate(a)
    BumperCorner();
    }
    }
    if (Layout == "DrillGuide") {
    projection(cut=true)
    Plate();
    }
  • Tour Easy: Fairing Strut Mounts, Redux

    Our Young Engineer’s Tour Easy followed us home, due to a non-survivable cycling commute and inadequate apartment storage space. What with its Zzipper fairing being off and having easy access to the strut, I conjured & installed another set of fairing mounting blocks:

    Tour Easy - Fairing Strut Mount Blocks
    Tour Easy – Fairing Strut Mount Blocks

    Should you be in need of a Tour Easy recumbent in good shape, well, have I got a deal for you. I’ll even conjure a Daytime Running Light mount, if that’s what it takes …

  • Homage Tektronix Circuit Computer: Ball-point Pens vs. Paper

    Extra Fine Pilot V5 pens have a 0.5 mm ball, in contrast to the 1.0 mm ball in the cheap pens I’ve been using, so they should produce much finer lines.

    Which turns out to be the case:

    Tek Circuit Computer - pen and paper comparison
    Tek Circuit Computer – pen and paper comparison

    That’s a stack of three “Homage” Tek CC bottom decks under a Genuine Tektronix Circuit Computer.

    The black scale at the top of the picture (and the bottom of the stack) came from a 1 mm cheap pen in the collet holder, the two green scales come from a 0.5 mm Pilot V5RT cartridge in its new holder, and the Original is (most likely) laser-printed back when that was a New Thing.

    As always, paper makes a big difference in the results. The brownish paper is 110 pound card stock with a relatively coarse surface finish. The white paper is ordinary 22 pound general-purpose laser / inkjet printer paper.

    The 1.0 mm pen (top) doesn’t much care what it’s writing on, producing results on the low side of OK: some light sections, no blobs. Perfectly serviceable, but not pretty.

    1.0 mm ball pen
    1.0 mm ball pen

    The Pilot V5RT really likes better paper, as it bleeds out on the card stock whenever the CNC 3018XL so much as pauses at the end of a stroke. Using white paper slows, but doesn’t completely stop, the bleeding, making the blobs survivable.

    0.5 mm ball Pilot V5RT pen
    0.5 mm ball Pilot V5RT pen

    I’ve been using card stock to get stiffer, more durable, and more easily manipulated decks, but the improved line quality on the white paper says I should laminate the decks in plastic, just like the original Tektronix design.

    No surprise there!

  • Google Pixel 3a Photomicrography vs. Ballpoint Pens

    The Google Pixel 3a camera, unlike the camera in my older Google Pixel XL, takes spectacularly good images through a widefield 5X eyepiece on the stereo zoom microscope:

    0.5 1.0 mm ball pens - 0.7 mm lead pencil
    0.5 1.0 mm ball pens – 0.7 mm lead pencil

    That’s hand-holding the phone against the eyepiece while manipulating it with the other hand. Definitely not the most stable arrangement, but the camera copes well with slight motions. I really need a gripping hand for the camera, to free up another for the microscope’s focus knob.

    For the record:

    Zooming in (because it’s a stereo zoom microscope and I can), the 1.0 mm ball seems surprisingly un-wetted by its ink:

    1.0 mm ball pen
    1.0 mm ball pen

    The Pilot V5 ball seems more smoothly covered:

    0.5 mm ball Pilot V5RT pen
    0.5 mm ball Pilot V5RT pen

    Those are at the same magnification & crop size, so they’re to the same scale.

    This definitely calls for a customized phone-to-eyepiece holder!

  • CNC 3018XL: Pilot V5RT Pen Holder

    It turns out my all-time favorite Pilot Precise V5 Extra Fine stick pen also comes in a clicky-top retractable version:

    Pilot V5 and V5RT pens
    Pilot V5 and V5RT pens

    The cartridge is a nice 6 mm cylinder, eminently transformable into a plotter pen:

    Pilot V5RT holder - installed
    Pilot V5RT holder – installed

    A few minutes with a caliper provides key measurements for a snout surrounding the business end:

    Pilot V5RT Pen Holder - snout dimension doodle
    Pilot V5RT Pen Holder – snout dimension doodle

    The green letters & numbers give the nearest drill sizes. The “T” values along the bottom are the tailstock turns (at 1.5 mm/turn) required to poke the drills to the indicated depths, eyeballed when the body just enters the hole.

    Having recently decomissioned the Thing-O-Matic and harvested its organs parts, I have a vast collection of 3/8 inch = 9.52 mm shafts and matching bronze bushings:

    9.52 mm shaft and bushings
    9.52 mm shaft and bushings

    Bronze bushings have low stiction, at least when they’re co-axial, and are much shorter than linear ball bearings.

    I chopped off a 70 mm length of shaft and faced the raw end:

    Pilot V5RT holder - facing shaft
    Pilot V5RT holder – facing shaft

    The other end had a maker’s logo, but I don’t recognize it:

    Pilot V5RT holder - center drill
    Pilot V5RT holder – center drill

    I really wanted an 8 mm bore around the snout, but it just didn’t work out. The ring around the 7.5 mm counterbore shows where the larger drill just … stopped:

    Pilot V5RT holder - drilled shaft
    Pilot V5RT holder – drilled shaft

    A trial fit with the pen cartridge:

    Pilot V5RT holder - pen in shaft
    Pilot V5RT holder – pen in shaft

    The top of the shaft gets a somewhat longer knurled ring for the 3 mm SHCS holding the cartridge in place:

    Pilot V5RT holder - knurling pen clamp
    Pilot V5RT holder – knurling pen clamp

    The screw bears on a split collar turned and drilled from a Delrin rod:

    Pilot V5RT holder - drilling Delrin clamp
    Pilot V5RT holder – drilling Delrin clamp

    The “split” came from a simple saw cut across one side and I milled a flat spot in the knurling to seat the screw. As usual, the knurled ring got epoxied to the shaft.

    The snout started as a 3/8 inch aluminum rod, drilled as shown in the sketch, with a (scant) 7.5 mm section to fit the shaft. The carbide insert left a nicely rounded shoulder that required trimming to fit snugly into the shaft:

    Pilot V5RT holder - shaping snout seat
    Pilot V5RT holder – shaping snout seat

    The compound can handle the shallow angle required to shape the snout:

    Pilot V5RT holder - tapering snout
    Pilot V5RT holder – tapering snout

    A trial fit showed the snout was a bit too long for comfort:

    Pilot V5RT holder - snout test fit
    Pilot V5RT holder – snout test fit

    Making something shorter doesn’t pose much of a challenge:

    Pilot V5RT holder - trimming snout
    Pilot V5RT holder – trimming snout

    Another trial fit shows it’s spot on:

    Pilot V5RT holder - shaft snout pen test fit
    Pilot V5RT holder – shaft snout pen test fit

    The critical part is having the snout support the plastic around the pen tip to prevent wobbulation.

    Epoxy the whole thing together, add a suitable spring, tighten the screws & nuts for the reaction plate, and it’s all good. I write with about 50 g of force for these pens, so a light preload seemed in order:

    Pilot V5RT Pen Holder - initial downforce measurement
    Pilot V5RT Pen Holder – initial downforce measurement

    If I’d weighed the full-up shaft + snout + collar + cartridge, I’d know if the Y intercept matches that weight. It seems a little lighter, but I’m not taking the thing apart to find out.

    The first version of the 3D printed holder (shown above) is a straightforward modification of the LM12UU diamond drag bit holder, but, after building enough of these things, I realized the circular reaction plate should be triangular to get more clearance in front of the Z-axis stepper motor when installing & removing the holder:

    Pilot V5RT Pen Holder - solid model - show view
    Pilot V5RT Pen Holder – solid model – show view

    It also has a recess for the serrated top of the bearing, to prevent the knurled collar from clicking annoyingly as the Z-axis rises at the end of each stroke.

    Now, to see how well it draws!

    The OpenSCAD source code as a GitHub Gist:

    // Diamond Scribe in linear bearings for CNC3018
    // Ed Nisley KE4ZNU – 2019-08-9
    Layout = "Build"; // [Build, Show, Base, Mount, Plate]
    /* [Hidden] */
    ThreadThick = 0.25; // [0.20, 0.25]
    ThreadWidth = 0.40; // [0.40, 0.40]
    /* [Hidden] */
    Protrusion = 0.1; // [0.01, 0.1]
    HoleWindage = 0.2;
    inch = 25.4;
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    ID = 0;
    OD = 1;
    LENGTH = 2;
    //- Adjust hole diameter to make the size come out right
    module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes
    Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
    FixDia = Dia / cos(180/Sides);
    cylinder(r=(FixDia + HoleWindage)/2,h=Height,$fn=Sides);
    }
    //- Dimensions
    PenOD = 6.1; // pen refill shaft, max OD
    Bearing = [(3.0/8.0)*inch,16.0,10.6]; // linear bearing body, ID = shaft diameter
    BearingFlange = [Bearing[OD],17.2,1.0]; // flange around end of bearing
    Spring = [8.5,9.5,15.5]; // compression spring around shaft, LENGTH = uncompressed
    SpringRecess = 4*ThreadThick;
    WallThick = 4.0; // minimum thickness / width
    Screw = [3.0,6.75,25.0]; // holding it all together, OD = washer
    Insert = [3.0,4.2,7.9]; // brass insert
    //Insert = [3.0,5.0,8.0];
    //Insert = [4.0,6.0,10.0];
    Clamp = [43.2,44.0,34.0]; // tool clamp ring, OD = clearance around top
    LipHeight = IntegerMultiple(2.0,ThreadThick); // above clamp for retaining
    BottomExtension = 15.0; // below clamp to reach workpiece
    MountOAL = LipHeight + Clamp[LENGTH] + BottomExtension; // total mount length
    echo(str("Mount OAL: ",MountOAL));
    Plate = [PenOD + 4*ThreadWidth,Clamp[ID] – 0*2*WallThick,WallThick]; // spring reaction plate
    echo(str("Screw length: ",Spring[LENGTH] + Plate[LENGTH] + Insert[LENGTH]));
    NumScrews = 3;
    ScrewBCD = Bearing[OD] + Insert[OD] + 2*WallThick;
    echo(str("Retainer max OD: ",ScrewBCD – Screw[OD]));
    NumSides = 9*4; // cylinder facets (multiple of 3 for lathe trimming)
    // Basic mount shape
    module CNC3018Base() {
    translate([0,0,MountOAL – LipHeight])
    cylinder(d=Clamp[OD],h=LipHeight,$fn=NumSides);
    translate([0,0,MountOAL – LipHeight – Clamp[LENGTH] – Protrusion])
    cylinder(d=Clamp[ID],h=(Clamp[LENGTH] + 2*Protrusion),$fn=NumSides);
    cylinder(d1=Bearing[OD] + 2*WallThick,d2=Clamp[ID],h=BottomExtension + Protrusion,$fn=NumSides);
    }
    // Mount with holes & c
    module Mount() {
    difference() {
    CNC3018Base();
    translate([0,0,-Protrusion]) // bearing
    PolyCyl(Bearing[OD],2*MountOAL,NumSides);
    translate([0,0,-Protrusion]) // bearing flanges
    PolyCyl(BearingFlange[OD],BearingFlange[LENGTH] + Protrusion,NumSides);
    translate([0,0,MountOAL – 1.5*BearingFlange[LENGTH]]) // sink into surface
    PolyCyl(BearingFlange[OD],2*BearingFlange[LENGTH],NumSides);
    for (i=[0:NumScrews – 1]) // clamp screws
    rotate(i*360/NumScrews)
    translate([ScrewBCD/2,0,MountOAL – Clamp[LENGTH]])
    rotate(180/8)
    PolyCyl(Insert[OD],Clamp[LENGTH] + Protrusion,8);
    }
    }
    module SpringPlate() {
    difference() {
    hull()
    for (i=[0:NumScrews – 1])
    rotate(i*360/NumScrews)
    translate([ScrewBCD/2,0,0])
    cylinder(d=Screw[OD] + 4*ThreadWidth,h=Plate[LENGTH],$fn=24);
    translate([0,0,-Protrusion])
    PolyCyl(Plate[ID],2*MountOAL,NumSides);
    translate([0,0,Plate[LENGTH] – SpringRecess]) // spring retainer
    PolyCyl(Spring[OD] + 4*ThreadWidth,SpringRecess + Protrusion,NumSides);
    for (i=[0:NumScrews – 1]) // clamp screws
    rotate(i*360/NumScrews)
    translate([ScrewBCD/2,0,-Protrusion])
    rotate(180/8)
    PolyCyl(Screw[ID],2*MountOAL,8);
    }
    }
    //—–
    // Build it
    if (Layout == "Base")
    CNC3018Base();
    if (Layout == "Mount")
    Mount();
    if (Layout == "Plate")
    SpringPlate();
    if (Layout == "Show") {
    Mount();
    translate([0,0,MountOAL + Plate[LENGTH] + Spring[LENGTH]])
    rotate([180,0,0])
    SpringPlate();
    }
    if (Layout == "Build") {
    translate([0,-0.75*Clamp[OD],MountOAL])
    rotate([180,0,0])
    Mount();
    translate([0,0.75*Plate[OD],0])
    SpringPlate();
    }