The Smell of Molten Projects in the Morning

Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.

Day: December 9, 2013

  • Browning Hi-Power Magazine: Nut Trap Block Trial

    The general idea is to reduce the capacity of a 13 round Browning Hi-Power magazine to 10 rounds, in compliance with the NY Safe Act, using a number of possibly invalid assumptions. The new Firearms tag will produce earlier posts.

    This early prototype tried out the sizes, shapes, and angles, using an M3x0.5 socket head cap screw:

    Browning Hi-Power Magazine Block - solid model - nut trap prototype
    Browning Hi-Power Magazine Block – solid model – nut trap prototype

    The bottom nut trap locates the block on the inner floor plate by capturing the nut. It might need a bit more clearance or a chamfer to allow for brazing material around the nut flats; cleaning up the brazed nut with a file might also help.

    The central trap holds a nut that anchors the block; the trap must be about 50% longer than the nut to allow for thread alignment, because the central hole is a loose tap fit.

    That central nut probably isn’t needed, because you’d fill the central shaft with metal-loaded epoxy, which would form a perfectly serviceable, exactly form-fitting, and utterly non-removable “nut”. The vent from the end of the screw shaft releases air trapped behind the epoxy by the screw; if you don’t have a vent, then air pressure will force the epoxy out of the cavity.

    If the epoxy “nut” is workable, then you can build it in a single piece printed vertically on the platform. Having a split version makes it easier to show off and, in truth, the cemented joint is about as strong as the rest of the object.

    Hot off the M2 3D printer, it looks like this:

    BHP magazine block - prototype nut trap - bare
    BHP magazine block – prototype nut trap – bare

    A few threads droop into the air vent, so that channel should be larger. The overall plastic block may be porous enough to release the air pressure even without a vent.

    With locating pins glued in place and a nut in the central trap:

    BHP magazine block - prototype nut trap
    BHP magazine block – prototype nut trap

    Pretty much as I expected, it doesn’t quite fit in the magazine, because it doesn’t have clearance for the little tab on the inner floor plate that captures the spring.

    One might argue that a plastic block isn’t “permanent”, but it’s definitely not “readily” removed:

    • PLA doesn’t dissolve in common solvents
    • It doesn’t actually melt and flow away at high temperatures
    • It’s protected by the spring and inner floor plate
    • It’s certainly strong enough to resist simple mechanical attacks

    This is a start…

    The OpenSCAD source code, replete with inadequacies:

    // Browning Hi-Power Magazine Plug
    // Ed Nisley KE4ZNU November 2013
    
    Layout = "Show";			// Show Whole Pin Build
    
    CrossSection = 1;			// -1, 0, 1 to select section side or none
    
    Section = (Layout == "Build") ? 1 : CrossSection;		// for cross-section for build
    
    //- Extrusion parameters must match reality!
    //  Print with 2 shells and 3 solid layers
    
    ThreadThick = 0.25;
    ThreadWidth = 0.40;
    
    HoleWindage = 0.2;
    
    Protrusion = 0.1;			// make holes end cleanly
    
    //----------------------
    // Dimensions
    
    Angle = 12.5;				// from vertical
    
    EndDia = 10.3;				// an 11/32 inch drill fits
    EndRadius = EndDia / 2;
    
    Length = 24.0;				// front-to-back perpendicular to magazine shaft
    Height = 14.0;				// bottom-to-top, parallel to magazine shaft
    							//  14 = 10 round capacity
    							//  28 = 7 round
    
    RectLength = Length - EndDia;	// block length between end radii
    
    ScrewOD = 3.0 - 0.5;		// bottom screw tapping diameter
    ScrewLength = 11.0;
    ScrewOffset = 0;			//   ... from centerline
    
    NutOD = 5.5;				// hex nut dia across flats
    NutThick = 2.4;				//  ... then add 50% for thread engagement & epoxy
    NutOffset = 6.0;			//  ... base height from floor
    
    VentWidth = 2*ThreadWidth;	// air vent from back of screw recess
    VentDepth = 4*ThreadThick;
    
    NumSides = 8*4;				// default cylinder sides
    
    PinOD = 1.72;				// alignment pins
    PinLength = 6.0;
    PinInset = 0.9*EndRadius;	// from outside edges
    echo(str("Alignment pin length: ",PinLength));
    
    Offset = 5.0/2;				// from centerline for build layout
    
    //----------------------
    // Useful routines
    
    // 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);
    
    }
    
    //----------------------
    // Components
    
    module Block(SectionSelect = 0) {
    
    Delta = tan(Angle)*(Length/2);				// incremental length due to angle
    
    CropHeight = Height*cos(Angle);				// block height perpendicular to base
    
    echo(str("Perpendicular height: ",CropHeight));
    
    	difference() {
    		intersection() {
    			rotate([Angle,0,0])
    				difference() {
    					translate([0,0,-Height/2])
    						linear_extrude(height=2*Height,convexity=2) {
    							for (i=[-1,1])
    								translate([0,(i*RectLength/2),0])
    									rotate(180/NumSides)
    										circle(r=EndRadius/cos(180/NumSides),
    												$fn=NumSides);
    							square([EndDia,RectLength],center=true);
    						}
    					for (i=[-1,1])
    						translate([0,
    									(i*(Length/2 - PinInset)),
    									(CropHeight/2 + i*(CropHeight/2 - PinInset))])
    							rotate([0,90,0]) rotate(45-Angle)
    								LocatingPin(PinOD,PinLength);
    				}
    			translate([0,0,CropHeight/2])
    				cube([2*EndDia,3*Length,CropHeight],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,1.5*NutThick,6);
    
    		translate([0,ScrewOffset,-Protrusion])		// nut clearance at base
    			rotate(180/6)
    				PolyCyl(NutOD,(1.1*NutThick + Protrusion),6);
    
    		translate([0,-(ScrewOffset + NutOD),(ScrewLength - Protrusion)/2])	// air vent
    			cube([VentDepth/2,VentWidth,(ScrewLength + Protrusion)],center=true);
    		translate([0,(ScrewOffset - NutOD/2),(ScrewLength - VentWidth/2)])
    			cube([VentDepth/2,NutOD,VentWidth],center=true);
    
    		if (SectionSelect == 1)
    			translate([EndDia,0,Height/2-Protrusion])
    				cube([2*EndDia,3*Length,Height+2*Protrusion],center=true);
    		else if (SectionSelect == -1)
    			translate([-EndDia,0,Height/2-Protrusion])
    				cube([2*EndDia,3*Length,Height+2*Protrusion],center=true);
    	}
    
    }
    
    //-------------------
    // Build it...
    
    ShowPegGrid();
    
    if (Layout == "Pin")
    	LocatingPin(PinOD,PinLength);
    
    if (Layout == "Show")
    	Block(CrossSection);
    
    if (Layout == "Whole")
    	Block(0);
    
    if (Layout ==  "Build") {
    	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);
    }