Browse Source

split H2N EM200 rendering to a separate file (like for other microphones), change rendering of the body of the H2N array so that we can mount a windscreen on it (leave old stuff as _no_ws modules for now), make the windscreen the same as for the SpHEAR EM200 standalone microphone

Fernando Pablo Lopez-Lezcano 9 years ago
parent
commit
e4f117f019
2 changed files with 424 additions and 113 deletions
  1. 186 0
      TinySpHEAR_H2N_EM200.scad
  2. 238 113
      TinySpHEAR_H2N_common.scad

+ 186 - 0
TinySpHEAR_H2N_EM200.scad

@@ -0,0 +1,186 @@
+//
+// Spherical Harmonics Ear Project (*SpHEAR)
+//
+// TinySpHEAR, First Order (B-format) Ambisonics Microphone
+// Add-on array for H2N with EM200 capsules
+// 
+// Copyright 2015-2017, Fernando Lopez-Lezcano, All Rights Reserved
+// nando@ccrma.stanford.edu
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+// 3d Models released under the Creative Commons license as follows:
+//   Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
+// http://creativecommons.org/licenses/by-nc-sa/4.0/
+
+include <SpHEAR_common.scad>;
+include <SpHEAR_windscreen.scad>;
+include <TinySpHEAR_common.scad>;
+include <TinySpHEAR_mount_pcb.scad>;
+include <TinySpHEAR_H2N_common.scad>;
+
+// dimensions of the EM200 electret microphone capsule
+capsule_radius = 14.6 / 2;
+capsule_height = 4.75;
+mic_radius = 11;
+
+// make triangular legs have the right height
+connect = 1;
+leg_thick = capsule_height;
+
+// adjust the depth of slots in mount
+mic_to_mount_fit = -0.7;
+
+////
+//// render the different assemblies
+////
+
+facets = 128;
+
+//// microphone body and array
+windscreen_thread_radius = mic_radius * 1.6;
+windscreen_thread_height = 8;
+
+// make winscreen radius and height the same as for the EM200 standalone microphone
+windscreen_height = 66;
+windscreen_radius = box_corner_radius + 6.0;
+
+// height of the lower windscreen
+windscreen_lower_height = 25;
+
+// render the whole thing
+
+difference() {
+union() {
+
+*h2n_ring(h2n_width_m, h2n_depth_m, h2n_depth * 0.425, h2n_band_height, h2n_col_tilt,
+         h2n_side_band_w, h2n_side_band, h2n_band_wall, h2n_band_wall, mount_radius, h2n_col_wall);
+
+*h2n_columns(h2n_width_m, h2n_column_height, h2n_band_height, h2n_col_tilt,
+            transition_height, h2n_mount_radius, h2n_col_wall, wall);
+
+translate([0, 0, h2n_column_height]) {
+    h2n_bridge((h2n_width_m / 2 + mount_radius - h2n_col_wall - h2n_column_height * tan(h2n_col_tilt)) * 2,
+               h2n_bridge_base_height, h2n_bridge_stalk_height, mount_radius, h2n_col_wall, h2n_stalk_wall, wall, 
+               windscreen_thread_radius, windscreen_thread_height);
+}
+
+// capsule array mount
+rotate([0, 0, -90]) translate([0, 0, 95]) {
+    tetra_capsule_array_mount([-45, 135], mount_radius, wall);
+}
+
+// cylindrical stalk
+translate([0, 0, 65]) {
+    difference() {
+        cylinder(r = mount_radius + wall, h = 30.0, $fn = facets);
+        cylinder(r = mount_radius, h = 30.0, $fn = facets);
+    }
+}
+
+// conical stalk
+translate([0, 0, 44]) {
+    difference() {
+        cylinder(r1 = windscreen_thread_radius - windscreen_thread_depth, r2 = mount_radius + wall, 
+                h = 21, $fn = facets);
+        cylinder(r1 = windscreen_thread_radius - windscreen_thread_depth - wall, r2 = mount_radius, 
+                h = 21, $fn = facets);
+    }
+}
+
+render_sphear_upper_windscreen(37.2 + 23 - 0.5);
+
+render_h2n_lower_windscreen(37.2);
+
+*translate([0, 0, h2n_column_height]) {
+    h2n_bridge_connector((h2n_width_m / 2 + mount_radius - h2n_col_wall - h2n_column_height * tan(h2n_col_tilt)) * 2,
+               h2n_bridge_base_height, mount_radius, h2n_col_wall, h2n_stalk_wall, wall);
+}
+
+*translate([0, 0, h2n_column_height + 40]) {
+    h2n_connector_to_stalk((h2n_width_m / 2 + mount_radius - h2n_col_wall - h2n_column_height * tan(h2n_col_tilt)) * 2,
+            h2n_xlr_height, h2n_xlr_thread_height, h2n_xlr_thread_diam, h2n_xlr_thread_pitch, h2n_xlr_shoulder, h2n_stalk_wall);
+}
+
+*translate([0, 0, h2n_column_height + h2n_xlr_height + 5 + 40]) {
+    h2n_stalk_to_array_mount((h2n_width_m / 2 + mount_radius - h2n_col_wall - h2n_column_height * tan(h2n_col_tilt)) * 2,
+            h2n_xlr_stalk_height, h2n_stalk_wall);
+}
+
+rotate([0, 0, 90]) {
+    render_tetra_capsule_array(h2n_column_height + h2n_bridge_base_height + h2n_bridge_stalk_height + 46);
+}
+
+translate([0, 0, 100]) {
+    *h2n_wind_screen_vertical_ring(h2n_width_m, 1.6, 10.0);
+    *rotate([0, 0, 180]) h2n_wind_screen_vertical_ring(h2n_width_m, 1.6, 10.0);
+    *h2n_wind_screen_horizontal_ring(h2n_width_m, 1.6);
+    *h2n_wind_screen_vertical_aux_ring(h2n_width_m, 1.6);
+}
+
+*rotate([0, 90, 0])
+    h2n_wind_screen_vertical_ring(h2n_width_m, 1.6, 10.0);
+
+
+*h2n_wind_screen_horizontal_ring(h2n_width_m, 1.6);
+
+
+*rotate([90, 180, 0])
+    h2n_wind_screen_vertical_aux_ring(h2n_width_m, 1.6);
+
+}
+*rotate([0, 0, 22.5/2]) translate([-40, -50, 0]) {
+    cube([80, 50, 170]);
+}
+}
+
+// individual capsule holders
+
+*render_tetra_capsule_top(0);
+
+*render_tetra_capsule_bot(0);
+
+// make sure dimensions are fine
+*translate([-(h2n_width_m - 0.1) / 2, - 0.5, 0]) {
+    cube([h2n_width_m - 0.1, 1, 1]);
+}
+
+*translate([-0.5, -(h2n_depth_m - 0.1) / 2, 0]) {
+    cube([1, h2n_depth_m - 0.1, 1]);
+}
+
+// some tests with traced profiles
+*difference() {
+    translate([0, -2.5, 0]) {
+        scale([2.15, 2.15, 1.0]) {
+            H2N_top_up_outline(5.0);
+        }
+    }
+// scale([1.75, 1.75, 1.0]) {
+    translate([0, -2.4, 0]) {
+        scale([2.02, 2.02, 1.0]) {
+            H2N_top_up_outline(5.0);
+        }
+    }
+}
+
+*scale(1.665) {
+    translate([0, 10, -0]) {
+        rotate([0, 0, 0]) {
+            H2N_front_outline(1.0);
+        }
+    }
+}
+*rotate([0, 0, 4]) translate([35, 0, 0])
+    cube([2, 80, 4]);

+ 238 - 113
TinySpHEAR_H2N_common.scad

@@ -25,6 +25,7 @@
 // http://creativecommons.org/licenses/by-nc-sa/4.0/
 
 include <SpHEAR_common.scad>;
+include <SpHEAR_windscreen.scad>;
 include <TinySpHEAR_common.scad>;
 include <TinySpHEAR_mount_pcb.scad>;
 
@@ -44,6 +45,11 @@ capsule_radius = 14.6 / 2;
 capsule_height = 4.75;
 mic_radius = 11;
 
+// dimensions of the EM182 electret microphone capsule (measured 10mm)
+//capsule_radius = 10.0 / 2;
+//capsule_height = 4.5;
+//mic_radius = 9.2;
+
 // adjust the depth of slots in mount
 mic_to_mount_fit = -0.4;
 
@@ -111,8 +117,9 @@ h2n_xlr_thread_diam = 10.0;
 h2n_xlr_thread_pitch = 0.75;
 h2n_xlr_thread_height = 6.0;
 h2n_xlr_thread_depth = 0.614 * h2n_xlr_thread_pitch;
-h2n_xlr_conn_height = 30;
-h2n_xlr_conn_shoulder = 1.25;
+h2n_xlr_height = 30;
+h2n_xlr_shoulder = 1.25;
+h2n_xlr_stalk_height = 40.0;
 
 
 module tube(or, ir, h) {
@@ -307,9 +314,10 @@ module h2n_column(height, ring_height, tilt, transition, radius, col_wall, wall)
                 }
             }
             // make hole for screw
+            // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
             translate([-(radius + 2 * wall), 0, radius]) {
                 rotate([0, 90, 0]) {
-                    cylinder(r = 0.5, h = radius + wall, $fn = facets);
+                    cylinder(r = 0.7, h = radius + wall, $fn = facets);
                 }
             }
         }
@@ -501,6 +509,32 @@ module h2n_bridge_old(width, base_height, stalk_height, radius, col_wall, wall)
 
 // base plate for upper band cover
 
+module h2n_center_cover_no_ws(width, base_height, radius, wall, offset) {
+    bot_step = h2n_bridge_band_h;
+    difference() {
+        union() {
+            for (m = [0, 1]) mirror([m, 0, 0]) {
+                // core of bridge
+                translate([width/2, -thin_mint / 2, 0]) {
+                    cylcube(width / 2 + offset, radius + offset + 2 * wall, bot_step, wall);
+                }
+                // we should derive the geometry for the aligment magic below...
+                side_fit = 1.05;
+                corner_radius = 2.0;
+                tilted_half_rounded_box(bot_step, width / 2 + offset - wall / 2, h2n_side_band_w / 2 + offset + wall,
+                    corner_radius, wall, 0);
+            }
+        }
+        // clear the inside
+        // outer frame
+        rounded_block(bot_step + thin_mint, width / 2 + offset - 1.5 * wall, h2n_side_band_w / 2 + offset, 2);
+        // inner frame
+        translate([-(width + offset) / 2, -(radius + wall + offset), 0]) {
+            cube([width + offset, (radius + wall + offset) * 2, bot_step + thin_mint]);
+        }
+    }
+}
+
 module h2n_center_cover(width, base_height, radius, wall, offset) {
     bot_step = h2n_bridge_band_h;
     difference() {
@@ -537,7 +571,7 @@ module h2n_center_dial_cover(radius, wall, offset) {
 
 // the core of the bridge, a solid offset-able version
 
-module h2n_bridge_core(width, base_height, radius, col_wall, wall, offset) {
+module h2n_bridge_core_no_ws(width, base_height, radius, col_wall, wall, offset) {
     hull() {
         // top of bridge
         translate([width / 2, 0, base_height]) {
@@ -562,9 +596,61 @@ module h2n_bridge_core(width, base_height, radius, col_wall, wall, offset) {
     }
 }
 
+module h2n_bridge_core(width, base_height, radius, col_wall, wall, thread_radius, thread_height, offset) {
+    pedestal = 0.5;
+    difference() {
+        hull() {
+            // top of bridge
+            translate([width / 2, 0, base_height]) {
+                rotate([0, -90, 0]) {
+                    // curvy ceiling
+                    semi_cylinder(r = radius + offset + col_wall, h = width + offset);
+                }
+            }
+            // spherical caps at ends
+            for (m = [0, 1]) mirror([m, 0, 0]) {
+                translate([width / 2, 0, base_height]) {
+                    quarter_sphere(r = radius + offset + col_wall);
+                }
+            }
+            // bottom plate
+            h2n_center_cover(width, base_height, radius, wall, offset);
+            // cover for center dial
+            h2n_center_dial_cover(h2n_bridge_circle / 2, wall, offset);
+            // base of windscreen mounting thread
+            if (thread_radius > 0) {
+                translate([0, 0, base_height + radius + col_wall + offset]) {
+                    cylinder(r = thread_radius + windscreen_thread_depth + offset, h = wall, $fn = facets);
+                }
+            }
+        }
+        // make hole for cables
+        translate([0, 0, base_height + radius + col_wall]) {
+            cylinder(r = thread_radius - windscreen_thread_depth - wall, h = wall + thin_mint, $fn = facets);
+        }
+    }
+    if (thread_radius > 0 && offset == 0) {
+        // pedestal for thread
+        translate([0, 0, base_height + radius + col_wall + offset + pedestal]) {
+            difference() {
+                cylinder(r = thread_radius + windscreen_thread_depth + offset, h = wall, $fn = facets);
+                cylinder(r = thread_radius - windscreen_thread_depth - wall, h = wall, $fn = facets);
+            }
+        }
+        // thread
+        translate([0, 0, base_height + radius + col_wall + wall + pedestal]) {
+            difference() {
+                metric_thread(diameter = thread_radius * 2, pitch = windscreen_thread_pitch,
+                    length = thread_height, angle = windscreen_thread_angle, internal = false);
+                cylinder(r = thread_radius - wall - windscreen_thread_depth, h = thread_height + thin_mint, $fn = facets);
+            }
+        }
+    }
+}
+
 // the bridge that holds the capsule array
 
-module h2n_bridge(width, base_height, stalk_height, radius, col_wall, stalk_wall, wall) {
+module h2n_bridge_no_ws(width, base_height, stalk_height, radius, col_wall, stalk_wall, wall) {
     // capsule array mount with the right orientation (left front top = #1)0
     rotate([0, 0, -90]) translate([0, 0, base_height + stalk_height]) {
         tetra_capsule_array_mount([-45, 135], mount_radius, stalk_wall);
@@ -596,6 +682,7 @@ module h2n_bridge(width, base_height, stalk_height, radius, col_wall, stalk_wall
                 }
             }
             // small supports for the screws that attach to the columns
+            // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
             for (m = [0, 1]) mirror([m, 0, 0]) {
                 translate([-(width / 2 + radius + 2 * wall), 0, radius]) {
                     rotate([0, 90, 0]) {
@@ -611,10 +698,40 @@ module h2n_bridge(width, base_height, stalk_height, radius, col_wall, stalk_wall
         translate([0, h2n_bridge_circle_max, 0]) {
             rotate([90, 0, 0]) cylinder(r = 2.0, h = h2n_bridge_circle_max * 2, $fn = facets);
         }
-        // holes for screws that attach to the columns
+        // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
         translate([-(width + 3 * radius + 2 * wall) / 2, 0, radius]) {
             rotate([0, 90, 0]) {
-                cylinder(r = 0.5, h = width + 4 * radius, $fn = facets);
+                cylinder(r = (1.6 + 0.1)/2, h = width + 4 * radius, $fn = facets);
+            }
+        }
+    }
+}
+
+// bridge with thread for windscreen mount
+
+module h2n_bridge(width, base_height, stalk_height, radius, col_wall, stalk_wall, wall, thread_radius, thread_height) {
+    difference() {
+        union() {
+            h2n_bridge_core(width, base_height, radius, col_wall, wall, thread_radius, thread_height, 0);
+            // small supports for the screws that attach to the columns
+            // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
+            for (m = [0, 1]) mirror([m, 0, 0]) {
+                translate([-(width / 2 + radius + 2 * wall), 0, radius]) {
+                    rotate([0, 90, 0]) {
+                        cylinder(r = 1.5, h = 2 * wall, $fn = facets);
+                    }
+                }
+            }
+        }
+        h2n_bridge_core(width, base_height, radius, col_wall, wall, thread_radius, thread_height, -wall);
+        // cut a window for the XY and MS leds
+        translate([0, h2n_bridge_circle_max, 0]) {
+            rotate([90, 0, 0]) cylinder(r = 2.0, h = h2n_bridge_circle_max * 2, $fn = facets);
+        }
+        // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
+        translate([-(width + 3 * radius + 2 * wall) / 2, 0, radius]) {
+            rotate([0, 90, 0]) {
+                cylinder(r = (1.6 + 0.1)/2, h = width + 4 * radius, $fn = facets);
             }
         }
     }
@@ -629,26 +746,26 @@ module h2n_mini_xlr_thread(diam, pitch, height) {
 
 // bridge and threaded housing for female mini-xlr connector
 
-module h2n_bridge_connector(width, base_height, stalk_height, radius, col_wall, stalk_wall, wall) {
+module h2n_bridge_connector(width, base_height, radius, col_wall, stalk_wall, wall) {
     difference() {
         union() {
             h2n_bridge_core(width, base_height, radius, col_wall, wall, 0);
             // connector
             translate([0, 0, base_height]) {
                 difference() {
-                    cylinder(r = h2n_xlr_thread_diam/2 + stalk_wall, h = h2n_xlr_conn_height, $fn = facets);
+                    cylinder(r = h2n_xlr_thread_diam/2 + stalk_wall, h = h2n_xlr_height, $fn = facets);
                     // remove the thread
-                    translate([0, 0, h2n_xlr_conn_height - h2n_xlr_thread_height - h2n_xlr_conn_shoulder]) {
-                        rotate([0, 0, 90]) {
+                    translate([0, 0, h2n_xlr_height - h2n_xlr_thread_height - h2n_xlr_shoulder]) {
+                        rotate([0, 0, 45]) {
                             h2n_mini_xlr_thread(h2n_xlr_thread_diam, h2n_xlr_thread_pitch, h2n_xlr_thread_height);
                         }
                     }
                     // remove excess above the thread
-                    translate([0, 0, h2n_xlr_conn_height - h2n_xlr_conn_shoulder]) {
-                        cylinder(r = h2n_xlr_thread_diam/2 + h2n_xlr_thread_depth, h = h2n_xlr_conn_shoulder, $fn = facets);
+                    translate([0, 0, h2n_xlr_height - h2n_xlr_shoulder]) {
+                        cylinder(r = h2n_xlr_thread_diam/2 + h2n_xlr_thread_depth, h = h2n_xlr_shoulder, $fn = facets);
                     }
                     // make hole below the thread
-                    cylinder(r = h2n_xlr_thread_diam/2, h = h2n_xlr_conn_height - h2n_xlr_thread_height - h2n_xlr_conn_shoulder,
+                    cylinder(r = h2n_xlr_thread_diam/2, h = h2n_xlr_height - h2n_xlr_thread_height - h2n_xlr_shoulder,
                              $fn = facets);
                     // remove stalk segment that is inside the bridge
                     translate([width / 2, 0, -1.0]) {
@@ -659,6 +776,7 @@ module h2n_bridge_connector(width, base_height, stalk_height, radius, col_wall,
                 }
             }
             // small supports for the screws that attach to the columns
+            // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
             for (m = [0, 1]) mirror([m, 0, 0]) {
                 translate([-(width / 2 + radius + 2 * wall), 0, radius]) {
                     rotate([0, 90, 0]) {
@@ -666,6 +784,17 @@ module h2n_bridge_connector(width, base_height, stalk_height, radius, col_wall,
                     }
                 }
             }
+            // add ridge for connector (stops the inner core of the connector from being pushed down)
+            h_fit = 0.95;
+            translate([0, 0, h2n_xlr_height - h2n_xlr_thread_height - h2n_xlr_shoulder + 5 - h_fit]) {
+                tube(h2n_xlr_thread_diam/2 + stalk_wall, h2n_xlr_thread_diam/2 - 1.0, 5);
+                translate([0, 0, -1.0]) {
+                    difference() {
+                        cylinder(r = h2n_xlr_thread_diam/2, h = 1.0, $fn = facets);
+                        cylinder(r2 = h2n_xlr_thread_diam/2 - 1.0, r1 = h2n_xlr_thread_diam/2, h = 1.0, $fn = facets);
+                    }
+                }
+            }
         }
         h2n_bridge_core(width, base_height, radius, col_wall, wall, -wall);
         // make a hole in the bridge for the cables
@@ -675,9 +804,10 @@ module h2n_bridge_connector(width, base_height, stalk_height, radius, col_wall,
             rotate([90, 0, 0]) cylinder(r = 2.0, h = h2n_bridge_circle_max * 2, $fn = facets);
         }
         // holes for screws that attach to the columns
+        // Number 0 Size, 1/4" Long = thread diameter: 1.6mm, head diameter: 2.75
         translate([-(width + 3 * radius + 2 * wall) / 2, 0, radius]) {
             rotate([0, 90, 0]) {
-                cylinder(r = 0.5, h = width + 4 * radius, $fn = facets);
+                cylinder(r = (1.6 + 0.1)/2, h = width + 4 * radius, $fn = facets);
             }
         }
     }
@@ -685,42 +815,51 @@ module h2n_bridge_connector(width, base_height, stalk_height, radius, col_wall,
 
 // threaded housing for male mini-xlr connector
 
-module h2n_connector_to_stalk(width, stalk_wall) {
+module h2n_connector_to_stalk(width, height, thread_height, thread_diam, thread_pitch, shoulder, stalk_wall) {
     difference() {
-        cylinder(r = h2n_xlr_thread_diam/2 + stalk_wall, h = h2n_xlr_conn_height, $fn = facets);
+        cylinder(r = thread_diam/2 + stalk_wall, h = height, $fn = facets);
         // remove the thread
-        translate([0, 0, h2n_xlr_conn_shoulder]) {
+        translate([0, 0, shoulder]) {
             rotate([0, 0, 90]) {
-                h2n_mini_xlr_thread(h2n_xlr_thread_diam, h2n_xlr_thread_pitch, h2n_xlr_thread_height);
+                h2n_mini_xlr_thread(thread_diam, thread_pitch, thread_height);
             }
         }
         // remove excess above the thread
-        translate([0, 0, h2n_xlr_conn_shoulder + h2n_xlr_thread_height]) {
-            cylinder(r = h2n_xlr_thread_diam/2, h = h2n_xlr_conn_height, $fn = facets);
+        translate([0, 0, shoulder + thread_height]) {
+            cylinder(r = thread_diam/2, h = height, $fn = facets);
         }
         // make hole below the thread
-        cylinder(r = h2n_xlr_thread_diam/2, h = h2n_xlr_conn_shoulder, $fn = facets);
+        cylinder(r = thread_diam/2, h = shoulder, $fn = facets);
+    }
+    // add ridge for connector (stops the inner core of the connector from being pushed down)
+    translate([0, 0, h2n_xlr_thread_height - h2n_xlr_shoulder + 1.0]) {
+        tube(h2n_xlr_thread_diam/2 + stalk_wall, h2n_xlr_thread_diam/2 - 1.0, 5);
+        translate([0, 0, -1.0]) {
+            difference() {
+                cylinder(r = h2n_xlr_thread_diam/2, h = 1.0, $fn = facets);
+                cylinder(r2 = h2n_xlr_thread_diam/2 - 1.0, r1 = h2n_xlr_thread_diam/2, h = 1.0, $fn = facets);
+            }
+        }
     }
 }
 
 // stalk and capsule array mount (clips on mini-xlr housing, rotates to orient capsule array)
 
-module h2n_stalk_to_array_mount(width, stalk_wall) {
-    stalk_height = 40;
+module h2n_stalk_to_array_mount(width, stalk_height, stalk_wall) {
     // conical stalk to the capsule array mount
     difference() {
         cylinder(r1 = h2n_xlr_thread_diam/2 + stalk_wall, r2 = mount_radius + stalk_wall, h = stalk_height, $fn = facets);
-        cylinder(r1 = h2n_xlr_thread_diam/2 - fit, r2 = mount_radius, h = stalk_height, $fn = facets);
+        cylinder(r1 = h2n_xlr_thread_diam/2, r2 = mount_radius, h = stalk_height, $fn = facets);
         // avoid overhang for printing
         trans = 1.0;
         difference() {
             cylinder(r2 = h2n_xlr_thread_diam/2 + stalk_wall * 2, r1 = h2n_xlr_thread_diam/2 + stalk_wall * 4, h = trans, $fn = facets);
-            cylinder(r2 = h2n_xlr_thread_diam/2 + stalk_wall, r1 = h2n_xlr_thread_diam/2 - fit, h = trans, $fn = facets);
+            cylinder(r2 = h2n_xlr_thread_diam/2 + stalk_wall, r1 = h2n_xlr_thread_diam/2, h = trans, $fn = facets);
         }
     }
     // press fit connector to stalk mini-xlr connector
     translate([0, 0, -3]) {
-        tube(h2n_xlr_thread_diam/2 - fit, h2n_xlr_thread_diam/2 - wall, 6.0);
+        tube(h2n_xlr_thread_diam/2, h2n_xlr_thread_diam/2 - wall, 6.0);
     }
     // capsule array mount with the right orientation (left front top = #1)0
     rotate([0, 0, -90]) translate([0, 0, stalk_height]) {
@@ -876,101 +1015,87 @@ module h2n_wind_screen_vertical_aux_ring(diameter, thickness) {
     }
 }
 
+// lower windscreen with threaded mount
 
-// render the whole thing
-
-difference() {
-union() {
-
-*h2n_ring(h2n_width_m, h2n_depth_m, h2n_depth * 0.425, h2n_band_height, h2n_col_tilt,
-         h2n_side_band_w, h2n_side_band, h2n_band_wall, h2n_band_wall, mount_radius, h2n_col_wall);
-
-*h2n_columns(h2n_width_m, h2n_column_height, h2n_band_height, h2n_col_tilt,
-            transition_height, h2n_mount_radius, h2n_col_wall, wall);
-
-*translate([0, 0, h2n_column_height]) {
-    h2n_bridge((h2n_width_m / 2 + mount_radius - h2n_col_wall - h2n_column_height * tan(h2n_col_tilt)) * 2,
-               h2n_bridge_base_height, h2n_bridge_stalk_height, mount_radius, h2n_col_wall, h2n_stalk_wall, wall);
-}
-
-translate([0, 0, h2n_column_height]) {
-    h2n_bridge_connector((h2n_width_m / 2 + mount_radius - h2n_col_wall - h2n_column_height * tan(h2n_col_tilt)) * 2,
-               h2n_bridge_base_height, h2n_bridge_stalk_height, mount_radius, h2n_col_wall, h2n_stalk_wall, wall);
-}
-
-translate([0, 0, h2n_column_height + 40]) {
-    h2n_connector_to_stalk((h2n_width_m / 2 + mount_radius - h2n_col_wall - h2n_column_height * tan(h2n_col_tilt)) * 2,
-            h2n_stalk_wall);
-}
-
-translate([0, 0, h2n_column_height + h2n_xlr_conn_height + 5 + 40]) {
-    h2n_stalk_to_array_mount((h2n_width_m / 2 + mount_radius - h2n_col_wall - h2n_column_height * tan(h2n_col_tilt)) * 2,
-            h2n_stalk_wall);
-}
-
-*rotate([0, 0, 90]) {
-    render_tetra_capsule_array(h2n_column_height + h2n_bridge_base_height + h2n_bridge_stalk_height + 26);
-}
-
-translate([0, 0, 100]) {
-    *h2n_wind_screen_vertical_ring(h2n_width_m, 1.6, 10.0);
-    *rotate([0, 0, 180]) h2n_wind_screen_vertical_ring(h2n_width_m, 1.6, 10.0);
-    *h2n_wind_screen_horizontal_ring(h2n_width_m, 1.6);
-    *h2n_wind_screen_vertical_aux_ring(h2n_width_m, 1.6);
-}
-
-*rotate([0, 90, 0])
-    h2n_wind_screen_vertical_ring(h2n_width_m, 1.6, 10.0);
-
-
-*h2n_wind_screen_horizontal_ring(h2n_width_m, 1.6);
-
-
-*rotate([90, 180, 0])
-    h2n_wind_screen_vertical_aux_ring(h2n_width_m, 1.6);
-
-}
-translate([-40, -50, 0]) {
-    cube([80, 50, 170]);
-}
+module h2n_lower_windscreen(sides, height, radius, wradius, beam_radius, conn_radius, pin_height, connectors = true) {
+    ang = 360 / sides;
+    // connector to upper frame
+    for (r = [1:360/sides:360]) rotate([0, 0, r]) {
+        translate([wradius, -beam_radius/2, height - pin_height + 1]) {
+            render() {
+                difference() {
+                    sphere(r = conn_radius, $fn = facets);
+                    translate([-2 * conn_radius, -2 * conn_radius, (conn_radius - beam_radius) / 2]) {
+                        cube([4 * conn_radius, 4 * conn_radius, 4 * conn_radius]);
+                    }
+                }
+                // pin
+                cylinder(r = beam_radius - fit, h = pin_height, $fn = facets);
+            }
+        }
+    }
+    // beams to threaded mount
+    rotate([0, 0, ang/2]) {
+        sphear_windscreen_inset_frame(sides, height - 4, wradius, 
+            radius, beam_radius, 1.66, 1.2);
+    }
+    // threaded mount
+    sphear_windscreen_round_mount(windscreen_thread_height, windscreen_thread_radius, windscreen_thread_radius + 4 * wall, 2 * wall);
 }
 
-// individual capsule holders
-
-*render_tetra_capsule_top(0);
+////
+//// Render components specific to the H2N design
 
-*render_tetra_capsule_bot(0);
+// render full windscreen with threaded mount
 
-// make sure dimensions are fine
-*translate([-(h2n_width_m - 0.1) / 2, - 0.5, 0]) {
-    cube([h2n_width_m - 0.1, 1, 1]);
-}
-
-*translate([-0.5, -(h2n_depth_m - 0.1) / 2, 0]) {
-    cube([1, h2n_depth_m - 0.1, 1]);
-}
-
-// some tests with traced profiles
-*difference() {
-    translate([0, -2.5, 0]) {
-        scale([2.15, 2.15, 1.0]) {
-            H2N_top_up_outline(5.0);
+module render_h2n_windscreen(zoffset) {
+    sides = 12;
+    ang = 360 / sides;
+    translate([0, 0, zoffset]) {
+        h2n_lower_windscreen(sides, height, radius, beam_radius, conn_radius, pin_height, connectors = true)
+        // dome at top
+        translate([0, 0, windscreen_height / 2+ windscreen_height]) {
+            sphear_windscreen_dome(sides,  box_corner_radius + 4 * beam_radius, beam_radius);
         }
-    }
-// scale([1.75, 1.75, 1.0]) {
-    translate([0, -2.4, 0]) {
-        scale([2.02, 2.02, 1.0]) {
-            H2N_top_up_outline(5.0);
+        // spiral wireframe
+        translate([0, 0, windscreen_height / 2]) {
+            sphear_windscreen_frame(sides, box_corner_radius + 4 * beam_radius, windscreen_height, beam_radius, 45);
+        }
+        // crossing reinforcements
+        // first mid crossing
+        translate([0, 0, windscreen_height / 2 + windscreen_height/3]) {
+            sphear_windscreen_frame_reinforcements(sides, box_corner_radius + 4 * beam_radius, beam_radius, ang/2, 0);
+        }
+        // second mid crossing
+        translate([0, 0, windscreen_height / 2 + windscreen_height*2/3]) {
+            sphear_windscreen_frame_reinforcements(sides, box_corner_radius + 4 * beam_radius, beam_radius, 0, 0);
+        }
+        // to dome
+        translate([0, 0, windscreen_height / 2 + windscreen_height]) {
+            sphear_windscreen_frame_reinforcements(sides, box_corner_radius + 4 * beam_radius, beam_radius, ang/2, 0);
+        }
+        // to threaded mount (these are tilted slightly and inset a little bit)
+        translate([0, 0, windscreen_height / 2]) {
+            sphear_windscreen_frame_reinforcements(sides, box_corner_radius + 4 * beam_radius - 0.15, beam_radius, 0, 10);
+        }
+        // beams to threaded mount
+        rotate([0, 0, ang/2]) {
+            sphear_windscreen_inset_frame(sides, windscreen_height/2, box_corner_radius + 4 * beam_radius, 
+                windscreen_thread_radius + 2 * wall, 
+                beam_radius, 1.66, 1.2);
+        }
+        // threaded mount
+        rotate([0, 0, 90]) {
+            sphear_windscreen_round_mount(windscreen_thread_height, windscreen_thread_radius, 2 * wall);
         }
     }
 }
 
-*scale(1.665) {
-    translate([0, 10, -0]) {
-        rotate([0, 0, 0]) {
-            H2N_front_outline(1.0);
-        }
+//
+
+module render_h2n_lower_windscreen(zoffset) {
+    translate([0, 0, zoffset]) {
+        h2n_lower_windscreen(12, windscreen_lower_height, windscreen_thread_radius + 2 * wall, windscreen_radius,
+                windscreen_beam_radius, windscreen_conn_radius, windscreen_pin_height, connectors = true);
     }
 }
-*rotate([0, 0, 4]) translate([35, 0, 0])
-    cube([2, 80, 4]);