LCD's PCB hole gained extra 1mm on OY to squeeze in more smoothly

use <lcd.scad>
use <menu_knob.scad>
use <menu_knob_manipulator.scad>
use <reset_button.scad>
use <sdcard_reader.scad>
use <cable_guide.scad>
include <positions.scad>

module front()
{
  difference()
  {
    union()
    {
      // main mounting legs
      for(offset = [ [boxSize[0]-16, 0, boxSize[2]-7], [boxSize[0]-70, 0, boxSize[2]-7] ])
        translate(offset)
          cube([16, 40+13, 7]);
      // side mounting wing
      translate([15, 0, 6])
        cube([18, 20, 7]);

      difference()
      {
        // main working area
        cube(boxSize);
        // prusa's framework  corner
        translate([15, 0, 0])
          cube([143-15, 53, boxSize[2]]);
        // LCD
        translate(lcdOffset)
        {
          // LCD itself
          translate([1/2-2/2, 10-1, 2])
            cube([97+2, 40+2, 10]);
          // place for PCB
          translate([-2/2, -1/2, -lcdOffset[2]-7])
            cube([98+2, 60+2, 10]);
          // place for cables
          translate([9, 60-5, -2])
            cube([39,10,4]);
          lcdBoard();
        }
        // encoder
        translate(encoderOffset)
        {
          translate([-2, -1/2, -8])
            cube([14+2*2, 12+1, 8+6]);
          menuKnob();
        }
        // SD card mount
        translate(sdCardOffset)
          rotate([0,180,0])
            sdCardReader();
        // reset button
        translate(resetButtonOffset)
        {
          translate([0, 0, -resetButtonOffset[2]])
          {
            cylinder(r=(16+2)/2, h=boxSize[2], $fs=1);
            translate([0, 0, 0])
              cylinder(r=(16+10)/2, h=boxSize[2]/2, $fs=1);
          }
          resetButton();
        }
        // cable guide drill
        translate([boxSize[0]-98-5, 40+16+6, 0])
          cableGuide();
        // side mounting wing cut-in, so that screw will hold tight
        cube([15, 40, 6]);
      }
    }

    // SD card mounting drills
    translate(sdCardOffset)
      rotate([0,180,0])
      {
        for(offset = [
                       [3/2+1, 3/2+1, -20/2],
                       [3/2+1, 31-3/2-1, -20/2]
                     ])
        {
          translate(offset)
            cylinder(r=(3+2)/2, h=20, $fs=1);
        }
      }
    // SD card mounting place
    translate(sdCardOffset + [+2/2, -2/2, 0])
      rotate([0,180,0])
        cube([45+2,31+2,2+8]);

    // LCD mounting drills
    translate(lcdOffset)
      for(offset = [
                     [3/2+1, 3/2+1, -1],
                     [98-3/2-1, 3/2+1, -1],
                     [3/2+1, 60-3/2-1, -1],
                     [98-3/2-1, 60-3/2-1, -1]
                   ])
      {
        translate(offset)
          cylinder(r=(3+2)/2, h=20, $fs=1);
      }

    // frame-mounting drills
    for(offsetOY = [ 13/2+5/2, 40+13+4])
      for(offsetOX = [15/2, boxSize[0]-70+16/2, boxSize[0]-16/2])
        translate([offsetOX, offsetOY, -1])
          cylinder(r=(5+2)/2, h=6+7+2, $fs=1);
  }

  // LCD stub
  %translate(lcdOffset)
    lcdBoard();
  // encoder stub
  %translate(encoderOffset)
  {
    menuKnob();
    translate([7, 6, 23+4])
      rotate([180,0,0])
        menuKnobManipulator();
  }
  // SD card mount stub
  %translate(sdCardOffset)
    rotate([0,180,0])
      sdCardReader();
  // reset button stub
  %translate(resetButtonOffset)
    resetButton();
}

rotate([180, 0, 0])
  front();

use <lcd.scad>
use <menu_knob.scad>
use <menu_knob_manipulator.scad>
use <reset_button.scad>
use <sdcard_reader.scad>
use <cable_guide.scad>
include <positions.scad>

module front()
{
  difference()
  {
    union()
    {
      // main mounting legs
      for(offset = [ [boxSize[0]-16, 0, boxSize[2]-7], [boxSize[0]-70, 0, boxSize[2]-7] ])
        translate(offset)
          cube([16, 40+13, 7]);
      // side mounting wing
      translate([15, 0, 6])
        cube([18, 20, 7]);

      difference()
      {
        // main working area
        cube(boxSize);
        // prusa's framework  corner
        translate([15, 0, 0])
          cube([143-15, 53, boxSize[2]]);
        // LCD
        translate(lcdOffset)
        {
          // LCD itself
          translate([1/2-2/2, 10-1, 2])
            cube([97+2, 40+2, 10]);
          // place for PCB
          translate([-2/2, -1/2, -lcdOffset[2]-7])
            cube([98+2, 60+1, 10]);
          // place for cables
          translate([9, 60-5, -2])
            cube([39,10,4]);
          lcdBoard();
        }
        // encoder
        translate(encoderOffset)
        {
          translate([-2, -1/2, -8])
            cube([14+2*2, 12+1, 8+6]);
          menuKnob();
        }
        // SD card mount
        translate(sdCardOffset)
          rotate([0,180,0])
            sdCardReader();
        // reset button
        translate(resetButtonOffset)
        {
          translate([0, 0, -resetButtonOffset[2]])
          {
            cylinder(r=(16+2)/2, h=boxSize[2], $fs=1);
            translate([0, 0, 0])
              cylinder(r=(16+10)/2, h=boxSize[2]/2, $fs=1);
          }
          resetButton();
        }
        // cable guide drill
        translate([boxSize[0]-98-5, 40+16+6, 0])
          cableGuide();
        // side mounting wing cut-in, so that screw will hold tight
        cube([15, 40, 6]);
      }
    }

    // SD card mounting drills
    translate(sdCardOffset)
      rotate([0,180,0])
      {
        for(offset = [
                       [3/2+1, 3/2+1, -20/2],
                       [3/2+1, 31-3/2-1, -20/2]
                     ])
        {
          translate(offset)
            cylinder(r=(3+2)/2, h=20, $fs=1);
        }
      }
    // SD card mounting place
    translate(sdCardOffset + [+2/2, -2/2, 0])
      rotate([0,180,0])
        cube([45+2,31+2,2+8]);

    // LCD mounting drills
    translate(lcdOffset)
      for(offset = [
                     [3/2+1, 3/2+1, -1],
                     [98-3/2-1, 3/2+1, -1],
                     [3/2+1, 60-3/2-1, -1],
                     [98-3/2-1, 60-3/2-1, -1]
                   ])
      {
        translate(offset)
          cylinder(r=(3+2)/2, h=20, $fs=1);
      }

    // frame-mounting drills
    for(offsetOY = [ 13/2+5/2, 40+13+4])
      for(offsetOX = [15/2, boxSize[0]-70+16/2, boxSize[0]-16/2])
        translate([offsetOX, offsetOY, -1])
          cylinder(r=(5+2)/2, h=6+7+2, $fs=1);
  }

  // LCD stub
  %translate(lcdOffset)
    lcdBoard();
  // encoder stub
  %translate(encoderOffset)
  {
    menuKnob();
    translate([7, 6, 23+4])
      rotate([180,0,0])
        menuKnobManipulator();
  }
  // SD card mount stub
  %translate(sdCardOffset)
    rotate([0,180,0])
      sdCardReader();
  // reset button stub
  %translate(resetButtonOffset)
    resetButton();
}

rotate([180, 0, 0])
  front();


added proper oring slot + calibrated parameters to tight-fit into the bottle's nozzle

use <m3d/fn.scad>

module oring(d_in, d_r)
{
  rotate_extrude(angle=360, convexity=20, $fn=fn(120))
    translate([d_in/2+d_r/2, 0, 0])
      circle(d=d_r, $fn=fn(40));
}

module oring_slot(d_in, d_r, d_ext, d_r_ext)
{
  rotate_extrude(angle=360, convexity=20, $fn=fn(120))
    hull()
    {
      translate([d_in/2+d_r/2, 0, 0])
        circle(d=d_r, $fn=fn(40));
      translate([d_ext/2+d_r_ext/2, 0, 0])
        circle(d=d_r_ext, $fn=fn(40));
    }
}

module nozzle()
{
  module body()
  {
    h = 15;
    cylinder(d=26.5, h=h, $fn=fn(100));
    translate([0,0,h])
    {
      h = 24.5;
      cylinder(d=32, h=h, $fn=fn(120));
      translate([0,0,h])
      {
        h = 5;
        cylinder(d1=32, d2=21, h=h, $fn=fn(200));
        translate([0,0,h])
        {
          difference()
          {
            cylinder(d=21, h=10, $fn=fn(200));
            translate([0, 0, 6])
            {
              d_in = 17-0.5;
              d_r = 2.5;
              oring_slot(d_in=d_in, d_r=d_r, d_ext=d_in+1.5, d_r_ext=d_r+0.75);
              %oring(d_in=d_in, d_r=d_r);
            }
          }
        }
      }
    }
  }

  difference()
  {
    body();
    translate([0,0,-1])
      cylinder(d=9, h=60, $fn=fn(50));
  }
}

//rotate([180, 0, 0])
intersection()
{
  translate([0, 0, 54.5])
  cube([50, 50, 20], center=true);
  nozzle();
}

//oring_slot(d_in=17-0.25, d_r=2.5, d_ext=20, d_r_ext=3);

use <m3d/fn.scad>

module nozzle()
{
  module oring(d_in, d_r)
  {
    rotate_extrude(angle=360, convexity=20, $fn=fn(120))
      translate([d_in/2+d_r/2, 0, 0])
        circle(d=d_r, $fn=fn(40));
  }

  module body()
  {
    h = 15;
    cylinder(d=26.5, h=h, $fn=fn(100));
    translate([0,0,h])
    {
      h = 24.5;
      cylinder(d=32, h=h, $fn=fn(120));
      translate([0,0,h])
      {
        h = 5;
        cylinder(d1=32, d2=21, h=h, $fn=fn(200));
        translate([0,0,h])
        {
          difference()
          {
            cylinder(d1=21, d2=20, h=10, $fn=fn(200));
            translate([0, 0, 6])
              oring(d_in=17+1.5, d_r=2.5+0.5);
          }
        }
      }
    }
  }

  difference()
  {
    body();
    translate([0,0,-1])
      cylinder(d=9, h=60, $fn=fn(50));
  }
}

rotate([180, 0, 0])
  nozzle();


added both elements to be printed symetrical

r_mount=(28.8+2*2.1)/2;
h=20;
eps=0.01;

module mount_rod_space()
{
  translate([0, 0, -eps])
    cylinder(r=r_mount, h=h+2*eps, $fn=180);
}

module body_core()
{
  // main rod with mounts
  rotate([0, 0, 180-30])
  {
    // main block
    hull()
      for(dx=[0, 90])
        translate([dx, 0, 0])
          cylinder(r=30/2, h=h);
    // support rods
    for(dx=[0, 29.5, 60.5])
      translate([90-dx, 0, h])
        cylinder(r=10.5/2, h=30, $fn=50);
  }
  // rod_slot
  difference()
  {
    // main block
    union()
    {
      cylinder(r=30/2, h=h);
      translate([-35, -50, 0])
        cube([50, 50, h]);
      // stubbing hole, between two elements
      translate([-35, 0, 0])
        cube([20, 10, h]);
    }
    // screw hole
    translate([-35-eps, -42, h/2])
      rotate([0, 90, 0])
        cylinder(r=3.5/2, h=50+2*eps, $fn=50);
    // place for bottom block
    translate([-20/2-r_mount, -20-40, -eps])
      cube([r_mount*2, 40, h+2*eps]);
  }
}

module buggy_troley_closure()
{
  dy=30;
  difference()
  {
    cube([r_mount*2, dy, h]);
    translate([r_mount, dy, 0])
      mount_rod_space();
    translate([-eps-10, 8, h/2])
      rotate([0, 90, 0])
        cylinder(r=3.5/2, h=55+2*eps, $fn=50);
  }
}

module buggy_troley_mount()
{
  difference()
  {
    body_core();
    translate([-20/2, -20, 0])
      mount_rod_space();
  }
}

for(pos=[[0,0,0], [180,1,35]])
  translate([pos[2], 0, 0])
    rotate([0, pos[0], 0])
      mirror([0, 0, pos[1]])
      {
        buggy_troley_mount();
        %translate([-20/2-r_mount, -50, 0])
          buggy_troley_closure();

        translate([-75, -30, 0])
          buggy_troley_closure();
      }

r_mount=(28.8+2*2.1)/2;
h=20;
eps=0.01;

module mount_rod_space()
{
  translate([0, 0, -eps])
    cylinder(r=r_mount, h=h+2*eps, $fn=180);
}

module body_core()
{
  // main rod with mounts
  rotate([0, 0, 180-30])
  {
    // main block
    hull()
      for(dx=[0, 90])
        translate([dx, 0, 0])
          cylinder(r=30/2, h=h);
    // support rods
    for(dx=[0, 29.5, 60.5])
      translate([90-dx, 0, h])
        cylinder(r=10.5/2, h=30, $fn=50);
  }
  // rod_slot
  difference()
  {
    // main block
    union()
    {
      cylinder(r=30/2, h=h);
      translate([-35, -50, 0])
        cube([50, 50, h]);
      // stubbing hole, between two elements
      translate([-35, 0, 0])
        cube([20, 10, h]);
    }
    // screw hole
    translate([-35-eps, -42, h/2])
      rotate([0, 90, 0])
        cylinder(r=3.5/2, h=50+2*eps, $fn=50);
    // place for bottom block
    translate([-20/2-r_mount, -20-40, -eps])
      cube([r_mount*2, 40, h+2*eps]);
  }
}

module buggy_troley_closure()
{
  dy=30;
  difference()
  {
    cube([r_mount*2, dy, h]);
    translate([r_mount, dy, 0])
      mount_rod_space();
    translate([-eps-10, 8, h/2])
      rotate([0, 90, 0])
        cylinder(r=3.5/2, h=55+2*eps, $fn=50);
  }
}

module buggy_troley_mount()
{
  difference()
  {
    body_core();
    translate([-20/2, -20, 0])
      mount_rod_space();
  }
}

buggy_troley_mount();
%translate([-20/2-r_mount, -50, 0])
  buggy_troley_closure();

translate([-75, -30, 0])
  buggy_troley_closure();


model of a single mount for a loudspeaker

eps=0.1;

module mount()
{
  wall=5;
  screw_d=4;
  ls_dim=[236+1, 162+1];
  ls_border=11.6-2;
  mount_len=60;
  mount_size=[30, 2*wall, mount_len+wall];

  module body_mount()
  {
    difference()
    {
      cube([ls_dim[0]+2*wall, ls_dim[1]+1*wall, mount_len+wall]);
      translate(wall*[1,1,1])
        cube([ls_dim[0], ls_dim[1]+eps, mount_len+eps]);
      translate(wall*[2,2,0]-[0,0,eps])
        cube([ls_dim[0]-2*wall, ls_dim[1]-1*wall+eps, wall+2*eps]);
    }
  }

  module screw_mount()
  {
    module screw()
    {
      rotate([-90, 0, 0])
        union()
        {
          $fn=50;
          cylinder(r1=(2*screw_d)/2, r2=screw_d/2, h=5);
          translate([0, 0, 5-eps])
            cylinder(r=screw_d/2, h=5+eps+10);
        }
    }

    translate([-mount_size[0], 0, 0])
      difference()
      {
        cube(mount_size);
        for(i=[-1,0,+1])
          translate([mount_size[0]/2, -eps, mount_size[2]/2+i*18])
            screw();
      }
  }

  body_mount();
  for(i=[0,1])
    translate([i*(ls_dim[0]+2*wall+mount_size[0]), ls_dim[1]-wall, 0])
      screw_mount();
}

mount();

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


zaxis/motorount: tweaks, increase clamp nut holder tolerances

include <MCAD/stepper.scad>
include <MCAD/motors.scad>

use <thing_libutils/triangles.scad>

include <config.scad>
include <rod-clamps.scad>

// inner_d, outer_d, thread
zaxis_nut = [20*mm, 36.5*mm, 8*mm];

zaxis_nut_mount_outer = zaxis_nut[1]/2 + zaxis_bearing[1]/2 + 3;

// place z rod on edge of motor
/*zaxis_rod_screw_distance_x = max(zaxis_nut_mount_outer, zaxis_rod_d/2 + lookup(NemaSideSize,zaxis_motor)/2);*/
zaxis_rod_screw_distance_x = zaxis_nut_mount_outer;

zmotor_w = lookup(NemaSideSize,zaxis_motor);
zmotor_h = lookup(NemaLengthLong,zaxis_motor);
zmotor_mount_thread_dia = lookup(ThreadSize, extrusion_thread);
zmotor_mount_width = zmotor_w+zmotor_mount_thickness*2 + zmotor_mount_thread_dia*8;
zmotor_mount_h = main_lower_dist_z+extrusion_size+zaxis_motor_offset_z;
zmotor_mount_rod_offset_x = zmotor_w/2+zaxis_rod_screw_distance_x+zmotor_mount_motor_offset;

zmotor_mount_clamp_dist = zaxis_rod_d*2.5;
zmotor_mount_clamp_thread = ThreadM4;
zmotor_mount_clamp_nut = MHexNutM4;
zmotor_mount_clamp_thread_dia = lookup(ThreadSize, zmotor_mount_clamp_thread);
zmotor_mount_clamp_nut_dia = lookup(MHexNutWidthMin, zmotor_mount_clamp_nut);
zmotor_mount_clamp_nut_thick = lookup(MHexNutThickness, zmotor_mount_clamp_nut);

zmotor_mount_clamp_width = zmotor_mount_clamp_dist+zmotor_mount_clamp_thread_dia*3;

zmotor_mount_conn_motor=[[-zmotor_mount_motor_offset, 0, 0],[0,1,0]];

module zaxis_motor_mount(show_motor=false)
{

    difference()
    {
        // top plate
        union()
        {

            difference()
            {
                union()
                {
                    // top plate
                    cubea([zmotor_mount_rod_offset_x-zmotor_mount_thickness, zmotor_w+zmotor_mount_thickness*2, zmotor_mount_thickness_h], align=[1,0,1]);
                    translate([zmotor_mount_rod_offset_x, 0, 0])
                    {
                        cubea([gantry_connector_thickness, zmotor_w+zmotor_mount_thickness*2, zmotor_mount_thickness_h], align=[-1,0,1]);
                    }

                    // reinforcement plate between motor and extrusion
                    cubea([zmotor_mount_thickness, zmotor_w, zmotor_h], align=[1,0,-1]);

                    // top extrusion mount plate
                    translate([0, 0,-extrusion_size-zaxis_motor_offset_z])
                        cubea([zmotor_mount_thickness, zmotor_mount_width, extrusion_size], align=[1,0,1]);

                    // bottom extrusion mount plate
                    translate([0, 0, -main_lower_dist_z-extrusion_size-zaxis_motor_offset_z])
                        cubea([zmotor_mount_thickness, zmotor_w, extrusion_size], align=[1,0,1]);

                    // side triangles
                    for(i=[-1,1])
                    {
                        translate([zmotor_mount_thickness, i*((zmotor_w/2)+zmotor_mount_thickness/2), 0])
                            rotate([90,90,0])
                            Right_Angled_Triangle(a=zmotor_mount_rod_offset_x-zmotor_mount_thickness, b=main_lower_dist_z+extrusion_size+zaxis_motor_offset_z, height=zmotor_mount_thickness, centerXYZ=[0,0,1]);

                        translate([0, i*((zmotor_w/2)+zmotor_mount_thickness/2), 0])
                            cubea([zmotor_mount_thickness, zmotor_mount_thickness, zmotor_mount_h], align=[1,0,-1]);
                    }

                }

                // cutout for motor cables
                translate([0,0,-30*mm])
                cubea([zmotor_mount_thickness*3, 20*mm, zmotor_h], align=[0,0,-1]);

                // screw holes top
                for(i=[-1,1])
                    translate([0, i*(zmotor_w/2+zmotor_mount_thread_dia*3), -extrusion_size])
                        fncylindera(h=zmotor_mount_thickness*3,d=zmotor_mount_thread_dia, orient=[1,0,0]);

                // screw hole bottom
                for(i=[0])
                    translate([0, i*(zmotor_w/2+zmotor_mount_thread_dia*3), -extrusion_size-main_lower_dist_z])
                        fncylindera(h=zmotor_mount_thickness*3,d=zmotor_mount_thread_dia,align=[0,0,0], orient=[1,0,0]);
            }

        }

        // cut out motor mount holes etc
        translate([zmotor_w/2+zmotor_mount_motor_offset,0,-1])
            linear_extrude(zmotor_mount_thickness_h+2)
            stepper_motor_mount(17, slide_distance=0, mochup=false);

        // cut out z rod
        translate([zmotor_mount_rod_offset_x, 0, 0])
            fncylindera(d=zaxis_rod_d*rod_fit_tolerance, h=100, orient=[0,0,1]);

        // cut out z rod mounting clamp nut traps
        for(i=[-1,1])
        {
            translate([zmotor_mount_rod_offset_x-7, i*zmotor_mount_clamp_dist/2, zmotor_mount_thickness_h/2])
            {
                cubea([zmotor_mount_clamp_nut_thick*1.3, zmotor_mount_clamp_nut_dia*1.1, zmotor_mount_clamp_nut_dia*1.01], extrasize=[0,0,zmotor_mount_thickness_h], extrasize_align=[0,0,1]);

                translate([-zmotor_mount_clamp_nut_thick*1.3/2,0,0])
                fncylindera(d=zmotor_mount_clamp_thread_dia, h=20, orient=[1,0,0], align=[1,0,0]);
            }
        }

        %if(show_motor)
        {
            attach([[lookup(NemaSideSize,zaxis_motor)/2,0,0],[0,0,0]],zmotor_mount_conn_motor)
            {
                // z motor/leadscrews
                motor(zaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);
            }
        }
    }
}

/*print = true;*/
/*if(print)*/
/*{*/
    /*rotate([0,-90,0])*/
        /*zaxis_motor_mount();*/

    /*translate([-25,0,zmotor_mount_thickness_h/2])*/
        /*mount_rod_clamp_half(*/
                /*rod_d=zaxis_rod_d,*/
                /*screw_dist=zmotor_mount_clamp_dist,*/
                /*thick=5,*/
                /*base_thick=5,*/
                /*width=zmotor_mount_thickness_h,*/
                /*thread=zmotor_mount_clamp_thread);*/
/*}*/

include <MCAD/stepper.scad>
include <MCAD/motors.scad>

use <thing_libutils/triangles.scad>

include <config.scad>

// inner_d, outer_d, thread
zaxis_nut = [20*mm, 36.5*mm, 8*mm];

zaxis_nut_mount_outer = zaxis_nut[1]/2 + zaxis_bearing[1]/2 + 3;

// place z rod on edge of motor
/*zaxis_rod_screw_distance_x = max(zaxis_nut_mount_outer, zaxis_rod_d/2 + lookup(NemaSideSize,zaxis_motor)/2);*/
zaxis_rod_screw_distance_x = zaxis_nut_mount_outer;

zmotor_w = lookup(NemaSideSize,zaxis_motor);
zmotor_h = lookup(NemaLengthLong,zaxis_motor);
zmotor_mount_thread_dia = lookup(ThreadSize, extrusion_thread);
zmotor_mount_width = zmotor_w+zmotor_mount_thickness*2 + zmotor_mount_thread_dia*8;
zmotor_mount_h = main_lower_dist_z+extrusion_size+zaxis_motor_offset_z;
zmotor_mount_rod_offset_x = zmotor_w/2+zaxis_rod_screw_distance_x+zmotor_mount_motor_offset;

zmotor_mount_clamp_dist = zaxis_rod_d*2.5;
zmotor_mount_clamp_thread = ThreadM4;
zmotor_mount_clamp_nut = MHexNutM4;
zmotor_mount_clamp_thread_dia = lookup(ThreadSize, zmotor_mount_clamp_thread);
zmotor_mount_clamp_nut_dia = lookup(MHexNutWidthMin, zmotor_mount_clamp_nut);
zmotor_mount_clamp_nut_thick = lookup(MHexNutThickness, zmotor_mount_clamp_nut);

zmotor_mount_clamp_width = zmotor_mount_clamp_dist+zmotor_mount_clamp_thread_dia*3;

zmotor_mount_conn_motor=[[-zmotor_mount_motor_offset, 0, 0],[0,1,0]];

module zaxis_motor_mount(show_motor=false)
{

    difference()
    {
        // top plate
        union()
        {

            difference()
            {
                union()
                {
                    // top plate
                    cubea([zmotor_mount_rod_offset_x-zmotor_mount_thickness, zmotor_w+zmotor_mount_thickness*2, zmotor_mount_thickness_h], align=[1,0,1]);
                    translate([zmotor_mount_rod_offset_x, 0, 0])
                    {
                        cubea([gantry_connector_thickness, zmotor_w+zmotor_mount_thickness*2, zmotor_mount_thickness_h], align=[-1,0,1]);
                    }

                    // reinforcement plate between motor and extrusion
                    cubea([zmotor_mount_thickness, zmotor_w, zmotor_h], align=[1,0,-1]);

                    // top extrusion mount plate
                    translate([0, 0,-extrusion_size-zaxis_motor_offset_z])
                        cubea([zmotor_mount_thickness, zmotor_mount_width, extrusion_size], align=[1,0,1]);

                    // bottom extrusion mount plate
                    translate([0, 0, -main_lower_dist_z-extrusion_size-zaxis_motor_offset_z])
                        cubea([zmotor_mount_thickness, zmotor_w, extrusion_size], align=[1,0,1]);

                    // side triangles
                    for(i=[-1,1])
                    {
                        translate([zmotor_mount_thickness, i*((zmotor_w/2)+zmotor_mount_thickness/2), 0])
                            rotate([90,90,0])
                            Right_Angled_Triangle(a=zmotor_mount_rod_offset_x-zmotor_mount_thickness, b=main_lower_dist_z+extrusion_size+zaxis_motor_offset_z, height=zmotor_mount_thickness, centerXYZ=[0,0,1]);

                        translate([0, i*((zmotor_w/2)+zmotor_mount_thickness/2), 0])
                            cubea([zmotor_mount_thickness, zmotor_mount_thickness, zmotor_mount_h], align=[1,0,-1]);
                    }

                }

                // cutout for motor cables
                translate([0,0,-30*mm])
                cubea([zmotor_mount_thickness*3, 20*mm, zmotor_h], align=[0,0,-1]);

                // screw holes top
                for(i=[-1,1])
                    translate([0, i*(zmotor_w/2+zmotor_mount_thread_dia*3), -extrusion_size])
                        fncylindera(h=zmotor_mount_thickness*3,d=zmotor_mount_thread_dia, orient=[1,0,0]);

                // screw hole bottom
                for(i=[0])
                    translate([0, i*(zmotor_w/2+zmotor_mount_thread_dia*3), -extrusion_size-main_lower_dist_z])
                        fncylindera(h=zmotor_mount_thickness*3,d=zmotor_mount_thread_dia,align=[0,0,0], orient=[1,0,0]);
            }

        }

        // cut out motor mount holes etc
        translate([zmotor_w/2+zmotor_mount_motor_offset,0,-1])
            linear_extrude(zmotor_mount_thickness_h+2)
            stepper_motor_mount(17, slide_distance=0, mochup=false);

        // cut out z rod
        translate([zmotor_mount_rod_offset_x, 0, 0])
            fncylindera(d=zaxis_rod_d*rod_fit_tolerance, h=100, orient=[0,0,1]);

        // cut out z rod mounting clamp nut traps
        for(i=[-1,1])
        {
            translate([zmotor_mount_rod_offset_x-7, i*zmotor_mount_clamp_dist/2, zmotor_mount_thickness_h/2])
            {
                cubea([zmotor_mount_clamp_nut_thick*1.1, zmotor_mount_clamp_nut_dia*1.01, zmotor_mount_clamp_nut_dia*1.01], extrasize=[0,0,zmotor_mount_thickness_h], extrasize_align=[0,0,1]);

                fncylindera(d=zmotor_mount_clamp_thread_dia, h=20, orient=[1,0,0], align=[1,0,0]);
            }
        }

        %if(show_motor)
        {
            attach([[lookup(NemaSideSize,zaxis_motor)/2,0,0],[0,0,0]],zmotor_mount_conn_motor)
            {
                // z motor/leadscrews
                motor(zaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);
            }
        }
    }
}


Need a little extra padding for my table

// This box is the housing for the scoring buttons that get mounted
// under the pingpong table. The buttons I used are these:
// https://www.sparkfun.com/products/11275
// In hindsight, these buttons are rather large. You could use smaller
// buttons and adjust some of these values accordingly.

// The overall radius of the button. The datasheet reports 100mm, but
// mine both measure 98.
button_radius = 49;

// The radius of the hole the button back needs.
hole_radius = 11.5;

// There's a bar on the front of my table that is 40mm high
table_padding = 40;

// I want 30mm around the button's hole
bottom_padding = 30;
extra_padding = 4;

// The thickness of the box walls
wall_thickness = 3;

// Dimensions for the overall box
mount_height = table_padding + extra_padding + button_radius + hole_radius + bottom_padding;
mount_depth = 50;
mount_width = (hole_radius * 2) + (bottom_padding * 2);

$fn=100;
font = "monaco.dxf";

// Comment or uncomment the body or cover, depending on which you need to render

// Body
union() {
    difference() {
        bottom();
        // You can inscribe something here. I print the box at lower resolution (.3mm), it
        // comes out OK but not very good looking. Higher res looks better.
        // name();
    }

    difference() {
        sides();
        cover_screws();
        mount_screws();
    }
}

// Cover
/*
difference() {
    translate([0, 0, mount_depth-wall_thickness])
    cover();
    cover_screws();
    // Remove this line if you don't want the project's name on the cover
    project();
}
*/

// You shouldn't have to configure anything below this, except maybe text
// attributes at the bottom if you're putting your own text in it.

module bottom() {
    difference() {
    hull() {
        // lower left
        translate([wall_thickness*2, wall_thickness*2, 0])
        cylinder(r=wall_thickness*2, h=wall_thickness);

        // lower right
        translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
        cylinder(r=wall_thickness*2, h=wall_thickness);

        // upper right
        translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
        cube(size=[wall_thickness*2, wall_thickness*2, wall_thickness]);

        // upper left
        translate([0, mount_height-(wall_thickness*2), 0])
        cube(size=[wall_thickness*2, wall_thickness*2, wall_thickness]);
    }

    union() {
        translate([mount_width/2, wall_thickness+7.5, -1])
        cylinder(r=3, h=wall_thickness+2);

        translate([mount_width/2-4.5, wall_thickness+7.5-2.5, wall_thickness-.8])
        cube(size=[9, 5, 1]);
    }
    }
}

module sides() {
    difference() {
        hull() {
            // lower left
            translate([wall_thickness*2, wall_thickness*2, 0])
            cylinder(r=wall_thickness*2, h=mount_depth);

            // lower right
            translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
            cylinder(r=wall_thickness*2, h=mount_depth);

            // upper right
            translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness*2, wall_thickness*2, mount_depth]);

            // upper left
            translate([0, mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness*2, wall_thickness*2, mount_depth]);
        }

        hull() {
            // lower left
            translate([wall_thickness*2, wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=mount_depth+1);

            // lower right
            translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=mount_depth+1);

            // upper right
            translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, mount_depth+1]);

            // upper left
            translate([wall_thickness, mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, mount_depth+1]);
        }
    }

    intersection() {
        translate([wall_thickness, wall_thickness, 0])
        cube([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), mount_depth]);

        union() {
            translate([wall_thickness, wall_thickness, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([wall_thickness, wall_thickness, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);

            translate([wall_thickness, mount_height/2, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([wall_thickness, mount_height/2, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);

            translate([mount_width-wall_thickness, wall_thickness, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([mount_width-wall_thickness, wall_thickness, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);

            translate([mount_width-wall_thickness, mount_height/2, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([mount_width-wall_thickness, mount_height/2, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);

            translate([mount_width-wall_thickness, mount_height-wall_thickness, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([mount_width-wall_thickness, mount_height-wall_thickness, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);

            translate([wall_thickness, mount_height-wall_thickness, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([wall_thickness, mount_height-wall_thickness, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);
        }
    }
}

module cover() {
    hole_center = mount_height - table_padding - button_radius;

    difference() {
        hull() {
            // lower left
            translate([wall_thickness*2, wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=wall_thickness);

            // lower right
            translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=wall_thickness);

            // upper right
            translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, wall_thickness]);

            // upper left
            translate([wall_thickness, mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, wall_thickness]);
        }

        translate([mount_width/2, hole_center, -1])
        cylinder(r=hole_radius, h=wall_thickness*2);
    }

    // Fake button
    // translate([mount_width/2, hole_center, 5])
    // cylinder(r=button_radius, h=20);
}

module cover_screws() {
    translate([wall_thickness+3.5, wall_thickness+3.5, mount_depth/2])
    cylinder(r=1.5, h=30);

    translate([mount_width-wall_thickness-3.5, wall_thickness+3.5, mount_depth/2])
    cylinder(r=1.5, h=30);

    translate([mount_width-wall_thickness-3.5, mount_height-wall_thickness-3.5, mount_depth/2])
    cylinder(r=1.5, h=30);

    translate([wall_thickness+3.5, mount_height-wall_thickness-3.5, mount_depth/2])
    cylinder(r=1.5, h=30);
}

module mount_screws() {
    spacing = 15;

    translate([spacing, mount_height, spacing])
    rotate([90, 0, 0])
    cylinder(r=2, h=wall_thickness+2);

    translate([spacing, mount_height, mount_depth-spacing])
    rotate([90, 0, 0])
    cylinder(r=2, h=wall_thickness+2);

    translate([mount_width-spacing, mount_height, mount_depth-spacing])
    rotate([90, 0, 0])
    cylinder(r=2, h=wall_thickness+2);

    translate([mount_width-spacing, mount_height, spacing])
    rotate([90, 0, 0])
    cylinder(r=2, h=wall_thickness+2);
}

// Text
module letter(l, h=100, i=0) {
    union() {
        linear_extrude(height=h) import(font, layer=l[i]);
        translate([dxf_dim(file=font, name="advx", layer=l[i]), dxf_dim(file=font, name="advy", layer=l[i]), 0])
        child();
    }
}

module word(wrd, h=100, i=0) {
    if (i < len(wrd)) {
        letter(wrd, h, i) word(wrd, h, i+1);
    } else {
        child();
    }
}

module name() {
    translate([18.5, mount_height - 20, wall_thickness-1.5])
    scale(0.002)
    word("YourTextHere", 1000);
}

module project() {
    translate([22, mount_height-20, mount_depth-1.5])
    scale(0.002)
     word("Pingduino", 1000);
}

// This box is the housing for the scoring buttons that get mounted
// under the pingpong table. The buttons I used are these:
// https://www.sparkfun.com/products/11275
// In hindsight, these buttons are rather large. You could use smaller
// buttons and adjust some of these values accordingly.

// The overall radius of the button. The datasheet reports 100mm, but
// mine both measure 98.
button_radius = 49;

// The radius of the hole the button back needs.
hole_radius = 11.5;

// There's a bar on the front of my table that is 40mm high
table_padding = 40;

// I want 30mm around the button's hole
bottom_padding = 30;
extra_padding = 2;

// The thickness of the box walls
wall_thickness = 3;

// Dimensions for the overall box
mount_height = table_padding + extra_padding + button_radius + hole_radius + bottom_padding;
mount_depth = 50;
mount_width = (hole_radius * 2) + (bottom_padding * 2);

$fn=100;
font = "monaco.dxf";

// Comment or uncomment the body or cover, depending on which you need to render

// Body
union() {
    difference() {
        bottom();
        // You can inscribe something here. I print the box at lower resolution (.3mm), it
        // comes out OK but not very good looking. Higher res looks better.
        // name();
    }

    difference() {
        sides();
        cover_screws();
        mount_screws();
    }
}

// Cover
/*
difference() {
    translate([0, 0, mount_depth-wall_thickness])
    cover();
    cover_screws();
    // Remove this line if you don't want the project's name on the cover
    project();
}
*/

// You shouldn't have to configure anything below this, except maybe text
// attributes at the bottom if you're putting your own text in it.

module bottom() {
    difference() {
    hull() {
        // lower left
        translate([wall_thickness*2, wall_thickness*2, 0])
        cylinder(r=wall_thickness*2, h=wall_thickness);

        // lower right
        translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
        cylinder(r=wall_thickness*2, h=wall_thickness);

        // upper right
        translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
        cube(size=[wall_thickness*2, wall_thickness*2, wall_thickness]);

        // upper left
        translate([0, mount_height-(wall_thickness*2), 0])
        cube(size=[wall_thickness*2, wall_thickness*2, wall_thickness]);
    }

    union() {
        translate([mount_width/2, wall_thickness+7.5, -1])
        cylinder(r=3, h=wall_thickness+2);

        translate([mount_width/2-4.5, wall_thickness+7.5-2.5, wall_thickness-.8])
        cube(size=[9, 5, 1]);
    }
    }
}

module sides() {
    difference() {
        hull() {
            // lower left
            translate([wall_thickness*2, wall_thickness*2, 0])
            cylinder(r=wall_thickness*2, h=mount_depth);

            // lower right
            translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
            cylinder(r=wall_thickness*2, h=mount_depth);

            // upper right
            translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness*2, wall_thickness*2, mount_depth]);

            // upper left
            translate([0, mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness*2, wall_thickness*2, mount_depth]);
        }

        hull() {
            // lower left
            translate([wall_thickness*2, wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=mount_depth+1);

            // lower right
            translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=mount_depth+1);

            // upper right
            translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, mount_depth+1]);

            // upper left
            translate([wall_thickness, mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, mount_depth+1]);
        }
    }

    intersection() {
        translate([wall_thickness, wall_thickness, 0])
        cube([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), mount_depth]);

        union() {
            translate([wall_thickness, wall_thickness, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([wall_thickness, wall_thickness, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);

            translate([wall_thickness, mount_height/2, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([wall_thickness, mount_height/2, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);

            translate([mount_width-wall_thickness, wall_thickness, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([mount_width-wall_thickness, wall_thickness, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);

            translate([mount_width-wall_thickness, mount_height/2, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([mount_width-wall_thickness, mount_height/2, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);

            translate([mount_width-wall_thickness, mount_height-wall_thickness, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([mount_width-wall_thickness, mount_height-wall_thickness, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);

            translate([wall_thickness, mount_height-wall_thickness, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([wall_thickness, mount_height-wall_thickness, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);
        }
    }
}

module cover() {
    hole_center = mount_height - table_padding - button_radius;

    difference() {
        hull() {
            // lower left
            translate([wall_thickness*2, wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=wall_thickness);

            // lower right
            translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=wall_thickness);

            // upper right
            translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, wall_thickness]);

            // upper left
            translate([wall_thickness, mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, wall_thickness]);
        }

        translate([mount_width/2, hole_center, -1])
        cylinder(r=hole_radius, h=wall_thickness*2);
    }

    // Fake button
    // translate([mount_width/2, hole_center, 5])
    // cylinder(r=button_radius, h=20);
}

module cover_screws() {
    translate([wall_thickness+3.5, wall_thickness+3.5, mount_depth/2])
    cylinder(r=1.5, h=30);

    translate([mount_width-wall_thickness-3.5, wall_thickness+3.5, mount_depth/2])
    cylinder(r=1.5, h=30);

    translate([mount_width-wall_thickness-3.5, mount_height-wall_thickness-3.5, mount_depth/2])
    cylinder(r=1.5, h=30);

    translate([wall_thickness+3.5, mount_height-wall_thickness-3.5, mount_depth/2])
    cylinder(r=1.5, h=30);
}

module mount_screws() {
    spacing = 15;

    translate([spacing, mount_height, spacing])
    rotate([90, 0, 0])
    cylinder(r=2, h=wall_thickness+2);

    translate([spacing, mount_height, mount_depth-spacing])
    rotate([90, 0, 0])
    cylinder(r=2, h=wall_thickness+2);

    translate([mount_width-spacing, mount_height, mount_depth-spacing])
    rotate([90, 0, 0])
    cylinder(r=2, h=wall_thickness+2);

    translate([mount_width-spacing, mount_height, spacing])
    rotate([90, 0, 0])
    cylinder(r=2, h=wall_thickness+2);
}

// Text
module letter(l, h=100, i=0) {
    union() {
        linear_extrude(height=h) import(font, layer=l[i]);
        translate([dxf_dim(file=font, name="advx", layer=l[i]), dxf_dim(file=font, name="advy", layer=l[i]), 0])
        child();
    }
}

module word(wrd, h=100, i=0) {
    if (i < len(wrd)) {
        letter(wrd, h, i) word(wrd, h, i+1);
    } else {
        child();
    }
}

module name() {
    translate([18.5, mount_height - 20, wall_thickness-1.5])
    scale(0.002)
    word("YourTextHere", 1000);
}

module project() {
    translate([22, mount_height-20, mount_depth-1.5])
    scale(0.002)
     word("Pingduino", 1000);
}


y/motormount: define parts

y/motormount: define parts

include <MCAD/stepper.scad>
include <MCAD/motors.scad>

use <thing_libutils/shapes.scad>
include <thing_libutils/attach.scad>
include <config.scad>
include <thing_libutils/pulley.scad>

yaxis_motor_mount_conn = [[0,0,+extrusion_size/2+yaxis_motor_offset_z],[1,0,0]];
yaxis_motor_mount_conn_motor = [[+yaxis_motor_offset_x, 0,+extrusion_size/2+yaxis_motor_offset_z],[0,0,1]];

ymotor_w = lookup(NemaSideSize, yaxis_motor);
ymotor_h = lookup(NemaLengthLong, yaxis_motor);
ymotor_mount_thread_dia = lookup(ThreadSize, extrusion_thread);
ymotor_mount_h = main_lower_dist_z+extrusion_size+yaxis_motor_offset_z;
ymotor_mount_width = ymotor_w+ymotor_mount_thickness*2 + ymotor_mount_thread_dia*8;

yaxis_motor_pulley_h = 17.5*mm;
yaxis_motor_mount_bearing_clamp_offset_z = yaxis_motor_pulley_h;

module yaxis_motor_mount_bearing_clamp(align=[0,0,0])
{
    bearing_d = bearing_625[1];
    bearing_h = bearing_625[2];
    width=ymotor_w+ymotor_mount_thickness;
    depth=ymotor_w+ymotor_mount_thickness*2;
    height=yaxis_motor_mount_bearing_clamp_offset_z;

    /*size_align(size=[width,depth,height], align=align);*/
    difference()
    {
        cubea([width, depth, height], align=[0,0,-1]);

        ymotor_round_d = lookup(NemaRoundExtrusionDiameter, yaxis_motor);

        translate([0,0,.1])
            cylindera(h=bearing_h*2, d=bearing_d*rod_fit_tolerance, orient=[0,0,1], align=[0,0,-1]);

        // cutout for belt path
        cylindera(d=bearing_d, h=height*2, orient=[0,0,1], align=[0,0,-1]);
        translate([depth/2, 0, -bearing_h])
            cubea([depth, ymotor_round_d, height-bearing_h+1], align=[0,0,-1]);

        // cut out motor mount holes etc
        screw_dist = lookup(NemaDistanceBetweenMountingHoles, yaxis_motor);
        for(x=[-1,1])
        for(y=[-1,1])
        translate([x*screw_dist/2, y*screw_dist/2, 1])
        cylindera(h=height, d=3*mm, orient=[0,0,1], align=[0,0,-1]);
    }

    // debug bearing
    %cylindera(h=bearing_h, d=bearing_d*rod_fit_tolerance, align=[0,0,-1], orient=[0,0,1]);
}

module motor_mount_top(width, depth, height, belt_cutout=true, belt_cutout_orient=[1,0,0], align=[0,0,0])
{
    size_align(size=[width, depth, height], align=align);
    difference()
    {
        cubea([width, depth, height], align=[0,0,1]);

        ymotor_round_d = lookup(NemaRoundExtrusionDiameter, yaxis_motor);

        // cutout for belt path
        cylindera(d=ymotor_round_d, h=height*2, orient=[0,0,1], align=[0,0,0]);
        translate([0, 0,-1])
            cubea([depth/2, ymotor_round_d, height*2], align=[1,0,1]);

        // cut out motor mount holes etc
        translate([0,0,-1])
            linear_extrude(height+2)
            stepper_motor_mount(17, slide_distance=0, mochup=false);
    }
}

module yaxis_motor_mount(show_motor=false)
{
    difference()
    {
        // top plate
        union()
        {
            translate([0,0,yaxis_motor_offset_z])
            {
                // top plate
                translate([ymotor_mount_thickness,0,extrusion_size/2])
                {
                    /*translate([ymotor_w/2,0,ymotor_mount_thickness_h+yaxis_motor_mount_bearing_clamp_offset_z+1])*/
                        /*yaxis_motor_mount_bearing_clamp(align=[0,0,-1]);*/

                    translate([ymotor_w/2,0,0])
                        motor_mount_top(width=ymotor_w+ymotor_mount_thickness,
                        depth=ymotor_w+ymotor_mount_thickness*2,
                        height=ymotor_mount_thickness_h,
                        belt_cutout=true,
                        belt_cutout_orient=[1,0,0]);
                }

                translate([0,0,extrusion_size/2])
                {
                    difference()
                    {
                        // reinforcement plate between motor and extrusion
                        cubea([ymotor_mount_thickness, ymotor_w+ymotor_mount_thickness*2, ymotor_h], align=[1,0,-1], extrasize=[0,0,ymotor_mount_thickness_h], extrasize_align=[0,0,1]);

                        // cutout for motor cables
                        translate([0,0,-20*mm])
                            cubea([ymotor_mount_thickness*3, 20*mm, ymotor_h], align=[0,0,-1]);
                    }
                }

                // side triangles
                for(i=[-1,1])
                {
                    translate([ymotor_mount_thickness, i*((ymotor_w/2)+ymotor_mount_thickness/2), extrusion_size/2])
                        triangle(
                                ymotor_w+ymotor_mount_thickness/2,
                                main_lower_dist_z+extrusion_size+yaxis_motor_offset_z,
                                depth=ymotor_mount_thickness,
                                align=[1,0,-1],
                                orient=[1,0,0]
                                );

                    translate([0, i*((ymotor_w/2)+ymotor_mount_thickness/2), extrusion_size/2])
                        cubea([ymotor_mount_thickness, ymotor_mount_thickness, ymotor_mount_h], align=[1,0,-1]);
                }
            }

            // top mount plate
            difference()
            {
                cubea([ymotor_mount_thickness, ymotor_mount_width, extrusion_size], align=[1,0,0]);

                for(i=[-1,1])
                    translate([0, i*(ymotor_w/2+ymotor_mount_thread_dia*3), 0])
                        cylindera(h=ymotor_mount_thickness*3,d=ymotor_mount_thread_dia, orient=[1,0,0]);
            }

            // bottom mount plate
            translate([0,0,-main_lower_dist_z])
            {
                difference()
                {
                    cubea([ymotor_mount_thickness, ymotor_w, extrusion_size], align=[1,0,0]);

                    for(i=[0])
                        translate([0, i*(ymotor_w/2+ymotor_mount_thread_dia*3), 0])
                            cylindera(h=ymotor_mount_thickness*3,d=ymotor_mount_thread_dia,align=[0,0,0], orient=[1,0,0]);
                }
            }

        }

    }

    if(show_motor)
    {
        attach(yaxis_motor_mount_conn_motor,[[0,0,0],[0,0,0]])
        {
            motor(yaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);

            translate([0,0,8*mm])
                %pulley(pulley_2GT_20T);
        }
    }
}

module part_y_motor_mount()
{
    attach(yaxis_motor_mount_conn_motor,[[0,0,0],[1,0,0]])
    {
        yaxis_motor_mount(show_motor=false);
    }
}

/*yaxis_motor_mount(show_motor=true);*/

include <MCAD/stepper.scad>
include <MCAD/motors.scad>

use <thing_libutils/shapes.scad>
include <thing_libutils/attach.scad>
include <config.scad>
include <thing_libutils/pulley.scad>

yaxis_motor_mount_conn = [[0,0,+extrusion_size/2+yaxis_motor_offset_z],[1,0,0]];
yaxis_motor_mount_conn_motor = [[+yaxis_motor_offset_x, 0,+extrusion_size/2+yaxis_motor_offset_z],[0,0,1]];

ymotor_w = lookup(NemaSideSize, yaxis_motor);
ymotor_h = lookup(NemaLengthLong, yaxis_motor);
ymotor_mount_thread_dia = lookup(ThreadSize, extrusion_thread);
ymotor_mount_h = main_lower_dist_z+extrusion_size+yaxis_motor_offset_z;
ymotor_mount_width = ymotor_w+ymotor_mount_thickness*2 + ymotor_mount_thread_dia*8;

yaxis_motor_pulley_h = 17.5*mm;
yaxis_motor_mount_bearing_clamp_offset_z = yaxis_motor_pulley_h;

module yaxis_motor_mount_bearing_clamp(align=[0,0,0])
{
    bearing_d = bearing_625[1];
    bearing_h = bearing_625[2];
    width=ymotor_w+ymotor_mount_thickness;
    depth=ymotor_w+ymotor_mount_thickness*2;
    height=yaxis_motor_mount_bearing_clamp_offset_z;

    /*size_align(size=[width,depth,height], align=align);*/
    difference()
    {
        cubea([width, depth, height], align=[0,0,-1]);

        ymotor_round_d = lookup(NemaRoundExtrusionDiameter, yaxis_motor);

        translate([0,0,.1])
            cylindera(h=bearing_h*2, d=bearing_d*rod_fit_tolerance, orient=[0,0,1], align=[0,0,-1]);

        // cutout for belt path
        cylindera(d=bearing_d, h=height*2, orient=[0,0,1], align=[0,0,-1]);
        translate([depth/2, 0, -bearing_h])
            cubea([depth, ymotor_round_d, height-bearing_h+1], align=[0,0,-1]);

        // cut out motor mount holes etc
        screw_dist = lookup(NemaDistanceBetweenMountingHoles, yaxis_motor);
        for(x=[-1,1])
        for(y=[-1,1])
        translate([x*screw_dist/2, y*screw_dist/2, 1])
        cylindera(h=height, d=3*mm, orient=[0,0,1], align=[0,0,-1]);
    }

    // debug bearing
    %cylindera(h=bearing_h, d=bearing_d*rod_fit_tolerance, align=[0,0,-1], orient=[0,0,1]);
}

module motor_mount_top(width, depth, height, belt_cutout=true, belt_cutout_orient=[1,0,0], align=[0,0,0])
{
    size_align(size=[width, depth, height], align=align);
    difference()
    {
        cubea([width, depth, height], align=[0,0,1]);

        ymotor_round_d = lookup(NemaRoundExtrusionDiameter, yaxis_motor);

        // cutout for belt path
        cylindera(d=ymotor_round_d, h=height*2, orient=[0,0,1], align=[0,0,0]);
        translate([0, 0,-1])
            cubea([depth/2, ymotor_round_d, height*2], align=[1,0,1]);

        // cut out motor mount holes etc
        translate([0,0,-1])
            linear_extrude(height+2)
            stepper_motor_mount(17, slide_distance=0, mochup=false);
    }
}

module yaxis_motor_mount(show_motor=false)
{
    difference()
    {
        // top plate
        union()
        {
            translate([0,0,yaxis_motor_offset_z])
            {
                // top plate
                translate([ymotor_mount_thickness,0,extrusion_size/2])
                {
                    /*translate([ymotor_w/2,0,ymotor_mount_thickness_h+yaxis_motor_mount_bearing_clamp_offset_z+1])*/
                        /*yaxis_motor_mount_bearing_clamp(align=[0,0,-1]);*/

                    translate([ymotor_w/2,0,0])
                        motor_mount_top(width=ymotor_w+ymotor_mount_thickness,
                        depth=ymotor_w+ymotor_mount_thickness*2,
                        height=ymotor_mount_thickness_h,
                        belt_cutout=true,
                        belt_cutout_orient=[1,0,0]);
                }

                translate([0,0,extrusion_size/2])
                {
                    difference()
                    {
                        // reinforcement plate between motor and extrusion
                        cubea([ymotor_mount_thickness, ymotor_w+ymotor_mount_thickness*2, ymotor_h], align=[1,0,-1], extrasize=[0,0,ymotor_mount_thickness_h], extrasize_align=[0,0,1]);

                        // cutout for motor cables
                        translate([0,0,-20*mm])
                            cubea([ymotor_mount_thickness*3, 20*mm, ymotor_h], align=[0,0,-1]);
                    }
                }

                // side triangles
                for(i=[-1,1])
                {
                    translate([ymotor_mount_thickness, i*((ymotor_w/2)+ymotor_mount_thickness/2), extrusion_size/2])
                        triangle(
                                ymotor_w+ymotor_mount_thickness/2,
                                main_lower_dist_z+extrusion_size+yaxis_motor_offset_z,
                                depth=ymotor_mount_thickness,
                                align=[1,0,-1],
                                orient=[1,0,0]
                                );

                    translate([0, i*((ymotor_w/2)+ymotor_mount_thickness/2), extrusion_size/2])
                        cubea([ymotor_mount_thickness, ymotor_mount_thickness, ymotor_mount_h], align=[1,0,-1]);
                }
            }

            // top mount plate
            difference()
            {
                cubea([ymotor_mount_thickness, ymotor_mount_width, extrusion_size], align=[1,0,0]);

                for(i=[-1,1])
                    translate([0, i*(ymotor_w/2+ymotor_mount_thread_dia*3), 0])
                        cylindera(h=ymotor_mount_thickness*3,d=ymotor_mount_thread_dia, orient=[1,0,0]);
            }

            // bottom mount plate
            translate([0,0,-main_lower_dist_z])
            {
                difference()
                {
                    cubea([ymotor_mount_thickness, ymotor_w, extrusion_size], align=[1,0,0]);

                    for(i=[0])
                        translate([0, i*(ymotor_w/2+ymotor_mount_thread_dia*3), 0])
                            cylindera(h=ymotor_mount_thickness*3,d=ymotor_mount_thread_dia,align=[0,0,0], orient=[1,0,0]);
                }
            }

        }

    }

    if(show_motor)
    {
        attach(yaxis_motor_mount_conn_motor,[[0,0,0],[0,0,0]])
        {
            motor(yaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);

            translate([0,0,8*mm])
                %pulley(pulley_2GT_20T);
        }
    }
}

module print_yaxis_motor_mount()
{
    attach(yaxis_motor_mount_conn_motor,[[0,0,0],[1,0,0]])
    {
        yaxis_motor_mount(show_motor=false);
    }
}

/*yaxis_motor_mount(show_motor=true);*/


added platform and mounting tabs

added platform and mounting tabs

// unified payload electronics mount

Bhole=2.38+.2;  // for brass tube
PCBhole = (25.4*3/32)/2;//1;  // found that 3/32" drill made good pilot for #4 self-piloting screw
include <JansenDefs.scad>;  // Bx
PCBholeSep=37;  // hole pattern for L298 module is a square this wide
PCBholeInset=15;  // from hole center to side of mount

thinWall=0.41;  // width of thinnest wall which will not get culled by slicer

//translate([0,20,0]) L298mount();

translate([0,0,7.8]) payloadPlatform();

braceSep = PCBholeInset+PCBholeSep/2;
%for(a=[0,180]) rotate([0,0,a]) translate([0,braceSep,0]) rotate([90,0,0])
      payloadBrace();

// -----------------------------------------------------

module payloadBrace() difference() {
   payloadMount(Bx,Bhole);

   #for(x=[-1,1]) translate([x*Bx,0,-1]) cylinder(r=Bhole,h=44,$fn=25);
   translate([0,0,-4]) cube([200,200,8],center=true);
}

// dovetail tabs for platform
tabZ=1.5;  // offset for tab
tabSep=40; // distance between tab centers
module tab() cylinder(r1=3,r2=2,h=6,$fn=3);

module payloadPlatform() difference() {
  payloadPlatformShell();
  payloadPlatformCutouts();
}

module payloadPlatformCutouts() {
  intersection() {
    difference() {
      hull() for(x=[-1,1]) for(y=[-1,1]) translate([x*45,y*(braceSep-5),0])
         cylinder(r1=2,r2=3,h=6,$fn=16,center=true);

      // cutouts for dovetail tabs
      for(a=[0,180]) rotate([0,0,a])
         for(x=[-tabSep,0,tabSep]) translate([x,braceSep-tabZ,-3])
            rotate([0,0,-30]) scale(2) tab();
    }
    hexGrid();
  }
}

module hexGrid() {
dh=3.1;
c30=cos(30);  $fn=6;   dx=3*dh;  dy=2*c30*dh;
//r1=hr+1.1;  r2=hr-.4;
 ch=thick+2;  dz=-1.6;
  translate([3*dh/2,-c30*dh,0])
    for(j=[-5:6]) for(i=[-5:4]) hex(i*dx,j*dy);
    for(j=[-5:5]) for(i=[-5:5]) hex(i*dx,j*dy);
}
module hex(x,y) translate([x,y,0])
   cylinder(r1=2,r2=2.6,h=6,$fn=6,center=true);

module payloadPlatformShell() {
  intersection() {
    difference() {
      cube([100,2*braceSep,5],center=true);

      // slots for dovetail tabs
      for(a=[0,180]) rotate([0,0,a])
         for(x=[-tabSep,0,tabSep]) translate([x,braceSep-tabZ,-3])
            rotate([0,0,-30]) scale(1.1) tab();
    }

    // round off corners
    hull()for(x=[-1,1])for(y=[-1,1])translate([x*46,y*(braceSep-4),0])
       scale([4.5,4.5,3.5])sphere(1,$fn=36);
  }
}

module L298mount() intersection() { cube([59,99,4],center=true);

  difference() {
    hull() for(x=[-1,1]) for(y=[-1,PCBholeInset-0.5])
       translate([x*(30-4),y,0])
          scale([4,4,3]) sphere(1,$fn=24);

    hull() {
       translate([0,12,0]) scale([ 9,4,6]) sphere(1,$fn=48);
       translate([0,22,0]) scale([18,1,8]) sphere(1,$fn=48);
    }

    difference() {
      union() {
        translate([0,4,0]) scale([ 5,2.5,5]) sphere(1,$fn=24);

        for(x=[-1,1]) {
          translate([x*PCBholeSep/2,PCBholeInset,-4])
            #cylinder(r=PCBhole,h=9,$fn=15);

          for (y=[6,14]) translate([x*26,y,-4]) cylinder(r=1.6,h=9,$fn=15);

          hull() {
            translate([x*21,7,0]) rotate([0,0,40*x])
                scale([5,1,5]) sphere(1,$fn=36);
            translate([x*22,13,0]) scale([1,2,5]) sphere(1,$fn=16);
          }
          hull() {
            translate([x*11,5,0]) rotate([0,0,30*x])
               scale([4,2,5]) sphere(1,$fn=36);
            translate([x*16,12,0]) scale([2,1,5]) sphere(1,$fn=12);
          }

        }
      }

      cube([99,99,thinWall],center=true); // leave support wall
    }
  }
}

module payloadMount(axisSep,axisRad) {
platOff=-34;  // L286 module mount platform offset
    union() {
      for (x=[-1,1]) //hull() {
        translate([x*axisSep,0,0])
           cylinder(r1=axisRad+3,r2=axisRad+2,h=12,$fn=36);
        //translate([x*(axisSep-14),0,0]) cylinder(r=0.4,h=1,$fn=4); }

      hull() { // top bar
        translate([0,5,2]) cube([2*axisSep,.5,4],center=true);
        cube([2*axisSep,1,1],center=true);
      }

      translate([0,platOff,0]) rotate([90,0,0]) L298mount();

      for(x=[-1,1]) {  // main side braces
        hull() {
          translate([x*axisSep,0,2]) scale([1.5,1,9]) sphere(1,$fn=16);
          translate([x*28,platOff,2]) scale([1,2,4]) sphere(1,$fn=16);
        }
        hull() {
          translate([x*axisSep,0 ,0.3]) scale([4,1,1.5]) sphere(1,$fn=16);
          translate([x*25,platOff,0.3]) scale([4,1,1.5]) sphere(1,$fn=16);
        }
      }

      for(x=[-tabSep,0,tabSep]) translate([x,5-1,tabZ])
         rotate([-90,0,0]) rotate([0,0,-30]) tab();
    }
}

// unified payload electronics mount

Bhole=2.38+.2;  // for brass tube
PCBhole = (25.4*3/32)/2;//1;  // found that 3/32" drill made good pilot for #4 self-piloting screw
include <JansenDefs.scad>;  // Bx
layer1bias = 0.4;
platformHeight = 45; // from bar to top platform
mountHeight=15; // from bar to electronics platform
PCBwidth=43;
HoleInset=3;

thick=5;
t2=thick/2;

sf = 16;  // sphere faces

difference() {
   payloadMount(Bx,Bhole,PCBwidth,HoleInset,PCBhole);

   #for(x=[-1,1]) translate([x*Bx,0,-1]) cylinder(r=Bhole,h=44,$fn=25);
   translate([0,0,-4]) cube([200,200,8],center=true);
}

//translate([0,20,0]) L298mount();

thinWall=0.41;  // width of thinnest wall which will not get culled by slicer

module L298mount() intersection() { cube([99,99,4],center=true);

  difference() {
    union() {
      hull() {
        cube([36,1,4],center=true);
        for(x=[-1,1]) translate([x*27,17,0])
          scale([5,5,3]) sphere(1,$fn=24);
      }
    }

    translate([0,20,0]) scale([16,11,4]) sphere(1,$fn=60);

    difference() {
      union() {
        //%scale([6,3,4]) sphere(1,$fn=36);

        for(x=[-1,1]) {
          translate([x*(PCBwidth/2-HoleInset),18,-4])
            #cylinder(r=PCBhole,h=9,$fn=15);

          translate([x*27,17,-4]) cylinder(r=1.6,h=9,$fn=15);
          translate([x*16,8,-4]) rotate([0,0,30]) cylinder(r=1.5,h=9,$fn=6);
          translate([x*23,10,-4]) rotate([0,0,30]) cylinder(r=2,h=9,$fn=6);
          translate([x*20.5,6,-4]) rotate([0,0,30]) cylinder(r=1.5,h=9,$fn=6);
          translate([x*17,4,-4]) rotate([0,0,30]) cylinder(r=1.5,h=9,$fn=6);
          translate([x*13,5,-4]) rotate([0,0,30]) cylinder(r=1.5,h=9,$fn=6);
          translate([x*9,4,-4]) rotate([0,0,30]) cylinder(r=2,h=9,$fn=6);
          translate([x*5,4,-4]) rotate([0,0,30]) cylinder(r=1.5,h=9,$fn=6);
        }
      }
      %cube([99,99,thinWall],center=true); // leave support wall
    }
  }
}

module payloadMount(axisSep,axisRad,platWidth,dHole,rHole) {
  //difference() {
    union() {
      //%braceBar(axisSep,axisRad);
      for (x=[-1,1]) hull() {
        translate([x*axisSep,0,0])
           cylinder(r1=axisRad+3,r2=axisRad+2,h=12,$fn=36);
        translate([x*(axisSep-14),0,0]) cylinder(r=0.4,h=1,$fn=4);
      }
      hull() {
        translate([0,5,2]) cube([2*axisSep,.5,4],center=true);
        cube([2*axisSep,1,1],center=true);
      }

      translate([0,-34,0]) rotate([90,0,0]) L298mount();

      for(x=[-1,1]) hull() {  // main side braces
        translate([x*axisSep,0,5]) scale([.6,.6,4]) sphere(1,$fn=16);
        translate([x*axisSep,0,0]) cube([2,2,1],center=true);
        translate([x*18,-34,0]) cube([4,4,1],center=true);
        translate([x*27,-34,8]) sphere(0.6,$fn=12);
      }

      *for(x=[-1,1]) hull() {  // secondary supports
        translate([x*1 , 4 ,0.5]) scale([3,1,1]) sphere(1,$fn=16);
        translate([x*16,-34,0.5]) scale([2,1,1]) sphere(1,$fn=16);
      }

    }
  //}
}