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

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() {
		difference() {
			translate([0,0,(BlockHeight + BlockHeightPad)/2])
		  for(x=[-1,1]) for(z=[0,1])
						(BlockHeight/2 + BlockHeightPad + DriveHoleZOffset - z*DriveHolesZ)])
							h=(BlockThick + Protrusion),
			for(x=[-1,1]) for(z=[0,1])
						(-(DriveBoltWeb + Protrusion)/2),
						(BlockHeight/2 + BlockHeightPad + DriveHoleZOffset - z*DriveHolesZ)])
							h=(BlockThick - DriveBoltWeb + Protrusion),
					((BlockThick - BeltThick + Protrusion)/2),
					(BlockHeight/2 + BlockHeightPad + BeltZOffset)])
			cube([(BlockWidth + 2*Protrusion),
				 (BeltThick + Protrusion),

	  translate([0,BearingStemLength/2 + BearingThick/2,TopZ])
	  translate([0,BearingStemLength/2 + BearingThick/2,BottomZ])

	translate([0,(BlockOffset - BearingStemLength/2),TopZ])
				h=(BlockThick + BearingStemLength + 2*Protrusion),
	translate([0,(BlockOffset - BearingStemLength/2),BottomZ])
				h=(BlockThick + BearingStemLength + 2*Protrusion),

			  (BlockThick + BearingStemLength + BearingThick/2 - (HBPNutRecess - Protrusion)/2),
			  (BlockHeightPad + BlockHeight/2 + HBPNutZOffset)])
		cylinder(r=HBPNutRadius,h=(HBPNutRecess + Protrusion),center=true);

	  cylinder(r=(RodRadius + RodClearCirc),h=RodLength,center=true,$fn=32);


// Arrange things for construction

if (Build)
	translate([0,(-BlockHeightPad/2),(BlockOffset + BlockThick/2)])

// Arrange things for convenient inspection

if (!Build) {







  1. #1 by Carmiac on 2011-04-20 - 08:46

    Nice to hear that it works so well! I’ve been planning on installing this next time I do a XY teardown. Are you planning on posting the script up on Thingiverse?

    • #2 by Ed on 2011-04-24 - 18:02

      Nice to hear that it works so well!

      It’s easy to print, only moderately annoying to install, and definitely a win!

      Somebody must report back on how well it fits the ABP plastic frame. Perhaps removing the padding block I added to the top will work better in that situation.

      posting the script up on Thingiverse?

      I suppose I should, but I admit to not being particularly enthusiastic about starting Yet Another Spot for updates & discussion… I have enough trouble keeping up with stuff here!

      If you think it works well enough to add to your list of TOM updates, that should suffice.

      I thought I posted this comment earlier…

      You had. We’re just back from a week of the DC touristy thing after a spur-of-the-moment decision. My wrists thank me for seven days of not typing, but the first couple of cold-turkey days were rough.

      Now that you’ve had a post approved, your comments will appear automagically. Alas, I must moderate first posts to weed out spammers.

      • #3 by Carmiac on 2011-04-29 - 11:19

        I’ve made a few changes to the script to make the belt notch more printable. Basically, I just flipped it on its side and added supports for the bearing stems. I’d like to release my version on Thingiverse, but since it is almost entirely your work, I feel I should have your permission and input on licenses. I would, of course, link back here and give you credit as primary author.


  2. #5 by Andrew P on 2011-04-20 - 08:50

    Very nice! This is where having a second machine comes in handy, to use each to upgrade the other. ;-)

  3. #6 by Carmiac on 2011-04-29 - 16:37

    Great, it’s up at

    The bearing stem support was an easy trick. I just turned it into a partial cone instead of a cylinder, so the overhang angle wasn’t too big.

    Oh! It fits great into an ABP just as is.

    • #7 by Ed on 2011-04-29 - 17:06

      When I print it again, it’ll be your version on the platform!

  4. #8 by Joakim on 2011-05-03 - 16:46

    Can’t find “units.scad” include file.
    Did acuire some bearings in the sugesset size 3x8x4 – the dont match – therefore i neet the include file to be able to do the mod for the new bearings.


    • #9 by Ed on 2011-05-03 - 18:15

      That’s part of the invaluable MCAD collection that no OpenSCAD program should be without…

  5. #10 by Brian on 2011-05-03 - 20:43

    Ok- trouble coming. Please provide a *.dxf file. I can’t run OpenSCAD on my dynosaur abacus.

    • #11 by Ed on 2011-05-03 - 21:08

      Looks like it’s time to upgrade the abacus, because OpenSCAD tells me it can’t turn the Follower into a DXF file: “Current top level object is not a 2D object.”

  1. HBP + Aluminum Build Plate (Re)Alignment « The Smell of Molten Projects in the Morning
  2. Thing-O-Matic: X Axis Rod Follower « The Smell of Molten Projects in the Morning
  3. Thing-O-Matic: Stepper Motor Torture Test « The Smell of Molten Projects in the Morning
  4. Fastest Thing-O-Matic EVAH! « The Smell of Molten Projects in the Morning
  5. Stepper Driver Waveforms: Current Control | The Smell of Molten Projects in the Morning