Add some pieces to be laser cut to make a support for potentiometer

width = 15;
beam_size = 10;
beam_thickness = 5;
thickness = 2;
bridge_length = 32;
potentiometer_width = 17;
total_length = bridge_length+2*width+2*thickness;

module bottom_beam(){
difference(){
union(){
		difference(){
		union(){
			cube(size = [total_length, beam_size, beam_thickness], center=true);

			translate([total_length/2 - thickness/2,0,0]) cube(size = [thickness, beam_size+2*thickness, beam_thickness], center=true);
			translate([-total_length/2 + thickness/2,0,0]) cube(size = [thickness, beam_size+2*thickness, beam_thickness], center=true);

			translate([total_length/2 - thickness/2-thickness-width,0,0]) cube(size = [thickness, beam_size+2*thickness, beam_thickness], center=true);
			translate([-total_length/2 + thickness/2+thickness+width,0,0]) cube(size = [thickness, beam_size+2*thickness, beam_thickness], center=true);
		}

	//Remove space to save weight?
		translate([bridge_length/2+width/2,0,0]) cube(size = [width, beam_size-2*thickness, 2*beam_thickness], center=true);
		translate([-bridge_length/2-width/2,0,0]) cube(size = [width, beam_size-2*thickness, 2*beam_thickness], center=true);
	}
		minkowski(){
			cube(size = [potentiometer_width, potentiometer_width, beam_thickness/2], center=true);
			cylinder(r= 2, h=beam_thickness/2,center=true);
}
	}
	cube(size = [potentiometer_width, potentiometer_width, beam_thickness*2], center=true);
	translate([0 , potentiometer_width/2],0) cube(size = [potentiometer_width, potentiometer_width, beam_thickness*2], center=true);
}

}
module top_beam(){
difference(){
	union(){
			difference(){
		union(){
			cube(size = [bridge_length+2*thickness, beam_size, beam_thickness], center=true);

			translate([total_length/2 - thickness/2-thickness-width,0,0]) cube(size = [thickness, beam_size+2*thickness, beam_thickness], center=true);
			translate([-total_length/2 + thickness/2+thickness+width,0,0]) cube(size = [thickness, beam_size+2*thickness, beam_thickness], center=true);
		}

	//Remove space to save weight?
		translate([bridge_length/2+width/2,0,0]) cube(size = [width, beam_size-2*thickness, 2*beam_thickness], center=true);
		translate([-bridge_length/2-width/2,0,0]) cube(size = [width, beam_size-2*thickness, 2*beam_thickness], center=true);
	}
		cylinder(r= 5+thickness, h= beam_thickness, center=true);
	}
	cylinder(r= 5, h= 2* beam_thickness, center=true);
}
}

translate([0, 0, beam_thickness+1]) top_beam();
bottom_beam();

translate([0, 0, 2* beam_thickness+2]) difference(){
 	cylinder(r=3+thickness,h=beam_thickness, center=true);
	cylinder(r=3, h=2*beam_thickness, center=true);
}

error: pathspec 'Hardware/potentiometer_support.scad' did not match any file(s) known to git


fixed full height of the box

fixed full height of the box

r_ext=(101+2*4)/2;
r_int=r_ext-2;
cut=5.9+0.1+0.2;
total_h=150;
cylinder_h=total_h-r_ext;

$fn=200;

module box()
{
  difference()
  {
    union()
    {
      // mount
      difference()
      {
        cube([68+r_ext, 2*r_ext, cut+2*2]);
        translate([-1, (2*r_ext-101)/2, -1])
          cube([68-0.2+1, 101, 20]);
        translate([0, (2*r_ext-101-2*2)/2, 2])
          cube([68+2, 101+2*2, cut]);
      }
      // box
      translate([68+2+2+r_ext, r_ext, 0])
      {
        cylinder(r=r_ext, h=cylinder_h);
        translate([0,0,cylinder_h])
          sphere(r=r_ext);
      }
    }
    // cut-in the box
    union()
    {
      translate([68+2+2+r_ext, r_ext, 0])
        translate([0,0,-1])
        {
          cylinder(r=r_int, h=cylinder_h+2);
          translate([0,0,cylinder_h])
            sphere(r=r_int);
        }
    }
  }
}

box();


main part made a bit thicker

main part made a bit thicker

difference()
{
  union()
  {
    // main cylinder
    difference()
    {
      cylinder(r=24.5/2, h=2.5);
      cylinder(r=16/2, h=1.5);
    }

    // 3 side blockers
    for(angle = [0, 120, 240])
      rotate([0, 0, angle])
        translate([-1/2, -1/2, 0] + [16/2-1/2, 0, 0])
          cube([1, 1, 2]);

    // main screw mount - bottom part
    intersection()
    {
      int_cube_size=7.2;
      rotate([0, 0, 0])
        translate([-int_cube_size/2, -int_cube_size/2, 0])
          cube([int_cube_size, int_cube_size, 2]);
      rotate([0, 0, 45])
        translate([-int_cube_size/2, -int_cube_size/2, 0])
          cube([int_cube_size, int_cube_size, 2]);
    }

    // main screw mount - top part
    {
      int_cube_size=9.5;
      translate([-int_cube_size/2, -int_cube_size/2, 0] + [0, 0, 2.5])
        cube([int_cube_size, int_cube_size, 7]);
    }
  }
  // screw hole
  translate([0, 0, 2.5+1])
    cylinder(r=(7+1.5)/2, h=7-1, $fs=1);
  cylinder(r=4/2, h=12, $fs=1);
}

difference()
{
  union()
  {
    // main cylinder
    difference()
    {
      cylinder(r=24.5/2, h=2.5);
      cylinder(r=16/2, h=2);
    }

    // 3 side blockers
    for(angle = [0, 120, 240])
      rotate([0, 0, angle])
        translate([-1/2, -1/2, 0] + [16/2-1/2, 0, 0])
          cube([1, 1, 2]);

    // main screw mount - bottom part
    intersection()
    {
      int_cube_size=7.2;
      rotate([0, 0, 0])
        translate([-int_cube_size/2, -int_cube_size/2, 0])
          cube([int_cube_size, int_cube_size, 2]);
      rotate([0, 0, 45])
        translate([-int_cube_size/2, -int_cube_size/2, 0])
          cube([int_cube_size, int_cube_size, 2]);
    }

    // main screw mount - top part
    {
      int_cube_size=9.5;
      translate([-int_cube_size/2, -int_cube_size/2, 0] + [0, 0, 2.5])
        cube([int_cube_size, int_cube_size, 7]);
    }
  }
  // screw hole
  translate([0, 0, 2.5+1])
    cylinder(r=(7+1.5)/2, h=7-1, $fs=1);
  cylinder(r=4/2, h=12, $fs=1);
}


Added LCD cutout model

Added LCD cutout model

difference() {
    cube([15, 15, 0.5], center=true);
    cube([8, 3.7,1], center=true);
    translate([0, -1, -2]){
        cylinder(5, 2, 2);
    }
}

error: pathspec 'CAD_models/lcd_cutout.scad' did not match any file(s) known to git


shapes: Extend size_align with orient parameter

use <misc.scad>

// translate children
module lineup(arr=undef)
{
    /*echo(arr);*/
    /*echo($children);*/
    if($children>0)
    {
        for (i = [0 : $children-1])
            translate(arr[i]) children(i);
    }
}

module stack(separations)
{
    union()
    {
        for (i = [0:len(separations)-1])
        {
            offset = v_sum(separations,i);
            /*echo("i",i,"offset",offset);*/
            translate ([0,0,offset])
            {
                child(i);
            }
        }
    }
}

module orient(zaxes, roll=0)
{
    zaxes = len(zaxes.x) == undef && zaxes.x != undef? [zaxes] : zaxes;
    for(zaxis=zaxes)
    {
        rotate(_orient_angles(zaxis))
        /*rotate(roll*z)*/
            children();
    }
}

module size_align(size=[10,10,10], align=[0,0,0], orient=[0,0,1])
{
    bounds = _rotate_matrix(_orient_angles(orient)) * [size.x,size.y,size.z,1];
    t=hadamard(align, [abs(bounds.x/2),abs(bounds.y/2),abs(bounds.z/2)]);
    translate(t)
    {
        orient(orient)
        {
            children();
        }
    }
}

module cubea(size=[10,10,10], align=[0,0,0], extrasize=[0,0,0], extrasize_align=[0,0,0])
{
    size_align(extrasize,extrasize_align)
    {
        size_align(size,align)
        {
            cube(size+extrasize, center=true);
        }
    }
}

module cylindera(h=10, r=undef, r1=undef, r2=undef, d=undef, d1=undef, d2=undef, align=[0,0,0], extra_h=0,extra_r=undef,extra_d=undef,extra_align=[0,0,0])
{
    extra_r_=(extra_r==undef?0:extra_r);
    extra_d_=(extra_d==undef?0:extra_d);
    extra_sizexy=extra_r_*2 + extra_d_;
    size_align([extra_sizexy,extra_sizexy,extra_h],extra_align)
    {
        r_=(r==undef?0:r);
        d_=(d==undef?0:d);
        sizexy=r_*2 + d_;
        size_align([sizexy,sizexy,h],align)
        {
            cylinder(h=h+extra_h, r=r+extra_r_, r1=r1, r2=r2, d=d+extra_d_, d1=d1, d2=d2, center=true);
        }
    }
}

module fncylinder(r, r2, d, d2, h, fn, center=false, enlarge=0, fnr=0.4){
    translate(center==false?[0,0,-enlarge]:[0,0,-h/2-enlarge]) {
        if (fn==undef) {
            if (r2==undef && d2==undef) {
                cylinder(r=r?r:d?d/2:1,h=h+enlarge*2,$fn=floor(2*(r?r:d?d/2:1)*PI/fnr));
            } else {
                cylinder(r=r?r:d?d/2:1,r2=r2?r2:d2?d2/2:1,h=h+enlarge*2,$fn=floor(2*(r?r:d?d/2:1)*PI/fnr));
            }
        } else {
            if (r2==undef && d2==undef) {
                cylinder(r=r?r:d?d/2:1,h=h+enlarge*2,$fn=fn);
            } else {
                cylinder(r=r?r:d?d/2:1,r2=r2?r2:d2?d2/2:1,h=h+enlarge*2,$fn=fn);
            }
        }
    }
}

// specify segment length with fnr, $fn not needed but if desired use fn instead but if desired use fn instead
module fncylindera(
        h=10,
        r=undef,
        r1=undef,
        r2=undef,
        d=undef,
        d1=undef,
        d2=undef,
        align=[0,0,0],
        extra_h=0,
        extra_r=undef,
        extra_d=undef,
        extra_align=[0,0,0],
        fn,
        fnr=0.4,
        debug=false
        )
{
    pi=3.1415926536;

    useDia = r == undef && (r1 == undef && r2 == undef);

    r_= useDia?d/2:(r==undef?0:r);
    r1_ = useDia?((d1==undef?undef:d1)/2):r1;
    r2_ = useDia?((d2==undef?undef:d2)/2):r2;
    extra_r_ = useDia?((extra_d==undef?0:extra_d)/2):((extra_r==undef)?0:extra_d/2);

    extra_sizexy=extra_r_*2;

    size_align([extra_sizexy,extra_sizexy,extra_h],extra_align)
    {

        fn_=fn==undef?(floor(2*(r_+extra_r_)*pi/fnr)):fn;

        if(debug)
            echo(useDia, h, r_, r1_, r2_, extra_r_, align, fn_);

        sizexy=r_*2;
        size_align([sizexy,sizexy,h],align)
        {
            cylinder(h=h+extra_h, r=r_+extra_r_, r1=r1_, r2=r2_, center=true, $fn=fn_);
        }
    }
}

module pie_slice_shape(r, start_angle, end_angle) {
    R = r * sqrt(2) + 1;
    a0 = (4 * start_angle + 0 * end_angle) / 4;
    a1 = (3 * start_angle + 1 * end_angle) / 4;
    a2 = (2 * start_angle + 2 * end_angle) / 4;
    a3 = (1 * start_angle + 3 * end_angle) / 4;
    a4 = (0 * start_angle + 4 * end_angle) / 4;
    if(end_angle > start_angle)
    {
        intersection() {
            circle(r);
            polygon([
                    [0,0],
                    [R * cos(a0), R * sin(a0)],
                    [R * cos(a1), R * sin(a1)],
                    [R * cos(a2), R * sin(a2)],
                    [R * cos(a3), R * sin(a3)],
                    [R * cos(a4), R * sin(a4)],
                    [0,0]
            ]);
        }
    }
}

module pie_slice(r, start_angle, end_angle, h)
{
    linear_extrude(h)
    {
        pie_slice_shape(r, start_angle, end_angle);
    }
}

/*%pie_slice(r=10, start_angle=-30, end_angle=270, h=10);*/

/*cubea([10,10,10],[1,0,0]);*/
/*%cubea([10,10,10],[1,0,0],[5,5,5],[1,1,1]);*/

/*%cubea([10,10,10],[-1,0,1]);*/
/*%cubea([10,10,10],[-1,0,1],[1,1,1],[-1,0,1]);*/
/*%cylindera(h=10, r=10/2, align=[-1,1,1], extra_r=5/2, extra_h=2, extra_align=[-1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[-1,1,1], extra_d=5, extra_h=2, extra_align=[-1,1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=15, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,-1,1], extra_d=5, extra_h=2, extra_align=[-1,-1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=5, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,0,0], extra_d=10);*/
/*%cylindera(h=10, r=5, align=[-1,0,0], extra_r=5);*/

use <misc.scad>

// translate children
module lineup(arr=undef)
{
    /*echo(arr);*/
    /*echo($children);*/
    if($children>0)
    {
        for (i = [0 : $children-1])
            translate(arr[i]) children(i);
    }
}

module stack(separations)
{
    union()
    {
        for (i = [0:len(separations)-1])
        {
            offset = v_sum(separations,i);
            /*echo("i",i,"offset",offset);*/
            translate ([0,0,offset])
            {
                child(i);
            }
        }
    }
}

module size_align(size=[10,10,10], align=[0,0,0])
{
    t=[align[0]*size[0]/2,align[1]*size[1]/2,align[2]*size[2]/2];
    /*echo(t);*/
    translate(t)
    {
        children();
    }
}

module cubea(size=[10,10,10], align=[0,0,0], extrasize=[0,0,0], extrasize_align=[0,0,0])
{
    size_align(extrasize,extrasize_align)
    {
        size_align(size,align)
        {
            cube(size+extrasize, center=true);
        }
    }
}

module cylindera(h=10, r=undef, r1=undef, r2=undef, d=undef, d1=undef, d2=undef, align=[0,0,0], extra_h=0,extra_r=undef,extra_d=undef,extra_align=[0,0,0])
{
    extra_r_=(extra_r==undef?0:extra_r);
    extra_d_=(extra_d==undef?0:extra_d);
    extra_sizexy=extra_r_*2 + extra_d_;
    size_align([extra_sizexy,extra_sizexy,extra_h],extra_align)
    {
        r_=(r==undef?0:r);
        d_=(d==undef?0:d);
        sizexy=r_*2 + d_;
        size_align([sizexy,sizexy,h],align)
        {
            cylinder(h=h+extra_h, r=r+extra_r_, r1=r1, r2=r2, d=d+extra_d_, d1=d1, d2=d2, center=true);
        }
    }
}

module fncylinder(r, r2, d, d2, h, fn, center=false, enlarge=0, fnr=0.4){
    translate(center==false?[0,0,-enlarge]:[0,0,-h/2-enlarge]) {
        if (fn==undef) {
            if (r2==undef && d2==undef) {
                cylinder(r=r?r:d?d/2:1,h=h+enlarge*2,$fn=floor(2*(r?r:d?d/2:1)*PI/fnr));
            } else {
                cylinder(r=r?r:d?d/2:1,r2=r2?r2:d2?d2/2:1,h=h+enlarge*2,$fn=floor(2*(r?r:d?d/2:1)*PI/fnr));
            }
        } else {
            if (r2==undef && d2==undef) {
                cylinder(r=r?r:d?d/2:1,h=h+enlarge*2,$fn=fn);
            } else {
                cylinder(r=r?r:d?d/2:1,r2=r2?r2:d2?d2/2:1,h=h+enlarge*2,$fn=fn);
            }
        }
    }
}

// specify segment length with fnr, $fn not needed but if desired use fn instead but if desired use fn instead
module fncylindera(
        h=10,
        r=undef,
        r1=undef,
        r2=undef,
        d=undef,
        d1=undef,
        d2=undef,
        align=[0,0,0],
        extra_h=0,
        extra_r=undef,
        extra_d=undef,
        extra_align=[0,0,0],
        fn,
        fnr=0.4,
        debug=false
        )
{
    pi=3.1415926536;

    useDia = r == undef && (r1 == undef && r2 == undef);

    r_= useDia?d/2:(r==undef?0:r);
    r1_ = useDia?((d1==undef?undef:d1)/2):r1;
    r2_ = useDia?((d2==undef?undef:d2)/2):r2;
    extra_r_ = useDia?((extra_d==undef?0:extra_d)/2):((extra_r==undef)?0:extra_d/2);

    extra_sizexy=extra_r_*2;

    size_align([extra_sizexy,extra_sizexy,extra_h],extra_align)
    {

        fn_=fn==undef?(floor(2*(r_+extra_r_)*pi/fnr)):fn;

        if(debug)
            echo(useDia, h, r_, r1_, r2_, extra_r_, align, fn_);

        sizexy=r_*2;
        size_align([sizexy,sizexy,h],align)
        {
            cylinder(h=h+extra_h, r=r_+extra_r_, r1=r1_, r2=r2_, center=true, $fn=fn_);
        }
    }
}

module pie_slice_shape(r, start_angle, end_angle) {
    R = r * sqrt(2) + 1;
    a0 = (4 * start_angle + 0 * end_angle) / 4;
    a1 = (3 * start_angle + 1 * end_angle) / 4;
    a2 = (2 * start_angle + 2 * end_angle) / 4;
    a3 = (1 * start_angle + 3 * end_angle) / 4;
    a4 = (0 * start_angle + 4 * end_angle) / 4;
    if(end_angle > start_angle)
    {
        intersection() {
            circle(r);
            polygon([
                    [0,0],
                    [R * cos(a0), R * sin(a0)],
                    [R * cos(a1), R * sin(a1)],
                    [R * cos(a2), R * sin(a2)],
                    [R * cos(a3), R * sin(a3)],
                    [R * cos(a4), R * sin(a4)],
                    [0,0]
            ]);
        }
    }
}

module pie_slice(r, start_angle, end_angle, h)
{
    linear_extrude(h)
    {
        pie_slice_shape(r, start_angle, end_angle);
    }
}

/*%pie_slice(r=10, start_angle=-30, end_angle=270, h=10);*/

/*cubea([10,10,10],[1,0,0]);*/
/*%cubea([10,10,10],[1,0,0],[5,5,5],[1,1,1]);*/

/*%cubea([10,10,10],[-1,0,1]);*/
/*%cubea([10,10,10],[-1,0,1],[1,1,1],[-1,0,1]);*/
/*%cylindera(h=10, r=10/2, align=[-1,1,1], extra_r=5/2, extra_h=2, extra_align=[-1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[-1,1,1], extra_d=5, extra_h=2, extra_align=[-1,1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=15, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,-1,1], extra_d=5, extra_h=2, extra_align=[-1,-1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=5, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,0,0], extra_d=10);*/
/*%cylindera(h=10, r=5, align=[-1,0,0], extra_r=5);*/


box is now thicker and a bit wider

box is now thicker and a bit wider

use <m3d/rounded_cube.scad>

eps = 0.01;
wall = 2;
box_size = [60, 35, 20];
roundings = 3;
split_h = 5;
int_size = box_size - 2*wall*[1,1,1];

module box_main()
{
  difference()
  {

    rounded_cube(box_size, roundings, $fn=40);
    // empty interior
    translate(wall*[1,1,1])
      rounded_cube(int_size, roundings-wall, $fn=40);
    // holes for cable
    translate([-eps, box_size[1]/2, 3.25/2+roundings])
    rotate([0, 90, 0])
      hull()
        for(dy=[-1, +1])
          translate([0, dy*(5.5-2*3.5/2)/2, 0])
            cylinder(d=3.5, h=box_size[0]+2*eps, $fn=30);
  }
}

module box_bottom()
{
  intersection()
  {
    box_main();
    cube(box_size - [0, 0, split_h]);
  }
}

module box_top()
{
  // cover
  intersection()
  {
    translate([0, box_size[1], box_size[2]])
      rotate([180, 0 , 0])
        box_main();
    cube([box_size[0], box_size[1], split_h]);
  }
  // side walls for glueing
  translate(wall*[1,1,1])
  {
    difference()
    {
      cube([int_size[0], int_size[1], split_h+3]);
      // just keep walls
      translate(1.2*[1,1,0])
        cube(int_size-2*1.2*[1,1,1]);
      // corners removed for more flexibility
      for(dx=[0,1])
        for(dy=[0,1])
          translate([dx*int_size[0], dy*int_size[1], 0])
            translate(-10/2*[1,1,0])
              cube([10, 10, int_size[2]]);
      // minimize size of side walls
      translate([box_size[0]/2 - int_size[0]/3/2 - wall, -eps, 0])
        cube([int_size[0]/3, box_size[1], int_size[2]]);
    }
  }
}

box_top();
translate([0, -box_size[1]-3, 0])
  box_bottom();

use <m3d/rounded_cube.scad>

eps = 0.01;
wall = 2*0.4;
box_size = [60, 25, 20];
roundings = 2;
split_h = 5;
int_size = box_size - 2*wall*[1,1,1];

module box_main()
{
  difference()
  {

    rounded_cube(box_size, roundings, $fn=30);
    // empty interior
    translate(wall*[1,1,1])
      rounded_cube(int_size, roundings-wall, $fn=30);
    // holes for cable
    translate([-eps, box_size[1]/2, 3.25/2+roundings])
    rotate([0, 90, 0])
      hull()
        for(dy=[-1, +1])
          translate([0, dy*(5.5-2*3.5/2)/2, 0])
            cylinder(d=3.5, h=box_size[0]+2*eps, $fn=20);
  }
}

module box_bottom()
{
  intersection()
  {
    box_main();
    cube(box_size - [0, 0, split_h]);
  }
}

module box_top()
{
  // cover
  intersection()
  {
    translate([0, box_size[1], box_size[2]])
      rotate([180, 0 , 0])
        box_main();
    cube([box_size[0], box_size[1], split_h]);
  }
  // side walls for glueing
  translate(wall*[1,1,1])
  {
    difference()
    {
      cube([int_size[0], int_size[1], split_h+3]);
      // just keep walls
      translate(0.5*[1,1,0])
        cube(int_size-2*0.5*[1,1,1]);
      // corners removed for more flexibility
      for(dx=[0,1])
        for(dy=[0,1])
          translate([dx*int_size[0], dy*int_size[1], 0])
            translate(-10/2*[1,1,0])
              cube([10, 10, int_size[2]]);
      // minimize size of side walls
      translate([box_size[0]/2 - int_size[0]/3/2 - wall, -eps, 0])
        cube([int_size[0]/3, box_size[1], int_size[2]]);
    }
  }
}

box_top();
translate([0, -28, 0])
  box_bottom();


fixup! transforms: add r,rx,ry,rz modules

/*include <../scad-utils/transformations.scad>*/
include <system.scad>
use <misc.scad>

module t(dist)
{
    translate(dist)
    children();
}

module tx(dist)
{
    translate(X*dist)
    children();
}

module ty(dist)
{
    translate(Y*dist)
    children();
}

module tz(dist)
{
    translate(Z*dist)
    children();
}

module r(a, v)
{
    rotate(a,v)
    children();
}

module rx(degrees)
{
    rotate(X*degrees)
    children();
}

module ry(degrees)
{
    rotate(Y*degrees)
    children();
}

module rz(degrees)
{
    rotate(Z*degrees)
    children();
}

// translate children
module position(positions)
{
    assert(positions!=U, "positions==U");
    for(pos=positions)
    translate(pos)
    children();
}

// translate children
module linup(arr=U)
{
    if($children>0)
    {
        for (i = [0 : $children-1])
        translate(arr[i]) children(i);
    }
}

module stack(dist=10, distances=U, axis=Z)
{
    if($children>0)
    {
        if(dist == U && distances != U)
        {
            for (i = [0:len(distances)-1])
            {
                offset = v_sum(distances,i);
                translate(axis*offset)
                    child(i);
            }
        }
        else if(dist != U && distances == U)
        {
            for (i = [0 : $children-1])
                translate(axis*(dist*i))
                    children(i);
        }
    }
}

module orient(axis=U, axis_ref=U, roll=0, extra_roll, extra_roll_orient)
{
    rotate(extra_roll_orient==U||extra_roll==U?0:extra_roll*extra_roll_orient)

    // orient to reference axis
    /*rotate(axis_ref==U?0:_orient_angles(axis_ref))*/
    /*multmatrix(axis_ref==U?0:v_rotate(90, axis_ref))*/
    rotate(axis_ref==U?0:_orient_angles(axis_ref))

    // roll around orient axis
    rotate(axis==U?0:roll*axis)

    // orient to axis
    /*multmatrix(axis==U?0:v_rotate(90, axis))*/
    rotate(axis==U?0:_orient_angles(axis))
    children();
}

module orient_(axis=U, axis_ref=U, roll=0, extra_roll, extra_roll_orient)
{
    rotate(extra_roll_orient==U||extra_roll==U?0:extra_roll*extra_roll_orient)

    // orient to reference axis
    multmatrix(axis_ref==U?0:v_rotate(90, axis_ref))

    // roll around orient axis
    rotate(axis==U?0:roll*axis)

    // orient to axis
    multmatrix(axis_ref==U?0:v_rotate(90, axis))
    children();
}

function _orient_bounds(orient, size) =
    (_rotate_matrix(_orient_angles(orient)) * [size.x,size.y,size.z,1]);

function _orient_t(orient, align, size) =
    let(bounds = _orient_bounds(orient, size))
    (hadamard(align, [abs(bounds.x/2),abs(bounds.y/2),abs(bounds.z/2)]));

module size_align(size=[10,10,10], extra_size=N, align=N, extra_align=N, orient=Z, orient_ref=Z, roll=0, extra_roll, extra_roll_orient)
{
    t = orient==U?N:_orient_t(orient, align, size);
    extra_t = (orient==U||extra_size==U||extra_size==[U,U,U]||extra_size==[0,0,0]||extra_align==U) ?
        N : _orient_t(orient, extra_align, extra_size);
    translate(t+extra_t)
    {
        orient(axis=orient, axis_ref=orient_ref, roll=roll, extra_roll=extra_roll, extra_roll_orient=extra_roll_orient)
        {
            children();
        }
    }
}

module hull_pairwise()
{
    for (i= [1:1:$children-1])
    {
        hull()
        {
            children(i-1);
            children(i);
        }
    }
}

module proj_extrude_axis(axis=Z, h=1, offset=0, cut=false)
{
    translate(-offset*axis)
    hull()
    {
        orient_(axis=axis, axis_ref=Z)
        {
            linear_extrude(h, center=false)
            projection(cut=cut)
            orient_(axis=Z, axis_ref=axis)
            translate(offset*axis)
            children();

            orient_(axis=Z, axis_ref=axis)
            translate(offset*axis)
            children();
        }
    }
}

module all_axes()
{
    for($axis=concat(AXES,-AXES))
    {
        $color = v_abs($axis*.3 + v_clamp(v_sign($axis),0,1)*.7);
        children();
    }
}

// test proj_extruder_axis
if(false)
{
    all_axes()
    color($color)
    translate(5*$axis)
    proj_extrude_axis(axis=$axis)
    translate(20*$axis)
    sphere(d=10);
}

if(false)
{
    translate(Y*10)
    proj_extrude_axis(axis=Y, offset=10)
    {
        sphere(d=10);
    }
}

/*include <../scad-utils/transformations.scad>*/
include <system.scad>
use <misc.scad>

module t(dist)
{
    translate(dist)
    children();
}

module tx(dist)
{
    translate(X*dist)
    children();
}

module ty(dist)
{
    translate(Y*dist)
    children();
}

module tz(dist)
{
    translate(Z*dist)
    children();
}

module r(a, v)
{
    rotate(a,v)
    children();
}

module rx(degrees)
{
    rotate(X*degrees)
    children();
}

module ry(degrees)
{
    rotate(X*degrees)
    children();
}

module rz(degrees)
{
    rotate(Z*degrees)
    children();
}

// translate children
module position(positions)
{
    assert(positions!=U, "positions==U");
    for(pos=positions)
    translate(pos)
    children();
}

// translate children
module linup(arr=U)
{
    if($children>0)
    {
        for (i = [0 : $children-1])
        translate(arr[i]) children(i);
    }
}

module stack(dist=10, distances=U, axis=Z)
{
    if($children>0)
    {
        if(dist == U && distances != U)
        {
            for (i = [0:len(distances)-1])
            {
                offset = v_sum(distances,i);
                translate(axis*offset)
                    child(i);
            }
        }
        else if(dist != U && distances == U)
        {
            for (i = [0 : $children-1])
                translate(axis*(dist*i))
                    children(i);
        }
    }
}

module orient(axis=U, axis_ref=U, roll=0, extra_roll, extra_roll_orient)
{
    rotate(extra_roll_orient==U||extra_roll==U?0:extra_roll*extra_roll_orient)

    // orient to reference axis
    /*rotate(axis_ref==U?0:_orient_angles(axis_ref))*/
    /*multmatrix(axis_ref==U?0:v_rotate(90, axis_ref))*/
    rotate(axis_ref==U?0:_orient_angles(axis_ref))

    // roll around orient axis
    rotate(axis==U?0:roll*axis)

    // orient to axis
    /*multmatrix(axis==U?0:v_rotate(90, axis))*/
    rotate(axis==U?0:_orient_angles(axis))
    children();
}

module orient_(axis=U, axis_ref=U, roll=0, extra_roll, extra_roll_orient)
{
    rotate(extra_roll_orient==U||extra_roll==U?0:extra_roll*extra_roll_orient)

    // orient to reference axis
    multmatrix(axis_ref==U?0:v_rotate(90, axis_ref))

    // roll around orient axis
    rotate(axis==U?0:roll*axis)

    // orient to axis
    multmatrix(axis_ref==U?0:v_rotate(90, axis))
    children();
}

function _orient_bounds(orient, size) =
    (_rotate_matrix(_orient_angles(orient)) * [size.x,size.y,size.z,1]);

function _orient_t(orient, align, size) =
    let(bounds = _orient_bounds(orient, size))
    (hadamard(align, [abs(bounds.x/2),abs(bounds.y/2),abs(bounds.z/2)]));

module size_align(size=[10,10,10], extra_size=N, align=N, extra_align=N, orient=Z, orient_ref=Z, roll=0, extra_roll, extra_roll_orient)
{
    t = orient==U?N:_orient_t(orient, align, size);
    extra_t = (orient==U||extra_size==U||extra_size==[U,U,U]||extra_size==[0,0,0]||extra_align==U) ?
        N : _orient_t(orient, extra_align, extra_size);
    translate(t+extra_t)
    {
        orient(axis=orient, axis_ref=orient_ref, roll=roll, extra_roll=extra_roll, extra_roll_orient=extra_roll_orient)
        {
            children();
        }
    }
}

module hull_pairwise()
{
    for (i= [1:1:$children-1])
    {
        hull()
        {
            children(i-1);
            children(i);
        }
    }
}

module proj_extrude_axis(axis=Z, h=1, offset=0, cut=false)
{
    translate(-offset*axis)
    hull()
    {
        orient_(axis=axis, axis_ref=Z)
        {
            linear_extrude(h, center=false)
            projection(cut=cut)
            orient_(axis=Z, axis_ref=axis)
            translate(offset*axis)
            children();

            orient_(axis=Z, axis_ref=axis)
            translate(offset*axis)
            children();
        }
    }
}

module all_axes()
{
    for($axis=concat(AXES,-AXES))
    {
        $color = v_abs($axis*.3 + v_clamp(v_sign($axis),0,1)*.7);
        children();
    }
}

// test proj_extruder_axis
if(false)
{
    all_axes()
    color($color)
    translate(5*$axis)
    proj_extrude_axis(axis=$axis)
    translate(20*$axis)
    sphere(d=10);
}

if(false)
{
    translate(Y*10)
    proj_extrude_axis(axis=Y, offset=10)
    {
        sphere(d=10);
    }
}


Update ADENIN.scad

Update ADENIN.scad

//Азотистое основание: Аденин

x=50;
y=19;
z=9;
dx=9; //Длина разъема магнита
d=2.67; //Диаметр гнезда магнита
p=6;  //Перемещине буквы А по плоскости
difference() {
union() {
 translate([0, 0, 0]) cube ([x-2, y, z-0.3], center=true);

  translate([-24, 0, 0]) rotate([0, 0, 45]) cube ([13.5, 13.5, z-0.3], center=true);

   translate([30.1, 0, 0]) cube ([13.1, 19, z-0.3], center=true);

}
  translate([6, 0, 3]) cube ([x-10, y+2, z/1.5], center=true); //Пространство для изменения объема поля с буквой

   translate([-34.8, 0, 0]) cube ([10.5, 10.5, z+2], center=true); //Для вырезки с переди

    rotate([0, 90, 0]) translate([0, 0, -34.8]) cylinder(dx, d, d);

     rotate([0, 90, 0]) translate([0, 0, 33.1]) cylinder(dx, d,  d);

// #rotate([0, 90, 0]) translate([0, -4.5, 33.1]) cylinder(dx, d,  d);
}

rotate([90, 0, 0]) translate([-13, 0, -9.5]) cylinder(19, 4.4, 4.4);

rotate([90, 0, 0]) translate([26.3, 0, -9.5]) cylinder(19, 4.4, 4.4);

//Буква А
difference() {
union () {
 translate([p, -7.55, 0]) rotate ([0, 0, 22]) cube ([2, 16, 2]);
  translate([p, -6.8, 2]) rotate ([45, 90, 22]) cube ([2, 16, 2]);
   translate([p-3.8, 2, 0]) cube ([9, 2, 2]);
}
 translate([p-6, -9, -2]) cube ([15, 2, 4]);
   translate([p-6, 7.1, -2]) cube ([15, 2, 4]);
}
#translate ([24.63,-11,-2])cube([12,22,4.2]);

//Азотистое основание: Аденин

x=50;
y=19;
z=9;
dx=9; //Длина разъема магнита
d=2.67; //Диаметр гнезда магнита
p=6;  //Перемещине буквы А по плоскости
difference() {
union() {
 #translate([0, 0, 0]) cube ([x-2, y, z-0.3], center=true);

  translate([-24, 0, 0]) rotate([0, 0, 45]) cube ([13.5, 13.5, z-0.3], center=true);

   #translate([30.1, 0, 0]) cube ([13.1, 19, z-0.3], center=true);

}
  translate([6, 0, 3]) cube ([x-10, y+2, z/1.5], center=true); //Пространство для изменения объема поля с буквой

   #translate([-34.8, 0, 0]) cube ([10.5, 10.5, z+2], center=true); //Для вырезки с переди

    #rotate([0, 90, 0]) translate([0, 0, -34.8]) cylinder(dx, d, d);

     #rotate([0, 90, 0]) translate([0, 0, 33.1]) cylinder(dx, d,  d);

// #rotate([0, 90, 0]) translate([0, -4.5, 33.1]) cylinder(dx, d,  d);
}

rotate([90, 0, 0]) translate([-13, 0, -9.5]) cylinder(19, 4.4, 4.4);

rotate([90, 0, 0]) translate([26.3, 0, -9.5]) cylinder(19, 4.4, 4.4);

//Буква А
difference() {
union () {
 translate([p, -7.55, 0]) rotate ([0, 0, 22]) cube ([2, 16, 2]);
  translate([p, -6.8, 2]) rotate ([45, 90, 22]) cube ([2, 16, 2]);
   translate([p-3.8, 2, 0]) cube ([9, 2, 2]);
}
 translate([p-6, -9, -2]) cube ([15, 2, 4]);
   translate([p-6, 7.1, -2]) cube ([15, 2, 4]);
}


top v2

top v2

tol = 0.25;
screen_tol = 0.8;
pcb_x = 100;
pcb_y = 100;
pcb_z = 4;
bolt_d = 3.6;
shift_bolt = 3;
shift_bolt_x = 4;
shift_bolt_y = 7;
board_w = 1;
board_h = 1;

m3_bolt_top_r = 2.9;
m3_bolt_top_h = 1.5;

// box thickness
th = 2;

// bolts
shift_x = th;
shift_y = th;

box_x = pcb_x + 2*th;
box_y = pcb_y + 2*th;

pcb_width = 1.6;

socket_h = 14.7;
socket_w = 10;
socket_n = 6;
socket_all_len = 85;
socket_int = socket_w + (socket_all_len - socket_n*socket_w)/(socket_n - 1);
start_socket_x = shift_x + (pcb_x - socket_all_len) / 2;
eps = 1e-1;

bottom_box_z = socket_h + th + pcb_width;

usb_type_b_w = 11;
usb_type_b_h = 11;
start_type_b_y = shift_y + pcb_y - 36;
start_type_b_z = bottom_box_z - pcb_width - usb_type_b_h - tol;

usb_type_a_w = 14.4;
usb_type_a_h = 6.3;
start_type_a_y = shift_y + 25;
start_type_a_z = bottom_box_z - pcb_width - usb_type_a_h - tol;

// programmator
micro_x = 10;
micro_y = 21.1;
micro_start_x = shift_x + 4.75;
micro_start_y = shift_y + pcb_y - 23.3 - micro_y;

contrast_start_x = shift_x + 38.4;
contrast_start_y = shift_y + 25.7;
//volume_start_x = shift_x + pcb_x - 39.2;
//volume_start_y = contrast_start_y;
pot_d = 7;
under_pcb = 13;
fn = 10;
gaika_h = 4;
gaika_w = 5.5;
stoiki_r = 4;
stoiki_h = socket_h;
wide_stoiki_r = stoiki_r + 2;

dynamic_x = shift_x + 20;
dynamic_y = shift_y + 31.5;
dynamic_r = 15.2;

volume_center_y = shift_y + 50;
volume_w = 15;
volume_start_y = volume_center_y - volume_w/2;
volume_h = 4;

translate([0,0,-50]) {

difference() {
  union() {
    difference() {
      union() {
        cube([box_x, box_y, bottom_box_z-board_h], false);
        translate([th - board_w, th - board_w, 0]) {
          cube([box_x - 2*(th - board_w), box_y - 2*(th - board_w), bottom_box_z], false);
        }
      }
      translate([th, th, th]) {
        cube([box_x-2*th+eps, box_y-2*th+eps, bottom_box_z-th+eps], false);
      }
    }
    // under_pcb, stoiki
    for (dy = [shift_y+shift_bolt_y, shift_y+pcb_y-shift_bolt_y]) {
      for (dx = [shift_x+shift_bolt_x, shift_x+pcb_x-shift_bolt_x]) {
        translate([dx,dy,th-eps]) {
          cylinder($fn=6, r=stoiki_r, h=stoiki_h + eps);
          //cylinder($fn=6, r=wide_stoiki_r, h=gaika_h);
        }
      }
    }
   translate([start_socket_x, th - eps, th - eps]) {
     cube([socket_all_len, th/2 + eps, stoiki_h + eps]);
   }
    //translate([box_x/2, box_y/2, th-eps]) {
      //cylinder($fn=6, r=stoiki_r, h=pcb_up);
    //}
  }

  // dynamic
  translate([dynamic_x, dynamic_y, -eps]) {
      cylinder($fn=20, r=dynamic_r, h = th+2*eps);
  }

  // sockets
  for (i = [0:1:socket_n-1]) {
      translate([start_socket_x+i*socket_int - tol, -eps, bottom_box_z - socket_h - pcb_width]) {
        cube(size=[socket_w + 2*tol, socket_h, socket_h + socket_h]);
      }
  }
  // bolts
  for (dx = [shift_x+shift_bolt_x, shift_x+pcb_x-shift_bolt_x]) {
    for (dy = [shift_y+shift_bolt_y, shift_y+pcb_y-shift_bolt_y]) {
      translate([dx,dy,-eps]) {
        cylinder($fn=fn, r=bolt_d/2, h=th+stoiki_h+2*eps);
        // bolt
        cylinder($fn=12, r=m3_bolt_top_r + 0.05, h=m3_bolt_top_h);
      }
    }
  }

//    // usb_in1 type b
    translate([box_x-th-eps, start_type_b_y-tol, start_type_b_z]) {
        cube(size=[th+2*eps, usb_type_b_w + 2*tol, bottom_box_z]);
    }

    // usb_out1 type a
    translate([box_x - eps - th, start_type_a_y - tol, start_type_a_z]) {
        cube(size=[th+2*eps, usb_type_a_w + 2*tol, bottom_box_z]);
    }

    // volume
    translate([-eps, volume_start_y, bottom_box_z - pcb_width - volume_h]) {
        cube(size=[th+2*eps, volume_w, volume_h + pcb_width + eps]);
    }

}
}

top_box_z = 10;
//stoiki_h = top_box_z - th;
wide_stoiki_h = 4;
pcb_room = 1;
screen_start_x = shift_x + 11;
screen_start_y = shift_y + 26;
screen_length_x = 78;
screen_length_y = 51;
screen_hold_x = 40;
screen_hold_y = 4;
screen_hold_start_z = 12.5;
screen_hold_y_shift = 2;
screen_hold_up_x = 15;
screen_hold_up_x_shift = 5;

master_button_y = shift_y + pcb_y - 7.5;
master_button_x = shift_x + 18.5;
master_button_int = 31.5;
master_button_r = 6;
top_bolt_h = 1.5;
top_bolt_r = 3.5;
speaker_shift = 18;
speaker_r = 15;
speaker_h = 15;
speaker_hole_d = 10;
speaker_hole_int = 3;
speaker_hole_w = 1.5;
speaker_shift = 18;

!difference() {
  union() {
    // board
    translate([0, 0, -board_h]) {
        difference() {
            cube([box_x, box_y, board_h + eps], false);
            translate([board_w, board_w, -eps]) {
                cube([box_x - 2*board_w, box_y - 2*board_w, board_h + 3*eps], false);
            }
        }
    }
    difference() {
      cube([box_x,box_y,top_box_z], false);
      translate([th, th, -eps]) {
        cube([box_x-2*th+eps, box_y-2*th+eps, top_box_z-th+eps], false);
      }
    }
    // stoiki
    for (dx = [shift_x+shift_bolt_x, shift_x+pcb_x-shift_bolt_x]) {
      for (dy = [shift_y+shift_bolt_y, shift_y+pcb_y-shift_bolt_y]) {
        translate([dx,dy,-eps]) {
          cylinder($fn=6, r=stoiki_r-0.5, h=top_box_z-th+eps);
        }
        translate([dx,dy,top_box_z-th-wide_stoiki_h+eps]) {
          cylinder($fn=6, r=wide_stoiki_r, h=wide_stoiki_h+th-2*eps);
        }
      }
    }
    // screen_hold
    //translate([screen_start_x + (screen_length_x - screen_hold_x)/2, screen_start_y - screen_hold_y_shift - screen_hold_y, screen_hold_start_z]) {
        //cube([screen_hold_x, screen_hold_y, top_box_z - screen_hold_start_z - th + eps]);
    //}
    //translate([screen_start_x + screen_length_x - screen_hold_up_x - screen_hold_up_x_shift, screen_start_y + screen_length_y + screen_hold_y_shift, screen_hold_start_z]) {
        //cube([screen_hold_up_x, screen_hold_y, top_box_z - screen_hold_start_z - th + eps]);
    //}
  }
  // bolts
  for (dx = [shift_x+shift_bolt_x, shift_x+pcb_x-shift_bolt_x]) {
    for (dy = [shift_y+shift_bolt_y, shift_y+pcb_y-shift_bolt_y]) {
      translate([dx,dy,-2*eps]) {
        cylinder($fn=fn, r=bolt_d/2, h=top_box_z+2*eps);
      }
      translate([dx, dy, top_box_z - wide_stoiki_h]) {
        cylinder($fn=6, r=gaika_w / 2 / cos(30) + 0.05, h=wide_stoiki_h+eps);
        //cylinder($fn=6, r=top_bolt_r, h=top_bolt_h + eps);
      }
    }
  }

  // screen
  translate([screen_start_x - screen_tol, screen_start_y - screen_tol, top_box_z - th - eps]) {
      cube([screen_length_x + 2*screen_tol, screen_length_y + 2*screen_tol, th + 2*eps]);
  }
  // master buttons
  for (i = [0:1:2]) {
    translate([master_button_x + master_button_int*i, master_button_y, top_box_z - th - eps]) {
      cylinder($fn=fn, r=master_button_r + tol, h=th+2*eps);
    }
  }
}

//// bolts
//for (dx = [shift_x+shift_bolt, shift_x+pcb_x-shift_bolt]) {
//  for (dy = [shift_y+shift_bolt, shift_y+pcb_y-shift_bolt]) {
//    difference() {
//      translate([dx,dy,pcb_up/2+th]) {
//        cube(size=[a,a,pcb_up], center=true);
//      }
//      translate([dx,dy,-eps]) {
//        cylinder($fn=20, r=bolt_d/2, h=th+pcb_up+2*eps);
//      }
//    }
//  }
//}

//leg_r = t;
//shift = t/2+leg_r;
//for (dx = [shift, a-shift])
//    for (dy = [shift, b-shift]) {
//        translate([dx, dy, 0]) {
//            cylinder(h=c, r=leg_r, $fn=40);
//        }
//    }

tol = 0.25;
screen_tol = 0.8;
pcb_x = 100;
pcb_y = 100;
pcb_z = 4;
bolt_d = 3.6;
shift_bolt = 3;
shift_bolt_x = 4;
shift_bolt_y = 7;
board_w = 1;
board_h = 1;

m3_bolt_top_r = 2.9;
m3_bolt_top_h = 1.5;

// box thickness
th = 2;

// bolts
shift_x = th;
shift_y = th;

box_x = pcb_x + 2*th;
box_y = pcb_y + 2*th;

pcb_width = 1.6;

socket_h = 14.7;
socket_w = 10;
socket_n = 6;
socket_all_len = 85;
socket_int = socket_w + (socket_all_len - socket_n*socket_w)/(socket_n - 1);
start_socket_x = shift_x + (pcb_x - socket_all_len) / 2;
eps = 1e-1;

bottom_box_z = socket_h + th + pcb_width;

usb_type_b_w = 11;
usb_type_b_h = 11;
start_type_b_y = shift_y + pcb_y - 36;
start_type_b_z = bottom_box_z - pcb_width - usb_type_b_h - tol;

usb_type_a_w = 14.4;
usb_type_a_h = 6.3;
start_type_a_y = shift_y + 25;
start_type_a_z = bottom_box_z - pcb_width - usb_type_a_h - tol;

// programmator
micro_x = 10;
micro_y = 21.1;
micro_start_x = shift_x + 4.75;
micro_start_y = shift_y + pcb_y - 23.3 - micro_y;

contrast_start_x = shift_x + 38.4;
contrast_start_y = shift_y + 25.7;
//volume_start_x = shift_x + pcb_x - 39.2;
//volume_start_y = contrast_start_y;
pot_d = 7;
under_pcb = 13;
fn = 10;
gaika_h = 4;
gaika_w = 5.5;
stoiki_r = 4;
stoiki_h = socket_h;
wide_stoiki_r = stoiki_r + 2;

dynamic_x = shift_x + 20;
dynamic_y = shift_y + 31.5;
dynamic_r = 15.2;

volume_center_y = shift_y + 50;
volume_w = 15;
volume_start_y = volume_center_y - volume_w/2;
volume_h = 4;

translate([0,0,-50]) {

!difference() {
  union() {
    difference() {
      union() {
        cube([box_x, box_y, bottom_box_z-board_h], false);
        translate([th - board_w, th - board_w, 0]) {
          cube([box_x - 2*(th - board_w), box_y - 2*(th - board_w), bottom_box_z], false);
        }
      }
      translate([th, th, th]) {
        cube([box_x-2*th+eps, box_y-2*th+eps, bottom_box_z-th+eps], false);
      }
    }
    // under_pcb, stoiki
    for (dy = [shift_y+shift_bolt_y, shift_y+pcb_y-shift_bolt_y]) {
      for (dx = [shift_x+shift_bolt_x, shift_x+pcb_x-shift_bolt_x]) {
        translate([dx,dy,th-eps]) {
          cylinder($fn=6, r=stoiki_r, h=stoiki_h + eps);
          //cylinder($fn=6, r=wide_stoiki_r, h=gaika_h);
        }
      }
    }
   translate([start_socket_x, th - eps, th - eps]) {
     cube([socket_all_len, th/2 + eps, stoiki_h + eps]);
   }
    //translate([box_x/2, box_y/2, th-eps]) {
      //cylinder($fn=6, r=stoiki_r, h=pcb_up);
    //}
  }

  // dynamic
  translate([dynamic_x, dynamic_y, -eps]) {
      cylinder($fn=20, r=dynamic_r, h = th+2*eps);
  }

  // sockets
  for (i = [0:1:socket_n-1]) {
      translate([start_socket_x+i*socket_int - tol, -eps, bottom_box_z - socket_h - pcb_width]) {
        cube(size=[socket_w + 2*tol, socket_h, socket_h + socket_h]);
      }
  }
  // bolts
  for (dx = [shift_x+shift_bolt_x, shift_x+pcb_x-shift_bolt_x]) {
    for (dy = [shift_y+shift_bolt_y, shift_y+pcb_y-shift_bolt_y]) {
      translate([dx,dy,-eps]) {
        cylinder($fn=fn, r=bolt_d/2, h=th+stoiki_h+2*eps);
        // bolt
        cylinder($fn=12, r=m3_bolt_top_r + 0.05, h=m3_bolt_top_h);
      }
    }
  }

//    // usb_in1 type b
    translate([box_x-th-eps, start_type_b_y-tol, start_type_b_z]) {
        cube(size=[th+2*eps, usb_type_b_w + 2*tol, bottom_box_z]);
    }

    // usb_out1 type a
    translate([box_x - eps - th, start_type_a_y - tol, start_type_a_z]) {
        cube(size=[th+2*eps, usb_type_a_w + 2*tol, bottom_box_z]);
    }

    // volume
    translate([-eps, volume_start_y, bottom_box_z - pcb_width - volume_h]) {
        cube(size=[th+2*eps, volume_w, volume_h + pcb_width + eps]);
    }

}
}

top_box_z = 15 + th;
//stoiki_h = top_box_z - th;
wide_stoiki_h = 4;
pcb_room = 1;
screen_start_x = shift_x + 29;
screen_start_y = shift_y + 38.9;
screen_length_x = 71.2;
screen_length_y = 24.2;
screen_hold_x = 40;
screen_hold_y = 4;
screen_hold_start_z = 12.5;
screen_hold_y_shift = 2;
screen_hold_up_x = 15;
screen_hold_up_x_shift = 5;

master_button_y = shift_y + 10;
master_button_x = shift_x + 43;
master_button_int = 21.8;
master_button_r = 5;
top_bolt_h = 1.5;
top_bolt_r = 3.5;
speaker_shift = 18;
speaker_r = 15;
speaker_h = 15;
speaker_hole_d = 10;
speaker_hole_int = 3;
speaker_hole_w = 1.5;
speaker_shift = 18;

difference() {
  union() {
    // board
    translate([0, 0, -board_h]) {
        difference() {
            cube([box_x, box_y, board_h + eps], false);
            translate([board_w, board_w, -eps]) {
                cube([box_x - 2*board_w, box_y - 2*board_w, board_h + 3*eps], false);
            }
        }
    }
    difference() {
      cube([box_x,box_y,top_box_z], false);
      translate([th, th, -eps]) {
        cube([box_x-2*th+eps, box_y-2*th+eps, top_box_z-th+eps], false);
      }
    }
    // stoiki
    for (dx = [shift_x+shift_bolt, shift_x+pcb_x-shift_bolt]) {
      for (dy = [shift_y+shift_bolt, shift_y+pcb_y-shift_bolt]) {
        translate([dx,dy,pcb_room]) {
          cylinder($fn=6, r=stoiki_r, h=top_box_z-th+eps);
        }
        translate([dx,dy,top_box_z-th-wide_stoiki_h+eps]) {
          cylinder($fn=6, r=wide_stoiki_r, h=wide_stoiki_h+th-2*eps);
        }
      }
    }
    // screen_hold
    translate([screen_start_x + (screen_length_x - screen_hold_x)/2, screen_start_y - screen_hold_y_shift - screen_hold_y, screen_hold_start_z]) {
	cube([screen_hold_x, screen_hold_y, top_box_z - screen_hold_start_z - th + eps]);
    }
    translate([screen_start_x + screen_length_x - screen_hold_up_x - screen_hold_up_x_shift, screen_start_y + screen_length_y + screen_hold_y_shift, screen_hold_start_z]) {
	cube([screen_hold_up_x, screen_hold_y, top_box_z - screen_hold_start_z - th + eps]);
    }
  }
  // - speaker na stoikah
  translate([shift_x + pcb_x - 18, shift_y + 18, 0]) {
    cylinder(r=speaker_r, h = 15, $fn=20);
  }
  // speaker_hole
  for (dy = [shift_y + speaker_shift - speaker_hole_int - speaker_hole_w*3/2,
             shift_y + speaker_shift - speaker_hole_w/2,
             shift_y + speaker_shift + speaker_hole_int + speaker_hole_w/2]) {
    translate([shift_x + pcb_x - speaker_shift - speaker_hole_d, dy, top_box_z-th-eps]) {
      cube(size=[speaker_hole_d, speaker_hole_w, th + 2*eps]);
    }
  }

  // bolts
  for (dx = [shift_x+shift_bolt, shift_x+pcb_x-shift_bolt]) {
    for (dy = [shift_y+shift_bolt, shift_y+pcb_y-shift_bolt]) {
      translate([dx,dy,-eps]) {
        cylinder($fn=fn, r=bolt_d/2, h=top_box_z+2*eps);
      }
      translate([dx, dy, top_box_z - top_bolt_h]) {
        //cylinder($fn=6, r=gaika_w / 2 / cos(30) + 0.05, h=wide_stoiki_h+eps);
        cylinder($fn=6, r=top_bolt_r, h=top_bolt_h + eps);
      }
    }
  }

  // screen
  translate([screen_start_x - screen_tol, screen_start_y - screen_tol, top_box_z - th - eps]) {
      cube([screen_length_x + 2*screen_tol, screen_length_y + 2*screen_tol, th + 2*eps]);
  }
  // sockets
  for (i = [0:1:socket_n-1]) {
      translate([start_socket_x+i*socket_int - tol, box_y-th-eps, -eps - board_h]) {
        cube(size=[socket_w + 2*tol, th+2*eps, socket_h + board_h]);
      }
  }
  // type_b
  translate([box_x - th - eps, start_type_b_y - tol, -tol - board_h]) {
      cube([th + 2*eps, usb_type_b_w + 2*tol, usb_type_b_h + 2*tol + board_h]);
  }
  // type_a
  translate([-eps, start_type_a_y - tol, -eps - board_h]) {
      cube([th + 2*eps, usb_type_a_w + 2*tol, usb_type_a_h + 2*eps + board_h]);
  }
  // master buttons
  for (i = [0:1:2]) {
    translate([master_button_x + master_button_int*i, master_button_y, top_box_z - th - eps]) {
      cylinder($fn=fn, r=master_button_r + tol, h=th+2*eps);
    }
  }
}

//// bolts
//for (dx = [shift_x+shift_bolt, shift_x+pcb_x-shift_bolt]) {
//  for (dy = [shift_y+shift_bolt, shift_y+pcb_y-shift_bolt]) {
//    difference() {
//      translate([dx,dy,pcb_up/2+th]) {
//        cube(size=[a,a,pcb_up], center=true);
//      }
//      translate([dx,dy,-eps]) {
//        cylinder($fn=20, r=bolt_d/2, h=th+pcb_up+2*eps);
//      }
//    }
//  }
//}

//leg_r = t;
//shift = t/2+leg_r;
//for (dx = [shift, a-shift])
//    for (dy = [shift, b-shift]) {
//        translate([dx, dy, 0]) {
//            cylinder(h=c, r=leg_r, $fn=40);
//        }
//    }