1
0

first_order.scad 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. //
  2. // SphEAR, First Order (B-format) Ambisonics Microphone
  3. //
  4. // Copyright 2015, Fernando Lopez-Lezcano, All Rights Reserved
  5. //
  6. // Source code released under the GNU GPL License
  7. // http://www.gnu.org/licenses/gpl-3.0.en.html
  8. //
  9. // 3d models released under Creative Commons Non-Commercial Share-Alike
  10. // CC-NC-SA 3.0
  11. // http://creativecommons.org/licenses/by-nc-sa/3.0/
  12. //
  13. // https://en.wikipedia.org/wiki/Tetrahedron
  14. // angle capsule to vertical = atan(sqrt(2)) = 54.7356103172
  15. //// model parameters
  16. // dimensions for the EM182 electret microphone
  17. capsule_radius = 5;
  18. capsule_height = 4.5;
  19. // distance between face of capsule and center of array
  20. mic_radius = 11;
  21. // separation between capsules (right now only used in stalk)
  22. cap_sep = 7;
  23. // dimensions of capsule holder legs
  24. leg_width = 4;
  25. leg_thick = 2.5;
  26. leg_length = mic_radius - (capsule_radius / sqrt(2));
  27. slot_depth = leg_thick;
  28. // dimensions of microphone holder
  29. hold_radius = 4;
  30. //// end of model parameters
  31. //// rendering control
  32. // what to render:
  33. // 0 -> ready to print
  34. // set = 0 -> one capsule, set = 1 -> four capsules
  35. // 1 -> the whole microhone with four capsules
  36. rendermic = 1;
  37. renderset = 0;
  38. // what type of connection between capsule holders:
  39. // 0 -> original cylinder beams
  40. // 1 -> interlocking beams (out)
  41. // 2 -> interlocking beams (in)
  42. connect = 2;
  43. //// end of rendering control
  44. // adjustment for the size of the capsule
  45. // (measured inside diameter was around 7.5 to 8.2 instead of 10, capsule diameter was 9.99)
  46. fudge = 0.15;
  47. // adjustment for fit of slots
  48. fit = 0.2;
  49. // wall thickness of cylinders
  50. wall = 1;
  51. // number of facets for cylinders
  52. facets = 64;
  53. ////////
  54. // microphone capsule holder
  55. // azimuth: orientation of the capsule
  56. // elevation: orientation of the capsure
  57. // twist: adjust the angle of the mounts so they match
  58. // mounts: number of mounts to create (2 or 3)
  59. module capsule (azimuth, elevation, twist, mounts) {
  60. rotate([0, 0, azimuth]) {
  61. rotate([0, (90 - elevation), 0]) {
  62. translate([0, 0, rendermic == 0 ? 0 : mic_radius - capsule_height]) {
  63. // the capsule holder
  64. difference () {
  65. union () {
  66. // main capsule holder
  67. cylinder(r = capsule_radius + wall, h = capsule_height, $fn = facets);
  68. // the attachment point to the other capsules
  69. for (rot = [-120 : 120 : mounts == 2 ? 0 : 120]) {
  70. rotate(a = rot + twist, v = [0, 0, 1]) {
  71. // connect with cylindrical beams, very pretty
  72. if (connect == 0) {
  73. translate([capsule_radius - wall, 0, capsule_height - wall]) {
  74. rotate(a = 145, v = [0, 1, 0]) {
  75. cylinder(d = wall * 4, h = 6, center = false, $fn = facets);
  76. }
  77. }
  78. }
  79. // connect with flat square beams pointing out
  80. if (connect == 1) {
  81. translate([capsule_radius - wall, 3 * wall / 4, wall]) {
  82. rotate(a = 90, v = [0, 1, 0]) {
  83. difference() {
  84. cube([wall * 2, wall * 4, capsule_height * 4], center = true);
  85. translate([0, 0, wall * 8]) {
  86. cube([wall * 2, wall * 1.5, capsule_height], center = true);
  87. }
  88. }
  89. }
  90. }
  91. }
  92. // connect with vertical legs
  93. if (connect == 2) {
  94. translate([capsule_radius + fudge, - leg_width / 3, - leg_length + capsule_height]) {
  95. difference() {
  96. // thickness, width
  97. cube([leg_thick, leg_width, leg_length]);
  98. // cut slot in connector
  99. translate([0, leg_width / 3 - (fit / 2), 0]) {
  100. cube([leg_thick, leg_width / 3 + fit, slot_depth]);
  101. }
  102. }
  103. }
  104. }
  105. }
  106. }
  107. // add ridges for microphone mount
  108. if (mounts == 2) {
  109. rotate(a = 120 + twist, v = [0, 0, 1]) {
  110. translate([capsule_radius + fudge, - wall , 0]) {
  111. difference() {
  112. cube([wall * 3, wall * 2, capsule_height], center = false);
  113. rotate([0, 55, 0]) {
  114. cube([wall * 3, wall * 2, capsule_height], center = false);
  115. }
  116. }
  117. }
  118. }
  119. }
  120. }
  121. // make the hole for the capsule
  122. translate ([0, 0, -2]) {
  123. cylinder(r = capsule_radius + fudge, h = capsule_height + 2, $fn = facets);
  124. }
  125. // remove any extra connecting beam material from the face of the holder
  126. //translate ([0, 0, capsule_height]) {
  127. // cylinder(r = capsule_radius + wall * 2, h = 2, $fn = facets);
  128. //}
  129. }
  130. }
  131. }
  132. }
  133. }
  134. module capsule_old (azimuth, elevation, micradius, cap_radius, cap_height, wall, twist, mounts) {
  135. rotate([0, 0, azimuth]) {
  136. rotate([0, (90 - elevation), 0]) {
  137. translate([0, 0, mic_radius - capsule_height]) {
  138. // the capsule holder
  139. difference () {
  140. union () {
  141. // main capsule holder
  142. cylinder(r = capsule_radius + wall, h = capsule_height, $fn = facets);
  143. // the attachment point to the other capsules
  144. for (rot = [-120 : 120 : mounts == 2 ? 0 : 120]) {
  145. // connect with cylindrical beams, very pretty
  146. rotate(a = rot + twist, v = [0, 0, 1]) {
  147. if (connect == 0) {
  148. translate([capsule_radius - wall, 0, capsule_height - wall]) {
  149. rotate(a = 145, v = [0, 1, 0]) {
  150. cylinder(d = wall * 4, h = 6, center = false, $fn = facets);
  151. }
  152. }
  153. }
  154. // connect with flat square beams pointing out
  155. if (connect == 1) {
  156. translate([capsule_radius - wall, 3 * wall / 4, wall]) {
  157. rotate(a = 90, v = [0, 1, 0]) {
  158. difference() {
  159. cube([wall * 2, wall * 4, capsule_height * 4], center = true);
  160. translate([0, 0, wall * 8]) {
  161. cube([wall * 2, wall * 1.5, capsule_height], center = true);
  162. }
  163. }
  164. }
  165. }
  166. }
  167. // connect with flat square beams pointing in
  168. if (connect == 2) {
  169. translate([capsule_radius + fudge, - wall * 1.29 , - capsule_height]) {
  170. difference() {
  171. cube([wall * 3, wall * 4, capsule_height * 2], center = false);
  172. translate([0, wall * 1.25, - wall * 2]) {
  173. cube([wall * 3, wall * 1.5, capsule_height], center = false);
  174. }
  175. }
  176. }
  177. }
  178. }
  179. }
  180. // add ridges for microphone mount
  181. rotate(a = 120 + twist, v = [0, 0, 1]) {
  182. translate([capsule_radius + fudge, - wall , 0]) {
  183. difference() {
  184. cube([wall * 3, wall * 2, capsule_height], center = false);
  185. rotate([0, 55, 0]) {
  186. cube([wall * 3, wall * 2, capsule_height], center = false);
  187. }
  188. }
  189. }
  190. }
  191. }
  192. // make the hole for the capsule
  193. translate ([0, 0, -2]) {
  194. cylinder(r = capsule_radius + fudge, h = capsule_height + 2, $fn = facets);
  195. }
  196. // remove any extra connecting beam material from the face of the holder
  197. translate ([0, 0, capsule_height]) {
  198. cylinder(r = capsule_radius + wall * 2, h = 2, $fn = facets);
  199. }
  200. }
  201. }
  202. }
  203. }
  204. }
  205. // microphone mount
  206. module mount (radius, length, wall, separation) {
  207. // mounting ring
  208. translate([0, 0, -separation]) {
  209. difference() {
  210. union() {
  211. cylinder(h = length, r = radius, center = true, $fn=128);
  212. // connection ridges
  213. for (rot = [0 : 180 : 360]) {
  214. rotate([0, 0, rot - 45]) {
  215. translate([0, - wall * 3 - fit, - length / 2]) {
  216. difference() {
  217. cube([wall * 6, wall * 2, length], center = false);
  218. }
  219. }
  220. translate([0, wall + fit, - length / 2]) {
  221. difference() {
  222. cube([wall * 6, wall * 2, length], center = false);
  223. }
  224. }
  225. }
  226. }
  227. }
  228. // the bore of the ring
  229. cylinder(h = length, r = radius - wall, center = true, $fn=128);
  230. // create the slopes in the ridges
  231. for (rot = [0 : 180 : 360]) {
  232. rotate([0, 0, rot]) {
  233. translate([- radius, radius, 3.5]) {
  234. rotate([55, 0, 45]) {
  235. cube([radius * 3, radius, radius * 3], center = true);
  236. }
  237. }
  238. }
  239. }
  240. }
  241. }
  242. }
  243. // some constants
  244. vang = atan(sqrt(2));
  245. // vectors pointing in the directions of the four capsules
  246. direction1 = [1, 1, 1];
  247. direction2 = [-1, 1, -1];
  248. direction3 = [-1, -1, 1];
  249. direction4 = [1, -1, -1];
  250. dist = sqrt(3);
  251. // azimuths
  252. az1 = atan2(1, 1);
  253. az2 = atan2(1, -1);
  254. az3 = atan2(-1, -1);
  255. az4 = atan2(-1, 1);
  256. // elevations
  257. el1 = asin(1/dist);
  258. el2 = -asin(1/dist);
  259. el3 = asin(1/dist);
  260. el4 = -asin(1/dist);
  261. // connect the four instances together
  262. if (rendermic == 1) {
  263. capsule(az1, el1, 60, 3);
  264. capsule(az2, el2, 240, 2);
  265. capsule(az3, el3, 60, 3);
  266. capsule(az4, el4, 240, 2);
  267. // the mount
  268. //mount(hold_radius, capsule_height, 1, mic_radius);
  269. }
  270. part_sep = capsule_radius * 2 * 3;
  271. echo("az = ", az1, az2, az3, az4, "elev = ", el1, el2, el3, el4);
  272. // just one to test
  273. if (rendermic == 0) {
  274. capsule(0, 90, 0, 3);
  275. //translate([0, part_sep, 0]) { capsule(0, 270, height, capsule_radius, capsule_height, 1, 0); }
  276. //translate([part_sep, 0, 0]) { capsule(0, 270, height, capsule_radius, capsule_height, 1, 0); }
  277. //translate([part_sep, part_sep]) { capsule(0, 270, height, capsule_radius, capsule_height, 1, 0); }
  278. }