Thing-O-Matic: X Axis Rod Follower

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
Prototype X Axis rod follower

The front view:

X Axis follower - model 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
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);

}

[Update: It’s installed and works wonderfully!]

[Update: You should use carmiac’s version, which prints better.]

27 thoughts on “Thing-O-Matic: X Axis Rod Follower

  1. For your next iteration, merge the rod follower part with whichever plywood part into one solid piece.

    1. Great idea! That would let it replace the Idler plate; I wouldn’t have to futz with the belt clamps.

      However, ABS has a glass transition temperature around 100 C, so the tabs sticking up into the plywood platform just below the heater might get a little more toasty than they should. I’d want to measure the temperature in there before assuming it’d Just Work.

      An advantage to a bolt-on widget attached to the Drive plate is that I don’t have to take the entire HBP apart again to install it; I’m getting really tired of taking this thing apart…

      1. Ed, Please supply a *.dxf file. I can use OpenSCAD and I have a workable 3D model of the very piece that your part attaches to. I would like to fashion a single piece for the bearings.

        Also – It would be safe for an ABS part to be below the HBP/ABP.

        Some items to note:

        * The heated built platform (HBP) termperatures are at/below the ABS melt temperature on most all prints.
        * Heat rises and would flow up, out and around the sides of the build plate.
        * The bottom plate of the HBP/ABP is plywood which is somewhat of an insulator from heat.
        * Air is a poor conductor of heat. The ~1/2″ of air space between the part and the 5mm insulating wood above the piece on the underside of the HBP should keep the part relatively quite cool. Safe from melt/warp.
        * For this proposed ABS part the area of near exposure is two small tabs and the rest of the subject part is beneath yet another 5mm insulating layer of plywood. Now the piece is more than 10mm insulation + ~1/2 air space away from the underside of a heat source On the v.2 ABP anyway.
        * Heat rises – again – The rising heat is displaced and would create a small localized vacuum drawing in cooler surrounding air which would come from below where the HBP/ABP is open to the Y-axis.

        Love your Stuff!

  2. Thoughts on letting the preload come from the weight of the platform? The belt might cause a problem there but one fewer bearing an no worries about printing it with perfect spacing.

    1. The thing needs two bearings, if only to keep the X stage from swinging freely the next time I turn the box up-side-down. The preload simply ensures that there’s no space for rattling… and to compensate for any size errors in the build.

      As it turns out, the two bearings went from that original 0.16 mm preload to a 0.07 mm gap, so (as you might expect) ABS isn’t dimensionally stable. It certainly makes no difference whatsoever in the final results… that minute gap is lost in the noise.

    1. Let me know how the Preload offset works out; I’d like to know how that’s behaving.

  3. I’ve printed and installed this on mine, big improvement on the resistance to motion. I had already cranked up the current on the x axis motor because it has caused me lots of headaches skipping steps in the past. I haven’t seen how low I can go now with it more properly built. I happened to have the same size bearings you used on my desk, I can’t even remember what I originally bought them for.

    Also I installed the larger y-axis nema 17 from ultimachine.com, that one now sounds musical compared to the grinding sound of the x-axis.

    I’d like to find a good replacement for that one, if we can find one that is short enough. The other option would be to raise the y-axis rods but then you would have lower the extruder and that seems like a decent amount of work.

    1. happened to have the same size bearings you used on my desk

      Ya gotta have stuff! [grin]

      I got a batch of 34 mm NEMA 17 steppers from the usual eBay source and have one installed on the X axis; the writeup should appear next week. Basically, using the right steppers for the job makes the printer run rapidly, quietly, and firmly. Highly recommended!

  4. I’m interested in seeing how fast we can push the feedrate without missing steps. With some kind of acceleration profile it would probably be rather higher but I don’t know that there is any drop in firmware and/or skein chain for the thing-o-matic that can handle acceleration I would go in on a bounty for that if others are interested.

    1. how fast we can push the feedrate without missing steps.

      After replacing the X & Y steppers (34 and 43 mm NEMA 17, about 2 ohm windings, 150 to 300 mNm pull-in torque, about 900 mA, details to follow), I just printed an octopus at 40 mm/s with 90 mm/s moves. The motors run dependably at 100 mm/s and are comfortably warm to the touch after a 35 minute printing session.

      That’s with no acceleration control at all, just the rubber-band effect of the belts moderating the initial jerk. Admittedly, my TOM has only a vague relation to stock MBI units at this point.

      The Reprap 5D firmware can evidently do all-axis blended acceleration. I have no idea how that fits in with the MBI hardware or what comes out of SF 40.

  5. Ed,

    Minor issue that I’m missing this

    include </home/ed/Thing-O-Matic/lib/MCAD/units.scad>

    from your source when rendering and, I think it’s either that file is missing or the Windows version of openscad is out of date?

    Getting these errors:

    Parsing design (AST generation)...
    Compiling design (CSG Tree generation)...
    WARNING: Ignoring unknown variable 'inch'.
    WARNING: Ignoring unknown variable 'inch'.
    WARNING: Ignoring unknown variable 'inch'.
    WARNING: Ignoring unknown variable 'inch'.
    ECHO: "Block Height: undef"
    ECHO: "Block Height Pad: undef"
    ECHO: "Block Thick: undef"
    Compilation finished.

    1. The missing MCAD library comes from Github. It’s a wonderful collection of more useful widgets than I’ll ever use…

      WordPress evidently eats anything unusual between angle brackets in its search for markup, so I tweaked your comment to make it more obvious what’s going on. It’s not clear to me what’s permitted in comments, because I seem to have weakly godlike editing powers that don’t apply when posting a comment.

    2. I had the same issue but it all stems from the inch definition, so you could also just add a line that says inch = 25.4 somewhere near the top

  6. Totally awesome ED. I like the idea of printing the part however I think I am going to go the route of milling it out. I’m really surprised MBI didn’t do this to begin with. When I first got the bot I wondered myself why they didn’t make it like the Y axis.

    This and replacement motors for the Y and X are a must!

    1. I thought about milling the follower out of aluminum, but one of the reasons I got this printer in the first place was to build close-to-net-size parts & prototypes. I’ll admit having to dismantle the printer to make the measurements, put it back together to make the part, and then tear it apart again to install the follower made me cast admiring glances at the Sherline!

      Print a prototype, see how well it fits, then chew on some aluminum…

      1. Yeah ill most definitely print one out its nice to have the object in hand quickly. But for the final one im gonna make it on the mill. I think I might mill this one out of acrylic or poly carbonate that I have around the shop, and see how well it holds up. Although ill probably endup making one out of aluminum too.

        1. Heres voting for polycarbonate above acrylic. I think acrylics biggest advantage is its strong suitability to laser cutting. Polycarbonate is much much tougher. That does increase the cutting forces involved very noticeably, but there are ways around that.

          1. Another vote for polycarbonate: acrylic is much too prone to shattering. I’ve cut acrylic parts with reasonable success, but all those folks with stress-cracked printer parts will tell you it’s not the right material for the job.

            Not to mention that acrylic disintegrates if you get threadlock on it… [sigh]

  7. Couln’t agree more about the polycarbonate. I just have boat loads of acrylic and wasn’t sure of the polycarbonate sheets thickness off the top of my head. Its something I was looking to do to the extruder parts as well. Iv seen all to many people have the stress fractures. I like the clear look but the acrylic isn’t happy up there with all that heat. Perhaps aluminum would look pretty sweet up there and then powder coated.

    1. then powder coated.

      See, now, around here I figure if it’s cool enough to touch and isn’t too slippery from cutting lube, it’s ready to bolt down and turn on…

    2. What? No pink anodized aluminum to compliment Ed’s original pink proto?

      1. You guys keep this up, I’m gonna buy me another pound o’ that pink stuff and make you suffer

Comments are closed.