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.

Author: Ed

  • Monthly Aphorism: On Repairs

    • Always test your brakes

    Our house has a long driveway that slopes downward to the (very busy) street in front. Every bike ride begins with a ceremonial checking-of-brakes as we start rolling.

    Once in a very great while, someone finds a brake that doesn’t work as well as it should. It’s much better to discover that fact at the top of the driveway than at the bottom…

    The newest driver in our household learned to tap the van’s brakes much in advance of traffic signals and stop signs, rather than waiting until the last possible moment. She also glides the van to a smooth stop, much as my father taught me back in the day; for a while, he was the chauffeur for a (perhaps the) rich guy in town and learned all about smooth driving.

  • Digital Caliper Thumbwheel Holder: Another Repair

    The digital caliper on my desk has been getting a lot of use lately and, as expected, that delicate glued repair failed.

    Well, I can fix that

    Thumbwheel holder - installed
    Thumbwheel holder – installed

    That’s a somewhat chopped-up Version 1; as always, I must build one prototype to see how everything fits, then make a real part incorporating all the changes. The models  and code below have those changes and should print fine.

    This picture from the previous repair shows what broke and why:

    Broken Roller Mount
    Broken caliper thumb roller mount

    I removed the remainder of the arch, filed the stub square, made a bunch of tedious measurements, and wrote a chunk of OpenSCAD code to create a repair part that looks like this:

    Thumbwheel holder - build model
    Thumbwheel holder – build model

    There’s also a layout arrangement to confirm that it’ll fit the stub:

    Thumbwheel holder - fit model
    Thumbwheel holder – fit model

    And then I printed four so I could pick the best one. The horizontal hole and notch come out surprisingly well, although this thing is right down around the minimum size you’d want to print:

    Thumbwheel holders - as built
    Thumbwheel holders – as built

    The 1-72 screw threads itself into the hole without a nut; I simply match-drilled a hole in the stub under the hole in the part. Of course, that means I must fit the next part to that hole…

    I really wish I was printing with, say, black filament. Even dark green would be better. Heck, I’d go with yellow, but if I don’t get rid of this pink stuff I’ll have it forever.

    The OpenSCAD source code:

    // Digital Caliper thumbwheel holder
    // Ed Nisley - KE4ZNU - Apr 2011
    
    Build = true;						// set true to generate buildable layout
    
    $fn = 8;							// default for holes
    
    // Extrusion values
    // Use 0 extra shells behind the perimeter
    //     2 solid shells on the top & bottom
    
    ThreadThickness = 0.33;
    ThreadWT = 1.75;
    ThreadWidth = ThreadThickness * ThreadWT;
    
    HoleWindage = ThreadWidth;			// enlarge hole dia by extrusion width
    
    Protrusion = 0.1;					// extend holes beyond surfaces for visibility
    
    // Caliper dimensions
    
    WheelDia = 10.0;					// thumbwheel OD
    WheelRadius = WheelDia/2;
    WheelMargin = 1.0;					// space around wheel
    WheelRimThick = 2.5;				// subtract from repair block
    
    ShaftDia = 2.90;					// axle between knurled wheels
    ShaftRadius = ShaftDia/2;
    ShaftLength = 2.7;
    ShaftRetainer = 3.0;				// thickness around shaft
    
    StubThick = 2.45;					// stub of holder on caliper head
    StubLength = 5.0;					// toward caliper head
    StubHeight = 6.0;					// perpendicular to caliper head
    StubClearance = 0.5;				// distance to caliper frame
    
    FrameLength = 50;					// for display only
    FrameHeight = 16.0;
    FrameThick = 3.0;
    
    // Repart part dimensions
    
    ForkLength = StubLength - StubClearance;	// toward caliper head around stub
    ForkHeight = StubHeight;			// perpendicular to caliper head
    ForkGap = 0.2;						// clearance to stub on all sides
    ForkBladeThick = 2.0;				// on each side of stub
    
    ShaftClearance = 0.0;				// Additional clearance around shaft
    ShaftOffset = 8.5;					// Shaft center to stub
    
    BoltHoleDia = 1.8;					// 1-72 machine screw, more or less
    BoltHoleRadius = BoltHoleDia/2;
    
    // Convenient sizes and shapes
    
    FrameBlock = [FrameLength,FrameThick,FrameHeight];
    
    StubBlock = [StubLength,StubThick,StubHeight];
    StubMargin = [ForkGap,2*ForkGap,ForkGap];
    
    RepairBlockLength = ForkLength + ShaftOffset;
    RepairBlockThick = 2*ForkBladeThick + StubThick;
    RepairBlockHeight = WheelRadius + ShaftRadius + ShaftRetainer;
    
    RepairBlock = [RepairBlockLength,RepairBlockThick,RepairBlockHeight];
    
    // Caliper parts to show how repair fits in
    
    module CaliperParts() {
      union() {
    	translate([0,0,-(StubClearance + FrameHeight/2)])
    	  cube(FrameBlock,center=true);
    	translate([-(StubLength/2 + ShaftOffset),0,(StubHeight/2)])
    	  cube(StubBlock,center=true);
      }
    }
    
    // Repair block with origin below wheel shaft
    
    module RepairPart() {
    
      difference() {
    
    // Body of repair part
    	union() {
    	  translate([-RepairBlockLength/2,0,RepairBlockHeight/2])
    		cube(RepairBlock,center=true);
    	  translate([0,0,WheelRadius])
    		rotate([90,0,0])
    		  cylinder(r=ShaftRadius+ShaftRetainer,h=ShaftLength,center=true,$fn=12);
    	}
    
    // wheels
    	translate([0,(ShaftLength + WheelRimThick)/2,WheelRadius])
    	  rotate([90,0,0])
    		cylinder(r=(WheelRadius + WheelMargin),h=WheelRimThick,center=true,$fn=16);
    	translate([-(WheelRadius + WheelMargin)/2,
    			  (ShaftLength + WheelRimThick)/2,
    			  (WheelRadius - Protrusion)/2])
    	  cube([(WheelRadius + WheelMargin),WheelRimThick,(WheelRadius + Protrusion)],
    			center=true);
    	translate([0,-(ShaftLength + WheelRimThick)/2,WheelRadius])
    	  rotate([90,0,0])
    		cylinder(r=(WheelRadius + WheelMargin),h=WheelRimThick,center=true,$fn=16);
    	translate([-(WheelRadius + WheelMargin)/2,
    			  -(ShaftLength + WheelRimThick)/2,
    			  (WheelRadius - Protrusion)/2])
    	  cube([(WheelRadius + WheelMargin),WheelRimThick,(WheelRadius + Protrusion)],
    			center=true);
    
    // axle clearance
    	translate([0,0,WheelRadius])
    	  rotate([90,0,0])
    		cylinder(r=ShaftRadius,h=(ShaftLength + 2*Protrusion),center=true);
    	translate([0,0,(WheelRadius - Protrusion)/2])
    	  cube([ShaftDia,(ShaftLength + 2*Protrusion),(WheelRadius + Protrusion)],
    		   center=true);
    
    // stub of previous wheel holder
    	translate([-(ShaftOffset + (ForkLength - ForkGap)/2 + Protrusion),
    			  0,
    			  (StubHeight + ForkGap - Protrusion)/2])
    	  cube([(ForkLength + ForkGap + Protrusion),
    		   (StubThick + 2*ForkGap),
    		   (StubHeight + ForkGap + Protrusion)],
    		   center=true);
    
    // mounting screw hole
    	translate([-(ShaftOffset + ForkLength/2),0,StubHeight/2])
    	  rotate([90,0,0])
    		cylinder(r=(BoltHoleDia + HoleWindage)/2,
    				 h=(RepairBlockThick + 2*Protrusion),
    				 center=true,$fn=6);
      }
    }
    
    // Build it!
    
    if (!Build) {
      CaliperParts();
      RepairPart();
    }
    
    if (Build) {
      translate([-RepairBlockLength/2,0,RepairBlockHeight])
    	rotate([0,180,0])
    	  RepairPart();
    }
    
  • ABS Plate Film: Bottom View

    I built a quartet of very small knots to see how they’d stick to the ABS film and whether Reversal could cope with tiny things.

    Multiple knots on platform
    Multiple knots on platform

    The left rear knot lost its footings and I removed the rubble while the nozzle was busy with another knot. The top grew surprisingly well out of a tangle deposited in mid-air.

    The ABS film peeled neatly off the aluminum plate and shows what the adhesion looks like from below. The tangle is now in the right front.

    Bottom view of ABS coating with knots
    Bottom view of ABS coating with knots

    Reversal at 20 rpm, 75 ms, no early start. Still some blobbing during travel, so the reverse parameter isn’t quite large enough.

    My Shop Assistant prettied one up by cleaning off the snots, dunking it in the jar of pink goo, and applying several layers of bronze acrylic paint. Next time, we’ll use thinner goo and scuff the knot a bit before painting.

    Painted knot
    Painted knot
  • Effect of First Layer Height on Holes

    This polyholes test piece started with the nozzle 0.45 to 0.50 mm above the build plate. The threads around the holes didn’t bond well to the plate, dragged slightly inward of their intended position, and didn’t join to their neighbors or the infill.

    Polyholes 0.33 mm layer - 0.5 mm starting height
    Polyholes 0.33 mm layer – 0.5 mm starting height

    Adjusting the nozzle downward to start at 0.28 to 0.39 above the plate produced this result:

    Polyholes 0.33 mm layer - 0.3 mm starting height
    Polyholes 0.33 mm layer – 0.3 mm starting height

    So, in round numbers, changing the nozzle’s height by 0.2 mm makes all the difference for an object printed with 0.33 mm layer thickness. That’s why I’ve been so focused on getting a flat, level build platform: a mere 0.2 mm is 60% of the layer thickness!

    The perimeter and additional threads around the holes are now where they should be, plus they’re all bonded to each other and the infill.

    I think Skeinforge positions the center of the perimeter thread at the very outside edge of the object, which means objects are one thread width larger than they should be and holes are one thread width smaller. The HoleWindage parameter I added to nophead’s code compensates for that, although you must manually add it to / subtract it from the critical dimensions.

    [Update: SF does the right thing. See the comments.]

    The larger holes in the second test piece (printed with the correct starting height) came out just about spot on, the mid-size holes are 0.25 mm too large, and the smaller holes are pretty close in absolute terms (and awful in relative terms). There’s no way to get perfect holes, but these are certainly good enough for most purposes and repeatable enough to not require much in the way of tweakage.

    The polyholes sheet is three layers thick. It presents quite an infill challenge, because there’s not much room around the holes (witness the open areas where the available space drops below one thread width) and the Fill plugin doesn’t lay the infill down from one end to the other. The myriad stops, starts, and movements presents many opportunities for blobs, of which you’ll see quite a few.

    Feed 40 mm/s, flow 2 rpm, 210 °C / 120 °C. First layer at 25% feed & flow. Reversal set for 20 rpm, 90 ms in & out, and no early action.

    I measured the thickness of the Outline thread around the actual objects, as described there, to get the first layer thickness. The starting heights for the first piece are the middle array there. These are the heights for the second piece, in units of 0.01 mm:

    33 28 29
    31 28
    31 31
    32 39
    28 32 37

    The OpenSCAD source, which is pretty much directly from nophead:

    // nophead polyholes
    // Modified to use parameters and add diameter Finagle Constant
    
    HoleWindage = 0.6;
    
    NumHoles = 9;
    
    PlateZ = 1.0;
    Protrusion = 0.1;
    HoleZ = PlateZ + 2*Protrusion;
    
    module polyhole(h, d) {
        n = max(round(2 * d),3);
        rotate([0,0,180])
            cylinder(h = h, r = (d / 2) / cos (180 / n), $fn = n);
    }
    
    difference() {
    	cube(size = [NumHoles*10,27,PlateZ]);
        union() {
        	for(i = [1:NumHoles]) {
                translate([(i * i + i)/2 + 3 * i , 8,-Protrusion])
                    polyhole(h = HoleZ, d = (i + HoleWindage));
    
                assign(d = i + 0.5)
                    translate([(d * d + d)/2 + 3 * d, 19,-Protrusion])
                        polyhole(h = HoleZ, d = (d + HoleWindage));
        	}
        }
    }
    
  • Initial Build Plate Height and Level Stability

    The three removable build plates came from the same sheet of aluminum, albeit with different histories and somewhat different construction details, so they’re pretty much the same thickness. After leveling the sub-platform, I built three objects in one session with a single maximum Z height setting in start.gcode to see how things changed.

    These measurements are from the Outline extrusion around the objects, with the number of data points (units of 0.01 mm) depending on the actual length of the side. Of course, I should have built three identical objects, but there’s only so much I’m willing to do for Science

    A 45 mm Companion Cube on Plate 1:

    30 26
    31 27
    32 29
    27 30

    A pair of slightly tweaked nophead Polyhole test plates on Plate 2:

    45 38
    47 38
    47 45
    48 48
    49 51

    A completely failed 3D Knot (too large = too much overhang) with a very small Outline on Plate 3:

    46
    48 49
    50

    Things went quite literally downhill after the first object, but only by 0.2 mm. Unfortunately, a 0.50 mm first-layer height (when you expect 0.33 mm) is entirely enough to prevent adhesion to the ABS build surface and ruin at least the first few layers.

    On the good side, the platform remains level within 0.05 mm, which is down around my measurement resolution.

  • HBP + Aluminum Build Plate (Re)Alignment

    Installing the X Rod Follower required realigning the aluminum sub-plate to get a level build platform. I got a crude initial setting by standing a 3 mm nut on edge under each adjusting bolt, then lowering the platform until it just touched each nut. Doing that procedure again with the height set to 119.5 mm produced these values:

    1.6 1.3 1
    1.3 1.1 0.9
    0.9 0.8 0.7

    I removed the silicone wiper to keep the Thermal Core insulation from landing atop it during the probing. A single wipe at the beginning is a Good Thing, but the wiper is just too tall.

    The rear left corner seems to be too low by about 0.7 mm, which is a bit more than one turn of the M3×0.5 bolt. Remember: larger numbers = lower platform, so you loosen the bolt to raise the platform. I almost got that right the first time. After doing that:

    1.1 0.9 0.8
    1 1 0.9
    0.9 0.9 0.8

    A final quarter-turn got the platform to this happy state:

    0.9 0.8 0.9
    0.9 0.9 0.9
    0.9 0.9 0.9

    That’s just the sub-platform at room temperature, but it looks pretty good.  The platform returns to the same position after pushing it down against the springs, so that seem stable enough.

    The next step is to run up the temperature and build something.

  • Thing-O-Matic: Useful Numbers

    Various numbers that I’ve either measured or collected, scraped into one untidy heap, with the intent of figuring out the stepper motor torques. One significant figure will be entirely enough for what we’re doing; kg & g are really kg-force and g-force; you know what I mean.

    Weights

    • X stage wood structure = 120 g
    • Aluminum build plate = 100 g
    • XY stage with plates & c =1.1 kg

    Forces

    • Guide rod in two bushings = nil
    • X stage with four bushings = 0.8 lb = 0.4 kg
    • X stage with X rod follower = nil
    • X stage with X follower and motor = 1 lb = 0.5 kg
    • Y stage = 2 ounces = nil
    • Y stage with motor = 1.5 kg static, 1 kg moving

    Distances

    The ReplicatorG/machines/thingomatic.xml file lists the X and Y pulleys as 10.82 mm diameter. I measure 12.5 mm over the belt and the belt is 0.78 mm thick, sooo that makes it 10.9 at the pulley surface (which I can’t get to without taking everything apart again). Let’s call them 11 mm.

    • X and Y = 47.069852 step/mm. Let’s call that 47 step/mm → 0.021 mm/step
    • Z = 200 step/mm → 0.005 mm/step

    [Update: see nophead’s comment for the right way to compute the X & Y distances. The answer is 47.0588 step/mm = 0.02125 mm/step, which is 0.1% off what I’d been using.]

    The XML file lists the MK6 extruder at 50.235478806907409 step/mm. Measuring the results on my geared extruder, using the same filament drive doodad as they do, works out to 48.2 step/mm and 1456 step/rev.

    • Extrusion thickness = 0.33 mm

    Speeds

    • Extrusion feed = 40 mm/s
    • Extrusion flow = 2 rpm
    • Traverse speed = 50 mm/s
    • First layer = 25% of normal