TinySpHEAR_H2N_common.scad 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151
  1. //
  2. // Spherical Harmonics Ear Project (*SpHEAR)
  3. //
  4. // TinySpHEAR, First Order (B-format) Ambisonics Microphone
  5. // Common files for H2N add-on array
  6. //
  7. // Copyright 2016-2017, Fernando Lopez-Lezcano, All Rights Reserved
  8. // nando@ccrma.stanford.edu
  9. //
  10. // This program is free software: you can redistribute it and/or modify
  11. // it under the terms of the GNU General Public License as published by
  12. // the Free Software Foundation, either version 3 of the License, or
  13. // (at your option) any later version.
  14. //
  15. // This program is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. // GNU General Public License for more details.
  19. //
  20. // You should have received a copy of the GNU General Public License
  21. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. //
  23. // 3d Models released under the Creative Commons license as follows:
  24. // Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
  25. // http://creativecommons.org/licenses/by-nc-sa/4.0/
  26. include <SpHEAR_common.scad>;
  27. include <SpHEAR_windscreen.scad>;
  28. include <TinySpHEAR_common.scad>;
  29. include <TinySpHEAR_mount_pcb.scad>;
  30. // http://dkprojects.net/openscad-threads/
  31. // used for the threads of the mini-xlm connectors
  32. include <threads.scad>;
  33. // outline of H2N front
  34. // include<h2n/H2N_front_outline.scad>;
  35. // outline of H2N top
  36. // include<h2n/H2N_top_up_outline.scad>;
  37. facets = 128;
  38. // dimensions of the EM200 electret microphone capsule (measured 14.59 max)
  39. capsule_radius = 14.6 / 2;
  40. capsule_height = 4.75;
  41. mic_radius = 11;
  42. // dimensions of the EM182 electret microphone capsule (measured 10mm)
  43. //capsule_radius = 10.0 / 2;
  44. //capsule_height = 4.5;
  45. //mic_radius = 9.2;
  46. // adjust the depth of slots in mount
  47. mic_to_mount_fit = -0.4;
  48. // make triangular legs have the height of the capsule
  49. connect = 1;
  50. leg_thick = capsule_height;
  51. // dimensions of H2R recorder
  52. // width and depth at middle of ring
  53. h2n_width = 62.00;
  54. h2n_depth = 42.66;
  55. h2n_width_up = 57.0;
  56. // h2n_column_height = 40;
  57. // h2n_column_height = 25.3;
  58. h2n_column_height = 23.2;
  59. transition_height = 30;
  60. // measured = 11.50, should be 13.1 -> ratio =
  61. h2n_side_band = 1.5;
  62. h2n_side_band_w = 13.4;
  63. // h2n_width_m: tried taking out 0.5mm from the original measurement of 63.0, but
  64. // it is too much and the "Menu" button stops working, 0.25mm seems fine
  65. h2n_width_m = 63.0 - 0.25;
  66. h2n_depth_m = 36.4;
  67. h2n_band_height = 6.0;
  68. // base band width
  69. h2n_band_wall = 1.6;
  70. // wall for the stalk
  71. h2n_stalk_wall = 1.0;
  72. // walls for the columns
  73. h2n_col_wall = 2 * wall;
  74. // tilt for the columnds
  75. h2n_col_tilt = 4.0;
  76. // radius of mount stalk
  77. h2n_mount_radius = mount_radius;
  78. // fit for connector from column to bridge
  79. h2n_mount_fit = 0.04;
  80. // bridge dimensions
  81. h2n_bridge_base_height = 7.0;
  82. h2n_bridge_stalk_height = 45.0;
  83. // bridge funnel and stalk dimensions
  84. h2n_bridge_array_height = 51;
  85. h2n_bridge_cylinder_height = 30;
  86. // thread pedestal
  87. h2n_thread_pedestal = 0.5;
  88. // bridge base dimensions
  89. h2n_bridge_circle = 24.00;
  90. h2n_bridge_band_w = 13.25;
  91. h2n_bridge_band_h = 3.30; // 26.5 - h2n_column_height;
  92. // we need to make the dial cover slightly elliptical
  93. h2n_bridge_circle_max = 26.5;
  94. h2n_bridge_circle_ratio = h2n_bridge_circle_max / h2n_bridge_circle;
  95. // mini-xlr connector parameters
  96. h2n_xlr_thread_diam = 10.0;
  97. h2n_xlr_thread_pitch = 0.75;
  98. h2n_xlr_thread_height = 6.0;
  99. h2n_xlr_thread_depth = 0.614 * h2n_xlr_thread_pitch;
  100. h2n_xlr_height = 30;
  101. h2n_xlr_shoulder = 1.25;
  102. h2n_xlr_stalk_height = 40.0;
  103. module tube(or, ir, h) {
  104. difference() {
  105. cylinder(r = or, h = h, $fn = facets);
  106. cylinder(r = ir, h = h, $fn = facets);
  107. }
  108. }
  109. // main support ring
  110. module h2n_ring(width, depth, radius, height, tilt, slot_w, slot_d, band_wall, wall, col_rad, col_wall) {
  111. // main support ring
  112. difference() {
  113. conical_rounded_box(height, width / 2 + band_wall, depth / 2 + band_wall, radius - thin_mint, band_wall, height * tan(tilt));
  114. for (m = [0, 1]) mirror([m, 0, 0]) {
  115. translate([-(width / 2 + col_rad - col_wall), 0, 0]) {
  116. tilted_cylinder(col_rad, height + thin_mint, height * tan(tilt));
  117. }
  118. }
  119. }
  120. // inner band
  121. difference() {
  122. conical_rounded_box(height, width / 2 + wall - h2n_side_band, depth / 2 + wall, radius - thin_mint, wall, height * tan(tilt));
  123. for (m = [0, 1]) mirror([m, 0, 0]) {
  124. // cut slots on the sides
  125. translate([-width / 2 - wall / 2, -h2n_side_band_w / 2, 0]) {
  126. cube([width / 2, h2n_side_band_w, height + thin_mint]);
  127. }
  128. }
  129. }
  130. // add TinySpHEAR "branding"
  131. translate([0, -(h2n_depth_m / 2 + band_wall - 0.55 * wall), h2n_band_height / 2]) scale(0.5) {
  132. rotate([90 - h2n_col_tilt, 0, 0]) {
  133. linear_extrude(height = wall, center = "true") {
  134. text("TinySpHEAR", size = 8.0, spacing = 1.1, halign = "center", valign = "center", font = "Liberation Sans");
  135. }
  136. }
  137. }
  138. }
  139. // side columns
  140. module tilted_cylinder(radius, height, offset) {
  141. hull() {
  142. cylinder(r = radius, h = thin_mint, $fn = facets);
  143. translate([offset, 0, height]) {
  144. cylinder(r = radius, h = thin_mint, $fn = facets);
  145. }
  146. }
  147. }
  148. module tilted_rounded_box(height, width, depth, radius, wall, offset) {
  149. difference() {
  150. hull() {
  151. rounded_block(thin_mint, width, depth, radius);
  152. translate([offset, 0, height]) {
  153. rounded_block(thin_mint, width, depth, radius);
  154. }
  155. }
  156. hull() {
  157. rounded_block_relative(thin_mint, width, depth, radius, -wall);
  158. translate([offset, 0, height]) {
  159. rounded_block_relative(thin_mint, width, depth, radius, -wall);
  160. }
  161. }
  162. }
  163. }
  164. module conical_rounded_box(height, width, depth, radius, wall, inset) {
  165. difference() {
  166. hull() {
  167. rounded_block(thin_mint, width, depth, radius);
  168. translate([0, 0, height]) {
  169. rounded_block_relative(thin_mint, width, depth, radius, -inset);
  170. }
  171. }
  172. hull() {
  173. rounded_block_relative(thin_mint, width, depth, radius, -wall);
  174. translate([0, 0, height]) {
  175. rounded_block_relative(thin_mint, width, depth, radius, -(wall + inset));
  176. }
  177. }
  178. }
  179. }
  180. module tilted_cube(width, depth, height, offset) {
  181. hull() {
  182. cube([width, depth, thin_mint]);
  183. translate([offset, 0, height]) {
  184. cube([width, depth, thin_mint]);
  185. }
  186. }
  187. }
  188. module tilted_half_rounded_box(height, width, depth, radius, wall, offset, e = 0.1) {
  189. difference() {
  190. tilted_rounded_box(height, width, depth, radius, wall, offset);
  191. translate([0, -(depth + e), 0]) {
  192. tilted_cube(width + e, (depth + e) * 2, height, offset);
  193. }
  194. }
  195. }
  196. module half_rounded_box(height, width, depth, radius, wall, e = 0.1) {
  197. difference() {
  198. rounded_box(height, width , depth, radius, wall);
  199. translate([0, -(depth + e), 0]) {
  200. cube([width + e, 2 * (depth + e), height]);
  201. }
  202. }
  203. }
  204. module h2n_column_core(height, ring_height, tilt, transition, radius, col_wall, wall, offset) {
  205. hull() {
  206. // angled column
  207. difference() {
  208. tilted_cylinder(radius + col_wall + offset, height, height * tan(tilt));
  209. translate([0, -(radius + col_wall + offset), 0]) {
  210. tilted_cube((radius + col_wall) * 2, (radius + col_wall) * 2, height, height * tan(tilt));
  211. }
  212. }
  213. // side sleeves
  214. // we should derive the geometry for the aligment magic below...
  215. side_fit = 0.5;
  216. translate([(radius + col_wall) / 2 + 2 * wall - side_fit, 0, 0]) {
  217. difference() {
  218. tilted_half_rounded_box(height, 3.8 + offset, h2n_side_band_w / 2 + wall + offset * 1.1,
  219. 2.0, wall, height * tan(tilt));
  220. translate([col_wall / 2 + wall - radius * 3 / 2 - side_fit, 0, 0]) {
  221. tilted_cylinder(radius, height, height * tan(tilt));
  222. }
  223. }
  224. }
  225. }
  226. }
  227. module h2n_column(height, ring_height, tilt, transition, radius, col_wall, wall, screw_mount) {
  228. difference() {
  229. union() {
  230. // side tubes for cables
  231. difference() {
  232. h2n_column_core(height, ring_height, tilt, transition, radius, col_wall, wall, 0);
  233. // hollow out the cylinder
  234. translate([0, 0, screw_mount]) tilted_cylinder(radius, height, height * tan(tilt));
  235. // and shave the inside for the screw mount side
  236. if (screw_mount > 0) {
  237. translate([0, -radius, 0]) {
  238. tilted_cube(wall * 2, radius * 2, height, height * tan(tilt));
  239. }
  240. }
  241. // this fine adjustment determines how much the side walls "hug" the H2N
  242. width_fit = 0.2;
  243. translate([radius + 2 * wall - width_fit, 0, 0]) {
  244. tilted_half_rounded_box(height + thin_mint, 3.8, h2n_side_band_w / 2, 1.5, 4 * wall, height * tan(tilt));
  245. }
  246. // trim side of tubes with a vertical plane
  247. translate([-(radius * 2 + col_wall) + col_wall / 2, -(radius + col_wall), 0]) {
  248. cube([col_wall * 2, (radius + col_wall) * 2, 30]);
  249. }
  250. }
  251. // add a thicker wall at the bottom of the side trim
  252. difference() {
  253. translate([-(radius), -(radius + col_wall), 0]) {
  254. cube([wall, (radius + col_wall) * 2, height]);
  255. }
  256. difference() {
  257. tilted_cylinder(radius * 4, height, height * tan(tilt));
  258. tilted_cylinder(radius + col_wall, height, height * tan(tilt));
  259. }
  260. }
  261. }
  262. // holes for screws that attach to the columns
  263. // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
  264. if (screw_mount > 0) {
  265. translate([-2 * radius, 0, screw_mount * 3/4]) {
  266. rotate([0, 90, 0]) {
  267. cylinder(r = (1.6 + 0.1)/2, h = 4 * radius, $fn = facets);
  268. }
  269. rotate([0, 90, 0]) {
  270. cylinder(r = 3.25/2, h = 1.75 * radius, $fn = facets);
  271. }
  272. }
  273. }
  274. }
  275. // connector to bridge
  276. translate([height * tan(tilt), 0, height]) {
  277. connector_height = 5.0;
  278. difference() {
  279. union() {
  280. difference() {
  281. union() {
  282. cylinder(r = radius + wall - h2n_mount_fit, h = connector_height, $fn = facets);
  283. h2n_column_core(h2n_bridge_band_h, ring_height, 0, transition, radius, col_wall, wall, -(wall + h2n_mount_fit));
  284. }
  285. cylinder(r = radius, h = connector_height, $fn = facets);
  286. translate([1.5, -(radius + wall) * 2, 0]) {
  287. cube([radius + wall, (radius + wall) * 4, connector_height]);
  288. }
  289. }
  290. // add anchor for retaining screw
  291. difference() {
  292. translate([-radius, 0, radius]) {
  293. sphere(r = radius * 2/3, $fn = facets);
  294. }
  295. // and clip out the rest of the sphere
  296. difference() {
  297. cylinder(r = 2 * radius + wall, h = height);
  298. cylinder(r = radius + wall - h2n_mount_fit, h = height);
  299. }
  300. translate([0, 0, connector_height]) {
  301. cylinder(r = radius + wall, h = connector_height);
  302. }
  303. }
  304. }
  305. // make hole for screw
  306. // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
  307. translate([-(radius + 2 * wall), 0, radius]) {
  308. rotate([0, 90, 0]) {
  309. cylinder(r = 0.7, h = radius + wall, $fn = facets);
  310. }
  311. }
  312. }
  313. }
  314. }
  315. module h2n_columns(width, height, ring_height, tilt, transition, radius, col_wall, wall) {
  316. for (m = [0, 1]) mirror([m, 0, 0]) {
  317. screw_mount = height * 3/4 * (1 - m);
  318. translate([-(width / 2 + col_wall - wall / 2), 0, 0]) {
  319. h2n_column(height, ring_height, tilt, transition, radius, col_wall, wall, screw_mount);
  320. }
  321. }
  322. }
  323. // old version of columns
  324. module h2n_columns_old(width, height, ring_height, tilt, transition, radius, col_wall, wall) {
  325. // side tubes for cables
  326. slot_height = 25.0;
  327. for (m = [0, 1]) mirror([m, 0, 0]) {
  328. translate([-(width / 2 + radius - col_wall), 0, 0]) {
  329. difference() {
  330. // angled column
  331. tilted_cylinder(radius + col_wall, height, height * tan(tilt));
  332. tilted_cylinder(radius, height, height * tan(tilt));
  333. // slots in the columns for cables
  334. translate([radius - col_wall - ring_height * tan(tilt), - radius * 2, -ring_height]) {
  335. rotate([0, tilt, 0]) {
  336. cube([5.0, radius * 4, slot_height]);
  337. translate([radius + col_wall, radius - col_wall, slot_height]) {
  338. rotate([0, 90, 90]) {
  339. cylinder(r = radius + col_wall, h = 15.0, $fn = facets);
  340. }
  341. }
  342. }
  343. }
  344. // trim side of tubes with a vertical plane
  345. translate([-(radius * 2 + col_wall) + col_wall / 2, -(radius + col_wall), 0]) {
  346. cube([col_wall * 2, (radius + col_wall) * 2, 30]);
  347. }
  348. }
  349. // add a thicker wall at the bottom of the side trim
  350. difference() {
  351. translate([-(radius), -(radius + col_wall), 0]) {
  352. cube([wall, (radius + col_wall) * 2, height]);
  353. }
  354. difference() {
  355. tilted_cylinder(radius * 4, height, height * tan(tilt));
  356. tilted_cylinder(radius + col_wall, height, height * tan(tilt));
  357. }
  358. }
  359. }
  360. // connector to bridge
  361. translate([-(width / 2 + radius - col_wall - height * tan(tilt)), 0, height]) {
  362. connector_height = 5.0;
  363. difference() {
  364. tube(radius + wall - h2n_mount_fit, radius, connector_height);
  365. translate([0, -(radius + wall), connector_height / 2]) {
  366. cube([radius + wall, (radius + wall) * 2, connector_height / 2]);
  367. }
  368. }
  369. }
  370. // side sleeves
  371. sleeve_height = slot_height;
  372. // XXX sleeve_height = slot_height - mount_radius - col_wall;
  373. for (m = [0, 1]) mirror([m, 0, 0]) {
  374. // we should derive the geometry for the aligment magic below...
  375. side_fit = 1.05;
  376. translate([-(width / 2 - (radius + col_wall) / 2 + wall - side_fit), 0, 0]) {
  377. difference() {
  378. tilted_half_rounded_box(sleeve_height, 3.8, h2n_side_band_w / 2 + wall, 2.0, wall, sleeve_height * tan(tilt));
  379. translate([col_wall / 2 + wall - radius * 3 / 2 - side_fit, 0, 0]) {
  380. tilted_cylinder(radius, height, height * tan(tilt));
  381. }
  382. }
  383. }
  384. }
  385. }
  386. }
  387. // bridge that connects to capsule array
  388. module semi_cylinder(r, h, e = thin_mint) {
  389. difference() {
  390. cylinder(h, r, r, $fn = facets);
  391. translate ([-r*2, -r, 0])
  392. cube([2*(r+e), 2*(r+e), h]);
  393. }
  394. }
  395. module quarter_sphere(r, e = thin_mint) {
  396. difference() {
  397. sphere(r, $fn = facets);
  398. translate([-(r+e), -(r+e), -(r+e)])
  399. cube([2*(r+e), 2*(r+e), r+e]);
  400. translate([-(r+e), -(r+e), -e])
  401. cube([r, 2*(r+e), (r+e)]);
  402. }
  403. }
  404. module cylcube(width, depth, height, wall) {
  405. difference() {
  406. semi_cylinder(r = depth, h = height);
  407. semi_cylinder(r = depth - wall, h = height);
  408. }
  409. translate([-(width + depth / 2), -depth, 0]) {
  410. difference() {
  411. cube([(width + depth / 2), depth * 2, height]);
  412. translate([0, wall, 0]) {
  413. cube([(width + depth), (depth - wall) * 2, height]);
  414. }
  415. }
  416. }
  417. }
  418. // old version of the bridge
  419. module h2n_bridge_old(width, base_height, stalk_height, radius, col_wall, wall) {
  420. // capsule array mount with the right orientation (left front top = #1)
  421. rotate([0, 0, -90]) translate([0, 0, base_height + stalk_height]) {
  422. tetra_capsule_array_mount([-45, 135]);
  423. }
  424. // stalk
  425. translate([0, 0, base_height]) {
  426. difference() {
  427. tube(radius + wall, radius, stalk_height);
  428. // remove stalk segment that is inside the bridge
  429. translate([width / 2, 0, -1.0]) {
  430. rotate([0, -90, 0]) {
  431. semi_cylinder(r = radius + col_wall, h = width);
  432. }
  433. }
  434. }
  435. // add marker for "back of microphone" orientation
  436. rotate([0, 0, 0]) {
  437. translate([0, radius + wall - wall * 2 / 3, stalk_height - radius]) {
  438. difference() {
  439. sphere(r = radius / 3, $fn = 32);
  440. translate([0, -radius + radius / 2, 0]) {
  441. cube([radius, radius, radius], center = true);
  442. }
  443. }
  444. }
  445. }
  446. }
  447. // top of bridge
  448. translate([width / 2, 0, base_height]) {
  449. rotate([0, -90, 0]) {
  450. difference() {
  451. // curvy ceiling
  452. semi_cylinder(r = radius + col_wall, h = width);
  453. semi_cylinder(r = radius + col_wall - wall, h = width);
  454. // make a hole for the cables
  455. translate([0, 0, width / 2]) {
  456. rotate([0, 90, 0]) {
  457. cylinder(r = radius, h = 10, $fn = facets);
  458. }
  459. }
  460. }
  461. }
  462. }
  463. // caps at ends
  464. for (m = [0, 1]) mirror([m, 0, 0]) {
  465. translate([width / 2, 0, base_height]) {
  466. difference() {
  467. quarter_sphere(r = radius + col_wall);
  468. quarter_sphere(r = radius + col_wall - wall);
  469. }
  470. }
  471. }
  472. // base of bridge
  473. translate([0, 0, 0]) {
  474. for (m = [0, 1]) mirror([m, 0, 0]) {
  475. translate([width / 2, 0, 0]) {
  476. cylcube(width / 2, radius + col_wall, base_height, wall);
  477. }
  478. }
  479. }
  480. // reinforcement beams at the base
  481. translate([-col_wall / 2, -(radius + wall), 0]) {
  482. cube([col_wall, (radius + wall) * 2, col_wall]);
  483. }
  484. for (m = [0, 1]) mirror([m, 0, 0]) {
  485. translate([-width / 2 + radius + wall, -(radius + wall), 0]) {
  486. cube([col_wall, (radius + wall) * 2, col_wall]);
  487. }
  488. }
  489. }
  490. // base plate for upper band cover
  491. module h2n_center_cover_no_ws(width, base_height, radius, wall, offset) {
  492. bot_step = h2n_bridge_band_h;
  493. difference() {
  494. union() {
  495. for (m = [0, 1]) mirror([m, 0, 0]) {
  496. // core of bridge
  497. translate([width/2, -thin_mint / 2, 0]) {
  498. cylcube(width / 2 + offset, radius + offset + 2 * wall, bot_step, wall);
  499. }
  500. // we should derive the geometry for the aligment magic below...
  501. side_fit = 1.05;
  502. corner_radius = 2.0;
  503. tilted_half_rounded_box(bot_step, width / 2 + offset - wall / 2, h2n_side_band_w / 2 + offset + wall,
  504. corner_radius, wall, 0);
  505. }
  506. }
  507. // clear the inside
  508. // outer frame
  509. rounded_block(bot_step + thin_mint, width / 2 + offset - 1.5 * wall, h2n_side_band_w / 2 + offset, 2);
  510. // inner frame
  511. translate([-(width + offset) / 2, -(radius + wall + offset), 0]) {
  512. cube([width + offset, (radius + wall + offset) * 2, bot_step + thin_mint]);
  513. }
  514. }
  515. }
  516. module h2n_center_cover(width, base_height, radius, wall, offset) {
  517. bot_step = h2n_bridge_band_h;
  518. difference() {
  519. union() {
  520. for (m = [0, 1]) mirror([m, 0, 0]) {
  521. // core of bridge
  522. translate([width/2, -thin_mint / 2, 0]) {
  523. cylcube(width / 2 + offset, radius + offset + 2 * wall, bot_step, wall);
  524. }
  525. // we should derive the geometry for the aligment magic below...
  526. side_fit = 1.05;
  527. corner_radius = 2.0;
  528. tilted_half_rounded_box(bot_step, width / 2 + offset - wall / 2, h2n_side_band_w / 2 + offset + wall,
  529. corner_radius, wall, 0);
  530. }
  531. }
  532. // clear the inside
  533. // outer frame
  534. rounded_block(bot_step + thin_mint, width / 2 + offset - 1.5 * wall, h2n_side_band_w / 2 + offset, 2);
  535. // inner frame
  536. translate([-(width + offset) / 2, -(radius + wall + offset), 0]) {
  537. cube([width + offset, (radius + wall + offset) * 2, bot_step + thin_mint]);
  538. }
  539. }
  540. }
  541. // base plate for upper center dial cover
  542. module h2n_center_dial_cover(radius, wall, offset) {
  543. scale([h2n_bridge_circle_ratio, 1, 1]) {
  544. tube(radius + wall + offset, radius + offset, h2n_bridge_band_h);
  545. }
  546. }
  547. // the core of the bridge, a solid offset-able version
  548. module h2n_bridge_core_no_ws(width, base_height, radius, col_wall, wall, offset) {
  549. hull() {
  550. // top of bridge
  551. translate([width / 2, 0, base_height]) {
  552. rotate([0, -90, 0]) {
  553. // curvy ceiling
  554. semi_cylinder(r = radius + offset + col_wall, h = width + offset);
  555. }
  556. }
  557. // spherical caps at ends
  558. for (m = [0, 1]) mirror([m, 0, 0]) {
  559. translate([width / 2, 0, base_height]) {
  560. quarter_sphere(r = radius + offset + col_wall);
  561. }
  562. }
  563. // bottom plate
  564. h2n_center_cover(width, base_height, radius, wall, offset);
  565. }
  566. // add cover for center dial
  567. hull() {
  568. cylinder(r = mount_radius + offset, h = base_height + radius, $fn = facets);
  569. h2n_center_dial_cover(h2n_bridge_circle / 2, wall, offset);
  570. }
  571. }
  572. module h2n_bridge_core(width, base_height, radius, col_wall, wall, thread_radius, thread_height, offset) {
  573. difference() {
  574. hull() {
  575. // top of bridge
  576. translate([width / 2, 0, base_height]) {
  577. rotate([0, -90, 0]) {
  578. // curvy ceiling
  579. semi_cylinder(r = radius + offset + col_wall, h = width + offset);
  580. }
  581. }
  582. // spherical caps at ends
  583. for (m = [0, 1]) mirror([m, 0, 0]) {
  584. translate([width / 2, 0, base_height]) {
  585. quarter_sphere(r = radius + offset + col_wall);
  586. }
  587. }
  588. // bottom plate
  589. h2n_center_cover(width, base_height, radius, wall, offset);
  590. // cover for center dial
  591. h2n_center_dial_cover(h2n_bridge_circle / 2, wall, offset);
  592. // base of windscreen mounting thread
  593. if (thread_radius > 0) {
  594. translate([0, 0, base_height + radius + col_wall + offset]) {
  595. cylinder(r = thread_radius + windscreen_thread_depth + offset, h = wall, $fn = facets);
  596. }
  597. }
  598. }
  599. // make hole for cables
  600. translate([0, 0, base_height + radius + col_wall]) {
  601. cylinder(r = thread_radius - windscreen_thread_depth - wall, h = wall + thin_mint, $fn = facets);
  602. }
  603. }
  604. if (thread_radius > 0 && offset == 0) {
  605. // pedestal for thread
  606. translate([0, 0, base_height + radius + col_wall + offset + h2n_thread_pedestal]) {
  607. difference() {
  608. cylinder(r = thread_radius + windscreen_thread_depth + offset, h = wall, $fn = facets);
  609. cylinder(r = thread_radius - windscreen_thread_depth - wall, h = wall, $fn = facets);
  610. }
  611. }
  612. // thread
  613. translate([0, 0, base_height + radius + col_wall + wall + h2n_thread_pedestal]) {
  614. difference() {
  615. metric_thread(diameter = thread_radius * 2, pitch = windscreen_thread_pitch,
  616. length = thread_height, angle = windscreen_thread_angle, internal = false);
  617. cylinder(r = thread_radius - wall - windscreen_thread_depth, h = thread_height + thin_mint, $fn = facets);
  618. }
  619. }
  620. }
  621. }
  622. // the bridge that holds the capsule array
  623. module h2n_bridge_no_ws(width, base_height, stalk_height, radius, col_wall, stalk_wall, wall) {
  624. // capsule array mount with the right orientation (left front top = #1)0
  625. rotate([0, 0, -90]) translate([0, 0, base_height + stalk_height]) {
  626. tetra_capsule_array_mount([-45, 135], mount_radius, stalk_wall);
  627. }
  628. difference() {
  629. union() {
  630. h2n_bridge_core(width, base_height, radius, col_wall, wall, 0);
  631. // stalk
  632. translate([0, 0, base_height]) {
  633. difference() {
  634. tube(radius + stalk_wall, radius, stalk_height);
  635. // remove stalk segment that is inside the bridge
  636. translate([width / 2, 0, -1.0]) {
  637. rotate([0, -90, 0]) {
  638. semi_cylinder(r = radius + stalk_wall, h = width);
  639. }
  640. }
  641. }
  642. // add marker for "back of microphone" orientation
  643. rotate([0, 0, 0]) {
  644. translate([0, radius + stalk_wall - stalk_wall * 2 / 3, stalk_height - (radius + stalk_wall)]) {
  645. difference() {
  646. sphere(r = (radius + stalk_wall) / 3, $fn = 64);
  647. translate([0, -(radius + stalk_wall) + (radius + stalk_wall) / 2, 0]) {
  648. cube([radius + stalk_wall, radius + stalk_wall, radius + stalk_wall], center = true);
  649. }
  650. }
  651. }
  652. }
  653. }
  654. // small supports for the screws that attach to the columns
  655. // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
  656. for (m = [0, 1]) mirror([m, 0, 0]) {
  657. translate([-(width / 2 + radius + 2 * wall), 0, radius]) {
  658. rotate([0, 90, 0]) {
  659. cylinder(r = 1.5, h = 2 * wall, $fn = facets);
  660. }
  661. }
  662. }
  663. }
  664. h2n_bridge_core(width, base_height, radius, col_wall, wall, -wall);
  665. // make a hole in the bridge for the cables
  666. cylinder(r = radius, h = base_height + radius + 2 * wall, $fn = facets);
  667. // cut a window for the XY and MS leds
  668. translate([0, h2n_bridge_circle_max, 0]) {
  669. rotate([90, 0, 0]) cylinder(r = 2.0, h = h2n_bridge_circle_max * 2, $fn = facets);
  670. }
  671. // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
  672. translate([-(width + 3 * radius + 2 * wall) / 2, 0, radius]) {
  673. rotate([0, 90, 0]) {
  674. cylinder(r = (1.6 + 0.1)/2, h = width + 4 * radius, $fn = facets);
  675. }
  676. }
  677. }
  678. }
  679. // bridge with thread for windscreen mount
  680. module h2n_bridge(width, base_height, stalk_height, radius, col_wall, stalk_wall, wall, thread_radius, thread_height) {
  681. translate([0, 0, base_height + radius + col_wall + thread_height + h2n_thread_pedestal]) {
  682. // capsule array mount
  683. rotate([0, 0, -90]) translate([0, 0, h2n_bridge_array_height]) {
  684. tetra_capsule_array_mount([-45, 135], mount_radius, wall);
  685. }
  686. // cylindrical stalk
  687. translate([0, 0, h2n_bridge_array_height - h2n_bridge_cylinder_height]) {
  688. difference() {
  689. cylinder(r = mount_radius + wall, h = h2n_bridge_cylinder_height, $fn = facets);
  690. cylinder(r = mount_radius, h = h2n_bridge_cylinder_height, $fn = facets);
  691. }
  692. }
  693. // conical funnel to bridge
  694. fun_height = h2n_bridge_array_height - h2n_bridge_cylinder_height;
  695. difference() {
  696. cylinder(r1 = windscreen_thread_radius - windscreen_thread_depth, r2 = mount_radius + wall,
  697. h = fun_height, $fn = facets);
  698. cylinder(r1 = windscreen_thread_radius - windscreen_thread_depth - wall, r2 = mount_radius,
  699. h = fun_height, $fn = facets);
  700. }
  701. }
  702. difference() {
  703. union() {
  704. h2n_bridge_core(width, base_height, radius, col_wall, wall, thread_radius, thread_height, 0);
  705. // small supports for the screws that attach to the columns
  706. // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
  707. for (m = [0, 1]) mirror([m, 0, 0]) {
  708. translate([-(width / 2 + radius + 2 * wall), 0, radius]) {
  709. rotate([0, 90, 0]) {
  710. cylinder(r = 1.5, h = 2 * wall, $fn = facets);
  711. }
  712. }
  713. }
  714. }
  715. h2n_bridge_core(width, base_height, radius, col_wall, wall, thread_radius, thread_height, -wall);
  716. // cut a window for the XY and MS leds
  717. translate([0, h2n_bridge_circle_max, 0]) {
  718. rotate([90, 0, 0]) cylinder(r = 2.0, h = h2n_bridge_circle_max * 2, $fn = facets);
  719. }
  720. // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
  721. translate([-(width + 3 * radius + 2 * wall) / 2, 0, radius]) {
  722. rotate([0, 90, 0]) {
  723. cylinder(r = (1.6 + 0.1)/2, h = width + 4 * radius, $fn = facets);
  724. }
  725. }
  726. }
  727. }
  728. // a bridge with detachable stalk and capsule array (attaches with an 8 pin mini-xlr connector)
  729. module h2n_mini_xlr_thread(diam, pitch, height) {
  730. metric_thread(diameter = diam, pitch = pitch, length = height, internal = true);
  731. }
  732. // bridge and threaded housing for female mini-xlr connector
  733. module h2n_bridge_connector(width, base_height, radius, col_wall, stalk_wall, wall) {
  734. difference() {
  735. union() {
  736. h2n_bridge_core(width, base_height, radius, col_wall, wall, 0);
  737. // connector
  738. translate([0, 0, base_height]) {
  739. difference() {
  740. cylinder(r = h2n_xlr_thread_diam/2 + stalk_wall, h = h2n_xlr_height, $fn = facets);
  741. // remove the thread
  742. translate([0, 0, h2n_xlr_height - h2n_xlr_thread_height - h2n_xlr_shoulder]) {
  743. rotate([0, 0, 45]) {
  744. h2n_mini_xlr_thread(h2n_xlr_thread_diam, h2n_xlr_thread_pitch, h2n_xlr_thread_height);
  745. }
  746. }
  747. // remove excess above the thread
  748. translate([0, 0, h2n_xlr_height - h2n_xlr_shoulder]) {
  749. cylinder(r = h2n_xlr_thread_diam/2 + h2n_xlr_thread_depth, h = h2n_xlr_shoulder, $fn = facets);
  750. }
  751. // make hole below the thread
  752. cylinder(r = h2n_xlr_thread_diam/2, h = h2n_xlr_height - h2n_xlr_thread_height - h2n_xlr_shoulder,
  753. $fn = facets);
  754. // remove stalk segment that is inside the bridge
  755. translate([width / 2, 0, -1.0]) {
  756. rotate([0, -90, 0]) {
  757. semi_cylinder(r = h2n_xlr_thread_diam/2 + stalk_wall, h = width);
  758. }
  759. }
  760. }
  761. }
  762. // small supports for the screws that attach to the columns
  763. // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
  764. for (m = [0, 1]) mirror([m, 0, 0]) {
  765. translate([-(width / 2 + radius + 2 * wall), 0, radius]) {
  766. rotate([0, 90, 0]) {
  767. cylinder(r = 1.5, h = 2 * wall, $fn = facets);
  768. }
  769. }
  770. }
  771. // add ridge for connector (stops the inner core of the connector from being pushed down)
  772. h_fit = 0.95;
  773. translate([0, 0, h2n_xlr_height - h2n_xlr_thread_height - h2n_xlr_shoulder + 5 - h_fit]) {
  774. tube(h2n_xlr_thread_diam/2 + stalk_wall, h2n_xlr_thread_diam/2 - 1.0, 5);
  775. translate([0, 0, -1.0]) {
  776. difference() {
  777. cylinder(r = h2n_xlr_thread_diam/2, h = 1.0, $fn = facets);
  778. cylinder(r2 = h2n_xlr_thread_diam/2 - 1.0, r1 = h2n_xlr_thread_diam/2, h = 1.0, $fn = facets);
  779. }
  780. }
  781. }
  782. }
  783. h2n_bridge_core(width, base_height, radius, col_wall, wall, -wall);
  784. // make a hole in the bridge for the cables
  785. cylinder(r = h2n_xlr_thread_diam/2, h = base_height + radius + 2 * wall, $fn = facets);
  786. // cut a window for the XY and MS leds
  787. translate([0, h2n_bridge_circle_max, 0]) {
  788. rotate([90, 0, 0]) cylinder(r = 2.0, h = h2n_bridge_circle_max * 2, $fn = facets);
  789. }
  790. // holes for screws that attach to the columns
  791. // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
  792. translate([-(width + 3 * radius + 2 * wall) / 2, 0, radius]) {
  793. rotate([0, 90, 0]) {
  794. cylinder(r = (1.6 + 0.1)/2, h = width + 4 * radius, $fn = facets);
  795. }
  796. }
  797. }
  798. }
  799. // threaded housing for male mini-xlr connector
  800. module h2n_connector_to_stalk(width, height, thread_height, thread_diam, thread_pitch, shoulder, stalk_wall) {
  801. difference() {
  802. cylinder(r = thread_diam/2 + stalk_wall, h = height, $fn = facets);
  803. // remove the thread
  804. translate([0, 0, shoulder]) {
  805. rotate([0, 0, 90]) {
  806. h2n_mini_xlr_thread(thread_diam, thread_pitch, thread_height);
  807. }
  808. }
  809. // remove excess above the thread
  810. translate([0, 0, shoulder + thread_height]) {
  811. cylinder(r = thread_diam/2, h = height, $fn = facets);
  812. }
  813. // make hole below the thread
  814. cylinder(r = thread_diam/2, h = shoulder, $fn = facets);
  815. }
  816. // add ridge for connector (stops the inner core of the connector from being pushed down)
  817. translate([0, 0, h2n_xlr_thread_height - h2n_xlr_shoulder + 1.0]) {
  818. tube(h2n_xlr_thread_diam/2 + stalk_wall, h2n_xlr_thread_diam/2 - 1.0, 5);
  819. translate([0, 0, -1.0]) {
  820. difference() {
  821. cylinder(r = h2n_xlr_thread_diam/2, h = 1.0, $fn = facets);
  822. cylinder(r2 = h2n_xlr_thread_diam/2 - 1.0, r1 = h2n_xlr_thread_diam/2, h = 1.0, $fn = facets);
  823. }
  824. }
  825. }
  826. }
  827. // stalk and capsule array mount (clips on mini-xlr housing, rotates to orient capsule array)
  828. module h2n_stalk_to_array_mount(width, stalk_height, stalk_wall) {
  829. // conical stalk to the capsule array mount
  830. difference() {
  831. cylinder(r1 = h2n_xlr_thread_diam/2 + stalk_wall, r2 = mount_radius + stalk_wall, h = stalk_height, $fn = facets);
  832. cylinder(r1 = h2n_xlr_thread_diam/2, r2 = mount_radius, h = stalk_height, $fn = facets);
  833. // avoid overhang for printing
  834. trans = 1.0;
  835. difference() {
  836. cylinder(r2 = h2n_xlr_thread_diam/2 + stalk_wall * 2, r1 = h2n_xlr_thread_diam/2 + stalk_wall * 4, h = trans, $fn = facets);
  837. cylinder(r2 = h2n_xlr_thread_diam/2 + stalk_wall, r1 = h2n_xlr_thread_diam/2, h = trans, $fn = facets);
  838. }
  839. }
  840. // press fit connector to stalk mini-xlr connector
  841. translate([0, 0, -3]) {
  842. tube(h2n_xlr_thread_diam/2, h2n_xlr_thread_diam/2 - wall, 6.0);
  843. }
  844. // capsule array mount with the right orientation (left front top = #1)0
  845. rotate([0, 0, -90]) translate([0, 0, stalk_height]) {
  846. tetra_capsule_array_mount([-45, 135], mount_radius, stalk_wall);
  847. }
  848. }
  849. // components for a wind screen cage
  850. module h2n_wind_screen_old(width) {
  851. *for (m = [0, 1]) mirror([m, 0, 0]) {
  852. translate([width/2, 0, 0]) {
  853. cube([2, 2, 90]);
  854. }
  855. }
  856. for (m = [0, 1]) mirror([0, m, 0]) {
  857. translate([0, 10, 0]) {
  858. rotate([0, 90, 90]) {
  859. half_rounded_box(2, 130, h2n_width_m/2 + mount_radius + h2n_col_wall, 25, 2);
  860. }
  861. }
  862. }
  863. translate([0, 0, 100]) {
  864. rounded_box(2, h2n_width_m/2 + mount_radius + h2n_col_wall, 30, 25, 2);
  865. }
  866. }
  867. // wind screen support modules
  868. module h2n_wind_screen_vertical_ring(diameter, thickness, collar_height) {
  869. radius = diameter / 2;
  870. w = thickness;
  871. // vertical main ring with four slots and half collar
  872. difference() {
  873. union() {
  874. translate([-w, 0, w/2]) {
  875. rotate([0, 90, 0]) {
  876. tube(radius, radius - w, w);
  877. // side locks
  878. for (r = [0, 1]) rotate([0, 0, 90 * r]) {
  879. for (m = [0, 1]) mirror([0, m, 0]) {
  880. translate([-w*1.5, radius - 2*w, 0]) {
  881. cube([w*3, w*1.5, w]);
  882. }
  883. }
  884. }
  885. }
  886. }
  887. }
  888. // cut slots for vertical rings
  889. tube(radius + w, radius - w, w);
  890. translate([0, -w/2, w/2]) {
  891. rotate([0, 90, 90]) {
  892. tube(radius + w, radius - w, w);
  893. }
  894. }
  895. // remove lower cylinder
  896. translate([0, 0, -radius]) {
  897. cylinder(r = h2n_mount_radius + h2n_col_wall, h = 3 * w, $fn = facets);
  898. }
  899. }
  900. // cylindrical attachment to mount
  901. difference() {
  902. union() {
  903. translate([0, 0, -(radius + 5)]) {
  904. tube(h2n_mount_radius + h2n_col_wall, h2n_mount_radius + wall, collar_height);
  905. }
  906. // mount for bottom screws
  907. for (m = [0, 1]) mirror([0, m, 0]) translate([-w, h2n_mount_radius + 2 * wall + 2.0, -(radius)]) {
  908. minkowski() {
  909. rotate([0, 90, 0]) {
  910. cylinder(r = 2.0, h = w, $fn = facets);
  911. }
  912. translate([0, -2, -2]) {
  913. cube([w, 1.5 * w, 4]);
  914. }
  915. }
  916. }
  917. }
  918. // remove half the tube
  919. translate([0, -2 * (h2n_mount_radius + h2n_col_wall), -(radius + collar_height / 2)]) {
  920. cube([h2n_mount_radius + h2n_col_wall, 4 * (h2n_mount_radius + h2n_col_wall), collar_height]);
  921. }
  922. // make holes for screws
  923. for (m = [0, 1]) mirror([0, m, 0]) translate([-w, h2n_mount_radius + 2 * wall + 2.0, -(radius)]) {
  924. rotate([0, 90, 0]) {
  925. cylinder(r = 1.0, h = w, $fn = facets);
  926. }
  927. }
  928. // remove inside mounts
  929. translate([0, 0, -(radius + 5)]) {
  930. cylinder(r = h2n_mount_radius + wall, h = collar_height, $fn = facets);
  931. }
  932. }
  933. }
  934. module h2n_wind_screen_horizontal_ring(diameter, thickness) {
  935. radius = diameter / 2;
  936. w = thickness;
  937. // horizontal ring with two slots
  938. difference() {
  939. union() {
  940. tube(radius, radius - w, w);
  941. // side lock supports
  942. rotate([0, 0, 90]) {
  943. for (m = [0, 1]) mirror([0, m, 0]) {
  944. translate([-w*1.5, radius - 2*w, 0]) {
  945. cube([w*3, w*1.5, w]);
  946. }
  947. }
  948. }
  949. // stops to assemble into vertical ring
  950. for (m = [0, 1]) mirror([0, m, 0]) translate([-2*w, radius - w, w]) {
  951. cube([w, w, w]);
  952. }
  953. }
  954. // cut slot for vertical secondary ring
  955. translate([0, -w/2, w/2]) {
  956. rotate([0, 90, 90]) {
  957. tube(radius + w, radius - w, w);
  958. }
  959. }
  960. // make into an arc (1/2 of the ring)
  961. translate([0, -diameter/2, 0]) {
  962. cube([diameter, diameter, w]);
  963. }
  964. }
  965. }
  966. module h2n_wind_screen_vertical_aux_ring(diameter, thickness) {
  967. radius = diameter / 2;
  968. w = thickness;
  969. difference() {
  970. union() {
  971. translate([0, -w/2, w/2]) {
  972. rotate([0, 90, 90]) {
  973. tube(radius, radius - w, w);
  974. }
  975. }
  976. // stop to assemble into vertical ring
  977. rotate([90, 0, 0]) translate([-2*w, radius - w/2, w/2]) {
  978. cube([w, w, w]);
  979. }
  980. }
  981. // remove lower cylinder
  982. translate([0, 0, -radius]) {
  983. cylinder(r = h2n_mount_radius + h2n_col_wall, h = 3 * w, $fn = facets);
  984. }
  985. // make into an arc (1/2 of the ring)
  986. rotate([0, 90, 90]) translate([-(diameter/2 + w/2), -diameter, -w]) {
  987. cube([diameter, diameter, 2*w]);
  988. }
  989. }
  990. }
  991. // lower windscreen with threaded mount
  992. module h2n_lower_windscreen(sides, height, radius, wradius, beam_radius, conn_radius, pin_height, connectors = true) {
  993. ang = 360 / sides;
  994. // connector to upper frame
  995. for (r = [1:360/sides:360]) rotate([0, 0, r]) {
  996. translate([wradius, -beam_radius/2, height - pin_height + 1]) {
  997. render() {
  998. difference() {
  999. sphere(r = conn_radius, $fn = facets);
  1000. translate([-2 * conn_radius, -2 * conn_radius, (conn_radius - beam_radius) / 2]) {
  1001. cube([4 * conn_radius, 4 * conn_radius, 4 * conn_radius]);
  1002. }
  1003. }
  1004. // pin
  1005. cylinder(r = beam_radius - fit, h = pin_height, $fn = facets);
  1006. }
  1007. }
  1008. }
  1009. // beams to threaded mount
  1010. rotate([0, 0, ang/2]) {
  1011. sphear_windscreen_inset_frame(sides, height - 4, wradius,
  1012. radius, beam_radius, 1.66, 1.2);
  1013. }
  1014. // threaded mount
  1015. sphear_windscreen_round_mount(windscreen_thread_height, windscreen_thread_radius, windscreen_thread_radius + 4 * wall, 2 * wall);
  1016. }
  1017. ////
  1018. //// Render components specific to the H2N design
  1019. // render full windscreen with threaded mount
  1020. module render_h2n_windscreen(zoffset) {
  1021. sides = 12;
  1022. ang = 360 / sides;
  1023. translate([0, 0, zoffset]) {
  1024. h2n_lower_windscreen(sides, height, radius, beam_radius, conn_radius, pin_height, connectors = true)
  1025. // dome at top
  1026. translate([0, 0, windscreen_height / 2+ windscreen_height]) {
  1027. sphear_windscreen_dome(sides, box_corner_radius + 4 * beam_radius, beam_radius);
  1028. }
  1029. // spiral wireframe
  1030. translate([0, 0, windscreen_height / 2]) {
  1031. sphear_windscreen_frame(sides, box_corner_radius + 4 * beam_radius, windscreen_height, beam_radius, 45);
  1032. }
  1033. // crossing reinforcements
  1034. // first mid crossing
  1035. translate([0, 0, windscreen_height / 2 + windscreen_height/3]) {
  1036. sphear_windscreen_frame_reinforcements(sides, box_corner_radius + 4 * beam_radius, beam_radius, ang/2, 0);
  1037. }
  1038. // second mid crossing
  1039. translate([0, 0, windscreen_height / 2 + windscreen_height*2/3]) {
  1040. sphear_windscreen_frame_reinforcements(sides, box_corner_radius + 4 * beam_radius, beam_radius, 0, 0);
  1041. }
  1042. // to dome
  1043. translate([0, 0, windscreen_height / 2 + windscreen_height]) {
  1044. sphear_windscreen_frame_reinforcements(sides, box_corner_radius + 4 * beam_radius, beam_radius, ang/2, 0);
  1045. }
  1046. // to threaded mount (these are tilted slightly and inset a little bit)
  1047. translate([0, 0, windscreen_height / 2]) {
  1048. sphear_windscreen_frame_reinforcements(sides, box_corner_radius + 4 * beam_radius - 0.15, beam_radius, 0, 10);
  1049. }
  1050. // beams to threaded mount
  1051. rotate([0, 0, ang/2]) {
  1052. sphear_windscreen_inset_frame(sides, windscreen_height/2, box_corner_radius + 4 * beam_radius,
  1053. windscreen_thread_radius + 2 * wall,
  1054. beam_radius, 1.66, 1.2);
  1055. }
  1056. // threaded mount
  1057. rotate([0, 0, 90]) {
  1058. sphear_windscreen_round_mount(windscreen_thread_height, windscreen_thread_radius, 2 * wall);
  1059. }
  1060. }
  1061. }
  1062. //
  1063. module render_h2n_lower_windscreen(zoffset) {
  1064. translate([0, 0, zoffset]) {
  1065. h2n_lower_windscreen(12, windscreen_lower_height, windscreen_thread_radius + 2 * wall, windscreen_radius,
  1066. windscreen_beam_radius, windscreen_conn_radius, windscreen_pin_height, connectors = true);
  1067. }
  1068. }