Advertisements

HP 7475A Plotter: Roland Knife Stabilizer, Improved

The objective being to wrap a nose around the cutter blade to allow some control over the cut depth, I lengthened the cylinder around the cutter body and modeled a discrete glue-on cap:

Roland knife stabilizer and nose - show

Roland knife stabilizer and nose – show

Which, with an additional 80 g of ballast, worked fine in the double-thick vinyl:

Roland knife stabilizer - nut weight

Roland knife stabilizer – nut weight

The pen-lift spring can just barely manage to heave that load off the vinyl, but it’s obviously running at the limit of its ability and this can’t possibly be a Good Thing for the mechanism in the long run.

After a bit more fiddling around, I noticed that the stabilizer wasn’t sitting flat on the pen holder and that there really wasn’t any good reason to have a separate cap, so I did one more revision:

Roland knife stabilizer with nose - side view

Roland knife stabilizer with nose – side view

The cutaway view shows the knife model now has tapered transition from the body to the grossly enlarged blade, so the model will build without supports inside the cylinder.

A little cutout on one wall lets the plate sit flat on the pen holder and a barely visible recess in the cylinder gives the carousel pen-capping actuator a bit more clearance:

Roland knife stabilizer with nose - Slic3r preview

Roland knife stabilizer with nose – Slic3r preview

It works about as well as the version shown above, minus the tedious gluing, so I’ll call it a success… even though it’s obviously not going to get much use. I don’t see any way to apply enough downforce to make the cutter work; the mechanical changes just aren’t worthwhile.

The OpenSCAD source code, which includes some tweaks and outright kludges since the first version, builds adapters for Sakura pens (which work just fine) as well as this knife stabilizer:

// HP 7475A plotter pen adapters
// Ed Nisley KE4ZNU April 2015

Layout = "BuildStabilizer";
							// ShowBody BuildBody BodyPoly
							// ShowPen ShowPenAdapter BuildPenAdapter Plug Pen PenPoly
							// ShowKnife BuildKnife KnifeAdapter Knife
							// ShowStabilizer 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];

//-- Plug for end of cut-off pen body
//   you need two plugs...

PlugOutline = [
	[0,0],							// 0 center of lid
	[9.5/2,0.0],[9.5/2,1.0],		// 1 lid rim <= body OD
	[7.9/2,1.0],					// 3 against end of pen
	[7.6/2,6.0],					// 4 taper inside pen body
	[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
	];

//-- Roland drag knife bearing assembly

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

//- Knife tweaked for pen adapter
/*
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 blade 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
	];
*/

//- Knife tweaked for stabilizer

KnifeOutline = [
	[0,0],							//  0 blade point (actually 0.25 mm offset)
	[3.0/2,0.0],					//  1  ... blunt end
	[3.0/2,4.0],					//  2  ... cylinder
	[3.0/2,4.0],					//  3 blade shank
	[6.0/2,5.9],					//  4  .. at bearing (taper to support nose)
	[6.0/2,5.9],					//  5 holder - shell

	[7.3/2 + ExpRK,8.3],			//  6 holder - taper to clear threads
	[7.3/2 + ExpRK,21.0 - AdjLen],	//  7  ..

	[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
	];

ThreadStart = KnifeOutline[8][HEIGHT];
ThreadOD = 2*KnifeOutline[11][RADIUS];

//-- Plotter pen holder stabilizer

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

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

HolderHeight = 30.0;				// top of holder to platen in pen-down position
HolderTopThick = 1.7;				// top of holder to top of pen flange

HolderNoseLength = 4.0;				// length of nose taper
HolderKnifeOffset = -3.0;			// additional downward adjustment range

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

UncapperHeight = -17.0;				// uncapping actuator arm from top of pen holder
UncapperOD = 11.0;					//  ... max OD that clears uncapper

// 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];		// rear support beam

TabWidth = HolderPlate[1][1] - HolderPlate[0][1];		// tab extending left beyond pen recess
TabClear = 3.0;											// maximum rim height over tab

HolderCylinderOutline = [
	[0,0],											//  0 center of nose
	[6.0/2,0.0],									//  1 flat nose surface OD
	[BodyOD/2,HolderNoseLength],			//  2 taper to cylinder OD
	[BodyOD/2,HolderHeight],				//  3 cylinder to top of holder plate
	[0,HolderHeight]								//  4 flat top
	];

//----------------------
// 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 ShowPolygon(pts) {
	polygon(pts);
}

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

//-- 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() {

	render(convexity=3)
		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);
			}
}

//-- nose cap for stabilizer cylinder

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

//-- Roland knife stabilizer atop pen holder
//   the trim blocks have offsets with magic numbers from the HolderPlate outline &c

module Stabilizer(SeeKnife = false) {

Cutout = (Layout == "ShowStabilizer") ? 0 : 1;

	difference() {
		union() {
			translate(-HolderOrigin)													// put center of pen at origin
			translate([0,0,-RimHeight])													// put top of holder at Z=0
				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([0,HolderPlate[0][1],-(TabClear + Protrusion)])		// trim tab behind pen recess
							cube([(HolderPlate[0][0] + Protrusion),TabWidth,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);					// punch out hold-down screw hole
				}

			difference() {
				translate([0,0,-HolderHeight])											// cylinder and nose
					rotate_extrude($fn=NumSides)
						polygon(points=HolderCylinderOutline);
				translate([-HolderOrigin[0],-(BodyOD + Cutout*UncapperOD/2),(UncapperHeight - HolderHeight)])	// uncapper clearance
					cube([2*HolderOrigin[0],BodyOD,HolderHeight]);
			}
		}

		translate([0,0,-HolderHeight + HolderKnifeOffset])
			if (SeeKnife)
#				Knife();
			else
				Knife();

	}
}

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

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

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

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

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

if (Layout == "BodyPoly") {
	ShowPolygon(BodyOutline);
	Body();
}

if (Layout == "PenPoly") {
	ShowPolygon(PenOutline);
	Pen();
}

if (Layout == "BuildBody") {
	Spacing = 0.75*BuildSpace;
	difference() {
		union() {
			translate([Spacing,0,-SplitHeight])
				Body();
			rotate([180,0,0])
				translate([-Spacing,0,-SplitHeight])
					Body();
		}
		translate([0,0,-BodyOAL])
			cube(2*BodyOAL,center=true);
		for (i = [-1,1])
			translate([i*Spacing,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 == "ShowPenAdapter") {
	color("AntiqueWhite") {
		translate([0.00*BodyOD,0,0])
			Pen();
		translate([-2.75*BodyOD,0,0])
			Pen();
	}

	translate([-1.50*BodyOD,0,0])
		color("SandyBrown")
			Body();

	translate([0.00*BodyOD,0,0])
		color("SandyBrown",0.35)
			PenAdapter();

	translate([3.00*BodyOD,0,0])
		color("SandyBrown")
			PenAdapter();

	translate([1.50*BodyOD,0,0])
		difference() {
			color("SandyBrown")
				PenAdapter();
			translate([-BodyOD,-2*BodyOD,0])
				cube([2*BodyOD,2*BodyOD,PenOAL]);
		}

}

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 == "BuildPenAdapter") {

	if (false) {
		for (j = [-1,1])
			translate([j*BuildSpace/2,-0.7*BuildSpace,0])
			Plug();

		translate([0,0,-CapOffset])
			Cap();
	}
	else {
		Plug();
	}

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

}

if (Layout == "BuildKnife") {

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

}

if (Layout == "BuildStabilizer") {

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

if (Layout == "ShowStabilizer") {

	translate([BuildSpace/2,0,HolderHeight])
			Stabilizer(true);
	translate([-BuildSpace/2,0,HolderKnifeOffset])
		Knife();
}
Advertisements

,

  1. #1 by Sam on 2015-04-30 - 08:30

    You have a signal telling it to raise the pen, couldn’t you put a servo loaded spring or electromagnet that reacts to the lack of this signal to add the extra downforce?

    • #2 by Ed on 2015-04-30 - 09:46

      As nearly as I can tell, there’s no structure that could absorb the additional force. The pen holder rides on the lower steel bar and guides against the upper aluminum bar. When the pen is down, the aluminum bar applies reaction force against the pen spring through the guide, but that’s nearly zero because it’s net of the tip force minus the holder weight. The flange applies no force to the pen at all, because it overtravels the distance required to get the pen tip on the paper, and must support only the weight of the holder when it’s retracted.

      It’s a very clever and lightweight design that works perfectly for plotter pens, but not for knives.

      I suppose one could gimmick up a powered knife holder with rolling bearings on the aluminum bar, but that’s a whole ‘nother level of crazy, even for me…

      • #3 by Sam on 2015-04-30 - 09:58

        Ah, I was thinking it was more like the intersecting axes on an Ultimaker, then it would have been a simple. I just looked at a Youtube video of it and see it’s moving the paper, got it. Yeah, not so straightforward. And vinyl cutters can be had for next to nothing these days.

      • #4 by David on 2015-04-30 - 17:59

        How about a steel strip under the bed and a solenoid coil electromagnet wrapped around the tip of the knife? Or even a neoodyminium ring magnet if you can beef up the up-actuator enough to unstick it…

        • #5 by Ed on 2015-04-30 - 19:10

          a steel strip under the bed

          The chassis pan has more galvanized steel in it than our entire Forester: I can work with that!

          [mutter]