After that failure, I thought maybe making the spring guide pocket a bit wider and seating the spring wire in a solid plug would work. A tweak to the OpenSCAD script produced this, along with slightly larger locating ribs around the battery compartment:

A closer look at the plug spring assembly:

The hole is now slightly larger, distinct from the side of the pocket, and the partition between the pocket and plug (although something of a formality) seats the plug during assembly. The plug started out at 3 mm in diameter, as I intended to try ramming a heated wire into a length of filament. That worked, mmmm, somewhat poorly, so I drilled a hole in a length of filament:

Unfortunately, that whole bodge didn’t work any better than the spring in the first pass at a holder, so I gave up and cast the springs in epoxy. The OpenSCAD code produces a 5 mm diameter hole that should provide a larger epoxy plate with better grip than the 3 mm holes in this picture, but it probably won’t make much difference:

The alert reader will note a complete faceplant: yeah, I forgot to solder the wires into the pins before blobbing the springs in place. Fortunately, the epoxy cures slowly enough that I could:
- Take the picture
- Immediately see the obvious problem
- Ease the music wire springs out just a tidge
- Extract the pins
- Quick-like-a-bunny solder wires to pins
- Insert pins with proper polarity
- Ease springs back in place
I hate it when that happens…
With springs & wires properly in place and the epoxy cured overnight, the pins had considerably better springiness and free motion than before, although they didn’t have quite the range of travel I wanted. I think the spring wire bent slightly on the first push, as the pins never came quite as far out after that.
So this was a qualified success, but not a solid win. Time for round three…
The OpenSCAD source code:
// Holder for Canon NB-5L Li-Ion battery // Ed Nisley KE4ZNU August 2011 include </home/ed/Thing-O-Matic/lib/MCAD/units.scad> include </home/ed/Thing-O-Matic/lib/MCAD/boxes.scad> include </home/ed/Thing-O-Matic/Useful Sizes.scad> // Layout options Layout = "Show"; // Case Lid Show Build Fit //- Extrusion parameters - must match reality! // Print with +2 shells and 3 solid layers ThreadThick = 0.33; ThreadWidth = 2.0 * ThreadThick; HoleWindage = 0.2; function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit); Protrusion = 0.1; // make holes end cleanly BuildOffset = 3.0; // clearance for build layout //- Battery dimensions - rationalized from several samples // Coordinate origin at battery corner by contact plates on bottom surface BatteryLength = 45.25; BatteryWidth = 32.17; BatteryThick = 7.85; ContactWidth = 2.10; ContactLength = 4.10; ContactRecess = 0.85; ContactOC = 3.18; // center-to-center across contact face ContactOffset = 4.45; // offset from battery edge ContactHeight = 3.05; // offset from battery bottom plane AlignThick = 2.2; // alignment recesses on contact face AlignDepth = 2.0; // into face AlignWidth1 = 0.7; // across face at contacts AlignWidth2 = 2.8; // ... other edge //- Pin dimensions PinTipDia = 1.6; PinTipLength = 10.0; PinTaperLength = 2.3; PinShaftDia = 2.4; PinShaftLength = 6.8; PinFerruleDia = 3.0; PinFerruleLength = 2.0; PinLength = PinTipLength + PinTaperLength + PinShaftLength + PinFerruleLength; PinHoleOffset = 13.9; // tip to spring hole ExtendRelax = 1.5 + ContactRecess; // pin extension when no battery is present ExtendOvertravel = 1.0; // ... beyond engaged position //- Holder dimensions GuideRadius = ThreadWidth; // friction fit ridges GuideOffset = 10; WallThick = 4*ThreadWidth; // holder sidewalls BaseThick = IntegerMultiple(6.0,ThreadThick); // bottom of holder to bottom of battery TopThick = 6*ThreadThick; // top of battery to top of holder ThumbRadius = 10.0; // thumb opening at end of battery CornerRadius = 3*ThreadThick; // nice corner rounding CaseLength = 2*WallThick + PinLength - ExtendRelax + ExtendOvertravel + BatteryLength + GuideRadius; CaseWidth = 2*WallThick + 2*GuideRadius + BatteryWidth; CaseThick = BaseThick + BatteryThick + TopThick; //- XY origin at front left battery corner, Z on platform below that CaseLengthOffset = -(WallThick + PinLength - ExtendRelax + ExtendOvertravel); CaseWidthOffset = -(WallThick + GuideRadius); CaseThickOffset = BaseThick; LidLength = ExtendRelax - CaseLengthOffset; //- Spring dimensions SpringPlugDia = 5.0; // epoxy plug holding spring wire SpringPlugLength = IntegerMultiple(1.5,ThreadThick); SpringDia = 0.024 * inch; // music wire spring SpringTravel = ExtendRelax + ExtendOvertravel; SpringLength = BaseThick + ContactHeight - SpringPlugLength - 2*ThreadThick; echo(str("Spring wire from end: ",WallThick + PinLength - PinHoleOffset)); echo(str(" from side: ",WallThick + GuideRadius + ContactOffset)); echo(str("Pin spacing on centers: ",ContactOC)); //---------------------- // 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); } 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); } //------------------- //-- Guides for tighter friction fit module Guides() { translate([GuideOffset,-GuideRadius,CaseThickOffset]) PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4); translate([GuideOffset,(BatteryWidth + GuideRadius),CaseThickOffset]) PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4); translate([(BatteryLength - GuideOffset),-GuideRadius,CaseThickOffset]) PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4); translate([(BatteryLength - GuideOffset),(BatteryWidth + GuideRadius),CaseThickOffset]) PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4); translate([(BatteryLength + GuideRadius),GuideOffset/2,CaseThickOffset]) PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4); translate([(BatteryLength + GuideRadius),(BatteryWidth - GuideOffset/2),CaseThickOffset]) PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4); } //-- Contact pins (holes therefore) module PinShape() { PolyPin = false; union() { if (PolyPin) PolyCyl(PinTipDia,(PinTipLength + Protrusion)); else cylinder(r=(PinTipDia + HoleWindage)/2,h=(PinTipLength + Protrusion),$fn=6); translate([0,0,PinTipLength]) if (PolyPin) PolyCyl(PinShaftDia,(PinTaperLength + PinShaftLength + Protrusion)); else cylinder(r=(PinShaftDia + HoleWindage)/2, h=(PinTaperLength + PinShaftLength + Protrusion),$fn=6); translate([0,0,(PinLength - PinFerruleLength)]) if (PolyPin) PolyCyl(PinFerruleDia,(PinFerruleLength + Protrusion)); else cylinder(r=(PinFerruleDia + HoleWindage)/2, h=(PinFerruleLength + Protrusion),$fn=6); translate([0,0,PinLength]) if (PolyPin) PolyCyl(PinFerruleDia,PinLength); // very long holes to punch case else cylinder(r=(PinFerruleDia + HoleWindage)/2,h=PinLength,$fn=6); } } module PinAssembly() { translate([ExtendRelax,ContactOffset,CaseThickOffset + ContactHeight]) { rotate([0,270,0]) { PinShape(); // pins translate([0,(2*ContactOC),0]) PinShape(); } } translate([-(PinHoleOffset - ExtendRelax + SpringTravel/2 - SpringDia/2 - HoleWindage/2), ContactOffset, (CaseThickOffset + ContactHeight - SpringLength/2 - Protrusion)]) { cube([(SpringTravel + SpringDia/2 + HoleWindage), PinShaftDia, (SpringLength + 2*Protrusion)], center=true); // spring deflection pocket translate([0,(2*ContactOC),0]) cube([(SpringTravel + SpringDia/2 + HoleWindage), PinShaftDia, (SpringLength + 2*Protrusion)], center=true); } translate([-(PinHoleOffset - ExtendRelax), ContactOffset, (-Protrusion/2)]) { PolyCyl(SpringDia,(BaseThick + ContactHeight + Protrusion),4); // spring wire PolyCyl(SpringPlugDia,(SpringPlugLength + Protrusion)); // wire holder translate([0,(2*ContactOC),0]) { PolyCyl(SpringDia,(BaseThick + ContactHeight + Protrusion),4); PolyCyl(SpringPlugDia,(SpringPlugLength + Protrusion)); } } } //-- Case with origin at battery corner module Case() { difference() { union() { difference() { translate([(CaseLength/2 + CaseLengthOffset), (CaseWidth/2 + CaseWidthOffset), (CaseThick/2)]) roundedBox([CaseLength,CaseWidth,CaseThick],CornerRadius); // basic case shape translate([-ExtendOvertravel,-GuideRadius,CaseThickOffset]) cube([(BatteryLength + GuideRadius + ExtendOvertravel), (BatteryWidth + 2* GuideRadius), (BatteryThick + Protrusion)]); // battery space } Guides(); translate([-ExtendOvertravel,-GuideRadius,BaseThick]) cube([(AlignDepth + ExtendOvertravel), (AlignWidth1 + GuideRadius), AlignThick]); // alignment blocks translate([-ExtendOvertravel, (BatteryWidth - AlignWidth2), BaseThick]) cube([(AlignDepth + ExtendOvertravel), (AlignWidth2 + GuideRadius), AlignThick]); } translate([(-ExtendOvertravel), (CaseWidthOffset - Protrusion), (CaseThickOffset + BatteryThick)]) cube([CaseLength, (CaseWidth + 2*Protrusion), (TopThick + Protrusion)]); // battery access translate([(CaseLengthOffset - Protrusion), (CaseWidthOffset - Protrusion), (CaseThickOffset + BatteryThick)]) cube([(CaseLength + 2*Protrusion), (CaseWidth + 2*Protrusion), (TopThick + Protrusion)]); // battery insertion allowance translate([(BatteryLength - Protrusion), (CaseWidth/2 + CaseWidthOffset), (CaseThickOffset + ThumbRadius)]) rotate([90,0,0]) rotate([0,90,0]) cylinder(r=ThumbRadius, h=(WallThick + GuideRadius + 2*Protrusion), $fn=22); // remove thumb notch PinAssembly(); } } module Lid() { difference() { translate([0,0,(CaseThick/2 - BaseThick - BatteryThick)]) roundedBox([LidLength, CaseWidth,CaseThick],CornerRadius); translate([0,0,-(CaseThick/2)]) cube([(LidLength + 2*Protrusion), (CaseWidth + 2*Protrusion), (CaseThick)],center=true); } } //------------------- // Build it! ShowPegGrid(); if (Layout == "Case") Case(); if (Layout == "Lid") Lid(); if (Layout == "Show") { // reveal pin assembly difference() { Case(); translate([(CaseLengthOffset - Protrusion), (CaseWidthOffset - Protrusion + WallThick + ContactOffset + ContactOC), (BaseThick + ContactHeight)]) cube([(-CaseLengthOffset + Protrusion), (CaseWidth + 2*Protrusion), CaseThick + BaseThick - ContactHeight + Protrusion]); translate([(CaseLengthOffset - Protrusion), (CaseWidthOffset - Protrusion), -Protrusion]) cube([(-CaseLengthOffset + Protrusion), (WallThick + GuideRadius + ContactOffset + Protrusion), CaseThick]); } translate([ExtendRelax,ContactOffset,CaseThickOffset + ContactHeight]) { // pins rotate([0,270,0]) { %PinShape(); // translate([0,(2*ContactOC),0]) // %PinShape(); } } } if (Layout == "Build") { translate([-(CaseLength/2 + CaseLengthOffset),-(CaseWidthOffset - BuildOffset),0]) Case(); translate([0,(CaseLengthOffset/2 - BuildOffset),0]) rotate([0,0,90]) Lid(); } if (Layout == "Fit") { Case(); translate([(-LidLength/2 + ExtendRelax), (CaseWidth/2 + CaseWidthOffset), (BaseThick + BatteryThick)]) Lid(); translate([ExtendRelax,ContactOffset,CaseThickOffset + ContactHeight]) { // pins rotate([0,270,0]) { %PinShape(); translate([0,(2*ContactOC),0]) %PinShape(); } } }
One thought on “NB-5L Holder: Plug Spring Holder”
Comments are closed.