Advertisement
Guest User

Untitled

a guest
Jul 21st, 2017
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.37 KB | None | 0 0
  1. // Tour Easy Fairing Flashlight Mount
  2. // Ed Nisley KE4ZNU - July 2017
  3.  
  4. /* [Build Options] */
  5.  
  6. FlashName = "AnkerLC40"; // [AnkerLC40,AnkerLC90,J5TactV2,InnovaX5]
  7.  
  8. Component = "Mount"; // [Ball, BallClamp, Mount, Plates, Bracket]
  9.  
  10. Layout = "Show"; // [Build, Show]
  11.  
  12. Support = false;
  13.  
  14. MountSupport = true;
  15.  
  16. /* [Extrusion] */
  17.  
  18. ThreadThick = 0.25; // [0.20, 0.25]
  19. ThreadWidth = 0.40; // [0.40]
  20.  
  21. function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
  22.  
  23. Protrusion = 0.01; // [0.01, 0.1]
  24.  
  25. HoleWindage = 0.2;
  26.  
  27. /* [Fairing Mount] */
  28.  
  29. ToeIn = 0; // inward from ahead
  30. Tilt = 20; // upward from forward
  31. Roll = 0; // outward from top
  32.  
  33. Shift = -5; // realign to plate center
  34.  
  35. //- Screws *c
  36.  
  37. /* [Hidden] */
  38.  
  39. ID = 0;
  40. OD = 1;
  41. LENGTH = 2;
  42.  
  43. /* [Screws and Inserts] */
  44.  
  45. BallInsert = [2.0,3.5,4.0];
  46. BallScrew = [2.0,3.5,2.0];
  47.  
  48. ClampInsert = [3.0,4.2,8.0];
  49. ClampScrew = [3.0,5.9,50.0]; // thread dia, head OD, screw length
  50. ClampScrewWasher = [3.0,6.75,0.5];
  51. ClampScrewNut = [3.0,6.1,4.0]; // nyloc nut
  52.  
  53. /* [Hidden] */
  54.  
  55. F_NAME = 0;
  56. F_GRIPOD = 1;
  57. F_GRIPLEN = 2;
  58.  
  59. LightBodies = [
  60. ["AnkerLC90",26.6,48.0],
  61. ["AnkerLC40",26.6,55.0],
  62. ["J5TactV2",25.0,30.0],
  63. ["InnovaX5",22.0,55.0]
  64. ];
  65.  
  66. NumSides = 8*4;
  67.  
  68. echo(str("Flashlight: ",FlashName));
  69.  
  70. FlashIndex = search([FlashName],LightBodies,1,0)[F_NAME];
  71.  
  72. BallThick = IntegerMultiple(5.0,ThreadWidth); // thickness of ball wall
  73. echo(str("Ball wall: ",BallThick));
  74.  
  75. BallOD = max(45,IntegerMultiple(LightBodies[FlashIndex][F_GRIPOD] + 2*(BallThick + BallInsert[OD]),2.0));
  76. echo(str(" OD: ",BallOD));
  77.  
  78. BallScrewOC = BallOD - BallThick - BallInsert[OD]; // from OD to allow different body diameters
  79. echo(str(" screw OC: ",BallScrewOC));
  80.  
  81. BallLength = min(sqrt(pow(BallOD,2) - pow(LightBodies[FlashIndex][F_GRIPOD],2)),
  82. LightBodies[FlashIndex][F_GRIPLEN]);
  83. echo(str(" hole len: ",BallLength));
  84.  
  85. ClampThick = 2*ClampInsert[OD];
  86. echo(str("Clamp wall: ",ClampThick));
  87.  
  88. ClampOD = BallOD + 2*ClampThick;
  89. echo(str(" OD: ",ClampOD));
  90.  
  91. ClampScrewOC = BallOD + 2*ClampInsert[OD];
  92. echo(str(" screw OC: ",ClampScrewOC));
  93.  
  94. ClampLength = 0.70 * BallLength;
  95. echo(str(" length: ",ClampLength));
  96.  
  97. //- Adjust hole diameter to make the size come out right
  98.  
  99. module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes
  100. Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
  101. FixDia = Dia / cos(180/Sides);
  102. cylinder(r=(FixDia + HoleWindage)/2,h=Height,$fn=Sides);
  103. }
  104.  
  105. //- Ball around flashlight
  106. // Must print two!
  107.  
  108. module BodyBall() {
  109.  
  110. difference() {
  111. intersection() {
  112. sphere(d=BallOD,$fn=2*NumSides); // basic ball
  113. cube([BallLength,2*BallOD,2*BallOD],center=true); // max of flashlight grip length
  114. }
  115. translate([-LightBodies[FlashIndex][F_GRIPOD],0,0])
  116. rotate([0,90,0]) rotate(180/NumSides)
  117. PolyCyl(LightBodies[FlashIndex][F_GRIPOD],2*BallOD,NumSides); // flashlight body
  118. for (j=[-1,1])
  119. translate([0,j*BallScrewOC/2,0]) // commmon screw offset
  120. translate([0,0,-BallOD])
  121. PolyCyl(BallInsert[ID],2*BallOD,6); // punch screw shaft through everything
  122. translate([0,BallScrewOC/2,-Protrusion])
  123. PolyCyl(BallInsert[OD],(BallInsert[LENGTH] + 3*ThreadThick + Protrusion),6); // threaded insert
  124. translate([0,-BallScrewOC/2,BallThick])
  125. PolyCyl(BallScrew[OD],BallOD,6); // screw head clearance
  126.  
  127. translate([0,0,-BallOD/2]) // remove bottom half
  128. cube(BallOD,center=true);
  129. translate([0,0,BallOD - BallThick/2]) // slice off top = bottom for E-Z build
  130. cube(BallOD,center=true);
  131. }
  132.  
  133. if (Support) {
  134. NumRibs = 24;
  135. RibHeight = (BallOD - LightBodies[FlashIndex][F_GRIPOD]/cos(180/NumSides) - BallThick) / 2;
  136. ChordC = 2*sqrt(BallThick*BallOD/2 - pow(BallThick/2,2));
  137. intersection() {
  138. cube([BallLength,2*BallOD,2*BallOD],center=true); // max of flashlight grip length
  139. translate([0,0,BallOD/2 - BallThick/2])
  140. for (i=[0:NumRibs - 1])
  141. rotate(i*360/NumRibs + 180/NumRibs) // avoid screw holes
  142. translate([ChordC/2 + BallOD/8,0,-RibHeight/2])
  143. cube([BallOD/4,2*ThreadWidth,RibHeight],center=true);
  144. }
  145. }
  146. }
  147.  
  148. //- Fairing Bracket
  149. // Magic numbers taken from the actual fairing mount
  150. // Centered on screw hole
  151.  
  152. /* [Hidden] */
  153.  
  154. inch = 25.4;
  155.  
  156. BracketHoleOD = 0.25 * inch; // 1/4-20 bolt holes
  157.  
  158. BracketHoleOC = 1.0 * inch; // fairing hole spacing
  159. // usually 1 inch, but 15/16 on one fairing
  160.  
  161. Bracket = [48.0,16.3,3.6 - 0.6]; // fairing bracket end plate overall size
  162. BracketHoleOffset = (3/8) * inch; // end to hole center
  163.  
  164. BracketM = 3.0; // endcap arc height
  165. BracketR = (pow(BracketM,2) + pow(Bracket[1],2)/4) / (2*BracketM); // ... radius
  166.  
  167. module Bracket() {
  168.  
  169. linear_extrude(height=Bracket[2],convexity=2)
  170. difference() {
  171. translate([(Bracket[0]/2 - BracketHoleOffset),0,0])
  172. offset(delta=ThreadWidth)
  173. intersection() {
  174. square([Bracket[0],Bracket[1]],center=true);
  175. union() {
  176. for (i=[-1,0,1]) // middle circle fills gap
  177. translate([i*(Bracket[0]/2 - BracketR),0])
  178. circle(r=BracketR);
  179. }
  180. }
  181. circle(d=BracketHoleOD/cos(180/8),$fn=8); // dead center at the origin
  182. }
  183.  
  184. }
  185.  
  186. //- General plate shape
  187. // Centered on the hole for the fairing bracket
  188.  
  189. Plate = [100.0,30.0,6*ThreadThick + Bracket[2]];
  190. PlateRad = Plate[1]/4;
  191.  
  192. echo(str("Base plate thick: ",Plate[2]));
  193.  
  194. module PlateBlank() {
  195.  
  196. difference() {
  197. translate([BracketHoleOC,0,0])
  198. intersection() {
  199. translate([0,0,Plate[2]/2]) // select upper half of spheres
  200. cube(Plate,center=true);
  201. hull()
  202. for (i=[-1,1], j=[-1,1])
  203. translate([i*(Plate[0]/2 - PlateRad),j*(Plate[1]/2 - PlateRad),0])
  204. resize([2*PlateRad,2*PlateRad,2*Plate[2]])
  205. sphere(r=PlateRad); // nice rounded corners!
  206. }
  207. translate([2*BracketHoleOC,0,-Protrusion]) // screw holes
  208. PolyCyl(BracketHoleOD,2*Plate[2],8);
  209. translate([0,0,-Protrusion])
  210. PolyCyl(BracketHoleOD,2*Plate[2],8);
  211. }
  212. }
  213.  
  214. //- Inner plate
  215.  
  216. module InnerPlate() {
  217.  
  218. difference() {
  219. PlateBlank();
  220. translate([0,0,Plate[2] - Bracket[2] + Protrusion]) // punch out fairing bracket
  221. Bracket();
  222. }
  223. }
  224.  
  225. //- Clamp around flashlight ball
  226.  
  227. module BallClamp() {
  228.  
  229. BossLength = ClampScrew[LENGTH] - ClampScrewNut[LENGTH] - 2*ClampScrewWasher[LENGTH] - 4*ThreadThick;
  230.  
  231. difference() {
  232. union() {
  233. intersection() {
  234. sphere(d=ClampOD,$fn=NumSides); // exterior ball blamp
  235. cube([ClampLength,2*ClampOD,2*ClampOD],center=true); // aiming allowance
  236. }
  237. for (i=[0])
  238. hull() {
  239. for (j=[-1,1])
  240. translate([i*(ClampLength/2 - ClampScrew[OD]),j*ClampScrewOC/2,-BossLength/2])
  241. rotate(180/8)
  242. cylinder(d=(ClampScrewWasher[OD] + 2*ThreadWidth),h=BossLength,$fn=8);
  243. }
  244. }
  245.  
  246. sphere(d=(BallOD + 1*ThreadThick),$fn=NumSides); // interior ball
  247.  
  248. for (i=[0] , j=[-1,1]) {
  249. translate([i*(ClampLength/2 - ClampScrew[OD]),j*ClampScrewOC/2,-ClampOD]) // screw clearance
  250. rotate(180/8)
  251. PolyCyl(ClampScrew[ID],2*ClampOD,8);
  252. }
  253.  
  254. }
  255.  
  256.  
  257. color("Yellow")
  258. if (Support) { // ad-hoc supports for top half
  259. NumRibs = 6;
  260. RibLength = 0.5 * BallOD;
  261. RibWidth = 1.9*ThreadWidth;
  262. SupportOC = ClampLength / NumRibs;
  263.  
  264. cube([ClampLength,RibLength,4*ThreadThick],center=true); // base plate for adhesion
  265.  
  266. intersection() {
  267. sphere(d=BallOD - 0*ThreadWidth); // cut at inner sphere OD
  268. cube([ClampLength + 2*ThreadWidth,RibLength,BallOD],center=true);
  269. union() { // ribs for E-Z build
  270. for (j=[-1,0,1])
  271. translate([0,j*SupportOC,0])
  272. cube([ClampLength,RibWidth,1.0*BallOD],center=true);
  273. for (i=[0:NumRibs]) // allow +1 to fill the far end
  274. translate([i*SupportOC - ClampLength/2,0,0])
  275. rotate([0,90,0])
  276. cylinder(d=BallOD - 2*ThreadThick,
  277. h=RibWidth,$fn=NumSides,center=true);
  278. }
  279. }
  280. }
  281. }
  282.  
  283. //- Mount between fairing plate and flashlight ball
  284.  
  285. module Mount() {
  286.  
  287. translate([-BracketHoleOC,0,0])
  288. PlateBlank();
  289.  
  290. translate([Shift,0,ClampOD/2])
  291. rotate([-Roll,ToeIn,Tilt])
  292. intersection() {
  293. translate([0,0,-ClampOD/2])
  294. cube([2*ClampOD,2*ClampOD,ClampOD],center=true);
  295. BallClamp();
  296. }
  297.  
  298. if (MountSupport) { // anchor outer corners during worst overhang
  299. RibWidth = 1.9*ThreadWidth;
  300. SupportOC = 0.1 * ClampLength;
  301. difference() {
  302. rotate([0,0,Tilt])
  303. translate([Shift + 0.3,0,0])
  304. for (i=[-4.5,-2.5,0,2.0,4.5])
  305. translate([i*SupportOC - 0.0,0,(ClampThick + Plate[2])/2])
  306. cube([RibWidth,0.8*ClampOD,(ClampThick + Plate[2])],center=true);
  307. # translate([Shift,0,ClampOD/2])
  308. rotate([-Roll,ToeIn,Tilt])
  309. sphere(d=ClampOD - 2*ThreadWidth,$fn=NumSides);
  310. }
  311. }
  312. }
  313.  
  314. //- Build things
  315.  
  316. if (Component == "Ball")
  317. if (Layout == "Show")
  318. BodyBall();
  319. else if (Layout == "Build") {
  320. translate([0,+1*(BallOD/2 + BallThick/2),0])
  321. translate([0,0,BallOD/2 - BallThick/2])
  322. rotate([180,0,0])
  323. BodyBall();
  324. translate([0,-1*(BallOD/2 + BallThick/2),0])
  325. translate([0,0,BallOD/2 - BallThick/2])
  326. rotate([180,0,0])
  327. BodyBall();
  328. }
  329.  
  330. if (Component == "BallClamp")
  331. if (Layout == "Show")
  332. BallClamp();
  333. else if (Layout == "Build") {
  334. Both = false;
  335. difference() {
  336. union() {
  337. translate([Both ? ClampLength : 0,0,0])
  338. BallClamp();
  339. if (Both)
  340. translate([-ClampLength,0,0])
  341. rotate([180,0,0])
  342. BallClamp();
  343. }
  344. translate([0,0,-ClampOD/2])
  345. cube([2*ClampOD,2*ClampOD,ClampOD],center=true);
  346. }
  347. }
  348.  
  349. if (Component == "Mount")
  350. Mount();
  351.  
  352. if (Component == "Plates") {
  353. translate([0,0.7*Plate[1],0])
  354. InnerPlate();
  355. translate([0,-0.7*Plate[1],0])
  356. PlateBlank();
  357. }
  358.  
  359. if (Component == "Bracket")
  360. Bracket();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement