Created
May 27, 2025 22:12
-
-
Save ednisley/8dc9fb628e172520754eb35f8ef90267 to your computer and use it in GitHub Desktop.
OpenSCAD source code: Handi-Quilter HQ Sixteen nose ring light mount
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// HQ Sixteen Nose Ring Lights | |
// Ed Nisley - KE4ZNU | |
// 2025-05-23 | |
include <BOSL2/std.scad> | |
Layout = "Show"; // [Show,Build,NosePlan,PowerCap] | |
// Number of side-by-side LED strips | |
Strips = 2; | |
/* [Hidden] */ | |
HoleWindage = 0.2; | |
Protrusion = 0.1; | |
NumSides = 3*3*4; | |
$fn=NumSides; | |
ID = 0; | |
OD = 1; | |
LENGTH = 2; | |
Gap = 5.0; | |
WallThick = 5.0; // default thickness for things | |
NoseRadius = 6.0; // corner roundoff | |
NoseOA = [44.0,36.5]; // overall nose size | |
NoseAngles = [87,87]; // front & rear inward angles wrt left side | |
NoseCenters = [ // centers of circles defining the nose corners | |
[NoseRadius, NoseOA.y/2 - NoseRadius], | |
[NoseRadius,-(NoseOA.y/2 - NoseRadius)], | |
[NoseOA.x - NoseRadius, NoseOA.y/2 - NoseRadius - (NoseOA.x - 2*NoseRadius)*tan(90 - NoseAngles[0])], | |
[NoseOA.x - NoseRadius,-(NoseOA.y/2 - NoseRadius - (NoseOA.x - 2*NoseRadius)*tan(90 - NoseAngles[1]))], | |
]; | |
LEDMargin = 1.0; | |
LEDStrip = [41.5 + LEDMargin,8.0 + LEDMargin,1.8 + 0.2]; // 24 V COB LED strip unit + windage | |
LEDBaseOA = [LEDStrip.x + Strips*LEDStrip.y,NoseOA.y + 2*Strips*LEDStrip.y,WallThick]; // LED mount | |
DraftAngle = 3.0; // angle of frame wrt horizontal at right end of nose | |
DraftWedge = [NoseOA.x,NoseOA.y + 2*LEDStrip.y,NoseOA.x*tan(DraftAngle)]; | |
HoleOffset = [-10.0,5.5,DraftWedge.z + 10.0]; // from left front corner of nose | |
HolePosition = HoleOffset + [0,-NoseOA.y/2,WallThick]; // absolute coordinates from origin | |
Screw = [4.0 + HoleWindage,9.0,2.0]; // LENGTH=button head | |
Bracket = [WallThick,Screw[OD] + 4.0,HoleOffset.z + Screw[OD/2] + 2.0 + WallThick]; | |
Supply = [46.0,30.0,21.0]; // 24 VDC power supply | |
SupplyScrewOffset = 5.0; // … M4 screw hole from end of supply case | |
CapWall = 3.0; | |
CapRadius = CapWall - 1.0; | |
CapInset = 1.0; | |
CapOA = [20.0,Supply.y + 2*CapWall,Supply.z + CapWall]; // x & y to cover existing holes | |
//---------- | |
// Define Shapes | |
//----- 2D outline of nose piece just under frame casting | |
module NosePlan() { | |
hull() | |
for (p = NoseCenters) | |
translate(p) circle(r=NoseRadius); | |
} | |
//----- LED mounting plate | |
module Mount() { | |
union() { | |
difference() { | |
union() { | |
right(LEDBaseOA.x/2 - Strips*LEDStrip.y) | |
cuboid(LEDBaseOA,rounding=WallThick/2,except=BOTTOM,anchor=BOTTOM); | |
up(LEDBaseOA.z) left(-HoleOffset.x/2) | |
yrot(DraftAngle) | |
cuboid(DraftWedge,rounding=WallThick/2,edges="Z",anchor=LEFT+BOTTOM); | |
} | |
down(Protrusion) | |
linear_extrude(LEDBaseOA.z + DraftWedge.z + Protrusion) | |
NosePlan(); | |
if (Strips > 1) | |
translate([HolePosition.x - Bracket.x/2,HolePosition.y - Bracket.y,-Protrusion]) | |
cyl(LEDBaseOA.z + 2*Protrusion,d=4.0,anchor=BOTTOM); | |
} | |
difference() { | |
union() { | |
translate([HolePosition.x,HolePosition.y,(Bracket.x/2)*sin(DraftAngle)]) | |
left(Bracket.x) | |
cuboid(Bracket,rounding=WallThick/2,edges=LEFT,anchor=BOTTOM+LEFT); | |
translate([HolePosition.x - Bracket.x/2,HolePosition.y,0]) // rounding filler | |
cuboid([LEDStrip.y,Bracket.y,WallThick],anchor=BOTTOM+LEFT); | |
} | |
translate(HolePosition) | |
xrot(180/6) xcyl(l=NoseOA.x,d=Screw[ID],$fn=6); | |
} | |
} | |
} | |
//----- Endcap for power supply | |
module EndCap() { | |
difference() { | |
cuboid(CapOA,rounding=CapRadius,except=BOTTOM,anchor=LEFT+BOTTOM); | |
right(CapOA.x - CapWall) down(Protrusion) | |
cuboid(Supply + [0,0,Protrusion],anchor=RIGHT+BOTTOM); | |
right(CapInset + SupplyScrewOffset) | |
zcyl(l=2*CapOA.z,d=Screw[ID],$fn=6,anchor=BOTTOM); | |
} | |
} | |
//---------- | |
// Build things | |
if (Layout == "NosePlan") { | |
NosePlan(); | |
} | |
if (Layout == "PowerCap") { | |
EndCap(); | |
} | |
if (Layout == "Show") { | |
Mount(); | |
ctr = 80; | |
ofs = Supply.x/2 - CapInset; | |
left(ctr - ofs) | |
EndCap(); | |
left(ctr + ofs) | |
xflip() | |
EndCap(); | |
color("Silver",0.6) | |
left (ctr) | |
cuboid(Supply,anchor=BOTTOM); | |
} | |
if (Layout == "Build") { | |
Mount(); | |
back((LEDBaseOA.y + CapOA.y)/2 + Gap) right(Gap) up(CapOA.z) zflip() | |
EndCap(); | |
back((LEDBaseOA.y + CapOA.y)/2 + Gap) left(Gap) zrot(180) up(CapOA.z) zflip() | |
EndCap(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment