Posts Tagged M2

HP 7475A Plotter: Full-up Sakura Micron Pen Tests

The HP 7475A plotter comes with a transparent smoke-brown plastic flip-up lid covering the carousel and pen holder, presumably to keep dust and fingers out of the moving parts. That lid also has has the side effect of limiting the pen length, presumably because HP didn’t want the 7475A to eat into their large-format plotter market. In any event, removing the lid leaves another barrier to longer pens: the rugged plastic case between the carousel and the pen holder.

Well, seeing as how this puppy has been fully depreciated, a bit of pull saw work opened that opportunity:

HP 7475A - long pen case cut

HP 7475A – long pen case cut

Despite appearances, all six Sakura Micron pens emerge vertical & parallel from their adapters in the carousel:

HP 7475A - Sakura 01 and 005 pens in carousel

HP 7475A – Sakura 01 and 005 pens in carousel

They pass neatly through the new channel:

HP 7475A - cover mod for long pens

HP 7475A – cover mod for long pens

And produce reasonable lines, with motion blur catching the pen holder in the midst of a pen-up / pen-down twitch:

HP7475A - Sakura Micro Pen Adapter - self-test plot

HP7475A – Sakura Micro Pen Adapter – self-test plot

That’s from an earlier test, before I sawed the slot in the case, with all the machinery behind the pen holder in full view.

The test plot, with the proper pen colors and widths loaded in the carousel, looks pretty good:

HP7475A - Sakura Micro Pens - self-test plot

HP7475A – Sakura Micro Pens – self-test plot

The pen holder wasn’t intended to support a long pen, so that shaft tends to torque the pen tip out of position, particularly while drawing characters:

HP 7475A - long black pen - misalignment

HP 7475A – long black pen – misalignment

The various pen tips don’t all point to the same place:

HP 7475A - long RGBK pen misalignment

HP 7475A – long RGBK pen misalignment

That could be non-concentric pen adapters, misalignment in the pen holder, or slightly off-center pen nibs. The offsets between the colors remains consistent in all the bar-chart columns, so the pen adapters aren’t shifting in the holder.

The worst-case error between bar-chart rectangles amounts to 0.5 mm parallel to the pen holder motion and 0.8 mm parallel to the paper motion. In round numbers, the pen tip is 30 mm from the flange, so moving it 0.5 mm to the side tips the pen 1°. The flange is 17 mm OD, which means a 1° tilt raises one edge by 0.3 mm or both edges by ±0.15 mm. Given a 0.25 mm 3D printed thread thickness, that’s certainly within reach of a random plastic blob.

Looking closely at the printed-and-glued flange shows plenty of room for misunderstanding betwixt pen and holder, even after cleaning off all that PETG hair:

HP7475A - Sakura Micro Pen Adapter - vs HP pen

HP7475A – Sakura Micro Pen Adapter – vs HP pen

Given that the Sakura pens aren’t intended for this application, a slight tip misalignment due to body molding tolerances isn’t unreasonable; a perfect adapter might not solve the problem.

The HP maintenance manual lists a BASIC program to produce a test plot that verifies pen alignment, although the prospect of transliterating 2+ pages of quoted strings from a scanned document doesn’t fill me with desire.

, ,

7 Comments

HP 7475A Plotter: Sakura Micron Pen Adapter

More digital caliper work produced this model of a Sakura Pigma Micron pen:

HP7475A - Sakura Micro Pen Body - solid model

HP7475A – Sakura Micron Pen Body – solid model

It’s much shorter than the actual pen, because there’s nothing happening beyond the top of the original HP pen body that will serve as an adapter holding this pen in the plotter. As before, the tip of the pen is at Z=0.

Some of the diameter values include a small Finagle Constant to provide a close sliding fit:

//-- Sakura Micron fiber-point pen

ExpRP = 0.15;						// expand critical sections (by radius)

//-- pen locates in holder against end of outer body

PenOutline = [
	[0,0],							//  0 fiber pen tip
	[0.6/2,0.0],[0.6/2,0.9],		//  1  ... cylinder
	[1.5/2,0.9],[1.5/2,5.3],		//  3 tip surround
	[4.7/2,5.8],					//  5 chamfer
	[4.9/2,12.3],					//  6 nose
//	[8.0/2,12.3],[8.0/2,13.1],		//  7 latch ring
//	[8.05/2,13.1],[8.25/2,30.5],	//  9 actual inner body
	[8.4/2 + ExpRP,12.3],[8.4/2 + ExpRP,30.5],	//  7 inner body - clear latch ring
	[9.5/2 + ExpRP,30.5],			//  9 outer body - location surface!
	[9.8/2 + ExpRP,50.0],			// 10 outer body - length > Body
	[7.5/2,50.0],					// 11 arbitrary length
	[7.5/2,49.0],					// 12 end of reservoir
	[0,49.0]						// 13 fake reservoir
	];

PenNose = PenOutline[6];
PenLatch = PenOutline[7];

PenOAL = PenOutline[11][HEIGHT];

The model excludes the latching ring that secures the pen cap, mostly because the fit was already snug enough.

Subtracting the Sakura pen from the HP pen body produces the adapter:

HP7475A - Sakura Micro Pen Adapter - solid model

HP7475A – Sakura Micro Pen Adapter – solid model

The plug floating overhead and the cap standing on the bottom are frills that I added after the first few iterations. The plug seals the cut-off sections of the pen body, assuming that you will cut the pens to a more plotter-friendly length, and you’ll need two of them… a fact that didn’t penetrate my thick skull until I was confronted with the two ends of a cut-up pen. The flange on the bottom of the cap provides enough of a grip that you can actually pull the cap off; depending on the tolerances, it will be a very tight fit on the pen.

The solid model pieces rearranged for printing:

HP7475A - Sakura Micro Pen Adapter - build layout

HP7475A – Sakura Micro Pen Adapter – build layout

As before, splitting the HP pen body in the middle of the flange makes it build-able without supports. The first few passes didn’t include any of the other parts and had a slightly longer lower section (left front):

HP7475A - Sakura Micro Pen Adapter - on platform

HP7475A – Sakura Micro Pen Adapter – on platform

I used Sakura Micron pens because they’re slightly smaller than my usual Sharpie Ultra Fine Point pens; Mary had been sketching quilting patterns with them. The difference between the Sakura and HP pen ODs amounts to barely more two filament widths, less than 1 mm:

HP 7475A - Sakura Pen Adapter - Slic3r Preview

HP 7475A – Sakura Pen Adapter – Slic3r Preview

Fortunately, Slic3r can dynamically adjust the thread width to eliminate voids between parallel outer walls with less than a thread width between them.

The interior step near the bottom of the part at the rear right in the picture locates the Sakura pen body inside the HP shell. In principle, that will put the tip at the same location as the HP pen tip, although making that happen required a bit of measurement fine-tuning:

HP7475A - Sakura Micro Pen Adapter - vs HP pen

HP7475A – Sakura Micro Pen Adapter – vs HP pen

I started out gluing the adapter halves together around a Sakura pen serving as a mandrel, but that didn’t work out well:

HP7475A - Sakura Micro Pen Adapter - gluing on pen

HP7475A – Sakura Micro Pen Adapter – gluing on pen

Although the IPS 4 adhesive didn’t attack the pen body, getting all the parts flying in formation required more dexterity than I could muster, plus that tape snippet didn’t seal the tip well at all. After doing a few adapters like that, I broke down and machined a steel mandrel with diameters matching the Sakura pen:

HP7475A - Sakura Micro Pen Adapter - mandrel

HP7475A – Sakura Micro Pen Adapter – mandrel

No, you can’t 3D print the mandrel.

You can see the discontinuities in the adapter shell, showing the internal step (in the right half) and the transition from 3D Honeycomb infill (just left of the flange) to a single thread of infill between the two outer walls (the rest of the left half).

After a few iterations, a full-length pen in an adapter produced some rather good-looking lines, if I do say so myself:

HP7475A - Sakura Micro Pen Adapter - first lines

HP7475A – Sakura Micro Pen Adapter – first lines

That’s done in Etch A Sketch mode with the plotter’s front-panel buttons. The blob under the pen tip shows why you can’t let the pen linger on the paper for more than an instant…

But, hey, it worked!

The OpenSCAD source code is in the HP pen body post.

8 Comments

HP 7475A Plotter: OEM Pen Body Model

You can buy new plotter pens for HP 7475A plotters at a bit over four bucks apiece and new-old-stock HP pens appear on eBay with similar prices, but what’s the fun in that?

You can refill the HP pens with liquid ink and continue plotting until the fiber tip wears out. That would limit me to the CMYK inkjet inks on the shelf, although I suppose investing in drafting inks might be amusing.

You can get refillable Koh-I-Noor pens and adapters, intended for specialized paper / vellum, at nearly $100 all-in per pen, plus ink & supplies, plus a hassle factor exceeding that of the continuous flow ink system on the Epson R380.

However, it should be feasible to build an adapter to hold an ordinary, albeit skinny, drawing / drafting pen, perhaps chopped down to be only a bit longer than the OEM plotter pens. That has the advantage of using cheap & readily available materials, doesn’t require much capital outlay, and, come to think of it, gives me a Digital Machinist column topic… [grin]

This is not, by any stretch of the imagination, a novel idea.

There’s a vague notion of converting the plotter into a vinyl / paper / stencil cutter, although I expect the snap-in pen holder can’t exert enough lateral force to hold a cutting knife in position, nor enough downward force to push the blade through the vinyl / paper / whatever. But ya never know until you try.

So, we begin…

A bit of digital caliper work provides a list of points defining the OEM pen body outline:

RADIUS = 0; // subscript for radius values
HEIGHT = 1; // ... height above Z=0

BodyOutline = [						// X values = (measured diameter)/2, Y as distance from tip
	[0.0,0.0],						//  0 fiber pen tip
//	[2.0/2,1.4],					//  1 ... taper (not buildable)
	[1.0/2,0.005],					//  1 ... faked point to remove taper
	[2.0/2,0.0],[2.0/2,2.7],		//  2 ... cylinder
	[3.7/2,2.7],[3.7/2,4.45],		//  4 tip surround
	[4.8/2,5.2],					//  6 chamfer
	[6.5/2,11.4],					//  7 rubber seal face
	[8.9/2,11.4],					//  8 cap seat
	[11.2/2,15.9],					//  9 taper to body
	[11.5/2,28.0],					// 10 lower body
	[13.2/2,28.0],[16.6/2,28.5],	// 11 lower flange = 0.5
	[16.6/2,29.5],[13.2/2,30.0],	// 13 flange rim = 1.0
	[11.5/2,30.0],					// 15 upper flange = 0.5
	[11.5/2,43.25],					// 16 upper body
	[0.0,43.25]						// 17 lid over reservoir
	];

Rather than computing the radius by hand, it’s easier to just divide the easily measured diameter by two and be done with it.

The point array defines a polygon in the XY plane:

HP7475A - HP Plotter Pen Body - plane polygon

HP7475A – HP Plotter Pen Body – plane polygon

Then you feed that polygon into a rotate_extrude(), which spins up a reasonable simulacrum of a plotter pen:

HP7475A - HP Plotter Pen Body - solid model

HP7475A – HP Plotter Pen Body – solid model

I picked the coordinates to put the tip at (0,0,0) and converted the tapered fiber nib into a plain cylinder.

That shape is obviously impossible to print without vast amounts of support, but splitting it across the middle of the flange and rearranging the pieces works just fine:

HP7475A - HP Plotter Pen Body - build layout

HP7475A – HP Plotter Pen Body – build layout

A pair of alignment pin holes simplifies gluing the parts back together:

HP7475A - HP Plotter Pen Body - solid model - bottom

HP7475A – HP Plotter Pen Body – solid model – bottom

There’s a subtle problem lurking in that flange, which is 2.0 mm thick at the base and 1.0 mm thick at the rim. Splitting it in half requires each part to build correctly from an integral number of thread layers, so you must use a thread thickness (that’s in the Z direction) that divides evenly into the required height. I’ve been using 0.2 mm, which would produce a 1.2 mm rim.

Slicing at 0.25 mm produced a 2.1 mm flange with a 1.1 mm rim, suggesting that:

I could apply a Slic3r Modifier Mesh to print the flange with 0.10 mm layers, but that seems like entirely too much effort right now.

At the other end of the model, converting the tapered tip into a blunt cylinder didn’t save it from melting down:

HP 7475A Plotter Pen - solid PETG

HP 7475A Plotter Pen – solid PETG

It might be possible to reduce the printing speed enough to produce that tiny cylinder, but I needed just the upper body to verify that it fit correctly into the carousel:

HP 7475A Plotter Pen Body - in carousel

HP 7475A Plotter Pen Body – in carousel

As you’d expect, the rubber boots that used to seal the pen tips have long since rotted out:

HP 7475A Carousel Rubber Boots

HP 7475A Carousel Rubber Boots

You can find sources for those boots, but at $252 (marked down to $144!) each, perhaps it’d be more feasible to gimmick up a two-part mold and cast silicone rubber duplicates; I could sell a set of six for $200 and get rich. Heck, I could even undercut their $40.32 two-year protection plan by a considerable margin.

Anyhow, the pen holder plucked it out of the carousel just like a real HP pen:

HP 7475A Plotter Pen Body - in holder

HP 7475A Plotter Pen Body – in holder

Note that the carousel and pen holder contact the flange and the cylindrical body, not either of the tapered sections down to the tip. That means I can carve away the entire bottom part of the body to make a drawing pen adapter…

The OpenSCAD source code includes a bunch of features & parts I’ll describe in the next few posts, but which certainly should not be regarded as final copy:

// HP7475A plotter pen adapters
// Ed Nisley KE4ZNU April 2015

Layout = "BuildBody";		// ShowKnife BuildKnife KnifeAdapter
							// ShowPen BuildPen Plug
							// ShowBody BuildBody
							// Pen Knife
							// Stabilizer BuildStabilizer

//- Extrusion parameters must match reality!

ThreadThick = 0.25;
ThreadWidth = 0.40;

HoleWindage = 0.2;

Protrusion = 0.1;			// make holes end cleanly

inch = 25.4;

function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);

//----------------------
// Dimensions
// Z=0 at pen tip!

NumSides = 8*4;						// number of sides on each "cylinder"

RADIUS = 0;							// subscript for radius values
HEIGHT = 1;							//   ... height above Z=0

//-- Original HP plotter pen, which now serves as a body for the actual pen

BodyOutline = [						// X values = (measured diameter)/2, Y as distance from tip
	[0.0,0.0],						//  0 fiber pen tip
//	[2.0/2,1.4],					//  1 ... taper (not buildable)
	[1.0/2,0.005],					//  1 ... faked point to remove taper
	[2.0/2,0.0],[2.0/2,2.7],		//  2 ... cylinder
	[3.7/2,2.7],[3.7/2,4.45],		//  4 tip surround
	[4.8/2,5.2],					//  6 chamfer
	[6.5/2,11.4],					//  7 rubber seal face
	[8.9/2,11.4],					//  8 cap seat
	[11.2/2,15.9],					//  9 taper to body
	[11.5/2,28.0],					// 10 lower body
	[13.2/2,28.0],[16.6/2,28.5],	// 11 lower flange = 0.5
	[16.6/2,29.5],[13.2/2,30.0],	// 13 flange rim = 1.0
	[11.5/2,30.0],					// 15 upper flange = 0.5
	[11.5/2,43.25],					// 16 upper body
	[0.0,43.25]						// 17 lid over reservoir
	];

TrimHeight = BodyOutline[9][HEIGHT];		// cut off at top of lower taper
SplitHeight = (BodyOutline[11][HEIGHT] + BodyOutline[14][HEIGHT])/2;	// middle of flange

FlangeOD = 2*BodyOutline[13][RADIUS];
FlangeTop = BodyOutline[15][HEIGHT];

BodyOD = 2*BodyOutline[16][RADIUS];
BodyOAL = BodyOutline[17][HEIGHT];

echo(str("Trim: ",TrimHeight));
echo(str("Split: ",SplitHeight));

BuildSpace = FlangeOD;

//-- Sakura Micron fiber-point pen

ExpRP = 0.15;						// expand critical sections (by radius)

//-- pen locates in holder against end of outer body

PenOutline = [
	[0,0],							//  0 fiber pen tip
	[0.6/2,0.0],[0.6/2,0.9],		//  1  ... cylinder
	[1.5/2,0.9],[1.5/2,5.3],		//  3 tip surround
	[4.7/2,5.8],					//  5 chamfer
	[4.9/2,12.3],					//  6 nose
//	[8.0/2,12.3],[8.0/2,13.1],		//  7 latch ring
//	[8.05/2,13.1],[8.25/2,30.5],	//  9 actual inner body
	[8.4/2 + ExpRP,12.3],[8.4/2 + ExpRP,30.5],	//  7 inner body - clear latch ring
	[9.5/2 + ExpRP,30.5],			//  9 outer body - location surface!
	[9.8/2 + ExpRP,50.0],			// 10 outer body - length > Body
	[7.5/2,50.0],					// 11 arbitrary length
	[7.5/2,49.0],					// 12 end of reservoir
	[0,49.0]						// 13 fake reservoir
	];

PenNose = PenOutline[6];
PenLatch = PenOutline[7];

PenOAL = PenOutline[11][HEIGHT];

PlugOutline = [
	[0,0],							// 0 center of lid
	[9.5/2,0.0],[9.5/2,1.0],		// 1 lid rim
	[7.8/2,1.0],					// 3 against end of pen
	[7.3/2,6.0],					// 4 taper inside pen
	[5.3/2,6.0],					// 5 against ink reservoir
	[4.0/2,1.0],					// 6 taper to lid
	[0.0,1.0]						// 7 flat end of taper
	];

PlugOAL = PlugOutline[5][HEIGHT];

//   cap locates against end of inner body at latch ring
//-- cap origin is below surface to let pen tip be at Z=0

CapGap = 1.0;						// gap to adapter body when attached
CapGripHeight = 2.0;				// thickness of cap grip flange
CapTipClearance = 1.0;				// clearance under fiber tip

CapOffset = -(CapGripHeight + CapTipClearance);	// align inside at pen tip Z=0

CapOutline = [
	[0,CapOffset],									// 0 base
	[FlangeOD/2,CapOffset],							// 1 finger grip flange
	[FlangeOD/2,CapOffset + CapGripHeight],			// 2  ... top
	[BodyOD/2,CapOffset + CapGripHeight],			// 3 shaft
	[BodyOD/2,TrimHeight - CapGap],					// 4  ... top with clearance
	[PenLatch[RADIUS],TrimHeight - CapGap],			// 5 around pen latch ring
	[PenLatch[RADIUS],PenNose[HEIGHT]],				// 6  ... location surface!
	[PenNose[RADIUS] + ExpRP,PenNose[HEIGHT]],		// 7 snug around  nose
	[PenNose[RADIUS] + ExpRP,-CapTipClearance],		// 8 clearance around tip
	[0,-CapTipClearance],							// 9  ... bottom
	];

//-- Drag knife holder

ExpRK = 0.30;						// expand critical sections (by radius)
AdjLen = 2.0;						// allowance for adjustment travel

KnifeOutline = [
	[0,0],							//  0 blade point (actually 0.25 mm offset)
	[1.0/2,0.0],					//  1  ... blunt end
	[1.0/2,4.0],					//  2  ... cylinder
	[2.0/2,4.0],					//  3 shank
	[2.0/2,5.9],					//  4  .. at bearing
	[6.0/2,5.9],					//  5 holder - shell
	[7.3/2 + ExpRK,8.3],			//  6 holder - taper to body
	[7.3/2 + ExpRK,21.0 - AdjLen],	//  7 holder body
	[8.8/2 + ExpRK,22.0 - AdjLen],	//  8 holder - threads bottom
	[8.8/2 + ExpRK,25.0],[9.0/2 + ExpRK,26.0],		//  9 clear threads to reduce friction
	[9.0/2 + ExpRK,32.0],[8.8/2 + ExpRK,33.0],		// 11  ... end clearance
	[8.8/2 + ExpRK,42.5 - AdjLen],	// 13 holder - threads top = locknut bottom
	[12.5/2,42.5 - AdjLen],			// 14 knurled locknut - adjustment travel
	[12.5/2,45.8],					// 15 knurled locknut - top
	[11.0/2,45.8],					// 16 holder - adjusting knurl
	[11.0/2,52.0],					// 17 holder - top surface
	[3.0/2,52.0],[3.0/2,57.2],		// 18 spring post
	[0.0,57.2]						// 19 end of post
	];

ThreadLength = KnifeOutline[13][HEIGHT] - KnifeOutline[8][HEIGHT];

//-- Plotter pen holder stabilizer

HolderPlateThick = 3.0;				// thickness of plate atop holder
RimHeight = 5.0;					// rim around sides of holder
RimThick = 2.0;

HolderOrigin = [17.0,12.2,0.0];		// center of pen relative to polygon coordinates

HolderZOffset = 30.0;				// top of holder in pen-down position
HolderTopThick = 1.7;				// top of holder to top of pen flange
HolderCylinderLength = 17.0;		// length of pen support structure

HolderKnifeOffset = -2.0;			// additional downward adjustment range (not below top surface)

LockScrewInset = 3.0;				// from right edge of holder plate
LockScrewOD = 2.0;					// tap for 2.5 mm screw

// Beware: update hardcoded subscripts in Stabilizer() when adding / deleting point entries 

HolderPlate = [
	[8.6,18.2],[8.6,23.9],			// 0 lower left corner of pen recess
	[13.9,23.9],[13.9,30.0],		// 2
//	[15.5,30.0],[15.5,25.0],		// 4 omit middle of support beam
//	[20.4,25.0],[20.4,30.0],		// 6
	[22.7,30.0],[22.7,27.5],		// 4
	[35.8,27.5],[35.8,20.7],		// 6 spring box corner
	[43.0,20.7],					// 8
	[31.5,0.0],						// 9
//	[24.5,0.0],[24.5,8.0],			// 10 omit pocket above pen clamp
//	[22.5,10.0],[22.5,16.5],		// 12
//	[20.5,18.2]						// 14
	[13.6,0.0],						// 10
	[8.6,5.0]						// 11
	];

BeamWidth = HolderPlate[4][0] - HolderPlate[2][0];

//----------------------
// Useful routines

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);
}

//- Locating pin hole with glue recess
//  Default length is two pin diameters on each side of the split

PinOD = 1.75;
PinOC = BodyOD / 2;

module LocatingPin(Dia=PinOD,Len=0.0) {

	PinLen = (Len != 0.0) ? Len : (4*Dia);

	translate([0,0,-ThreadThick])
		PolyCyl((Dia + 2*ThreadWidth),2*ThreadThick,4);

	translate([0,0,-2*ThreadThick])
		PolyCyl((Dia + 1*ThreadWidth),4*ThreadThick,4);

	translate([0,0,-(Len/2 + ThreadThick)])
		PolyCyl(Dia,(Len + 2*ThreadThick),4);

}

module LocatingPins(Length) {
	for (i=[-1,1])
	translate([0,i*PinOC/2,0])
		rotate(180/4)
		LocatingPin(Len=Length);
}

//----------------------
// Basic shapes

//-- HP plotter pen body

module Body() {
	render(convexity=3)
		rotate_extrude($fn=NumSides)
			polygon(points=BodyOutline);
}

//-- HP plotter pen holder
//   the trim block offsets use magic numbers from the HolderPlate outline

module Stabilizer() {

	difference() {
		union() {
			translate(-HolderOrigin)													// put center of pen at origin
				difference() {
						render(convexity=4)
						linear_extrude(height=(HolderPlateThick + RimHeight))			// overall flange around edges
							offset(r=RimThick)
									polygon(points=HolderPlate);

						render(convexity=4)
						translate([0,0,-Protrusion])									// recess for pen holder plate
							linear_extrude(height=(RimHeight + Protrusion))
								polygon(points=HolderPlate);

						translate([HolderPlate[7][0] - Protrusion,HolderPlate[7][1] - Protrusion,-Protrusion])	// trim spring box from top plate
							cube([30,20,(RimHeight + HolderPlateThick + 2*Protrusion)]);

						translate([27.0,HolderPlate[6][1] - Protrusion,-Protrusion])	// trim pivot plate clearance
							cube([30,20,(RimHeight + HolderPlateThick + 2*Protrusion)]);

						translate([HolderPlate[2][0],20,-Protrusion])					// trim left support beam
							cube([BeamWidth,20,(RimHeight + Protrusion)]);

						translate([HolderPlate[9][0] - LockScrewInset,RimThick,RimHeight - HolderTopThick - LockScrewOD/2])												// lock screw on front edge
							rotate([90,0,0])
								rotate(180/4)
									PolyCyl(LockScrewOD,3*RimThick);					// hold-down screw hole
				}

			translate([0,0,(RimHeight - HolderCylinderLength + Protrusion)])
				cylinder(d=BodyOD,h=HolderCylinderLength + Protrusion,$fn=NumSides);				// surround knife threads
		}

		translate([0,0,-HolderZOffset + HolderKnifeOffset])
			Knife();
	}
}

//-- Sakura drawing pen body

module Pen() {
	rotate_extrude($fn=NumSides)
		polygon(points=PenOutline);
}

//-- Plug for top of Sakura pen

module Plug() {
	render(convexity = 2)
		rotate_extrude($fn=NumSides)
			polygon(points=PlugOutline);
}

//-- Cap for tip of Sakura pen

module Cap() {
	render(convexity = 2)
		rotate_extrude($fn=NumSides)
			polygon(points=CapOutline);
}

//-- Sakura pen adapter

module PenAdapter(TrimZ = false) {

Trans = TrimZ ? - TrimHeight : 0;

	render(convexity=5)
		translate([0,0,Trans])
			difference() {
				Body();
				Pen();
				translate([0,0,TrimHeight/2])
					cube([2*FlangeOD,2*FlangeOD,TrimHeight],center=true);
			}
}

//-- Roland knife body

module Knife() {
	render(convexity=3)
		rotate_extrude($fn=NumSides)
			polygon(points=KnifeOutline);
}

//-- Roland knife adapter

module KnifeAdapter(TrimZ = false) {

Trans = TrimZ ? - TrimHeight : 0;

	render(convexity=5)
		translate([0,0,Trans])
			difference() {
				Body();
				Knife();
				translate([0,0,TrimHeight/2])
					cube([2*FlangeOD,2*FlangeOD,TrimHeight],center=true);
			}
}

//----------------------
// Build it

if (Layout == "Pen")
	Pen();

if (Layout == "Knife")
	Knife();

if (Layout == "Stabilizer")
	Stabilizer();

if (Layout == "ShowBody")
	Body();

if (Layout == "BuildBody")
	difference() {
		union() {
			translate([BuildSpace,0,-SplitHeight])
				Body();
			rotate([180,0,0])
				translate([-BuildSpace,0,-SplitHeight])
					Body();
		}
		translate([0,0,-BodyOAL])
			cube(2*BodyOAL,center=true);
		for (i = [-1,1])
			translate([i*BuildSpace,0,0])
				LocatingPins(5.0);
	}

if (Layout == "Plug")
	Plug();

if (Layout == "KnifeAdapter")
	KnifeAdapter();

if (Layout == "ShowPen") {

	color("AntiqueWhite") {
		Pen();
		translate([-1.5*BodyOD,0,0])
			Pen();
	}
	color("Magenta",0.35) {
		translate([0,0,PlugOAL + PenOAL + 3.0])
			rotate([180,0,0])
				Plug();
		PenAdapter();
		Cap();
	}
	color("Magenta") {
		translate([1.5*BodyOD,0,PlugOAL + PenOAL + 3.0])
			rotate([180,0,0])
				Plug();
		translate([1.5*BodyOD,0,0]) {
			PenAdapter();
			Cap();
		}
	}

}

if (Layout == "ShowKnife") {

	color("Goldenrod") {
		Knife();
		translate([-1.5*BodyOD,0,0])
			Knife();
	}
	color("Magenta",0.35)
		KnifeAdapter();
	color("Magenta") {
		translate([1.5*BodyOD,0,0])
			KnifeAdapter();
	}

}

if (Layout == "BuildPen") {

	translate([0,BuildSpace/2,0])
		Plug();
	translate([0,-BuildSpace/2,-CapOffset])
		Cap();

	difference() {
		union() {
			translate([BuildSpace,0,-SplitHeight])
				PenAdapter(false);
			rotate([180,0,0])
				translate([-BuildSpace,0,-SplitHeight])
					PenAdapter(false);
		}
		translate([0,0,-BodyOAL])
			cube(2*BodyOAL,center=true);
	}

}

if (Layout == "BuildKnife") {

	difference() {
		union() {
			translate([BuildSpace,0,-SplitHeight])
				KnifeAdapter(false);
			rotate([180,0,0])
				translate([-BuildSpace,0,-SplitHeight])
					KnifeAdapter(false);
		}
		translate([0,0,-BodyOAL])
			cube(2*BodyOAL,center=true);
	}

}

if (Layout == "BuildStabilizer") {

	translate([0,0,(HolderPlateThick + RimHeight)])
		rotate([0,180,0])
			Stabilizer();
}

,

10 Comments

Tour Easy Rear Fender Bracket

I’d originally secured the rear fender to the steel strap connecting the chainstays on Mary’s Tour Easy with a cable tie: small, simple, light weight, reliable. Unfortunately, that put the end of the fender just slightly lower than the strap and, I fear, sprayed water all over the strap, where it worked its way through a paint flaw and rusted the steel under the paint. A simple metal clip would chew its way through the pain[t] on the strap, so, seeing as how we’re living in the future…

The C-shaped block on the top grips the steel cross-strap, the trough fits the fender’s curve, the little spider supports the inside of the nut recess, and a pair of alignment pin holes (one visible) help during gluing:

Tour Easy Rear Fender Bracket - solid model - show

Tour Easy Rear Fender Bracket – solid model – show

Although it’s tempting to 3D print both parts as a single unit, laying them out like this aligns the threads for best strength in each piece:

Tour Easy Rear Fender Bracket - solid model - build

Tour Easy Rear Fender Bracket – solid model – build

Pressing the bracket on the glass slab (flat side up, nubblies on the bottom) with the clamps in place finished the job. The slightly crushed support spider from the nut recess sits in the foreground:

Tour Easy rear fender bracket - gluing

Tour Easy rear fender bracket – gluing

Magenta PETG matches the red Tour Easy paint surprisingly well:

Tour Easy - rear fender bracket - installed - top

Tour Easy – rear fender bracket – installed – top

From below, you can see why the top block can’t extend all the way to the bottom of the fender mount:

Tour Easy rear fender bracket - installed

Tour Easy rear fender bracket – installed

That rubber boot needs replacing in the worst possible way, but I didn’t have anything suitable on hand and wouldn’t dismount that cable even if I had; cables never go back on properly.

Alas, because the brakes weren’t mounted when I did the measurements, I had to build one to find out why a long block wouldn’t work:

Tour Easy rear fender bracket - long back

Tour Easy rear fender bracket – long back

The screw atop the block (on the left in that picture) presses a small plastic slug against the steel strap, in the hopes it won’t chew through the paint quite as rapidly. The screws & nuts are stainless, so at least they’ll survive for a while.

The curve in the trough comes from the chord equation applied to these crude measurements:

Tour Easy Rear Fender Bracket - measurement doodle

Tour Easy Rear Fender Bracket – measurement doodle

Fortunately, it’s tucked into a spot where nobody ever looks…

The OpenSCAD source code:

// Tour Easy rear fender bracket
// Ed Nisley KE4ZNU March 2015

Layout = "Build";		// Build Show TabHolder Block

//- Extrusion parameters must match reality!

ThreadThick = 0.25;
ThreadWidth = 0.40;

HoleWindage = 0.2;

Protrusion = 0.1;			// make holes end cleanly

inch = 25.4;

function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);

//----------------------
// Dimensions

PlateWidth = 45;		// Tour Easy frame plate
PlateDepth = 17;
PlateThick = 3.3;		//  ... allow for a bit of crud

TabWidth = 32;			// fender tab
TabLength = 40;
TabThick = 1.5;
TabDepth = 8;

ChordM = TabDepth - TabThick;	// find fender tab's radius of curvature
ChordC = TabWidth;

TabRadius = ((ChordM * ChordM) + (ChordC * ChordC)/4) / (2 * ChordM);
echo(str("Fender radius: ", TabRadius));

FenderOffset = -25.0;		// from bottom of frame plate

ScrewClear = 5.0;			// close enough to 10-32
ScrewTap = ScrewClear - 1.0;

NutThick = 3.1;				// 10-32 nut
NutOD = 9.5;				//  ... across flats

Chamfer = 5.0;					// edge chamfer

BlockSlab = 10.0;
BlockWidth = TabWidth;
BlockDepth = PlateDepth + BlockSlab;
BlockHeight = TabLength + PlateThick + BlockSlab;

BlockOutline = [
	[TabDepth/2,0],
	[TabDepth/2,TabLength],
	[PlateDepth,TabLength],
	[PlateDepth,TabLength + PlateThick],
	[0,TabLength + PlateThick],
	[0,BlockHeight - Chamfer],
	[Chamfer,BlockHeight],
	[BlockDepth - Chamfer,BlockHeight],
	[BlockDepth,BlockHeight - Chamfer],
	[BlockDepth,TabLength - BlockSlab + Chamfer],
	[BlockDepth - Chamfer,TabLength - BlockSlab],
	[BlockSlab + Chamfer,TabLength - BlockSlab],
	[BlockSlab,TabLength - BlockSlab - Chamfer],
//	[BlockSlab,Chamfer],								// full-length tab (TrimBlock = false)
//	[BlockSlab - Chamfer,0],							//   ""
	[TabDepth/2,TabLength - BlockSlab - Chamfer]		// trim lower tab (TrimBlock = true)
	];

TrimBlock = true;

BuildGap = 5.0;

//----------------------
// Useful routines

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);
}

//- Locating pin hole with glue recess
//  Default length is two pin diameters on each side of the split

PinOD = 1.75;
PinOC = TabLength / 2;

module LocatingPin(Dia=PinOD,Len=0.0) {

	PinLen = (Len != 0.0) ? Len : (4*Dia);

	translate([0,0,-ThreadThick])
		PolyCyl((Dia + 2*ThreadWidth),2*ThreadThick,4);

	translate([0,0,-2*ThreadThick])
		PolyCyl((Dia + 1*ThreadWidth),4*ThreadThick,4);

	translate([0,0,-(Len/2 + ThreadThick)])
		PolyCyl(Dia,(Len + 2*ThreadThick),4);

}

module LocatingPins(Length) {
	for (i=[-1,1])
	translate([i*PinOC/2,0,0])
		rotate(180/4)
		LocatingPin(Len=Length);
}

//----------------------
// Pieces

module TabHolder() {

	difference() {
		translate([-TabWidth/2,-TabLength,0])
			cube([TabWidth,TabLength,2*TabDepth],center=false);

		translate([0,-TabLength/4,0])
			LocatingPins(5.0);

if (!TrimBlock)
		translate([0,-3*TabLength/4,0])
			LocatingPins(5.0);

		translate([0,FenderOffset,-Protrusion])
			rotate(180/6)
				PolyCyl(ScrewClear,3*TabDepth,6);

if (TrimBlock)
		translate([0,FenderOffset,-Protrusion])
			rotate(180/6)
				PolyCyl(NutOD,NutThick + Protrusion,6);

		translate([0,TabLength,TabRadius + TabDepth/2])
			rotate([90,0,0])
				rotate(180/(6*4))
					cylinder(r=TabRadius,h=3*TabLength,$fn=6*4);
	}

if (TrimBlock)
	color("Yellow")
	translate([0,FenderOffset,0])
		for (Seg=[0:5]) {
			rotate(30 + 360*Seg/6)
			cube([NutOD/2,
				2*ThreadWidth,
				(NutThick - ThreadThick)],center=false);
		}

}

module Block() {

	difference() {
		linear_extrude(height=BlockWidth,convexity=3)
			polygon(points=BlockOutline);

if (!TrimBlock)
		translate([TabDepth/2,TabLength/4,BlockWidth/2])
			rotate([0,90,0])
				LocatingPins(5.0);

		translate([TabDepth/2,3*TabLength/4,BlockWidth/2])
			rotate([0,90,0])
				LocatingPins(5.0);

		translate([-BlockDepth,TabLength + FenderOffset,BlockWidth/2])
			rotate([0,90,0])
				rotate(180/6)
					PolyCyl(ScrewClear,3*BlockDepth,6);

		translate([PlateDepth/2,BlockHeight - BlockSlab - Protrusion,BlockWidth/2])
			rotate([-90,0,0])
					PolyCyl(ScrewTap,2*BlockSlab,6);

if (!TrimBlock)
		translate([(BlockSlab - NutThick),(TabLength + FenderOffset),BlockWidth/2])
			rotate([0,90,0])
				rotate(180/6)
					PolyCyl(NutOD,NutThick + Protrusion,6);

	}

}

//----------------------
// Build it

if (Layout == "TabHolder")
	TabHolder();

if (Layout == "Block")
	Block();

if (Layout == "Show") {
	translate([0,BlockWidth/2,0])
		rotate([90,0,0]) {
			color("Magenta")
				Block();
			color("Orange")
				translate([0,TabLength,TabWidth/2])
					rotate([0,-90,0])
						TabHolder();
		}
}

if (Layout == "Build") {

	translate([-BuildGap,0,0])
		rotate(-90)
			TabHolder();

	translate([BuildGap,TrimBlock ? -BlockHeight/1.5 : -BlockHeight/3,0])
		Block();
}

,

3 Comments

Tour Easy Chainstay Rust Repair

While replacing the well-worn sprocket / chain / chainrings on Mary’s bike, I finally got around to repairing some damaged paint tucked in an inconvenient spot…

Over the years, a flaw in the paint underneath the strap connecting the chainstays on Mary’s Tour Easy let in enough moisture to dislodge the paint over a considerable area. I chipped off the loose paint and used Evapo-Rust to convert the oxide to phosphate; there’s not much damage to the steel parts, despite what it may look like in the pictures.

A top view from the right rear, minus the wheel & fender, looking toward the left chainstay:

Tour Easy - rusted chainstay strap

Tour Easy – rusted chainstay strap

Two epoxy fillets in the concave sections where the strap meets the chainstays should eliminate problems in those sections forever more:

Tour Easy - chainstay strap - epoxy fillet

Tour Easy – chainstay strap – epoxy fillet

Some rusty-metal primer and a few coats of red paint conceal most of the ugliness:

Tour Easy - rear fender bracket - installed - top

Tour Easy – rear fender bracket – installed – top

It’ll never be mistaken for showroom quality, but our bikes are tools, not art objects.

The obviously 3D printed red block in the middle of the strap holds the fender in place, about which more tomorrow…

,

2 Comments

MakerGear M2: Platform Z-axis Switch Repeatability

Having run off four quick prints with identical settings, I measured the thickness of the skirt threads around each object:

Skirt Thread Consistency

Skirt Thread Consistency

They’re all slightly thicker than the nominal 0.25 mm layer thickness, but centered within ±0.02 mm of the average 0.27 mm. Tweaking the G92 offset in the startup G-Code by 0.02 would fix that.

The 0.29 mm skirt surrounded the first object, which had a truly cold start: 14 °C ambient in the Basement Laboratory. After that, they’re pretty much identical.

Some informal measurements over a few days suggests the actual repeatability might be  ±0.05 mm, which is Good Enough for layers around 0.20 to 0.25 mm.

The larger skirt suggests that the platform has a slight tilt, but the caliper resolution is only 0.01 mm.

When I realigned everything after installing the V4 hot end, the last set of thinwall boxes looked like this:

Thinwall Calibration Cubes - 5 copies

Thinwall Calibration Cubes – 5 copies

Their heights were:

4.96 5.01
4.98
4.91 4.92

Not enough to worry about, in any event, sez I…

5 Comments

Lurid Filament Colors vs. Monochrome Images

An experiment with images of an object made with translucent magenta PETG…

The Slic3r preview of the object looks like this, just so you know what you should be seeing:

Necklace Heart - Slic3r Preview

Necklace Heart – Slic3r Preview

It’s pretty much a saturated red blob with the Canon SX230HS in full color mode:

Necklace Heart - Slic3r Preview

Necklace Heart – Slic3r Preview

Unleashing The GIMP and desaturating the image based on luminosity helps a lot:

Necklace Heart - magenta PETG - desaturate luminosity

Necklace Heart – magenta PETG – desaturate luminosity

Desaturating based on either lightness or average, whatever that is, produced similar results.

Auto level adjustment plus manual value tweaking brings out more detail from that image:

Necklace Heart - magenta PETG - desaturated - adjusted

Necklace Heart – magenta PETG – desaturated – adjusted

I also tried using the camera in its B&W mode to discard the color information up front:

Necklace Heart - circle detail

Necklace Heart – circle detail

It’s taken through the macro adapter with the LEDs turned off and obviously benefits from better lighting, with an LED flashlight at grazing incidence. You can even see the Hilbert Curve top infill.

The object of the exercise was to see if those tiny dots would print properly, which they did:

Necklace Heart - dots detail

Necklace Heart – dots detail

Now, admittedly, PETG still produces fine hairs, but those dots consist of two layers and two thread widths, so it’s a harsh retraction test.

A look at the other side:

Necklace Heart - detail

Necklace Heart – detail

All in all, both the object and the pix worked out much better than I expected.

Leaving the camera in full color mode and processing the images in The GIMP means less fiddling with the camera settings, which seems like a net win.

Leave a comment