Advertisement
Guest User

Untitled

a guest
Apr 26th, 2017
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.33 KB | None | 0 0
  1. // Badge Lanyard Reel Mount
  2. // Ed Nisley KE4ZNU April 2017
  3. // Reel center at origin, lanyard exit toward +X
  4.  
  5. Layout = "Show";
  6.  
  7. Support = true;
  8.  
  9. //- Extrusion parameters must match reality!
  10.  
  11. ThreadThick = 0.20;
  12. ThreadWidth = 0.40;
  13.  
  14. HoleWindage = 0.2;
  15.  
  16. Protrusion = 0.05; // make holes end cleanly
  17.  
  18. inch = 25.4;
  19.  
  20. function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
  21.  
  22. //----------------------
  23. // Dimensions
  24.  
  25. ID = 0; // for round things
  26. OD = 1;
  27. LENGTH = 2;
  28.  
  29. Carabiner = [30.7,35.3,3.5]; // metal carabiner around original reel
  30. Latch = [6.0,-15,8.0]; // wire spring latch: offset from OD + thickness
  31. LatchAngle = 60; // max deflection angle to center from -X direction
  32.  
  33. LatchPoints = [[0,0],
  34. [Latch[1]/tan(LatchAngle),0],
  35. [Latch[1]/tan(LatchAngle),-Latch[1]]]; // polygon in as-cut orientation
  36.  
  37. echo(str("Latch polygon: ",LatchPoints));
  38.  
  39. Screw = [2.0,3.8 + 0*ThreadWidth,10.0]; // M2 screw: ID = clear, OD = head
  40. ScrewHeadLength = 2.0;
  41. ScrewSides = 8;
  42. ScrewRecess = 5*ThreadThick;
  43.  
  44. MountSides = ScrewSides; // suitably gritty corners
  45.  
  46. MountThick = Screw[LENGTH] / cos(180/MountSides) + ScrewRecess + 2.0;
  47.  
  48. Insert = [Screw[ID],3.4,4.0]; // brass insert for screws
  49.  
  50. BCD = Carabiner[OD] + 2.5*Insert[OD];
  51.  
  52. BoltAngles = [20,110]; // ± angles to bolt holes
  53.  
  54. Reel = [5.3,25.5 + 2*ThreadWidth,6.0 + 2*ThreadThick]; // lanyard cord reel
  55. ShimThick = 2*ThreadThick; // covers open side of reel for better sliding
  56.  
  57. Bezel = [31.0,32.0,7.5]; // PCB holder + shell, LENGTH = post + shell
  58. BezelSides = 6*4;
  59. BezelBlock = [5.5,7.5,3.6] + [ThreadWidth,ThreadWidth,ThreadThick]; // block around lanyard eyelet
  60.  
  61. Eyelet = [3.5,4.5,3.0];
  62.  
  63. Bullet = [2.0,6.5,2.0]; // brass badge holder, LENGTH = recess into mount
  64.  
  65. //----------------------
  66. // Useful routines
  67.  
  68. module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes
  69.  
  70. Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
  71.  
  72. FixDia = Dia / cos(180/Sides);
  73.  
  74. cylinder(r=(FixDia + HoleWindage)/2,
  75. h=Height,
  76. $fn=Sides);
  77. }
  78.  
  79. //-- Lanyard reel mockup
  80.  
  81. module Reel() {
  82.  
  83. cylinder(d=Reel[OD],h=Reel[LENGTH],center=true,$fn=6*4);
  84.  
  85. }
  86.  
  87. // Carabiner metal mockup
  88. // Some magic numbers lie in wait
  89.  
  90. module Beener() {
  91.  
  92. difference() {
  93. hull() {
  94. cylinder(d=Carabiner[OD],
  95. h=Carabiner[LENGTH] + 2*ThreadThick,
  96. center=true,$fn=BezelSides);
  97. translate([-Carabiner[OD]/2,0,0])
  98. cylinder(d=Carabiner[OD] - 2.0,
  99. h=Carabiner[LENGTH] + 2*ThreadThick,
  100. center=true,$fn=6*4);
  101. }
  102. cylinder(d=Carabiner[ID],
  103. h=2*Carabiner[LENGTH],
  104. center=true,$fn=BezelSides);
  105. translate([Carabiner[ID]/4,0,0])
  106. cube([Carabiner[ID],7.0,2*Carabiner[LENGTH]],center=true);
  107. }
  108. }
  109.  
  110. // mockup of PCB holder atop remains of old mount with reel post
  111. // Z = 0 at midline of case
  112.  
  113. module BezelMount() {
  114.  
  115. rotate(180/BezelSides) {
  116. PolyCyl(Bezel[ID] + HoleWindage,MountThick,BezelSides); // PCB punches through mount
  117. PolyCyl(Bezel[OD] + HoleWindage,Bezel[LENGTH] - Reel[LENGTH]/2,BezelSides);
  118. }
  119.  
  120. translate([Reel[OD]/2,0,BezelBlock[2]/2])
  121. scale([2,1,1])
  122. cube(BezelBlock,center=true);
  123. }
  124.  
  125. // Main mount around holder & carabiner
  126.  
  127. module Mount(Section="All") {
  128.  
  129. render()
  130. difference() {
  131. hull() {
  132. for (a = BoltAngles) // spheres defining corners
  133. for (i=[-1,1])
  134. rotate(i*a)
  135. translate([BCD/2,0,0])
  136. sphere(d=MountThick,$fn=MountSides);
  137. cylinder(d=Carabiner[OD] + 4*ThreadWidth,
  138. h=MountThick,center=true); // capture carabiner ring
  139. }
  140.  
  141. for (a = BoltAngles) // screw & insert holes, head recess
  142. for (i=[-1,1])
  143. rotate(i*a)
  144. translate([BCD/2,0,0])
  145. rotate(0*i*180/ScrewSides) {
  146. translate([0,0,-(Insert[LENGTH] + 2*ThreadThick)])
  147. PolyCyl(Insert[OD],
  148. Insert[LENGTH] + 2*ThreadThick + Protrusion,ScrewSides);
  149. for (k = [-2:2]) // epoxy retaining grooves
  150. translate([0,0,-(k*3*ThreadThick + Insert[LENGTH]/2)])
  151. PolyCyl(Insert[OD] + 1*ThreadWidth,
  152. 2*ThreadThick,ScrewSides);
  153. PolyCyl(Screw[ID],Screw[LENGTH],ScrewSides);
  154. translate([0,0,MountThick/2 - ScrewRecess]) // recess screw heads
  155. PolyCyl(Screw[OD],Screw[LENGTH],ScrewSides);
  156. }
  157.  
  158. translate([0,0,-1*ThreadThick]) // Minkowski Z extends only top surface!
  159. minkowski() { // space for metal carabiner
  160. Beener();
  161. // cube([ThreadWidth,ThreadWidth,2*ThreadThick]);
  162. cylinder(d=ThreadWidth,h=2*ThreadThick,$fn=6);
  163. }
  164.  
  165. rotate([0,90,0]) rotate(180/6) // cord channel = brass tube clearance
  166. PolyCyl(Bullet[ID],Carabiner[ID],6);
  167.  
  168. translate([Eyelet[LENGTH] + 2.0,0,0]) // eyelet, large end inward
  169. rotate([0,90,0]) rotate(180/6)
  170. PolyCyl(Eyelet[OD] + HoleWindage, Reel[OD]/2,6);
  171.  
  172. if (false)
  173. translate([Reel[OD]/2 + Eyelet[LENGTH]/2,0,0]) // eyelet, small end outward
  174. rotate([0,90,0]) rotate(180/6)
  175. PolyCyl(Eyelet[ID],Eyelet[LENGTH],6);
  176.  
  177. translate([(BCD/2 + MountThick/2)*cos(BoltAngles[0]) - Bullet[LENGTH],0,0]) // bullet recess
  178. rotate([0,90,0]) rotate(180/6)
  179. PolyCyl(Bullet[OD],Carabiner[ID],6);
  180.  
  181. BezelMount(); // PCB holder clearance
  182.  
  183. Reel(); // reel clearance
  184.  
  185. translate([0,0,-(Reel[LENGTH] + ShimThick)/2]) // sliding plate on open side of reel
  186. cylinder(d=Reel[OD],h=ShimThick,center=true,$fn=6*4);
  187.  
  188. translate([-Carabiner[OD]/2 + Latch[0],Latch[1],0])
  189. linear_extrude(height=Latch[2],center=true)
  190. polygon(LatchPoints);
  191.  
  192. if (Section == "Upper") // display & build section cutting
  193. translate([0,0,-2*Carabiner[LENGTH]])
  194. cube(4*Carabiner,center=true);
  195. else if (Section == "Lower")
  196. translate([0,0,2*Carabiner[LENGTH]])
  197. cube(4*Carabiner,center=true);
  198.  
  199. }
  200.  
  201. if (Support) { // Completely ad-hoc support structures
  202. color("Yellow", Layout == "Show" ? 0.3 : 1.0) {
  203. if (false && Section == "Upper") {
  204. Spokes = BezelSides;
  205. Offset = 6*ThreadWidth;
  206. for (i = [2:Spokes - 2])
  207. rotate(i * 360/Spokes)
  208. translate([Offset,-ThreadWidth,0*(Carabiner[LENGTH]/2)/2])
  209. cube([Carabiner[OD]/2 - Offset - 0*ThreadWidth,
  210. 2*ThreadWidth,
  211. Carabiner[LENGTH]/2],center=false);
  212. for (i = [0:Spokes - 1])
  213. rotate(i * 360/Spokes)
  214. translate([Offset,-ThreadWidth,0])
  215. cube([Bezel[OD]/2 - Offset,
  216. 2*ThreadWidth,
  217. Bezel[LENGTH] - Reel[LENGTH]/2 - 2*ThreadThick],center=false);
  218. Bars = 7;
  219. render()
  220. difference() {
  221. union() {
  222. for (i = [-floor(Bars/2) : floor(Bars/2)])
  223. translate([-Carabiner[ID]/2,i*Carabiner[OD]/Bars,Carabiner[LENGTH]/4])
  224. cube([Carabiner[ID]/3,2*ThreadWidth,Carabiner[LENGTH]/2],center=true);
  225. translate([-Carabiner[ID]/2,0,ThreadThick/2])
  226. cube([Carabiner[ID]/3,Carabiner[ID],ThreadThick],center=true);
  227. }
  228. cylinder(d=Carabiner[ID] + 2*ThreadWidth,h=Carabiner[LENGTH]);
  229. }
  230. }
  231. if (Section == "Lower") {
  232. translate([0,0,-(Reel[LENGTH]/4 + ShimThick/2 - ThreadThick/2)])
  233. for (i = [0:8])
  234. rotate(i * 360/8)
  235. cube([Reel[OD] - 2*ThreadWidth,
  236. 2*ThreadWidth,
  237. Reel[LENGTH]/2 + ShimThick - ThreadThick],center=true);
  238. if (false) {
  239. Bars = 7;
  240. render()
  241. difference() {
  242. union() {
  243. for (i = [-floor(Bars/2) : floor(Bars/2)])
  244. translate([-Carabiner[ID]/2,i*Carabiner[OD]/Bars,-Carabiner[LENGTH]/4])
  245. cube([Carabiner[ID]/3,2*ThreadWidth,Carabiner[LENGTH]/2],center=true);
  246. translate([-Carabiner[ID]/2,0,-ThreadThick/2])
  247. cube([Carabiner[ID]/3,Carabiner[ID],ThreadThick],center=true);
  248. }
  249. translate([0,0,-Carabiner[LENGTH]])
  250. cylinder(d=Carabiner[ID] + 0*ThreadWidth,h=Carabiner[LENGTH]);
  251. }
  252. }
  253. }
  254. }
  255. }
  256.  
  257. }
  258.  
  259.  
  260.  
  261. //----------------------
  262. // Build it
  263.  
  264. if (Layout == "Beener")
  265. Beener();
  266.  
  267. if (Layout == "Mount")
  268. Mount();
  269.  
  270. if (Layout == "Reel")
  271. Reel();
  272.  
  273. if (Layout == "BezelMount")
  274. BezelMount();
  275.  
  276. Gap = 25;
  277. if (Layout == "Show") {
  278. translate([0,0,Gap/2])
  279. Mount("Upper");
  280. translate([0,0,-Gap/2])
  281. Mount("Lower");
  282. color("Green",0.3)
  283. Beener();
  284. color("Brown",0.3)
  285. Reel();
  286. color("Red",0.3)
  287. translate([0,0,-(Reel[LENGTH] + ShimThick)/2])
  288. cylinder(d=Reel[OD],h=ShimThick,center=true,$fn=6*4);
  289. }
  290.  
  291. if (Layout == "Build") {
  292. translate([(BCD + MountThick)/2,0,0])
  293. rotate(180)
  294. Mount("Upper");
  295. rotate([180,0,0])
  296. translate([-(BCD + MountThick)/2,0,0])
  297. Mount("Lower");
  298. }
  299.  
  300. if (Layout == "BuildUpper")
  301. Mount("Upper");
  302.  
  303. if (Layout == "BuildLower")
  304. rotate([180,0,0])
  305. Mount("Lower");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement