Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.
As the Y stage moves front-to-back, the X axis motor wires tend to bend at the cable tie lashing them to the Y stage. While I had the XY stage apart, I wrapped a bit of self-vulcanizing tape around the skein of motor wires to provide some strain relief.
A batch of LED ring lights arrived from halfway around the planet and I’d earmarked one for a microscope ring illuminator, despite the crappy color spectrum of white LEDs. It’s better than the fluorescent desk lamp I’d been using up to this point.
This shows the business end of the LED ring light, which would probably look better more professional without the full-frontal Barbie color scheme:
Microscope LED Ring light – snout view
It’s less overwhelming from the top:
Microscope with LED illuminator
The power cable came with the ring. I unsoldered it, fed the end through the shade, resoldered it, snipped off the automobile lamp adapter, wired it to a switch and a 12 V 200 mA wall wart, and hot-melt-glued the switch to the microscope. Yet another vampire load, alas.
The two parts must be printed separately to eliminate any problem with overhang, as the finished widget would have vertical walls on both sides. I thought about support material, realized that would be a lot like work, and split the thing into two parts.
LED ring light – mounting plate and shade
The walls on the shade ring show the same backlash problem that cropped up there; I built these before tweaking the belts.
The mounting plate screws into the microscope’s accessory thread:
Microscope LED Ring Light – Mount Plate
Admittedly, “screws into” may be an exaggeration: the mount is just a cylindrical feature slightly larger than the microscope’s minor thread diameter; it’s barely more than a snug friction fit. I clipped out four small sections to allow that ring to bend slightly as it engages the threads.
A shade contains the LED ring and keeps direct light off the objective lenses. There’s a tiny hole on one side to let the power wires out:
Microscope LED Ring Light – Shade
The two parts got glued together with the same ABS-in-MEK gunk that I apply to the aluminum build plate:
Clamping LED ring light parts
I applied three blobs of hot-melt glue inside the shade, lined up the LED ring’s power wire with the exit hole, and smooshed it into place. Pause for a breath and it’s done!
The result actually looks pretty good, despite the weird yellow-and-blue spectrum you get free with every “white” LED. I reset the camera’s color correction using a white sheet of paper. This is an ordinary M3 socket head cap screw, familiar to Thing-O-Matic owners everywhere, and a tweaked needle-point tweezer:
Sample image using LED ring light
The microscope camera mount works surprisingly well, particularly given how simple it was to build.
The OpenSCAD source makes the shade walls a bit taller than you see above. When I run out of pink filament, this one’s on the rebuild list!
// Microscope LED Ring Illuminator Mount
// Ed Nisley - KE4ZNU - Mar 2011
// Build with...
// extrusion parameters matching the values below
// 2 extra shells
// 3 solid surfaces at top + bottom
Build = "Ring"; // Mount or Ring
// Extrusion parameters for successful building
ThreadZ = 0.33; // should match extrusion thickness
WT = 1.75; // width over thickness
ThreadWidth = ThreadZ * WT; // should match extrusion width
HoleWindage = ThreadWidth; // enlarge hole dia by extrusion width
// Screw mount dimensions
MountOD = 46.85 - ThreadWidth; // Microscope thread diameter (thread minor)
MountDepth = 2.5; // ... length
MountID = MountOD - 6*ThreadWidth; // ID of mount body -- must clear lenses
echo(str("Mount ID: ",MountID));
echo(str("Mount OD: ",MountOD));
PlateThick = 3*ThreadZ; // Thickness of mounting plate beyond rings
echo(str("Plate: ",PlateThick));
// LED Ring holder dimensions
RingID = 54.0;
RingOD = 71.0;
RingFit = 0.5; // radial gap from ID and OD
InnerShade = 6.0; // Shade walls around ring
OuterShade = 10.0;
ShadeWall = 4*ThreadWidth; // wall thickness
HolderID = RingID - 2*RingFit - 2*ShadeWall;
HolderOD = RingOD + 2*RingFit + 2*ShadeWall;
echo(str("Holder ID:",HolderID));
echo(str("Holder OD:",HolderOD));
LeadWidth = 4.0 + HoleWindage; // LED power lead hole
LeadTall = 2.0 + HoleWindage;
Protrusion = 0.1; // extend holes beyond surfaces for visibility
//---------------
// Create thread gripper and plate
module Mount() {
difference() {
union() {
translate([0,0,PlateThick])
cylinder(r=(MountOD/2 + HoleWindage),h=MountDepth);
cylinder(r=HolderOD/2,h=PlateThick);
}
translate([0,0,-Protrusion])
cylinder(r=MountID/2,h=(PlateThick + MountDepth + 2*Protrusion));
}
}
//----------------
// Create LED ring holder
module Ring() {
difference() {
union() {
cylinder(r=HolderOD/2,h=PlateThick);
translate([0,0,PlateThick]) {
difference() {
cylinder(r=HolderOD/2,h=OuterShade);
cylinder(r=(HolderOD/2 - ShadeWall),h=(OuterShade + Protrusion));
}
cylinder(r=(HolderID/2 + ShadeWall),h=InnerShade);
}
}
translate([0,0,-Protrusion])
cylinder(r=HolderID/2,h=(InnerShade + PlateThick + 2*Protrusion));
translate([(HolderOD/2 - ShadeWall/2),0,(PlateThick + ShadeWall/2 + LeadTall/2)]) {
scale([ShadeWall*2,LeadWidth,LeadTall])
rotate(a=[0,90,0])
cylinder(r=0.5,h=1.0,center=true,$fn=12);
}
}
}
//---------------
// Build what's needed
if (Build == "Mount") {
Mount();
}
else {
Ring();
}
This represents the first pass at un-constraining the X stage, so the poor little X axis stepper motor doesn’t have such a hard time of it and we can all get out of the sand-the-plywood-to-fit mindset. The Y stage has a similar mechanism, albeit with three bearings on the rod.
As seen from the front, the rear guide rod constrains the X stage in roll and yaw, while this Follower constrains pitch. The bearings turn in X, slide very slightly as needed in Y, and prevent motion in Z. Slight angle and distance mismatches between the rods no longer matter; I think the as-built (pre-sanding) rods will be sufficiently parallel for all practical purposes.
I have yet to install this, as I have a few other thing to do before tearing the entire XY assembly apart again; this is just a see-if-it-fits prototype:
Prototype X Axis rod follower
The front view:
X Axis follower – model front view
I wanted to mount it on the rear face of the X stage Idler plate, but there’s simply not enough room between the rod and the plywood Idler plate. Indeed, this version may be slightly too chubby for the space available in front of the Drive plate.
The OpenSCAD code produces a recess that clamps the belt into the drive serrations; the prototype doesn’t have that. The rear view shows the recess; I don’t know if that will build successfully. The dimple just below the top bearing bolt hole fits around the nut holding the build platform in place.
X Axis follower – model rear view
My Little Box o’ Tiny Bearings disgorged a pair of hard-inch bearings, but something along the lines of a 603 or 693 bearing would be better. Having shields on both sides would be a nice touch. The recently expanded table there gives some useful bearing dimensions.
The M3x12 bolts on the bearings cut their own threads on the way into the slightly undersized holes. I think that will be adequate, but you could sink nuts into the back.
The OpenSCAD source code will should auto-size the Follower around the bearings and your own measured / guesstimated clearances. Obviously, smaller bearings are better and there’s precious little clearance to the Y stage even with 3/8 inch OD bearings.
Make sure the extrusion settings near the top match your actual build values and that both collections match what the printer actually produces, because there’s not much room around the features for fill.
The top fits flush underneath the HBP stage to maintain proper alignment. That’s not really necessary, given the four bolts holding the Follower to the Drive plate, but there it is.
The Preload value adjusts the Z position of the lower bearing: + up, – down. It’s at zero for the prototype and the as-built Follower has 0.16 mm of preload: the bearings are 0.16 mm too close together. I think that’s OK, although I might dial it back a little bit by setting Preload=-0.1. For all I know, it’ll relax to fit and eventually wind up being marginally rattly.
The Build value at the top controls whether the model has the rods & bearings to show how it fits together (as above) or just the Follower block laid on its back for exporting to the STL file.
The OpenSCAD source:
// Thing-O-Matic X Stage rear guide rod follower
// Ed Nisley - KE4ZNU - Mar 2011
include </home/ed/Thing-O-Matic/lib/MCAD/units.scad>
Build = false; // set true to generate buildable layout
$fn = 8; // default for holes
// Extrusion values
// Use 2 extra shells behind the perimeter
// ... and 3 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
// Bearing dimensions
BearingOD = (3/8) * inch; // I used a hard-inch bearing -- try a 603 or 693
BearingID = (1/8) * inch;
BearingThick = (5/32) * inch;
BearingBoltDia = 3.0; // allow this to shrink: drill & tap the threads!
BearingBoltRadius = BearingBoltDia/2;
BearingStemOD = BearingBoltDia + 6*ThreadWidth;
BearingStemRadius = BearingStemOD/2;
BearingStemLength = 2.0;
// X guide rod dimensions
RodDia = (3/8) * inch; // hard inch rod
RodRadius = RodDia/2;
RodLength = 75; // for display convenience
RodClearTop = 12.6; // clearance from HBP to rod
RodClearSide = 9.0; // ... idler to rod
RodClearBottom = 10.7; // ... rod to Y stage
RodClearCirc = 1.5; // ... around circumference
// Drive mounting piece (from ABP teardown)
DriveHolesX = 16.0; // on-center distance
DriveHolesZ = 9.0; // on-center distance
DriveHoleZOffset = -5.0; // below bottom of HBP platform
DriveHeight = 28.0;
DriveBoltDia = 3.0 + HoleWindage; // bolt dia to hold follower in place
DriveBoltRadius = DriveBoltDia/2;
DriveBoltHeadDia = 6.0 + HoleWindage;
DriveBoltHeadRadius = DriveBoltHeadDia/2;
DriveBoltWeb = 4.5; // leave this on block for 12 mm bolts
HBPNutDia = 4.0; // HBP mounting nut in middle of idler
HBPNutRadius = HBPNutDia/2;
HBPNutRecess = 0.5; // ... pocket for corner of nut
HBPNutZOffset = -10.0; // ... below bottom of HBP platform
BeltWidth = 7.0; // drive belt slots
BeltThick = 1.2; // ... backing only, without teeth
BeltZOffset = -22.5; // ... below bottom of HBP platform
// Bearing locations
Preload = 0.0; // positive to add pressure on lower bearing
TopZ = RodRadius + BearingOD/2;
BottomZ = Preload - TopZ;
// Follower dimensions
BlockWidth = 28.0; // along X axis, must clear bolts in idler
BlockHeight = RodDia + 2*BearingOD - Preload;
BlockThick = (RodClearSide + RodRadius) - BearingThick/2 - BearingStemLength;
BlockHeightPad = RodClearTop - BearingOD;
echo(str("Block Height: ",BlockHeight));
echo(str("Block Height Pad: ",BlockHeightPad));
echo(str("Block Thick: ",BlockThick));
BottomPlateWidth = 10.0;
BottomPlateThick = 5.0;
BlockTop = RodRadius + RodClearTop;
BlockOffset = BlockThick/2 + BearingThick/2 + BearingStemLength;
// Construct the follower block with
module Follower() {
difference() {
union() {
translate([0,BlockOffset,0])
difference() {
union(){
cube([BlockWidth,BlockThick,BlockHeight],center=true);
translate([0,0,(BlockHeight + BlockHeightPad)/2])
cube([BlockWidth,BlockThick,BlockHeightPad],center=true);
}
for(x=[-1,1]) for(z=[0,1])
translate([x*DriveHolesX/2,
Protrusion/2,
(BlockHeight/2 + BlockHeightPad + DriveHoleZOffset - z*DriveHolesZ)])
rotate([90,0,0])
cylinder(r=DriveBoltRadius,
h=(BlockThick + Protrusion),
center=true);
for(x=[-1,1]) for(z=[0,1])
translate([x*DriveHolesX/2,
(-(DriveBoltWeb + Protrusion)/2),
(BlockHeight/2 + BlockHeightPad + DriveHoleZOffset - z*DriveHolesZ)])
rotate([90,0,0])
cylinder(r=DriveBoltHeadRadius,
h=(BlockThick - DriveBoltWeb + Protrusion),
center=true);
translate([0,
((BlockThick - BeltThick + Protrusion)/2),
(BlockHeight/2 + BlockHeightPad + BeltZOffset)])
cube([(BlockWidth + 2*Protrusion),
(BeltThick + Protrusion),
BeltWidth],center=true);
}
translate([0,BearingStemLength/2 + BearingThick/2,TopZ])
rotate([90,0,0])
cylinder(r=BearingStemRadius,h=BearingStemLength,center=true,$fn=10);
translate([0,BearingStemLength/2 + BearingThick/2,BottomZ])
rotate([90,0,0])
cylinder(r=BearingStemRadius,h=BearingStemLength,center=true,$fn=10);
}
translate([0,(BlockOffset - BearingStemLength/2),TopZ])
rotate([90,0,0])
cylinder(r=BearingBoltRadius,
h=(BlockThick + BearingStemLength + 2*Protrusion),
center=true);
translate([0,(BlockOffset - BearingStemLength/2),BottomZ])
rotate([90,0,0])
cylinder(r=BearingBoltRadius,
h=(BlockThick + BearingStemLength + 2*Protrusion),
center=true);
translate([0,
(BlockThick + BearingStemLength + BearingThick/2 - (HBPNutRecess - Protrusion)/2),
(BlockHeightPad + BlockHeight/2 + HBPNutZOffset)])
rotate([90,0,0])
cylinder(r=HBPNutRadius,h=(HBPNutRecess + Protrusion),center=true);
rotate([0,90,0])
cylinder(r=(RodRadius + RodClearCirc),h=RodLength,center=true,$fn=32);
}
}
// Arrange things for construction
if (Build)
translate([0,(-BlockHeightPad/2),(BlockOffset + BlockThick/2)])
rotate([-90,0,0])
Follower();
// Arrange things for convenient inspection
if (!Build) {
Follower();
translate([0,0,TopZ])
rotate([90,0,0])
#cylinder(r=BearingOD/2,h=BearingThick,center=true,$fn=32);
translate([0,0,BottomZ])
rotate([90,0,0])
#cylinder(r=BearingOD/2,h=BearingThick,center=true,$fn=32);
rotate([0,90,0])
#cylinder(r=RodDia/2,h=RodLength,center=true,$fn=32);
}
A bit of laparoscopic surgery on the front yard unearthed the drain line from the septic tank to the leach field. Drilling a 1-1/2 inch hole in the top of the pipe revealed that it’s 3/4 full of sludge, which is a Bad Thing: the leach field should get only liquid from the middle of the septic tank.
On the other paw, the house was built a bit over half a century ago and the records that came with it showed the tank was pumped two decades before we arrived. So it goes.
Rather than leave the hole in the pipe open until we get a new drain field, I built a plug that fit the 5 inch OD drain pipe and the 1-1/2 inch drilled hole.
Plug on aluminum plate
The aluminum build plate produces a smooth surface that’s entirely irrelevant on this part. The ABS film covers the blind hole in the middle that will serve as a drill guide in the unlikely event I must remove the plug.
Pipe plug – bottom view
I’ll admit it looks a bit out of place down there, though. I slobbered urethane adhesive around the central pillar and across the saddle, plugged it in, put a rock on top, and the adhesive foamed into a sludge-tight seal. At least I hope that’s how it worked out; I’m not going to pop it off just to find out.
Pipe plug in position
The solid model looks about like you’d expect:
Leach Pipe Plug Solid model
Never let it be said that a Thing-O-Matic lacks practical applications…
The OpenSCAD source:
// Plug for septic drain field pipe hole
// Ed Nisley - KE4ZNU - Mar 2011
include </home/ed/Thing-O-Matic/lib/MCAD/units.scad>
// Extrusion values
ThreadThickness = 0.33;
ThreadWT = 1.75;
ThreadWidth = ThreadThickness * ThreadWT;
HoleWindage = ThreadWidth; // enlarge hole dia by extrusion width
// Pipe dimensions
PipeOD = 5 * inch; // which is *4* inch cast iron pipe
PipeWall = (3/8) * inch;
PipeID = PipeOD - 2*PipeWall;
PipeLength = 2*PipeOD; // for ease of viewing
HoleDia = (1 + 1/2) * inch; // from a 1-1/2 inch hole saw
PatchOD = 2*HoleDia;
PatchThick = 10.0; // a burly patch for a big old pipe
DrillDia = (1/4) * inch; // pilot hole for removal, just in case
// Convenience settings
Protrusion = 0.1; // extend holes beyond surfaces for visibility
// The central plug
module PlugBody() {
difference() {
cylinder(r=HoleDia/2,h=(PipeOD/2 + PatchThick));
rotate([90,90,0])
cylinder(r=PipeID/2,h=PipeLength,center=true);
}
}
// The shell on the pipe
module PlugShell() {
difference() {
cylinder(r=PatchOD/2,h=(PipeOD/2 + PatchThick));
rotate([90,90,0])
cylinder(r=PipeOD/2,h=PipeLength,center=true);
}
}
// Build it, with rotate/translate to put it flat on its back
rotate([0,180,0])
translate([0,0,-(PipeOD/2 + PatchThick)])
difference() {
union() {
PlugBody();
PlugShell();
}
translate([0,0,PipeOD/2])
cylinder(r=DrillDia/2,h=(PatchThick + Protrusion));
}
While putting the HBP back together and stuffing it into the Thing-O-Matic, I did some weighing and measuring with the intent of finally putting numbers on the required motor torques.
The X stage weighs 114 g without the HBP heater and hardware. The aluminum build plates weigh 100 g each.
The assembled XY stages, HBP hardware, and two aluminum plates weigh about 1.1 kg.
The individual rods slide back and forth in their bearings with essentially no force at all; it’s less than the resolution of my pull scale. Call it 1 ounce = 0.3 N = 30 g.
After aligning the rods, I popped the X-stage HBP back in the Y stage, where I discovered I’d adapted the holes to suit the very-much-misaligned ABP’s rods. A bit of sanding freed up things up, but the final result was disappointing: sliding the X stage required about 0.75 pounds = 3.3 N = 340 g from my pull scale. Those rods remain over-constrained despite my best efforts.
The pull scale required less than 2 ounces = 0.6 N = 60 g to haul the Y stage back and forth after it was back in the Thing-O-Matic, so those ball bearings on the left-hand rod work really well. I must doodle up something similar for the X stage, for sure!
With the belts tensioned and the motors unplugged from the drivers, both the X and Y stages require about 2 pounds = 9 N = 0.9 kg of force to move. Those numbers depend strongly on belt tension, to the extent that the tension ought to be a measured quantity. The Y stage has some stiction that I guesstimate around 1.5 kg, but that’s not a reliable number.
So…
Moving a well-adjusted X stage requires 5 times more force than the Y stage. What it’s like for a built-as-shipped X stage boggles the mind.
With the belts more-or-less properly tensioned, the force jumps dramatically for both stages. The force required to move the Y stage dwarfs the bearing resistance. The force for a carefully adjusted X stage is about twice the bearing resistance.
The motor drive pulley has about 5 mm radius, so the torque to (slowly) move a 1 kg = 10 N load will be about 50 mN·m = 10 N × 0.005 m.
This torque-speed curve from the Kysan product information page for the 1123029 (aka 42BYG034-4.78) motor used in Cupcakes and Thing-O-Matics shows that the pull-in torque starts at 14 mN·m and goes downhill from there, as is customary for stepper motors:
Cupcake TOM Stepper Torque Curve
However, the “test conditions” apply 400 mA from a 24 V source.
In a Thing-O-Matic, the motor windings sport a 35 ohm resistance and are driven from a 12 V power supply. Ignoring voltage drops in wiring, current-sense resistors, and driver transistors, you cannot push more than 340 mA = 12 V / 35 Ω into the winding. The current is likely around 300 mA, after taking all those factors into account.
The REF pot on the stepper driver board has no magic properties. If the REF voltage is higher than about 0.6 V = 300 mA, then the driver can’t regulate the current. Increasing REF simply eliminates the microsteps around the current peaks: their reduced current values remain higher than the maximum possible motor current.
For example, the MBI instructions specify X and Y motor REF voltages of 1.5 V = 750 mA, a factor of 2.5 more than the motor can actually draw at 12 V. That means only microsteps that reduce the current below 40% of the maximum have any effect; in 1/8 step mode that means only 10 of the 32 microsteps reduce the current and the other 22 use 300 mA.
By and large, the X and Y motors run in L/R mode with no microstepping; that horrible sound you hear is the motors screaming in agony. All of the touted advantage of microstepping do not apply to these motors and drivers under these conditions.
Motor torque is roughly proportional to winding current, so the actual pull-in torque would be at most 3/4 of the amount shown in the graph: call it 10 mN·m.
Therefore, the torque required to move a Thing-O-Matic stage against the forces described above exceeds the motor’s pull-in torque rating by a factor of 5. That ignores the torque required to accelerate / decelerate the stage mass.
No wonder those poor motors lose steps at the slightest provocation!
The motor’s rated holding torque is 240 mN·m, which derates to 180 mN·m at 300 mA. If the motor runs slowly enough, it can drag the stage along step-by-step.
At 100 rev/min, the lowest speed on the torque-speed graph, the stage moves at:
I’ve been running my Thing-O-Matic at 40-50 mm/s, but that’s about the upper limit even after a whole bunch of careful adjustments. Now I understand why: these are the wrong motors for the job.
The motors operate at the ragged edge of their performance ratings even while moving at conservative feed rates. They probably produce more torque than their ratings, which is the only reason they work as well as they do. They’re certainly not suited for speeds over 50 mm/s, even if some folks have gotten them running up there; I could jog them at 70 mm/s with marginal reliability.
In addition, the very high winding resistance dissipates a tremendous amount of power that doesn’t contribute to turning the rotor: 3.2 W = (300 mA)2 × 35 Ω in each winding, 6.4 W for both. That’s derated very slightly by the few active microsteps, but it still makes for a rather toasty motor.
[Update: More brain fade. The motor max power spec equals a single winding at rated current times rated voltage. Derate the current in multiple windings so the total does not exceed that power.]
What’s needed is a NEMA 17 motor with decent pull-in torque, a few ohms of resistance per coil, and maybe a 1 A rating. Sort of like the one I’m using on the geared stepper extruder…
Having salvaged the sliding bearings from the ABP, I built up the HBP, stuck it into the Thing-O-Matic, and wasn’t in the least surprised to discover that it was mechanically jammed solid on the rods. This time, however, I wanted to measure the actual rod (mis)alignment to see what was going on.
Remember that, as described there, the X stage overconstrains the rods by forcing them through four bearings. It would be much better to use a pair of sliding bearings on one rod and a set of ball bearings rolling on the other, much as MBI did with the Y stage. Something involving 603 or 693 bearings, perhaps… there’s a scant 12 mm clearance from the top of the rod to the bottom of the HBP.
So I laid it upside down on the surface plate and tickled it with a scribe mounted in a surface gage. Of course, I’m doing it all wrong, but the results are close enough. What you can’t see are the two half-inch chrome-steel lathe bits supporting the platform; it may be warped a bit, but that’s part of what’s being measured.
Measuring HBP rod misalignment
I adjusted the scribe to just kiss the slip of waxed paper (0.02 mm) atop each end of each rod, which turns out to be surprisingly easy to do by feel.
Measuring rod height
Then eyeball the result on a scale.
Rod height on scale
One should tweak the surface gage until a dial test indicator reads zero, then stack up gage blocks to the same height. I actually hauled out my box o’ blocks before I came to my senses.
Anyhow.
The far rod was spot-on level and the front rod was off by 1 mm from one end to the other. They were within 0.2 mm of equal spacing horizontally, which was somewhat surprising given the amount of side sanding required to fit the ABP into Y stage.
Height
Right
Center
Left
Back
42.6
42.7
42.7
Front
43.5
43
42.5
Separation
39.93
39.72
I sanded out one of the holes, laid a bead of expanding urethane adhesive around the bearing housing, slid it into place, and then held the rod level with the tip of the scribe. The two random cylinders held the rods in the proper horizontal alignment.
Setting HBP rod alignment
When the glue cured, the rods were basically dead parallel in both planes.
Note the nuts epoxied on the bottom surface. That’s part of the cough precision platform alignment system…
After modifying the ABP to use an aluminum build plate, I’m going to junk it and modify a Heated Build Platform to get much more precise control over the plate alignment.
As with the ABP, the HBP instructions tell you to use short-headed bolts to clear the guide rod. There’s no need to do that if you take the time to modify the plywood clamps, as described there, so they actually clamp across the entire width of the belt, thusly: