-
Thing-O-Matic: X Axis Rod Follower Installed
The prototype X Rod Follower turned out to be pretty good fit, after I filed a slot in the back for the belt clamp. The bearings wound up 1.5 mm too close to the centerline, but a pair of #4 washers on each post solved that problem. The tweaked OpenSCAD source below should produce a drop-in replacement.

X Axis follower in place It’s important to center the bearings on the rod, because they’re designed to support only radial loads. In a normal application the bearings live in a slip-fit pocket that supports the entire outer race, but here an off-center point contact applies an axial force and misaligns the bearing races. They can’t handle axial forces at all: you (well, I) can easily feel the difference an axial millimeter makes.
With the follower in place, the force required to move the beltless X stage dropped from 0.75 pounds to zero: the stage slides back and forth across the entire length of the rods with a finger tap! The mechanical overconstraint on rods simply Went Away, pretty much as I expected.
[Update: In case it’s not obvious from the picture, you must remove both bronze bushings from the front of the X stage when you install this Follower. Leave the back pair in place.]
After installing and tensioning the drive belt, the stage still requires about 1 pound = 0.5 kg = 5 N to push along the rods, but now there’s no mechanical binding at any point along the way. That’s with the motor unplugged from the driver; you don’t want to count the effort required to light the LEDs!
Now, to reassemble and realign the rest of the build platform again.
The OpenSCAD source has only a few dimension numbers changed from the previous version, but here it is in one cut-n-paste lump:
[Update: You should use carmiac’s version, which prints better. The original code says “rear guide rod follower” but it turned out to fit better on the front of the X stage.]
// Thing-O-Matic X Stage front 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.7; // ... 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 + BearingStemLength + BearingThick/2; echo(str("Drive wall to rod center: ",BlockThick + BearingStemLength + BearingThick/2)); // 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); }