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

  • MPCNC: Re-Improved Endstop Switch Mount

    As part of entombing the endstop PCBs in epoxy, I tweaked the switch mounts to (optionally) eliminate the screw holes and (definitely) rationalize the spacings:

    MPCNC MB Endstop Mount - No screws
    MPCNC MB Endstop Mount – No screws

    The sectioned view shows the cable tie slot neatly centered between the bottom of the switch terminal pit and the EMT rail, now with plenty of meat above the cable tie latch recess. The guide ramp on the other side has a more-better position & angle, too.

    A trial fit before dabbing on the epoxy:

    MPCNC - Endstop Mount for epoxy coating - trial fit
    MPCNC – Endstop Mount for epoxy coating – trial fit

    The 3M black foam tape works wonderfully well!

    After the epoxy cures, it’s all good:

    MPCNC - Epoxy-coated Endstop - Installed
    MPCNC – Epoxy-coated Endstop – Installed

    The OpenSCAD source code as a GitHub Gist:

    // MPCNC Endstop Mount for Makerbot PCB on EMT tubing
    // Ed Nisley KE4ZNU – 2017-12-04
    /* [Build Options] */
    Layout = "Show"; // [Build, Show, Block]
    Holes = false; // holes for switch screws
    Section = true; // show internal details
    /* [Extrusion] */
    ThreadThick = 0.25; // [0.20, 0.25]
    ThreadWidth = 0.40; // [0.40]
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    /* [Hidden] */
    Protrusion = 0.01; // [0.01, 0.1]
    HoleWindage = 0.2;
    ID = 0;
    OD = 1;
    LENGTH = 2;
    /* [Sizes] */
    RailOD = 23.5; // actual rail OD
    SwitchHeight = 8.0; // switch PCB distance from rail OD
    Strap = [5.5,50,2.0]; // nylon strap securing block to rail
    StrapHead = [8.2,3.0,5.5]; // recess for strap ratchet head
    Screw = [2.0,3.6,7.0]; // thread dia, head OD, screw length
    HoleOffset = [2.5,19.0/2]; // PCB mounting holes from PCB edge, rail center
    SwitchClear = [6.0,15,3.0]; // clearance around switch pins
    SwitchOffset = [6.0,0]; // XY center of switch from holes
    StrapHeight = (SwitchHeight – SwitchClear[2])/2; // strap center from rail
    Block = [16.4,26.0,RailOD/2 + SwitchHeight]; // basic block shape
    //- 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);
    }
    //- Shapes
    // Main block constructed centered on XY with Z=0 at top of rail
    module PCBBlock() {
    difference() {
    translate([-Block[0]/2,-Block[1]/2,-RailOD/2])
    cube(Block,center=false);
    translate([(SwitchOffset[0] + HoleOffset[0] – Block[0]/2),
    SwitchOffset[1],
    (SwitchHeight – SwitchClear[2]/2 + Protrusion/2)])
    cube(SwitchClear + [0,0,Protrusion],center=true);
    if (Holes)
    for (j=[-1,1])
    translate([HoleOffset[0] – Block[0]/2,j*HoleOffset[1],(Block[2]/2 – Screw[LENGTH])])
    rotate(180/6)
    if (true) // true = loose fit
    PolyCyl(Screw[ID],Screw[LENGTH] + Protrusion,6);
    else
    cylinder(d=Screw[ID],h=Screw[LENGTH] + Protrusion,$fn=6);
    translate([0,0,StrapHeight])
    cube(Strap,center=true);
    translate([0, // strap head recess
    (Block[1]/2 – StrapHead[1]/2 + Protrusion),
    StrapHeight – Strap[2]/2 + StrapHead[2]/2])
    cube(StrapHead + [0,Protrusion,0],center=true);
    StrapAngle = atan((StrapHeight + RailOD/4)/Strap[2]); // a reasonable angle
    echo(str("Strap Angle: ",StrapAngle));
    translate([0,-(Block[1]/2 – Strap[2]/(2*sin(StrapAngle))),StrapHeight])
    rotate([StrapAngle,0,0])
    translate([0,-Strap[1]/2,0])
    cube(Strap,center=true);
    if (Section)
    translate([Block[0]/2,0,0])
    cube(Block + [0,2*Protrusion,2*Block[2]],center=true);
    }
    }
    module Mount() {
    difference() {
    translate([0,0,RailOD/2])
    PCBBlock();
    rotate([0,90,0])
    cylinder(d=RailOD,h=3*Block[0],center=true);
    }
    }
    //- Build things
    if (Layout == "Show") {
    Mount();
    color("Yellow",0.5)
    rotate([0,90,0])
    cylinder(d=RailOD,h=3*Block[0],center=true);
    }
    if (Layout == "Block")
    PCBBlock();
    if (Layout == "Build")
    translate([0,0,Block[2]])
    rotate([180,0,0])
    Mount();
  • MPCNC: Epoxy-Coated Endstop Switches

    Using 3D printer style endstop switches has the advantage of putting low-pass filters (i.e. caps) at the switches, plus adding LED blinkiness, but it does leave the +5 V and Gnd conductors hanging out in the breeze. After mulling over various enclosures, it occured to me I could just entomb the things in epoxy and be done with it.

    The first step was to get rid of the PCB mounting screws and use 3M permanent foam tape:

    MPCNC - Epoxy-coated Endstop - Adhesive Tape
    MPCNC – Epoxy-coated Endstop – Adhesive Tape

    Get all the switches set up and level, mix up 2.8 g of XTC-3D (because I have way too much), and dab it on the switches until all the exposed conductors have at least a thin coat:

    MPCNC - Epoxy-coated Endstop - Installed
    MPCNC – Epoxy-coated Endstop – Installed

    You should use a bit more care than I: the epoxy can creep around the corner of the switch and immobilize the actuator in its relaxed position. Some deft X-Acto knife work solved the problem, but only after firmly smashing the X axis against the nonfunctional switch.

    Epoxy isn’t a particularly good encapsulant, because it cures hard and tends to crack components off the board during temperature extremes. These boards live in the basement, cost under a buck, and I have plenty of spares, so let’s see what happens.

    At least it’s now somewhat more difficult to apply a dead short across the Arduino’s power supply, which comes directly from a Raspberry Pi’s USB port.

  • MPCNC: A4988 Driver Microstep Waveforms

    I measured stepper motor winding current with a pair of Tek Hall effect probes for future reference.

    MPCNC - X Axis current measurement setup - overview
    MPCNC – X Axis current measurement setup – overview

    The pistol-shaped A6303 measures up to 100 A, so it’s grossly overqualified for the job. The much smaller A6302 goes to 20 A and is definitely the right hammer. The single-trace pix show 200 mA/div.

    I’m using the default 12 V6 A MPCNC stepper power supply, with A4988 stepper driver boards on the Protoneer CNC Shield atop a knockoff Arduino UNO running GRBL firmware. The blue USB cable goes off to a Raspberry Pi running minicom for manual control.

    All the pix use the same G-Code command: G1 X2.4 F180. Running at 180 mm/min = 3 mm/s eliminates pretty nearly all visible acceleration.

    Each picture requires:

    • m9 to disable stepper power
    • Remove X axis A4988 driver board
    • Set jumpers to select new microstep mode
    • Reinstall driver board
    • Change GRBL $100 step/mm setting to match jumpers
    • Ctrl-X = reset GRBL
    • $x = unlock
    • m8 = enable power
    • Enable scope trigger (single-trigger mode)
    • g1x2.4f180 motion for next image
    • x0 = return to origin

    With the A4988 stepper driver in 16:1 microstep mode:

    MPCNC g1x2.4f180 - 16 ustep - 200 mA-div
    MPCNC g1x2.4f180 – 16 ustep – 200 mA-div

    Notice how some of the microsteps aren’t particularly crisp, notably around the zero crossings. I think the relatively low 12 V supply doesn’t give the A4988 enough control authority to boss the current around, resulting in difficulty holding the current setpoint, even at low speed:

    MPCNC X 10mm 60mm-s 500mA-div
    MPCNC X 10mm 60mm-s 500mA-div

    More on that problem in a while.

    In 8:1 microstep mode:

    MPCNC g1x2.4f180 - 8 ustep - 200 mA-div
    MPCNC g1x2.4f180 – 8 ustep – 200 mA-div

    In 4:1 microstep mode:

    MPCNC g1x2.4f180 - 4 ustep - 200 mA-div
    MPCNC g1x2.4f180 – 4 ustep – 200 mA-div

    In 2:1 microstep mode:

    MPCNC g1x2.4f180 - 2 ustep - 200 mA-div
    MPCNC g1x2.4f180 – 2 ustep – 200 mA-div

    And, a rarity in modern times, both windings at 500 mA/div in full step mode:

    MPCNC g1x2.4f180 - 1 ustep - dual 500 mA-div
    MPCNC g1x2.4f180 – 1 ustep – dual 500 mA-div

    The A4988 driver reduces the peak current to 1/√2 of the stepped sine wave peak to maintain the same average power dissipation and torque. For reasons I cannot explain, the full-step move takes far less time than the others; it must have something to do with how GRBL computes the average speed. It sounds like a robotic woodpecker hammering on the MPCNC’s frame, so I flipped back to 16:1 microstep mode after taking that picture.

    Now I can refer to these from elsewhere …

  • MPCNC: Stepper Motor Power Control

    GRBL responds to critical errors by disabling its outputs, which seems like a useful feature for a big-enough-to-hurt CNC machine like the MPCNC. Unlike the RAMPS 1.4 board, there’s no dedicated power-control pin, so I connected the Coolant output to the same DC-DC SSR I tried out with the RAMPS board:

    MPCNC - CNC Shield - Power SSR
    MPCNC – CNC Shield – Power SSR

    With homing enabled, GRBL emerges from power-on resets and error conditions with the spindle and coolant turned off and the G-Code interpreter in a locked state requiring manual intervention, so turning the stepper power on fits right in:

    • $x – Unlock the controls
    • m8 – Coolant output on = enable stepper power
    • $h – Home all axes

    The steppers go clunk as the power supply turns on, providing an audible confirmation. The dim red LED on the SSR isn’t particularly conspicuous.

    Turning the stepper power off:

    • m9 – Coolant output off = disable stepper power

    I think the A4988 drivers maintain their microstep position with the stepper power supply off, because their logic power remains on. In any event, you probably wouldn’t want to restart after an emergency stop without clearing the fault and re-homing the axes.

    The board has Cycle Start, Feed Hold, and Abort inputs just crying out for big colorful pushbutton switches.

    Unlike the RAMPS board, the Prontoneer CNC Shield does not feed stepper power to the underlying Arduino UNO, leaving it safely powered by USB or the coax jack.

     

  • MPCNC: Z Axis Coupler Backlash Prevention

    The MPCNC has the entire weight of the Z axis motor and stage resting on the leadscrew, so the instructions call for preloading the spring coupler by stretching it with the leadscrew butted against the motor shaft. The leadscrew end isn’t particularly flat, so I inserted a 1/4 inch ball bearing between the two before the stretch:

    MPCNC - Z Axis leadscrew - coupler bearing
    MPCNC – Z Axis leadscrew – coupler bearing

    I’m reasonably sure the ball won’t make the slightest difference, but two slightly misaligned shafts can now pivot on a point, rather than grind against each other. There’s no evidence of misalignment; I feel better and that’s what counts.

  • MPCNC: Belt Tensioners

    The GT2 / GT3 belt specs call for 10-ish pounds of tension, but I don’t yet have a good feel for the actual MPCNC belt tension … and it’s hard to measure in-situ. So I picked up some spring tensioners and yanked one with a luggage scale:

    GT2 Belt Tensioner - 4 kg
    GT2 Belt Tensioner – 4 kg

    You’re looking at 4 kg = 8-ish pounds of tension. When they’re relaxed, the arms sit at roughly right angles.

    I installed them on the far end of the belts, although that’s a bit snug under the roller:

    GT2 Belt Tensioner - installed
    GT2 Belt Tensioner – installed

    An endstop switch will eventually add some clearance and it’ll be all good.

    Even though they’re neither linear nor precisely calibrated, they’ll serve as a reminder to check the tension every now and again.

    Install them with the same casual disregard you reserve for fish hooks and you’ll emerge unscathed.

  • Monthly Science: USDA Inspection Stamps

    I recently bought a pair of pork belly packages, one labeled “Local” at an additional buck a pound. They were packaged skin side downward, so the USDA inspection stamps came as a surprise:

    Pork Belly Skin - USDA Stamps
    Pork Belly Skin – USDA Stamps

    Turns out the digits give the “establishment number”, which you can look up online. These came from a processor in Pine Plains.

    We presume they keep track of their pigs …

    The meat is curing even as I type. Next week: smoking.