/*
 * Rigid SMA design
 * Copyright 2023 Pierre Lecomte - sekisushai@gmail.com
 */

/*
The rigid SMA is composed of two hemispherical shells to render separately for 3D printing.
*/
//top_shell_all();
bottom_shell_all();

// EDIT BELOW

/*[ Global parameters ]*/
// Resolution of outter surface (360 for 3D printing)
res = 32;

/*[ Array parameters ]*/
// sphere radius (mm):
r = 80;

// shell thickness (mm):
e = 6;

// microphones zenith coordinates (°):
theta = [0, 90, 90, 90, 90, 180, 54.7356, 54.7356, 54.7356, 54.7356, 125.264, 125.264, 125.264, 125.264];

// microphone azimuth coordinates (°):
phi = [0, 0, 90, 180, 270, 0, 45, 135, 225, 315, 45, 135, 225, 315];

// microphone type
mic_type = "1/4"; // [1/4:Quarter_Inch, PDM:PDM MEMS]

// include USB sound card (only for digital MEMS mics)
usb_card = true;

/* the microphone array can be rotated to be in accordance with the array cut and mic stand position
*/
// microphones global rotation (°):
mics_rotate = [-90, 0, 0];

/*[ Cut parameters ]*/
// minimal zenith angle for the cut (°):
angle_min = 75;

// maximal zenith angle for the cut (°):
angle_max = 82;

// screws diameter, metric (mm):
d_screw = 3;

// screws number
n_screw = 4;

// screws azimuth angle offset (°):
screw_phi_offset =  0;

/*[ Mounting holes parameters ]*/
/* 
The hole for passing the microphone cables is centered on the sphere cut. This eases the cable mounting and allows reducing the hole diameter because the mics plugs don't have to pass through the hole when assembling the SMA.
    To optimize the hole diameter see here : http://hydra.nat.uni-magdeburg.de/packing/cci/cci.html#overview
*/
// azimuth offset for the cable hole (°):
hole_phi_offset = 45;

// hole diameter (mm):
d_hole = 10;

/*
The mic stand threaded hole should be close to the passing cable hole. It's direction is set as an offset from the cable hole direction.
*/
// threaded hole offset from cable hole [theta(°), phi(°)]:
dir_thread = [13, 0];

// DO NOT EDIT BELOW HERE
include <threads.scad>

// Hollow sphere
module hollow(r1=r-e, r2=r, fn1=$fn, fn2=$fn){
    difference(){
        sphere(r=r2, $fn=fn1);
        sphere(r=r1, $fn=fn2);
    }
}

// Torus for O-ring for 1/4" mics
module b_k(){
mirror([0,0,-1])
rotate_extrude($fn=32){
square([10.5/2,10]);
translate([10.6/2-1, 0])
circle(r=1,$fn=32);
translate([0,-1.1*e])
square([3.55, 1.1*e]);
}
}

// Adafruit PDM MEMS breakout. 
// https://www.adafruit.com/product/3492
module pdm_breakout(l=14-5, w=13-5){
$fn=64;

translate([-l/2,-w/2,-5]){

// big condo
linear_extrude(7){
translate([l/2+4.5,w/2,0])
square([3,4],center=true);
}

// small condo
linear_extrude(5.75){
translate([l/2+2.75,w/2,0])
square([3,4],center=true);
}

// tiny resistor
linear_extrude(5.5){
translate([l/2-2.9,w/2+1,0])
square([3,2],center=true);
}

// mic
linear_extrude(6){
translate([l/2,w/2-0.5,0])
square([3.5,4.5],center=true);
}
linear_extrude(50){
translate([l/2,w/2,0])
circle(d=2);
}


// wires
translate([0,0,5])
linear_extrude(2){
translate([l/2,w,0])
square([l+4,2.5],center=true);
}

linear_extrude(5){
difference(){
minkowski(){
square([l,w]);
circle(2.6);
}
}
}
}
}

module mics(type){
        rotate(mics_rotate)
for (i = [0 : len(theta)-1]){
    rotate([theta[i], 0, phi[i]])
    translate([0, 0, r-e+1]){
        if (type=="1/4")
    b_k();
        else 
    pdm_breakout();
    translate([3,3,e-1.8])
        linear_extrude(3)
    text(str(i+1), size=3);
    }
}
}

module mchstreamer(){
    $fn=64;
    adj = 0.2; // adjustment
    // usb_cart dimensions
    w_usb = 40+adj;
    l_usb = 60+adj;
    h_usb = 15+adj;
    attach_l = 20;
    attach_w = 7.3 + adj;
    attach_h = 8.2+adj;
    rotate([0,-90,90])
    translate([r-l_usb-attach_l/2,-w_usb/2,-h_usb/2])
    union(){
    cube(size = [l_usb, w_usb, h_usb], center = false);
        plug_l = 20;
        plug_w = 12+adj;
        plug_h = 10.7+adj;
        translate([l_usb - plug_l/2, w_usb/2 - plug_w/2, 1.8+adj])
        cube(size = [1.5*plug_l, plug_w, plug_h], center =false);
        translate([l_usb - attach_l + 2, 1, 2.4+adj])
        attach();
        translate([l_usb - attach_l + 2, w_usb - attach_h -1, 2.4+adj])
        attach();
        translate([w_usb + 2, 0, 0])
        cube(size=[attach_l, w_usb, 2.7]);
     
    }
    module attach(){

    rotate([0, 90, 0]){
        translate([-attach_w/2, attach_h/2, attach_l/2]){
union(){
        cube(size=[attach_w, attach_h, attach_l], center = true);
        cylinder(r=1.5, h=2*attach_l );
    }
    }}
}
}

module bottom_shell(r1= r-e, r2=r-e/2, r3=r, delta=0.2) {
    union(){
    difference(){
    hollow(r1, r2-delta/2, fn1=24, fn2=24);
    translate([0, 0, r2 * sin(90 - angle_min)-delta])
    cylinder(r=1.1*r2, h=2*r);  
    }
    difference(){
    hollow(r1, r3, fn2=24, fn1=res);
    translate([0, 0, r3 * sin(90 - angle_max)])
    cylinder(r=1.1*r3, h=2*r);
    }
}
}

module top_shell(r1= r-e, r2=r-e/2, r3=r, delta=0) {
    union(){
    difference(){
    hollow(r1, r2+0.1, fn1=24, fn2=24);
    translate([0, 0, -2*r+r2 * sin(90 - angle_min)])
    cylinder(r=1.1*r2, h=2*r);  
    }
    difference(){
    hollow(r2, r3, fn1=res, fn2=24);
    translate([0, 0, -2*r+r3 * sin(90 - angle_max)])
    cylinder(r=1.1*r3, h=2*r);
    }
}
}

module vis(d = d_screw, $fn=72) {
union(){
cylinder(d=d+0.2,h=e);
// param = [nut thickness, nut diameter, screw_head thikness]
param = d == 2 ? [1.6, 4.6, 1.2] : // M2 
        d == 2.5 ? [2, 5.8, 1.5] : // M2.5
        d == 3 ? [2.4, 6.4, 1.7] : // M3
        d == 4 ? [3.2, 8.1, 2.3] : // M4
        d == 5 ? [4, 9.2, 2.8] : // M5
        d == 6 ? [5, 11.5, 3.3] : false; // M6
translate([0,0,e-param[2]-0.2]){
    cylinder(d1=d,d2=2*d,h=param[2]);
        translate([0, 0, param[2]])
            cylinder(d=2*d, h=1);
    }
translate([0,0,-e/2])
cylinder(d=param[1]+0.2, h=param[0]+1, $fn=6);
}
}

module attach() {
rotate([(angle_min+angle_max)/2,0,hole_phi_offset]){
if (usb_card==false)
cylinder(d=d_hole, h=100);
else
mchstreamer();
    }
rotate([(angle_min+angle_max)/2 + dir_thread[0],0, hole_phi_offset + dir_thread[1]])
translate([0,0,(r-3*e)])
render()
/* 
    Change here the type of threaded hole for mounting on a mic stand. See threads.scad file for help
*/
//english_thread(3/8,16,3.5*e/25.4,internal=true);
metric_thread (diameter=6, pitch=1, length=20);
}


module vis_all(){
for (i = [0 : n_screw-1]){
rotate([(angle_min+angle_max)/2, 0, i*90+screw_phi_offset])
    translate([0,0,r-e])
    vis();
}
}

module bottom_shell_all(){
difference(){
bottom_shell();
attach();
vis_all();
mics(mic_type); 
}
}

module top_shell_all(){
difference(){
top_shell();
attach();
mics(mic_type);
vis_all();
}
}

module test_vis(){
    difference(){
    translate([0,0,e/2])
    cube([11, 11, e], center=true);
    vis();
    }
}

module test_mic(){
  difference(){
      translate([0, 0, -e/2])
  cube([13, 13, e], center=true);
  union(){
  cylinder(r=3.55,h=2*e, center= true);
  translate([0, 0, -1])
  torus();
  }
  }
}