1
0

first_order.scad 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. //
  2. // First Order (B-format) Ambisonics Microphone, or SphEAR for short
  3. //
  4. // Copyright 2015 Fernando Lopez-Lezcano
  5. //
  6. // Source code released under the GNU GPL License
  7. // http://www.gnu.org/licenses/gpl-3.0.en.html
  8. //
  9. // 3d model 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. //// model parameters
  13. // dimensions for the EM182 electret microphone
  14. mic_radius = 5;
  15. mic_height = 4.5;
  16. // distance between face of capsule and center of array
  17. amb_radius = 12.5;
  18. // dimensions of microphone holder
  19. hold_radius = 3;
  20. // separation between capsules (right now only used in stalk)
  21. cap_sep = 7;
  22. // what to render:
  23. // 0 -> a single capsule holder
  24. // 1 -> the whole microhone with four capsules
  25. rendermic = 1;
  26. // what type of connection between capsule holders:
  27. // 0 -> original cylinder beams
  28. // 1 -> interlocking beams (out)
  29. // 2 -> interlocking beams (in)
  30. connect = 2;
  31. // adjustment for the size of the capsule
  32. // (measured inside diameter was around 7.5 to 8.2 instead of 10, capsule diameter was 9.99)
  33. fudge = 0.15;
  34. // adjustment for fit of ridges
  35. fit = 0.2;
  36. // number of facets for cylinders
  37. facets = 64;
  38. ////////
  39. // microphone capsule holder
  40. // azimuth: orientation of the capsule
  41. // elevation: orientation of the capsure
  42. // separation: how far from the center to displace the capsule
  43. // radius: radius of the microphone
  44. // height: height of the microphone
  45. // wall: thickness of the microphone housing walls
  46. // twist: adjust the angle of the mounts so they match
  47. // mounts: number of mounts to create (2 or 3)
  48. module capsule (azimuth, elevation, ambradius, radius, height, wall, twist, mounts) {
  49. rotate([0, 0, azimuth]) {
  50. rotate([0, (90 - elevation), 0]) {
  51. translate([0, 0, ambradius - height]) {
  52. // the capsule holder
  53. difference () {
  54. union () {
  55. // main capsule holder
  56. cylinder(r = radius + wall, h = height, $fn = facets);
  57. // the attachment point to the other capsules
  58. for (rot = [-120 : 120 : mounts == 2 ? 0 : 120]) {
  59. // connect with cylindrical beams, very pretty
  60. rotate(a = rot + twist, v = [0, 0, 1]) {
  61. if (connect == 0) {
  62. translate([radius - wall, 0, height - wall]) {
  63. rotate(a = 145, v = [0, 1, 0]) {
  64. cylinder(d = wall * 4, h = 6, center = false, $fn = facets);
  65. }
  66. }
  67. }
  68. // connect with flat square beams pointing out
  69. if (connect == 1) {
  70. translate([radius - wall, 3 * wall / 4, wall]) {
  71. rotate(a = 90, v = [0, 1, 0]) {
  72. difference() {
  73. cube([wall * 2, wall * 4, height * 4], center = true);
  74. translate([0, 0, wall * 8]) {
  75. cube([wall * 2, wall * 1.5, height], center = true);
  76. }
  77. }
  78. }
  79. }
  80. }
  81. // connect with flat square beams pointing in
  82. if (connect == 2) {
  83. translate([radius + fudge, - wall * 1.29 , - height]) {
  84. difference() {
  85. cube([wall * 3, wall * 4, height * 2], center = false);
  86. translate([0, wall * 1.25, - wall * 2]) {
  87. cube([wall * 3, wall * 1.5, height], center = false);
  88. }
  89. }
  90. }
  91. }
  92. }
  93. }
  94. // add ridges for microphone mount
  95. rotate(a = 120 + twist, v = [0, 0, 1]) {
  96. translate([radius + fudge, - wall , 0]) {
  97. difference() {
  98. cube([wall * 3, wall * 2, height], center = false);
  99. rotate([0, 55, 0]) {
  100. cube([wall * 3, wall * 2, height], center = false);
  101. }
  102. }
  103. }
  104. }
  105. }
  106. // make the hole for the capsule
  107. translate ([0, 0, -2]) {
  108. cylinder(r = radius + fudge, h = height + 2, $fn = facets);
  109. }
  110. // remove any extra connecting beam material from the face of the holder
  111. translate ([0, 0, height]) {
  112. cylinder(r = radius + wall * 2, h = 2, $fn = facets);
  113. }
  114. }
  115. }
  116. }
  117. }
  118. }
  119. // microphone mount
  120. module mount (radius, length, wall, separation) {
  121. // mounting ring
  122. translate([0, 0, -separation]) {
  123. difference() {
  124. union() {
  125. cylinder(h = length, r = radius, center = true, $fn=128);
  126. // connection ridges
  127. for (rot = [0 : 180 : 360]) {
  128. rotate([0, 0, rot - 45]) {
  129. translate([0, - wall * 3 - fit, - length / 2]) {
  130. difference() {
  131. cube([wall * 6, wall * 2, length], center = false);
  132. }
  133. }
  134. translate([0, wall + fit, - length / 2]) {
  135. difference() {
  136. cube([wall * 6, wall * 2, length], center = false);
  137. }
  138. }
  139. }
  140. }
  141. }
  142. // the bore of the ring
  143. cylinder(h = length, r = radius - wall, center = true, $fn=128);
  144. // create the slopes in the ridges
  145. for (rot = [0 : 180 : 360]) {
  146. rotate([0, 0, rot]) {
  147. translate([- radius, radius, radius + wall / 2]) {
  148. rotate([55, 0, 45]) {
  149. cube([radius * 3, radius, radius * 3], center = true);
  150. }
  151. }
  152. }
  153. }
  154. }
  155. }
  156. }
  157. // vectors pointing in the directions of the four capsules
  158. direction1 = [1, 1, 1];
  159. direction2 = [-1, 1, -1];
  160. direction3 = [-1, -1, 1];
  161. direction4 = [1, -1, -1];
  162. dist = sqrt(3);
  163. // azimuths
  164. az1 = atan2(1, 1);
  165. az2 = atan2(1, -1);
  166. az3 = atan2(-1, -1);
  167. az4 = atan2(-1, 1);
  168. // elevations
  169. el1 = asin(1/dist);
  170. el2 = -asin(1/dist);
  171. el3 = asin(1/dist);
  172. el4 = -asin(1/dist);
  173. // connect the four instances together
  174. if (rendermic == 1) {
  175. capsule(az1, el1, amb_radius, mic_radius, mic_height, 1, 60, 3);
  176. capsule(az2, el2, amb_radius, mic_radius, mic_height, 1, 240, 2);
  177. capsule(az3, el3, amb_radius, mic_radius, mic_height, 1, 60, 3);
  178. capsule(az4, el4, amb_radius, mic_radius, mic_height, 1, 240, 2);
  179. // the mount
  180. mount(hold_radius, mic_height, 1, amb_radius);
  181. }
  182. part_sep = mic_radius * 2 * 3;
  183. // just one to test
  184. if (rendermic == 0) {
  185. capsule(0, 270, height, mic_radius, mic_height, 1, 0);
  186. translate([0, part_sep, 0]) { capsule(0, 270, height, mic_radius, mic_height, 1, 0); }
  187. translate([part_sep, 0, 0]) { capsule(0, 270, height, mic_radius, mic_height, 1, 0); }
  188. translate([part_sep, part_sep]) { capsule(0, 270, height, mic_radius, mic_height, 1, 0); }
  189. }