Advertisements

Archive for January 6th, 2014

Browning Hi-Power Magazine Capacity Reduction Block: Steel Version

The Shapeways stainless steel process produces nice results:

Browning HP Mag Blocks - stainless and plastic - side

Browning HP Mag Blocks – stainless and plastic – side

It’s actually bronze-infused stainless steel powder, so it’s not exactly solid steel. The parts spend a day rattling around in a vibratory polisher that slightly rounds off their edges and smooths the surface, but (as with all 3D printed objects) you must learn to love the results; it’s certainly more photogenic than the black plastic version from my M2.

The bottom view shows the hole I added to reduce the metallic volume; they charge a bit under $0.01/mm3, which encourages airy design:

Browning HP Mag Blocks - stainless and plastic - bottom

Browning HP Mag Blocks – stainless and plastic – bottom

A cross-section view of the solid model shows the interior structure:

Browning Hi-Power Magazine Block - steel - solid model - section

Browning Hi-Power Magazine Block – steel – solid model – section

The vent pipes are somewhat larger than in the plastic version and, obviously, I didn’t include the yellow support structures in the model I sent to Shapeways.

Their specs give a minimum wall thickness of 3.0 mm, which I’m definitely pushing on some of the internal features. The pipes came out perfectly, as nearly as I can tell, although some polishing media did get wedged in the smaller hole. Air passes freely across the top, which is the important part.

Although the specs list a ±2 mm (!) tolerance, a comment in a Shapeways forum said that applies to larger objects, with 0.2 mm being typical for smaller objects. The steel and plastic parts match within 0.2 mm of the nominal model dimensions, so that lower tolerance seems about right; I have no idea how consistent it is.

Another comment recommended carbide tools for secondary operations and that’s definitely true; I wrecked a perfectly good HSS tap trying to thread the central hole. Fortunately, I made the block slightly smaller outside and slightly larger inside, specifically to avoid having a deep thread; I intend to ram a standard M3x0.5 SHCS into that hole and epoxy it in place without worrying about thread damage.

A trial fit shows it captures the spring tab just like the plastic version did:

Browning Hi-Power magazine - steel block trial fit

Browning Hi-Power magazine – steel block trial fit

I must contact my legislators again, as I’m pretty sure they’re not going to contact me.

The OpenSCAD source code:

// Browning Hi-Power Magazine Plug
// Ed Nisley KE4ZNU December 2013

Layout = "Show";			// Show Whole Split
							//  Show = section view for demo, not for building
							//  Whole = upright for steel or plastic
							//  Split = laid flat for plastic show-n-tell assembly

AlignPins = (Layout == "Split");					// pins only for plastic show-n-tell

Support = true && (Layout != "Split");				// no support for split, optional otherwise

//- Extrusion parameters must match reality!
//  Print with 2 shells and 3 solid layers

ThreadThick = 0.15;
ThreadWidth = 0.40;

HoleWindage = 0.2;

Protrusion = 0.1;			// make holes end cleanly

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

Angle = 12.5;				// from vertical

SpringID = 10.3;			// magazine spring curvature (measure with drill shank)
SpringRadius = SpringID / 2;

Length = 23.0;				// front-to-back perpendicular to magazine shaft
Height = 18.0;				// bottom-to-top, parallel to magazine shaft
							//  18 = 10 round max capacity

RectLength = Length - SpringID;	// block length between end radii

HornBaseOD = 8.0;			// fits between follower pegs to prevent shortening
HornTipOD = 5.0;
HornAddTip = (HornTipOD/2)*tan(Angle);
HornAddBase = (HornBaseOD/2)*tan(Angle);
HornAddLength = HornAddTip + HornAddBase + 2*Protrusion;
HornLength = 12.0;			// should recompute ODs, but *eh*

ScrewOD = 3.0 - 0.25;		// screw hole dia - minimal thread engagement
ScrewLength = 13.0;
ScrewOffset = -1.5;			//   ... from centerline
							//  OEM = 0.0
							//  generic A = -1.5

NutOD = 5.6;				// hex nut dia across flats
NutThick = 2.4;				//  ... generous allowance for nut
NutTrapLength = 1.5*NutThick;		// allow for epoxy buildup
NutOffset = 6.0;			//  ... base height from floor

TrimHeight = 2.5;			// vertical clearance for spring clip on base plate
							//   OEM = 2.5
							//   generic A = 2.5

TrimOffset = -9.5 + ScrewOffset;	// ... horizontal from centerline
							//	 OEM = 0.0
							//   generic A = 1.5

SupportLength = 4.0;		// length of support struts under Trim
SupportWidth = SpringID;	// ... width

VentDia = 2.5;				// air vent from back of screw recess
VentOffset = ScrewOffset - 6.0;

RecessDia = 5.0;			// recess to reduce weight
RecessLength = 0.66*Length;	//  ... internal length
RecessOffset = 8.5;	//  ... offset from centerline

PinOD = 1.72;				// alignment pins
PinLength = 6.0;
PinInset = 0.6*SpringRadius;	// from outside edges
echo(str("Alignment pin length: ",PinLength));

NumSides = 8*4;				// default cylinder sides

Offset = 5.0/2;				// from centerline for build layout

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

function Delta(a,l) = l*tan(a);				// incremental length due to angle

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

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

module ShowPegGrid(Space = 10.0,Size = 1.0) {

  Range = floor(50 / Space);

	for (x=[-Range:Range])
	  for (y=[-Range:Range])
		translate([x*Space,y*Space,Size/2])
		  %cube(Size,center=true);

}

//----------------------
// The magazine block

module Block(SectionSelect = 0) {

CropHeight = Height*cos(Angle);				// block height perpendicular to base
echo(str("Perpendicular height: ",CropHeight));

	difference() {
		union() {
			intersection() {
				rotate([Angle,0,0])
					hull() {
						for (i=[-1,1])
							translate([0,i*RectLength/2,-((Length/2)*sin(Angle) + Protrusion)])						cylinder(r=SpringRadius,
										h=(Height + 2*(Length/2)*sin(Angle) + 2*Protrusion),
										$fn=NumSides);
					}
				translate([0,0,CropHeight/2])
					cube([2*SpringID,3*Length,CropHeight],center=true);
			}
			translate([0,-Height*sin(Angle),Height*cos(Angle)])
				resize([SpringID,0,0])
					intersection() {
						rotate([Angle,0,0])
							translate([0,0,-(HornAddBase + Protrusion)])
								cylinder(r1=HornBaseOD/2,
										r2=HornTipOD/2,
										h=(HornLength + HornAddLength + Protrusion),
										$fn=NumSides);
					cube([2*SpringID,Length,2*(HornLength*cos(Angle) + Protrusion)],center=true);
				}
		}

		translate([0,ScrewOffset,-Protrusion])		// screw
			rotate(180/6)
				PolyCyl(ScrewOD,(ScrewLength + Protrusion),6);

		translate([0,ScrewOffset,NutOffset])		// nut trap in center
			rotate(180/6)
				PolyCyl(NutOD,NutTrapLength,6);

		translate([0,ScrewOffset,-Protrusion])		// nut clearance at base
			rotate(180/6)
				PolyCyl(NutOD,(1.1*NutThick + Protrusion),6);

		translate([SpringID/2,TrimOffset,-Protrusion])
			rotate(180)
				cube([SpringID,Length,(TrimHeight + Protrusion)],center=false);

		if (AlignPins)								// alignment pins
			for (i=[-1,1])
				rotate([Angle,0,0])
				translate([0,
							(i*((Length/2)*cos(Angle) - PinInset)),
							(CropHeight/2 - i*2*PinInset)])
					rotate([0,90,0]) rotate(45 - Angle)
						LocatingPin(PinOD,PinLength);

		translate([0,(ScrewOffset + 1.25*NutOD),ScrewLength])	// air vent
			rotate([90,0,0]) rotate(180/8)
				PolyCyl(VentDia,3*NutOD,8);
		translate([0,VentOffset,-(VentDia/2)*tan(Angle)])
			rotate([Angle,0,0]) rotate(180/8)
				PolyCyl(VentDia,(RecessLength + (VentDia/2)*tan(Angle)),8);

		translate([0,(RecessOffset + ScrewOffset),0])			// weight reduction recess
			rotate([Angle,0,0]) rotate(180/8)
				translate([0,0,-((RecessDia/2)*tan(Angle))])
				PolyCyl(RecessDia,(RecessLength + (RecessDia/2)*tan(Angle)),8);

		if (SectionSelect == 1)
			translate([0*SpringID,-2*Length,-Protrusion])
				cube([2*SpringID,4*Length,(Height + HornLength + 2*Protrusion)],center=false);
		else if (SectionSelect == -1)
			translate([-2*SpringID,-2*Length,-Protrusion])
				cube([2*SpringID,4*Length,(Height + HornLength + 2*Protrusion)],center=false);
	}

SupportBars = floor((SupportWidth/2) / (4*ThreadWidth));

	if (Support) {									// add support structures
		for (i = [-SupportBars:SupportBars])
			translate([i*4*ThreadWidth,
					   (TrimOffset - SupportLength/2 - ThreadWidth),
					   (TrimHeight - ThreadThick)/2])
				color("Yellow")
				cube([(2*ThreadWidth),SupportLength,(TrimHeight - ThreadThick)],center=true);

		translate([0,(TrimOffset - SupportLength - ThreadWidth),(TrimHeight - ThreadThick)/2])
			color("Yellow")
			cube([SupportWidth,(2*ThreadWidth),(TrimHeight - ThreadThick)],center=true);

		translate([0,ScrewOffset,0])
			for (j=[0:5]) {
			rotate(30 + 360*j/6)
				translate([(NutOD/2 - ThreadWidth)/2,0,(1.1*NutThick - ThreadThick)/2])
					color("Yellow")
					cube([(NutOD/2 - ThreadWidth),
						  (2*ThreadWidth),
						  (1.1*NutThick - ThreadThick)],
						  center=true);
        }
	}

}

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

ShowPegGrid();

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

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

if (Layout ==  "Split") {
	translate([(Offset + Length/2),Height/2,0])
		rotate(90) rotate([0,-90,-Angle])
			Block(-1);
	translate([-(Offset + Length/2),Height/2,0])
		rotate(-90) rotate([0,90,Angle])
			Block(1);
}
Advertisements

,

5 Comments