rack updated 4

rack updated 4

height = 2400;
depth  = 1400;
width  = 1300;
tube_square_size = 80;
tube_thickness  = 3;
sheet_thickness = 2;
pin_length = 25+sheet_thickness*2+80;
bar_height = 2000;

module SquareTube(h=height, w=tube_square_size, xyz=[0,0,0]) {
    TT = tube_thickness;
    color([0.5, 0.5, 0.5, 0.5])
    translate(xyz) {
        translate([w/2, w/2, 0]) {
            difference () {
                linear_extrude(height=h)
                    square([w, w], center=true);
                translate([0, 0, -5])
                    linear_extrude(height=h+6)
                        square([w-TT, w-TT], center=true);
            }
        }
    }
}

module Frame(h=height, d=depth, w=tube_square_size) {
    SquareTube();
    SquareTube(xyz=[0,d+w,0]);
    rotate([-90]) {
        SquareTube(h=d, xyz=[0,-w,w]);
        SquareTube(h=d, xyz=[0,-h,w]);
    }
    QuadLock();
}

module Pin(len=pin_length) {
    color([0.8, 0.2, 0.1, 0.5])
    translate([0,0,-(len/2-15)])
        linear_extrude(height=pin_length)
            circle(d=16);
}

module Lock(sz=240, d=sheet_thickness) {
    color([0.5, 0.5, 0.2, 0.5])
    translate([0,120,120])
        rotate([0,-90]) {
            difference() {
                linear_extrude(d)
                    square([sz, sz], center=true);
                translate([125,125,-10])
                    rotate([0,0,45])
                        linear_extrude(d+20)
                            square([sz, sz], center=true);

                }
            }
}

module DoubleLock(w=tube_square_size) {
    Lock();
    translate([tube_square_size+sheet_thickness,0,0]) {
        Lock();
    }
    // pins
    translate([0,120,120])
        rotate([0,-90]) {
            translate([w,-w,-(pin_length/2)]) { Pin(); }
            translate([-w,w,-(pin_length/2)]) { Pin(); }
            translate([-w,-w,-(pin_length/2)]) { Pin(); }
            translate([w-w,-w,-(pin_length/2)]) { Pin(); }
            translate([-w,w-w,-(pin_length/2)]) { Pin(); }
        }
}

module PairLock(w=tube_square_size) {
    DoubleLock();
    rotate(180)
        translate([-w,-depth-w*2,0])
        DoubleLock();

}

module QuadLock(w=tube_square_size) {
    PairLock();
    translate([0,depth+w*2,height])
        rotate([180,0,0])
            PairLock();
}

module Flank(w=tube_square_size) {
    rotate([0,-90,0]) {
        linear_extrude(sheet_thickness)
            square([240, 80], center=true);
        translate([-w, w-w, (pin_length/4)]) { Pin(); }
        translate([w, w-w, (pin_length/4)]) { Pin(); }
    }
}

module Horbar(w=tube_square_size, bh=bar_height) {
    translate([w+sheet_thickness, w/2, bh]) {
        Flank();
        rotate([0,90]) {
            linear_extrude(width-w-sheet_thickness*2)
                circle(16);
        }
        translate([width-w-sheet_thickness*2,0,0])
            rotate([0,180]) {
                Flank();
            }
    }
}

Frame();
translate([width,0,0])
    Frame();

Horbar();

translate([-350, 1450, 800]) {
    rotate([0,90]) {
        linear_extrude(2020)
        circle(16);
    }
}

translate([40, depth+78, 770]) {
    rotate([0,0,270]) {
        Flank();
        rotate([0,-90,0]) {
            translate([0, 0, (pin_length/4)]) {
                color([0.2, 0.2, 0.1, 0.5])
                translate([0,0,-80])
                linear_extrude(height=190)
                circle(d=28);
                color([0.2, 0.2, 0.1, 0.5])
                    translate([-20, -20, -80-sheet_thickness]) {
                        linear_extrude(sheet_thickness)
                            square(40);
                    }
            }
        }
    }
}

height = 2400;
depth  = 1400;
width  = 1300;
tube_square_size = 80;
tube_thickness  = 3;
sheet_thickness = 2;
pin_length = 25+sheet_thickness*2+80;
bar_height = 2000;

module SquareTube(h=height, w=tube_square_size, xyz=[0,0,0]) {
    TT = tube_thickness;
    color([0.5, 0.5, 0.5, 0.5])
    translate(xyz) {
        translate([w/2, w/2, 0]) {
            difference () {
                linear_extrude(height=h)
                    square([w, w], center=true);
                translate([0, 0, -5])
                    linear_extrude(height=h+6)
                        square([w-TT, w-TT], center=true);
            }
        }
    }
}

module Frame(h=height, d=depth, w=tube_square_size) {
    SquareTube();
    SquareTube(xyz=[0,d+w,0]);
    rotate([-90]) {
        SquareTube(h=d, xyz=[0,-w,w]);
        SquareTube(h=d, xyz=[0,-h,w]);
    }
    QuadLock();
}

module Pin(len=pin_length) {
    color([0.8, 0.2, 0.1, 0.5])
    translate([0,0,-(len/2-15)])
        linear_extrude(height=pin_length)
            circle(d=16);
}

module Lock(sz=240, d=sheet_thickness) {
    color([0.5, 0.5, 0.2, 0.5])
    translate([0,120,120])
        rotate([0,-90]) {
            difference() {
                linear_extrude(d)
                    square([sz, sz], center=true);
                translate([125,125,-10])
                    rotate([0,0,45])
                        linear_extrude(d+20)
                            square([sz, sz], center=true);

                }
            }
}

module DoubleLock(w=tube_square_size) {
    Lock();
    translate([tube_square_size+sheet_thickness,0,0]) {
        Lock();
    }
    // pins
    translate([0,120,120])
        rotate([0,-90]) {
            translate([w,-w,-(pin_length/2)]) { Pin(); }
            translate([-w,w,-(pin_length/2)]) { Pin(); }
            translate([-w,-w,-(pin_length/2)]) { Pin(); }
            translate([w-w,-w,-(pin_length/2)]) { Pin(); }
            translate([-w,w-w,-(pin_length/2)]) { Pin(); }
        }
}

module PairLock(w=tube_square_size) {
    DoubleLock();
    rotate(180)
        translate([-w,-depth-w*2,0])
        DoubleLock();

}

module QuadLock(w=tube_square_size) {
    PairLock();
    translate([0,depth+w*2,height])
        rotate([180,0,0])
            PairLock();
}

module flank(w=tube_square_size) {
    rotate([0,-90,0]) {
        linear_extrude(sheet_thickness)
            square([240, 80], center=true);
        translate([-w, w-w, (pin_length/4)]) { Pin(); }
        translate([w, w-w, (pin_length/4)]) { Pin(); }
    }
}

module horbar(w=tube_square_size, bh=bar_height) {
    translate([w+sheet_thickness, w/2, bh]) {
        flank();
        rotate([0,90]) {
            linear_extrude(width-w-sheet_thickness*2)
                circle(16);
        }
        translate([width-w-sheet_thickness*2,0,0])
            rotate([0,180]) {
                flank();
            }
    }
}

Frame();
translate([width,0,0])
    Frame();

horbar();


fixed position of mounting for manupulator

module menuKnobManipulator()
{
  difference()
  {
    // part's body
    cylinder(r=30/2, h=10, $fs=1);
    // hole for encoder's sticking-out part ;)
    translate([0,0,10-6])
      cylinder(r=(6+1)/2, h=6, $fs=1);
  }
  // driver part 1
  translate([-(1-0.4)/2, -1/2+3, 10-6])
    cube([1-0.2, 1, 6]);
  // driver part 2
  translate([-(1-0.4)/2, -1/2-3, 10-6])
    cube([1-0.2, 1, 6]);
}

menuKnobManipulator();

module menuKnobManipulator()
{
  difference()
  {
    // part's body
    cylinder(r=30/2, h=10, $fs=1);
    // hole for encoder's sticking-out part ;)
    translate([0,0,10-6])
      cylinder(r=(6+1)/2, h=6, $fs=1);
  }
  // driver part 1
  translate([-(1-0.4)/2, -1/2+2.5, 10-6])
    cube([1-0.2, 1, 6]);
  // driver part 2
  translate([-(1-0.4)/2, -1/2-2.5, 10-6])
    cube([1-0.2, 1, 6]);
}

menuKnobManipulator();


Resolve conflict.

Resolve conflict.

// fishbox.scad
//  - Enclosure design for zebrafish Skinner box
//
//  Author: Mark Liffiton
//  Date: Oct, 2014 - Jan, 2015
//
//  Units are mm

// Set thickness to account for thickness of material
// PLUS needed clearance for cuts into which material should fit.
thickness = 1.8;  // 1.8mm = 0.07" (looks good based on cut test piece)

// Interior box dimensions (from centerpoints of walls, so actual dimension is minus material thickness)
width = 290;    // x = 29cm wall-to-wall
depth = 350;    // y = 35cm to accomodate 34.5cm tank length
i_height = 180+thickness;
                // z = 18cm to accomodate 16cm tank height plus light holder, plus cover
                // (i_height because 'height' is used for height of entire box)

// amount faces extend past each other at corners
overhang = 20;

// amount horizontal support bars extend past side supports
outset = overhang/2;

// tank base plate
base_depth = depth-thickness*2;
base_height = overhang;

// create height var to account for raised base
height = i_height + base_height;

// light bar
light_bar_width = 30;
light_pos_x = 50;
light_height = height-thickness*2-10;

// for slight offsets/tweaks
epsilon = 1;

// vars to control projection for DXF export (see makefile)
if (DXF_TOP) {
    projection() top_cover();
} else if (DXF_BOTTOM) {
    projection() tank_base();
} else if (DXF_SIDE1) {
    projection() rotate(a=[90,0,0]) side(y=0);
} else if (DXF_SIDE2) {
    projection() rotate(a=[90,0,0]) side(y=depth);
} else if (DXF_END1) {
    projection() rotate(a=[0,90,0]) vert_face(x=0);
} else if (DXF_END2) {
    projection() rotate(a=[0,90,0]) vert_face(x=width);
} else if (DXF_LIGHT_BAR) {
    projection() light_bar();
}
else {
    // 3D model
    // components to include (comment out unwanted)
    vert_face(x=0);
    vert_face(x=width);
    side(y=0);
    side(y=depth);
    tank_base();
    light_bar();
    // camera supports
    hanging_supports(x=width, y=depth/2, z=height/2, out=20, up=30, spacing=20);
    // rpi support
    hanging_support(x=width, y=depth/4+9, z=height/2, out=3, up=85);
    mock_rpi(x=width, y=depth/4, z=height/2);
    top_cover();
}

//////////////////////////////////////////////////////////////////
// Module definitions
//

module vert_face(x=0) {
    difference() {
        vert_face_base(x);
        camera_opening();
        // camera supports
        hanging_supports(x=width+thickness, y=depth/2, z=height/2+10, out=20, up=30, spacing=20);
        // rpi supports
        hanging_support(x=width+thickness, y=depth/4+9, z=height/2+10, out=3, up=85);
        side(y=0);
        side(y=depth);
        tank_base();
    }
}

module vert_face_base(x) {
    translate([x-thickness/2,-overhang])
        cube([thickness,depth+overhang*2,height]);
}

module camera_opening() {
    translate([width, depth/2, height/2])
        cube([thickness*2,10,10], center=true);
}

module hanging_supports(x, y, z, out, up, spacing) {
    hanging_support(x, y + spacing/2, z, out, up);
    hanging_support(x, y - spacing/2, z, out, up);
}

module hanging_support(x, y, z, out, up) {
    inner_w = out+thickness;
    inner_h = up;
    inner_offset = 5;
    translate([x,y,z])
    // shift down to center on camera opening
    translate([0,0,-inner_offset])
    // push inner opening up against vert face
    translate([inner_w/2,0,0])
    difference() {
        cube([inner_w+20, thickness, inner_h+30], center=true);
        // cutout for camera
        translate([0,0,inner_offset])
            cube([inner_w, thickness*2, inner_h], center=true);
        // cutout for passing through vertface
        translate([-10-epsilon,0,0])
            cube([inner_w, thickness*2, inner_h-10], center=true);
        // bottom cutout
        translate([-inner_w/2,0,-25])
            cube([thickness, thickness*2, 10], center=true);
    }
}

module top_cover() {
    color("Grey", alpha=0.5)
    translate([-outset,-outset,height-thickness])
    difference() {
        cube([width+outset*2,depth+outset*2,thickness]);
        cutouts(5,width-thickness,outset,rot=0,trans=[width/2+outset,0,0]);
        cutouts(5,width-thickness,outset,rot=180,trans=[width/2+outset,depth+outset*2,0]);
        cutouts(5,depth-thickness,outset,rot=-90,trans=[0,depth/2+outset,0]);
        cutouts(5,depth-thickness,outset,rot=90,trans=[width+outset*2,depth/2+outset,0]);
    }
}

module tank_base() {
    translate([-outset,thickness,base_height])
    difference() {
        cube([width+outset*2, base_depth, thickness]);
        cutouts(5,depth,outset,rot=-90,trans=[0,base_depth/2,0]);
        cutouts(5,depth,outset,rot=90,trans=[width+outset*2,base_depth/2,0]);
    }
}

module light_bar_opening() {
    // A wider opening, so the bar can slide out of the way of placing or removing the fish tank
    translate([light_pos_x, -outset, light_height])
        cube([light_bar_width*2, depth+outset*2, thickness]);
}

module light_bar() {
    translate([light_pos_x-light_bar_width/2, -outset, light_height])
    difference() {
        cube([light_bar_width, depth+outset*2, thickness]);
        cutouts(2,light_bar_width,outset,rot=0,trans=[light_bar_width/2,0,0]);
        cutouts(2,light_bar_width,outset,rot=180,trans=[light_bar_width/2,depth+outset*2,0]);
    }
}

module cutouts(num, width, outset, rot, trans) {
    w = width / ((num-1) * 2);
    translate(trans)
    rotate([0,0,1], a=rot)
    for (i = [0 : num-1]) {
        translate([-width/2 - w/2 + i*2*w, -thickness/2, -epsilon])
            cube([w, outset+thickness, thickness+epsilon*2]);
    }
}

module light_wire_opening() {
    translate([light_pos_x, 0, light_height-10])
    scale([2,1,1])
    rotate(v=[1,0,0], a=90)
        cylinder(d=10, h=thickness+epsilon, center=true);
}

module side(y=0) {
    difference() {
        side_base(y);
        scale([1,1,0.5])
            vert_face_base(x=0);
        scale([1,1,0.5])
            vert_face_base(x=width);
        light_bar();
        light_wire_opening();
        top_cover();
    }
}

module side_base(y) {
    translate([-overhang,y-thickness/2,overhang/2])
        cube([width+overhang*2, thickness, height-overhang/2]);
}

module mock_rpi(x, y, z) {
    translate([x+thickness, y, z])
        rotate(v=[0,1,0], a=90)
            translate([-85/2, -56/2, 0])
                union() {
                    cube([85, 56, 2]);
                    // USB1
                    translate([67, 41, 2])
                        cube([20, 12, 12]);
                    // USB2
                    translate([67, 23, 2])
                        cube([20, 12, 12]);
                }
}

// fishbox.scad
//  - Enclosure design for zebrafish Skinner box
//
//  Author: Mark Liffiton
//  Date: Oct, 2014
//
//  Units are mm

// Set thickness to account for thickness of material
// PLUS needed clearance for cuts into which material should fit.
thickness = 6.35;  // 6.35mm = 1/4"

// Interior box dimensions (from centerpoints of walls, so actual dimension is minus material thickness)
width = 290;    // x = 29cm wall-to-wall
depth = 350;    // y = 35cm to accomodate 34.5cm tank length
i_height = 180+thickness;
                // z = 18cm to accomodate 16cm tank height plus light holder, plus cover
                // (i_height because 'height' is used for height of entire box)

// amount faces extend past each other at corners
overhang = 20;

// amount horizontal support bars extend past side supports
outset = overhang/2;

// tank base plate
base_width = width-thickness*2;
base_height = overhang;

// create height var to account for raised base
height = i_height + base_height;

// light bar
light_bar_width = 30;
light_pos_x = 50;
light_height = height-thickness*2-10;

// for slight offsets/tweaks
epsilon = 1;

// vars to control projection for DXF export (see makefile)
if (DXF_TOP) {
    projection() top_cover();
} else if (DXF_BOTTOM) {
    projection() tank_base();
} else if (DXF_SIDE1) {
    projection() rotate(a=[90,0,0]) side(y=0);
} else if (DXF_SIDE2) {
    projection() rotate(a=[90,0,0]) side(y=depth);
} else if (DXF_END1) {
    projection() rotate(a=[0,90,0]) vert_face(x=0);
} else if (DXF_END2) {
    projection() rotate(a=[0,90,0]) vert_face(x=width);
} else if (DXF_LIGHT_BAR) {
    projection() light_bar();
}
else {
    // 3D model
    // components to include (comment out unwanted)
    vert_face(x=0);
    vert_face(x=width);
    side(y=0);
    side(y=depth);
    tank_base();
    light_bar();
    // camera supports
    hanging_supports(x=width, y=depth/2, z=height/2, out=20, up=30, spacing=20);
    // rpi support
    hanging_support(x=width, y=depth/4+9, z=height/2, out=3, up=85);
    mock_rpi(x=width, y=depth/4, z=height/2);
    top_cover();
}

//////////////////////////////////////////////////////////////////
// Module definitions
//

module vert_face(x=0) {
    difference() {
        vert_face_base(x);
        camera_opening();
        // camera supports
        hanging_supports(x=width+thickness, y=depth/2, z=height/2+10, out=20, up=30, spacing=20);
        // rpi supports
        hanging_support(x=width+thickness, y=depth/4+9, z=height/2+10, out=3, up=85);
        scale([1,1,0.5])
            side_base(y=0);
        scale([1,1,0.5])
            side_base(y=depth);
    }
}

module vert_face_base(x) {
    translate([x-thickness/2,-overhang,overhang])
        cube([thickness,depth+overhang*2,height-overhang]);
}

module camera_opening() {
    translate([width, depth/2, height/2])
        cube([thickness*2,10,10], center=true);
}

module hanging_supports(x, y, z, out, up, spacing) {
    hanging_support(x, y + spacing/2, z, out, up);
    hanging_support(x, y - spacing/2, z, out, up);
}

module hanging_support(x, y, z, out, up) {
    inner_w = out+thickness;
    inner_h = up;
    inner_offset = 5;
    translate([x,y,z])
    // shift down to center on camera opening
    translate([0,0,-inner_offset])
    // push inner opening up against vert face
    translate([inner_w/2,0,0])
    difference() {
        cube([inner_w+20, thickness, inner_h+30], center=true);
        // cutout for camera
        translate([0,0,inner_offset])
            cube([inner_w, thickness*2, inner_h], center=true);
        // cutout for passing through vertface
        translate([-10-epsilon,0,0])
            cube([inner_w, thickness*2, inner_h-10], center=true);
        // bottom cutout
        translate([-inner_w/2,0,-25])
            cube([thickness, thickness*2, 10], center=true);
    }
}

module top_cover() {
    color("Grey", alpha=0.5)
    translate([-outset,-outset,height-thickness])
    difference() {
        cube([width+outset*2,depth+outset*2,thickness]);
        cutouts(5,width-thickness,outset,rot=0,trans=[width/2+outset,0,0]);
        cutouts(5,width-thickness,outset,rot=180,trans=[width/2+outset,depth+outset*2,0]);
        cutouts(5,depth-thickness,outset,rot=-90,trans=[0,depth/2+outset,0]);
        cutouts(5,depth-thickness,outset,rot=90,trans=[width+outset*2,depth/2+outset,0]);
    }
}

module tank_base() {
    translate([thickness,-outset,base_height])
    difference() {
        cube([base_width, depth+outset*2, thickness]);
        cutouts(5,base_width,outset,rot=0,trans=[base_width/2,0,0]);
        cutouts(5,base_width,outset,rot=180,trans=[base_width/2,depth+outset*2,0]);
    }
}

module light_bar_opening() {
    // A wider opening, so the bar can slide out of the way of placing or removing the fish tank
    translate([light_pos_x, -outset, light_height])
        cube([light_bar_width*2, depth+outset*2, thickness]);
}

module light_bar() {
    translate([light_pos_x-light_bar_width/2, -outset, light_height])
    difference() {
        cube([light_bar_width, depth+outset*2, thickness]);
        cutouts(2,light_bar_width,outset,rot=0,trans=[light_bar_width/2,0,0]);
        cutouts(2,light_bar_width,outset,rot=180,trans=[light_bar_width/2,depth+outset*2,0]);
    }
}

module cutouts(num, width, outset, rot, trans) {
    w = width / ((num-1) * 2);
    translate(trans)
    rotate([0,0,1], a=rot)
    for (i = [0 : num-1]) {
        translate([-width/2 - w/2 + i*2*w, -thickness/2, -epsilon])
            cube([w, outset+thickness, thickness+epsilon*2]);
    }
}

module light_wire_opening() {
    translate([light_pos_x, 0, light_height-10])
    scale([2,1,1])
    rotate(v=[1,0,0], a=90)
        cylinder(d=10, h=thickness+epsilon, center=true);
}

module side(y=0) {
    difference() {
        side_base(y);
        vert_face(x=0);
        vert_face(x=width);
        tank_base();
        light_bar_opening();
        light_wire_opening();
        top_cover();
    }
}

module side_base(y) {
    translate([-overhang,y-thickness/2,0])
        cube([width+overhang*2, thickness, height]);
}

module mock_rpi(x, y, z) {
    translate([x+thickness, y, z])
        rotate(v=[0,1,0], a=90)
            translate([-85/2, -56/2, 0])
                union() {
                    cube([85, 56, 2]);
                    // USB1
                    translate([67, 41, 2])
                        cube([20, 12, 12]);
                    // USB2
                    translate([67, 23, 2])
                        cube([20, 12, 12]);
                }
}


mount extra height param

mount extra height param

$fs = 0.25;
$fa = 8;

use <hcsr04.scad>
use <utils.scad>

// horizontal sonar mounting holes
module mount_holes(center = true, left = 2, right = 2)
{
    if (center) translate ([-5,    0, -15]) cylinder(d=3.2, h=15, center=false);

    if (left >= 1) translate ([-5,  9.5, -15]) cylinder(d=3.2, h=15, center=false);
    if (left >= 2) translate ([-5,  19, -15]) cylinder(d=3.2, h=15, center=false);

    if (right >= 1) translate ([-5, -9.5, -15]) cylinder(d=3.2, h=15, center=false);
    if (right >= 2) translate ([-5, -19, -15]) cylinder(d=3.2, h=15, center=false);
}

// sonar mount bracket
module mount(extra = 7) {

    top_r = 3;
    bottom_r = 5;

    // mount plate
    color ("gray") {

        // front
        difference() {

            // front plate
            translate ([1.5, -48/2, -extra])
                #union() {
                    cube(size=[3, 48, 19+extra], center=false);
                    translate ([0, top_r, 0]) cube(size=[3, 48-2*top_r, 19+extra+top_r], center=false);
                    translate ([0, 48-top_r, 19+extra]) rotate([90, 0, 90]) cylinder(r=top_r, h=3, center=false);
                    translate ([0, top_r, 19+extra]) rotate([90, 0, 90]) cylinder(r=top_r, h=3, center=false);
                }

            // hc-sr04 cutouts
            translate ([0, -45/2, 0]) rotate([90, 0, 90]) {

                // sonar holes
                translate([45/2-(42-16)/2,18/2+1,1.3]) cylinder(d=17, h=15);
                translate([45/2+(42-16)/2,18/2+1,1.3]) cylinder(d=17, h=15);

                //xtals holes - bot upside and downwards
                hull () {
                    translate([45/2-3.25,20-3.5,1.3])
                    {
                        translate([0,0,0]) cylinder(d=6, h=5);
                        translate([6.5,0,0]) cylinder(d=6, h=5);
                    }
                    translate([45/2-3.25, 4,1.3]) hull()
                    {
                        translate([0,-2,0]) cylinder(d=6, h=5);
                        translate([6.5,-2,0]) cylinder(d=6, h=5);
                    }
                }

                // screws
                translate([   1.0,    1.0, 4.5-0.5]) screw2x6bore();
                translate([45-1.0, 20-1.5, 4.5-0.5]) screw2x6bore();
                translate([45-1.0,    1.0, 4.5-0.5]) screw2x6bore();
                translate([   1.0, 20-1.5, 4.5-0.5]) screw2x6bore();
            }

            // center cleanup
            translate ([3, 0, 10]) cube(size=[5, 20, 11], center=true);
        }

        //base
        difference() {
            #union() {
                translate ([-3.5, -48/2, -extra]) cube(size=[10-bottom_r, 48, 5], center=false);
                translate ([-3.5-bottom_r, -48/2+5, -extra]) cube(size=[10, 48-2*bottom_r, 5], center=false);
                translate ([-3.5, -48/2+5, -extra]) cylinder(r=bottom_r, h=5, center=false);
                translate ([-3.5, 48/2-5, -extra]) cylinder(r=bottom_r, h=5, center=false);
            }
            mount_holes();
        }
    }
}

// horizantaly mounted sonar
module horizontal_sonar() {

    // horizontal sonar
    translate ([0, -45/2, 0]) rotate([90, 0, 90]) hcsr04();

    mount();

    // sonar ray
    //color("white") translate ([20+1000/2, 0, 10]) rotate([0, 90, 0]) cylinder(d1=40, d2=520,h=1000, center=true);
}

// horizantaly mounted sonar - mockup
module vertical_sonar() {

    // vertical sonar
    translate ([0, -10, 45]) rotate([0, 90, 0]) hcsr04();

    // mount bracket outline
    color("gray") translate ([1.5, -10, -6]) cube(size=[3, 20, 51], center=false);
    color("gray") translate ([-8.5, -10, -6]) cube(size=[10, 20, 5], center=false);

    // sonar ray
    //color("white") translate ([20+1000/2, 0, 22.5]) rotate([0, 90, 0]) cylinder(d1=40, d2=520,h=1000, center=true);
}

//translate ([0, 0, 4.5]) rotate([0, 90, 0]) mount(); // std version
translate ([0, 0, 4.5]) rotate([0, 90, 0]) mount(15); // tall

$fs = 0.25;
$fa = 8;

use <hcsr04.scad>
use <utils.scad>

// horizontal sonar mounting holes
module mount_holes(center = true, left = 2, right = 2)
{
    if (center) translate ([-5,    0, -15]) cylinder(d=3.2, h=15, center=false);

    if (left >= 1) translate ([-5,  9.5, -15]) cylinder(d=3.2, h=15, center=false);
    if (left >= 2) translate ([-5,  19, -15]) cylinder(d=3.2, h=15, center=false);

    if (right >= 1) translate ([-5, -9.5, -15]) cylinder(d=3.2, h=15, center=false);
    if (right >= 2) translate ([-5, -19, -15]) cylinder(d=3.2, h=15, center=false);
}

// sonar mount bracket
module mount() {

    extra = 7;
    top_r = 3;
    bottom_r = 5;

    // mount plate
    color ("gray") {

        // front
        difference() {

            // front plate
            translate ([1.5, -48/2, -extra])
                #union() {
                    cube(size=[3, 48, 19+extra], center=false);
                    translate ([0, top_r, 0]) cube(size=[3, 48-2*top_r, 19+extra+top_r], center=false);
                    translate ([0, 48-top_r, 19+extra]) rotate([90, 0, 90]) cylinder(r=top_r, h=3, center=false);
                    translate ([0, top_r, 19+extra]) rotate([90, 0, 90]) cylinder(r=top_r, h=3, center=false);
                }

            // hc-sr04 cutouts
            translate ([0, -45/2, 0]) rotate([90, 0, 90]) {

                // sonar holes
                translate([45/2-(42-16)/2,18/2+1,1.3]) cylinder(d=17, h=15);
                translate([45/2+(42-16)/2,18/2+1,1.3]) cylinder(d=17, h=15);

                //xtals holes - bot upside and downwards
                hull () {
                    translate([45/2-3.25,20-3.5,1.3])
                    {
                        translate([0,0,0]) cylinder(d=6, h=5);
                        translate([6.5,0,0]) cylinder(d=6, h=5);
                    }
                    translate([45/2-3.25, 4,1.3]) hull()
                    {
                        translate([0,-2,0]) cylinder(d=6, h=5);
                        translate([6.5,-2,0]) cylinder(d=6, h=5);
                    }
                }

                // screws
                translate([   1.0,    1.0, 4.5-0.5]) screw2x6bore();
                translate([45-1.0, 20-1.5, 4.5-0.5]) screw2x6bore();
                translate([45-1.0,    1.0, 4.5-0.5]) screw2x6bore();
                translate([   1.0, 20-1.5, 4.5-0.5]) screw2x6bore();
            }

            // center cleanup
            translate ([3, 0, 10]) cube(size=[5, 20, 11], center=true);
        }

        //base
        difference() {
            #union() {
                translate ([-3.5, -48/2, -extra]) cube(size=[10-bottom_r, 48, 5], center=false);
                translate ([-3.5-bottom_r, -48/2+5, -extra]) cube(size=[10, 48-2*bottom_r, 5], center=false);
                translate ([-3.5, -48/2+5, -extra]) cylinder(r=bottom_r, h=5, center=false);
                translate ([-3.5, 48/2-5, -extra]) cylinder(r=bottom_r, h=5, center=false);
            }
            mount_holes();
        }
    }
}

// horizantaly mounted sonar
module horizontal_sonar() {

    // horizontal sonar
    translate ([0, -45/2, 0]) rotate([90, 0, 90]) hcsr04();

    mount();

    // sonar ray
    //color("white") translate ([20+1000/2, 0, 10]) rotate([0, 90, 0]) cylinder(d1=40, d2=520,h=1000, center=true);
}

// horizantaly mounted sonar - mockup
module vertical_sonar() {

    // vertical sonar
    translate ([0, -10, 45]) rotate([0, 90, 0]) hcsr04();

    // mount bracket outline
    color("gray") translate ([1.5, -10, -6]) cube(size=[3, 20, 51], center=false);
    color("gray") translate ([-8.5, -10, -6]) cube(size=[10, 20, 5], center=false);

    // sonar ray
    //color("white") translate ([20+1000/2, 0, 22.5]) rotate([0, 90, 0]) cylinder(d1=40, d2=520,h=1000, center=true);
}

translate ([0, 0, 4.5]) rotate([0, 90, 0]) mount();