Add endstop definition.

Add endstop definition.

// To use, print 2x and use with a switch like D2F-L or D2F-FL.
// Holes are sized for M2 or smaller machine screw (#2 wood screw does not fit
// through microswitch holes).  For use with Grbl shield, wire up X,Y,Z to pins
// D9-D11.  TODO figure out which of normally open or normally closed works
// with firmware.  Note that X and Y use different lengths, see end of file.

// TODOS
// * make h= var do something useful
// * slightly enlarge so it fits snugly and doesn't move around
// * figure out why the hole doesn't go all the way through
// * come up with a plate that has both types
// * document sizing of hole (2.2mm) vs size of screw (down to M1.4)
// * templatize based on something (hopefully total distance + trigger from datasheet)
// * split out profile, so I can use it for other things. Note that this is 20x20 extrusion.

// * cable clip, for if you want to run in the channel
// * version with a tuning fork sort of shape, so a screw can tighten the
//   spacer area (tried something like this once, and it didn't print well --
//   was brittle).

gPlateRows = 1;
gPlateCols = 2;

e = 0.01;

h = 18;
rail_thick = 2.5;

// Set this to 10 if you only want the internal tips trimmed, 40 if you want the outside part to line up too.
tip_trim = 40;

module main() {
  union() {
    difference() {
      bulk();
      // trim exposed part
      translate([-40/2-1,0,0]) cube([40,40,h+2], center=true);
      // mounting hole
      //translate([5,0,h/2-5]) rotate([0,90,0]) cylinder(r1=5.1/2, r2=4/2, h=13, center=true, $fn=30);
    }
    // part the endstop attaches to
    difference() {
      translate([-4/2-e,0,-4]) cube([4,14,10], center=true);
      // mounting holes
      translate([0,7/2,-4]) rotate([0,90,0]) rotate([0,0,180]) cylinder(r=2.2/2, h=30, $fn=3, center=true);
      translate([0,-7/2,-4]) rotate([0,90,0]) rotate([0,0,180]) cylinder(r=2.2/2, h=30, $fn=3, center=true);
    }
  }
}

// This is intentionally untrimmed on the "top" part, so the caller can adjust
// height.
module bulk() {
  difference() {
    translate([-8.5,0,0]) rotate([0,0,45]) cube([25, 25, h], center=true);
    // trim bottom
    translate([24/2+6,0,0]) cube([24, 24, h+2], center=true);

    // trim top (this aligns the left edge with the center line)
    translate([rail_thick/2,12.5,0]) cube([rail_thick,20,h+2], center=true);
    // trim bottom
    translate([rail_thick/2,-12.5,0]) cube([rail_thick,20,h+2], center=true);

    // trim one tip
    translate([5,10,0]) cube([tip_trim,10,h+2], center=true);
    // trim other tip
    translate([5,-10,0]) cube([tip_trim,10,h+2], center=true);
  }
}

difference() {
  union() {
    // place on z=0
    translate([0,0,10])
    for(i = [0:gPlateRows-1]) {
      for(j = [0:gPlateCols-1]) {
        translate([i*20,j*20,0]) main();
      }
    }
  }
  // Trim length of stop varies depending on use (on a Shapeoko):
  // 100/2+15 for y stops
  // 100/2+22 for x stops
  translate([0,0,100/2+22]) cube([100,100,100], center=true);
}

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


enclosure: minor adjustments

enclosure: minor adjustments

tol = 0.5;
pcb_x = 130;
pcb_y = 110;
pcb_z = 4;
bolt_d = 3.6;
shift_bolt = 5;

// box thickness
th = 2;

shift_x = 4;
shift_y = th + 1;

box_x = pcb_x + shift_x + 4;
box_y = pcb_y + shift_y + th;

pcb_width = 2;
pcb_up = 9;

box_z = th + pcb_up + pcb_width - 1;

socket_h = 15;
socket_w = 10;
socket_n = 5;
socket_int = 20;
start_socket_x = 20 + shift_x;
start_socket_z = th + pcb_z + tol;
eps = 1e-1;

usb_type_b_w = 12;
usb_type_b_h = 11;
start_type_b_y = shift_y + 81.5;
//start_type_b_z = th + pcb_z + tol;

usb_type_a_w = 13.4;
usb_type_a_h = 7.3;
start_type_a_y = shift_y + 47;
//start_type_a_z = th + pcb_z + 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.6;
stoiki_r = 4;
wide_stoiki_r = stoiki_r + 2;

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

difference() {
  union() {
    difference() {
      cube([box_x,box_y,box_z], false);
      translate([th, th, th]) {
        cube([box_x-2*th+eps, box_y-2*th+eps, box_z-th+eps], false);
      }
    }
    // under_pcb, stoiki
    for (dy = [shift_y+shift_bolt, shift_y+pcb_y-shift_bolt]) {
      for (dx = [shift_x+shift_bolt, shift_x+pcb_x-shift_bolt]) {
//        translate([dx,dy,pcb_up/2+th-eps]) {
//          cube(size=[under_pcb,under_pcb,pcb_up], center=true);
//        }
        translate([dx,dy,th-eps]) {
          cylinder($fn=6, r=stoiki_r, h=pcb_up);
          cylinder($fn=6, r=wide_stoiki_r, h=gaika_h);
        }
      }
    }
    translate([box_x/2, box_y/2, th-eps]) {
      cylinder($fn=6, r=stoiki_r, h=pcb_up);
    }
  }

  // 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=th+pcb_up+2*eps);
        // gaika
        cylinder($fn=6, r=gaika_w / 2 / cos(30) + 0.05, h=gaika_h);
      }
    }
  }

//    for (i = [0:1:socket_n-1]) {
//        translate([start_socket_x+i*socket_int-tol, box_y-th-eps, start_socket_z]) {
//            cube(size=[socket_w+2*tol, th+2*eps, box_z]);
//        }
//    }

//    // 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, box_z]);
//    }

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

    // programmator
    translate([micro_start_x-tol,micro_start_y-tol, -eps]) {
      cube(size=[micro_x+2*tol, micro_y+2*tol, th+2*eps]);
    }

    // contrast
    translate([contrast_start_x, contrast_start_y, -eps]) {
      cylinder($fn=fn, r=pot_d/2, h=th+2*eps);
    }

    // volume
//    translate([volume_start_x, volume_start_y, -eps]) {
//      cylinder($fn=20, r=pot_d/2, h=th+2*eps);
//    }
}
}

top_box_z = 15 + th;
stoiki_h = top_box_z - th;
wide_stoiki_h = 2;
pcb_room = 0.5;
screen_start_x = shift_x + 28;
screen_start_y = shift_y + 40;
screen_length_x = 72;
screen_length_y = 24;
screen_hold_x = 40;
screen_hold_y = 4;
screen_hold_start_z = 12;
screen_hold_y_shift = 2;
screen_hold_up_x = 25;
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 = 3;
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() {
    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=top_bolt_r, h=top_bolt_h + eps);
      }
    }
  }

  // screen
  translate([screen_start_x, screen_start_y, top_box_z - th - eps]) {
      cube([screen_length_x, screen_length_y + 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]) {
	  cube(size=[socket_w+2*tol, th+2*eps, socket_h]);
      }
  }
  // type_b
  translate([box_x - th - eps, start_type_b_y - tol, -tol]) {
      cube([th + 2*eps, usb_type_b_w + 2*tol, usb_type_b_h + 2*tol]);
  }
  // type_a
  translate([-eps, start_type_a_y, -eps]) {
      cube([th + 2*eps, usb_type_a_w+eps, usb_type_a_h+2*eps]);
  }
  // master buttons
  for (i = [0:1:2]) {
    dx = master_button_x + master_button_int*i;
    translate([dx, 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.5;
pcb_x = 130;
pcb_y = 110;
pcb_z = 4;
bolt_d = 3.6;
shift_bolt = 5;

// box thickness
th = 2;

shift_x = 4;
shift_y = th + 1;

box_x = pcb_x + shift_x + 4;
box_y = pcb_y + shift_y + th;

pcb_width = 2;
pcb_up = 9;

box_z = th + pcb_up + pcb_width - 1;

socket_h = 15;
socket_w = 10;
socket_n = 5;
socket_int = 20;
start_socket_x = 20 + shift_x;
start_socket_z = th + pcb_z + tol;
eps = 1e-1;

usb_type_b_w = 12;
usb_type_b_h = 11;
start_type_b_y = shift_y + 81.5;
//start_type_b_z = th + pcb_z + tol;

usb_type_a_w = 13.4;
usb_type_a_h = 7.3;
start_type_a_y = shift_y + 47;
//start_type_a_z = th + pcb_z + 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.6;
stoiki_r = 4;
wide_stoiki_r = stoiki_r + 2;

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

difference() {
  union() {
    difference() {
      cube([box_x,box_y,box_z], false);
      translate([th, th, th]) {
        cube([box_x-2*th+eps, box_y-2*th+eps, box_z-th+eps], false);
      }
    }
    // under_pcb, 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_up/2+th-eps]) {
//          cube(size=[under_pcb,under_pcb,pcb_up], center=true);
//        }
        translate([dx,dy,th-eps]) {
          cylinder($fn=6, r=stoiki_r, h=pcb_up);
          cylinder($fn=6, r=wide_stoiki_r, h=gaika_h);
        }
      }
    }
  }

  // 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=th+pcb_up+2*eps);
        // gaika
        cylinder($fn=6, r=gaika_w / 2 / cos(30) + 0.05, h=gaika_h);
      }
    }
  }

//    for (i = [0:1:socket_n-1]) {
//        translate([start_socket_x+i*socket_int-tol, box_y-th-eps, start_socket_z]) {
//            cube(size=[socket_w+2*tol, th+2*eps, box_z]);
//        }
//    }

//    // 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, box_z]);
//    }

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

    // programmator
    translate([micro_start_x-tol,micro_start_y-tol, -eps]) {
      cube(size=[micro_x+2*tol, micro_y+2*tol, th+2*eps]);
    }

    // contrast
    translate([contrast_start_x, contrast_start_y, -eps]) {
      cylinder($fn=fn, r=pot_d/2, h=th+2*eps);
    }

    // volume
//    translate([volume_start_x, volume_start_y, -eps]) {
//      cylinder($fn=20, r=pot_d/2, h=th+2*eps);
//    }
}
}

top_box_z = 17 + th;
stoiki_h = top_box_z - th;
wide_stoiki_h = 2;
pcb_room = 0.5;
screen_start_x = shift_x + 28;
screen_start_y = shift_y + 40;
screen_length_x = 72;
screen_length_y = 24;
screen_hold_x = 40;
screen_hold_y = 4;
screen_hold_start_z = 14;
screen_hold_y_shift = 2;
screen_hold_up_x = 25;
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 = 3;
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() {
    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=top_bolt_r, h=top_bolt_h + eps);
      }
    }
  }

  // screen
  translate([screen_start_x, screen_start_y, top_box_z - th - eps]) {
      cube([screen_length_x, screen_length_y + 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]) {
	  cube(size=[socket_w+2*tol, th+2*eps, socket_h+tol]);
      }
  }
  // type_b
  translate([box_x - th - eps, start_type_b_y - tol, -tol]) {
      cube([th + 2*eps, usb_type_b_w + 2*tol, usb_type_b_h + 2*tol]);
  }
  // type_a
  translate([-eps, start_type_a_y, -eps]) {
      cube([th + 2*eps, usb_type_a_w+eps, usb_type_a_h+2*eps]);
  }
  // master buttons
  for (dx = [master_button_x, master_button_x + master_button_int*2])
      translate([dx, 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);
//        }
//    }


minor

minor

include <printer.scad>;

$fn = 12; // 36
$detailed = false; // true
$display_projection = false;

rotate([90,0,0]) {
  printer(2);
}

include <printer.scad>;

$fn = 12; // 36
$detailed = false; // true
$display_projection = true;

rotate([90,0,0]) {
  printer(2);
}


xaxis/ends: tweaks

xaxis/ends: tweaks

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

include <config.scad>
include <thing_libutils/misc.scad>
include <thing_libutils/bearing.scad>
use <thing_libutils/metric-screw.scad>

motor_mount_wall_thick = xaxis_pulley[1] - xaxis_pulley[0]/2 + 4*mm;
xaxis_end_motorsize = lookup(NemaSideSize,xaxis_motor);
xaxis_end_motor_offset=[xaxis_end_motorsize/2+9*mm,motor_mount_wall_thick-2*mm,0];
xaxis_end_wz = xaxis_rod_distance+xaxis_bearing[2]+5*mm;

module xaxis_end_body(with_motor, nut_top=false)
{
    x_side = with_motor?1:-1;
    nut_h = zaxis_nut[4];
    wx = zaxis_bearing[1]/2+zaxis_nut[1];
    wx_ = with_motor? xaxis_end_motorsize+xaxis_end_motor_offset[0] - xaxis_end_motorsize/2 : wx;

    /*%cuberounda([wx_, xaxis_rod_d*2, xaxis_end_wz], rounding_radius=3, align=[with_motor?1:-1,0,0]);*/

    if(with_motor)
    translate(xaxis_end_motor_offset)
    cuberounda([xaxis_end_motorsize, motor_mount_wall_thick, xaxis_end_motorsize], rounding_radius=3, align=[0,-1,0]);

    // nut mount
    mirror([0,0,nut_top?1:0])
    translate([x_side*zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2])
    {
        union()
        {
            fncylindera(h=zaxis_nut[4], d=zaxis_nut[1], align=[0,0,1]);

            // lead screw
            // ensure some support for the leadscrew cutout all the way to the top
            /*fncylindera(h=xaxis_end_wz, d=zaxis_nut[2]*2, align=[0,0,1]);*/
        }
    }

    // x axis rod holders
    for(z=[-1,1])
    translate([0,0,z*(xaxis_rod_distance/2)])
        fncylindera(h=wx_,d=xaxis_rod_d+5*mm, orient=[1,0,0], align=[x_side,0,0]);

    // support around z axis bearings
    translate([0, -xaxis_zaxis_distance_y, 0])
    {
        difference()
        {
            sizey= zaxis_bearing[1]+10*mm;
            fncylindera(h=xaxis_end_wz,d=sizey, orient=[0,0,1], align=[0,0,0]);
            translate([0,0,.1])
            cubea([sizey/2+.1, sizey+.2, xaxis_end_wz+.4], orient=[0,0,1], align=[-x_side,0,0]);
        }
    }
}

module xaxis_end(with_motor=false, show_motor=false, nut_top=false, show_nut=false, show_rods=false)
{
    x_side = with_motor?1:-1;
    nut_h = zaxis_nut[4];
    wx = zaxis_bearing[1]/2+zaxis_nut[1];
    wx_ = with_motor? xaxis_end_motorsize+xaxis_end_motor_offset[0] - xaxis_end_motorsize/2 : wx;
    xaxis_end_wz = xaxis_rod_distance+xaxis_bearing[2]+5*mm;
    difference()
    {
        extrasize = with_motor?0*mm:0*mm;
        extrasize_align = with_motor?-1:1;

        hull()
        {
            xaxis_end_body(with_motor, nut_top);

            // projection against z, ensure easy print
            translate([0,0,-xaxis_end_wz/2])
                linear_extrude(1)
                projection(cut=false)
                xaxis_end_body(with_motor);
        }

        xaxis_end_beltpath();

        // z smooth bearing mounts
        for(z=[-1,1])
            translate([0,0,z*xaxis_rod_distance/2])
                translate([0, -xaxis_zaxis_distance_y, 0])
                bearing_mount_holes(
                        zaxis_bearing,
                        ziptie_type,
                        ziptie_bearing_distance,
                        orient=[0,0,1],
                        show_zips=false
                );

        // x smooth rods
        for(z=[-1,1])
            translate([0,0,z*(xaxis_rod_distance/2)])
                fncylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=[1,0,0]);

        if(with_motor)
        {
            screw_dist = lookup(NemaDistanceBetweenMountingHoles, xaxis_motor);

            // axle
            translate(xaxis_end_motor_offset)
            {
                round_d=1.1*lookup(NemaRoundExtrusionDiameter, xaxis_motor);
                translate([0, .1, 0])
                translate([0,1,0])

                fncylindera(d=round_d, h=motor_mount_wall_thick, orient=[0,1,0], align=[0,1,0]);
                rotate([0,45,0])
                difference()
                {
                    cubea([round_d, motor_mount_wall_thick, round_d], align=[0,-1,0]);

                    cubea([round_d, motor_mount_wall_thick, round_d/2], align=[0,-1,-1]);
                    cubea([round_d/2, motor_mount_wall_thick, round_d], align=[1,-1,0]);
                }

                // motor axle
                translate([0, .1, 0])
                fncylindera(d=1.2*lookup(NemaAxleDiameter, xaxis_motor), h=lookup(NemaFrontAxleLength, xaxis_motor)+3*mm, orient=[0,1,0], align=[0,1,0]);

                // bearing for offloading force on motor shaft
                translate([0, -2.5*mm-xaxis_pulley[1]-.1, 0])
                scale(1.03)
                bearing(bearing_MR105, override_h=6*mm, orient=[0,1,0], align=[0,-1,0]);

                xaxis_motor_thread=ThreadM3;
                xaxis_motor_nut=MHexNutM3;
                for(x=[-1,1])
                for(z=[-1,1])
                translate([x*screw_dist/2, -motor_mount_wall_thick, z*screw_dist/2])
                {
                    screw_cut(xaxis_motor_nut, h=motor_mount_wall_thick, with_nut=false, orient=[0,1,0], align=[0,1,0]);
                }
            }

        }

        // nut mount
        mirror([0,0,nut_top?1:0])
        translate([x_side*zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2])
        {
            union()
            {
                translate([0,0,-.1])
                {
                    // nut
                    fncylindera(h=nut_h+1, d=zaxis_nut[0]*1.05, align=[0,0,1]);

                    // lead screw
                    translate([0,0,-.1])
                    fncylindera(h=xaxis_end_wz+1, d=zaxis_nut[2]*1.5, align=[0,0,1]);

                    for(i=[-1,1])
                        translate([i*13.5, 0, 0])
                            fncylindera(h=5, r=1.6, align=[0,0,1]);
                }
            }
        }
    }

    if(with_motor && show_motor)
    {
            /*translate([0,5,0])*/
        translate(xaxis_end_motor_offset)
        {
            /*translate([0,-motor_mount_wall_thick,0])*/
            /*translate([0,-5,0])*/
            /*translate([0,-xaxis_pulley[0]/2,0])*/

            // 1mm due to motor offset
            translate([0,-1*mm,0])
            {
                // 1mm between pulley and motor
                /*translate([0,-1*mm,0])*/
                    /*pulley(xaxis_pulley, flip=false, orient=[0,1,0], align=[0,-1,0]);*/
                /*motor(xaxis_motor, NemaMedium, dualAxis=false, orientation=[-90,0,0]);*/
            }
        }
    }

    %if(show_nut)
    {
        mirror([0,0,nut_top?1:0])
        translate([x_side*zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2-zaxis_nut[3]])
        xaxis_end_znut();
    }

    %if(show_rods)
    {
        for(z=[-1,1])
            translate([0,0,z*xaxis_rod_distance/2])
            translate([0, -xaxis_zaxis_distance_y, 0])
            fncylindera(d=zaxis_rod_d, h=zaxis_rod_l, orient=[0,0,1]);
    }
}

xaxis_end_beltpath_height = xaxis_pulley_inner_d+5*mm;
xaxis_end_beltpath_width = max(belt_width+3*mm, xaxis_pulley[0]+3*mm);

module xaxis_end_beltpath(xaxis_end_beltpath_length=1000)
{
    diag = pythag_hyp(xaxis_end_beltpath_width,xaxis_end_beltpath_width)/2;

    /*cubea([xaxis_end_beltpath_length, xaxis_end_beltpath_width, xaxis_end_beltpath_height+diag/2]);*/

    hull()
    for(z=[-1,1])
    translate([0,0,z*xaxis_end_beltpath_height/2])
    translate([-diag/2,0,0])
    translate([diag/2,0,0])
    rotate([z*-45,0,0])
    cubea([xaxis_end_beltpath_length, diag, diag]);
}

module xaxis_end_idlerholder(xaxis_end_beltpath_length=10)
{
    diag = pythag_hyp(xaxis_end_beltpath_width,xaxis_end_beltpath_width)/2;

    difference()
    {
        union()
        {
            cubea([10*mm, xaxis_end_beltpath_width/sqrt(2), xaxis_rod_distance], align=[1,0,0]);

            translate([10*mm, 0,0])
                cubea([15*mm, xaxis_idler_pulley[0]+8*mm, xaxis_rod_distance+xaxis_rod_d*2], align=[1,0,0]);
        }

        // x smooth rods
        for(z=[-1,1])
            translate([0,0,z*(xaxis_rod_distance/2)])
                fncylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=[1,0,0]);

        translate([20,0,0])
            pulley(xaxis_idler_pulley, orient=[0,1,0]);

        translate([10*mm+15*mm/2,0,0])
        fncylindera(d=lookup(ThreadSize, ThreadM5), h=100, orient=[0,1,0]);

        xaxis_end_beltpath();
    }
}

module xaxis_end_znut()
{
    difference()
    {
        union()
        {
            fncylindera(d=zaxis_nut[1], h=zaxis_nut[3], orient=[0,0,1], align=[0,0,1]);
            fncylindera(d=zaxis_nut[0], h=zaxis_nut[4], orient=[0,0,1], align=[0,0,1]);
        }
        translate([0,0,-.1])
            fncylindera(d=zaxis_nut[2], h=zaxis_nut[4]+.2, orient=[0,0,1], align=[0,0,1]);
    }
}

if(false)
{
    // x smooth rods
    for(z=[-1,1])
        translate([0,0,z*(xaxis_rod_distance/2)])
            %fncylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=[1,0,0]);

    xaxis_end(with_motor=true, show_motor=false, nut_top=false, show_nut=true, show_rods=true);

    translate([150,0,0])
    {
        xaxis_end(with_motor=false, show_motor=true, nut_top=false, show_nut=true, show_rods=true);
        xaxis_end_idlerholder();
    }
}

if(false)
{
    translate([0,0,xaxis_end_wz/2])
    xaxis_end(with_motor=true, show_motor=true, show_nut=false);

    /*translate([100,0,xaxis_end_wz/2])*/
    /*xaxis_end(with_motor=false, show_nut=false);*/

    /*translate([50,30,25])*/
        /*rotate([0,90,0])*/
        /*xaxis_end_idlerholder();*/
}

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

include <config.scad>
include <thing_libutils/misc.scad>
include <thing_libutils/bearing.scad>
use <thing_libutils/metric-screw.scad>

motor_mount_wall_thick = xaxis_pulley[1] - xaxis_pulley[0]/2 + 4*mm;
xaxis_end_motorsize = lookup(NemaSideSize,xaxis_motor);
xaxis_end_motor_offset=[xaxis_end_motorsize/2+9*mm,motor_mount_wall_thick-2*mm,0];
xaxis_end_wz = xaxis_rod_distance+xaxis_bearing[2]+5*mm;

module xaxis_end_body(with_motor, nut_top=false)
{
    x_side = with_motor?1:-1;
    nut_h = zaxis_nut[4];
    wx = zaxis_bearing[1]/2+zaxis_nut[1];
    wx_ = with_motor? xaxis_end_motorsize+xaxis_end_motor_offset[0] - xaxis_end_motorsize/2 : wx;

    /*%cuberounda([wx_, xaxis_rod_d*2, xaxis_end_wz], rounding_radius=3, align=[with_motor?1:-1,0,0]);*/

    if(with_motor)
    translate(xaxis_end_motor_offset)
    cuberounda([xaxis_end_motorsize, motor_mount_wall_thick, xaxis_end_motorsize], rounding_radius=3, align=[0,-1,0]);

    // nut mount
    mirror([0,0,nut_top?1:0])
    translate([x_side*zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2])
    {
        union()
        {
            fncylindera(h=zaxis_nut[4], d=zaxis_nut[1], align=[0,0,1]);

            // lead screw
            // ensure some support for the leadscrew cutout all the way to the top
            /*fncylindera(h=xaxis_end_wz, d=zaxis_nut[2]*2, align=[0,0,1]);*/
        }
    }

    // x axis rod holders
    for(z=[-1,1])
    translate([0,0,z*(xaxis_rod_distance/2)])
        fncylindera(h=wx_,d=xaxis_rod_d+5*mm, orient=[1,0,0], align=[x_side,0,0]);

    // support around z axis bearings
    translate([0, -xaxis_zaxis_distance_y, 0])
    {
        difference()
        {
            sizey= zaxis_bearing[1]+10*mm;
            fncylindera(h=xaxis_end_wz,d=sizey, orient=[0,0,1], align=[0,0,0]);
            translate([0,0,.1])
            cubea([sizey/2+.1, sizey+.2, xaxis_end_wz+.4], orient=[0,0,1], align=[-x_side,0,0]);
        }
    }
}

module xaxis_end(with_motor=false, show_motor=false, nut_top=false, show_nut=false, show_rods=false)
{
    x_side = with_motor?1:-1;
    nut_h = zaxis_nut[4];
    wx = zaxis_bearing[1]/2+zaxis_nut[1];
    wx_ = with_motor? xaxis_end_motorsize+xaxis_end_motor_offset[0] - xaxis_end_motorsize/2 : wx;
    xaxis_end_wz = xaxis_rod_distance+xaxis_bearing[2]+5*mm;
    difference()
    {
        extrasize = with_motor?0*mm:0*mm;
        extrasize_align = with_motor?-1:1;

        hull()
        {
            xaxis_end_body(with_motor, nut_top);

            // projection against z, ensure easy print
            translate([0,0,-xaxis_end_wz/2])
                linear_extrude(1)
                projection(cut=false)
                xaxis_end_body(with_motor);
        }

        xaxis_end_beltpath();

        // z smooth bearing mounts
        for(z=[-1,1])
            translate([0,0,z*xaxis_rod_distance/2])
                translate([0, -xaxis_zaxis_distance_y, 0])
                bearing_mount_holes(
                        zaxis_bearing,
                        ziptie_type,
                        ziptie_bearing_distance,
                        orient=[0,0,1],
                        show_zips=false
                );

        // x smooth rods
        for(z=[-1,1])
            translate([0,0,z*(xaxis_rod_distance/2)])
                fncylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=[1,0,0]);

        if(with_motor)
        {
            screw_dist = lookup(NemaDistanceBetweenMountingHoles, xaxis_motor);

            // axle
            translate(xaxis_end_motor_offset)
            {
                translate([0, .1, 0])
                translate([0,1,0])
                fncylindera(d=1.1*lookup(NemaRoundExtrusionDiameter, xaxis_motor), h=motor_mount_wall_thick, orient=[0,1,0], align=[0,1,0]);

                // motor axle
                translate([0, .1, 0])
                fncylindera(d=1.2*lookup(NemaAxleDiameter, xaxis_motor), h=lookup(NemaFrontAxleLength, xaxis_motor)+2*mm, orient=[0,1,0], align=[0,1,0]);

                // bearing for offloading force on motor shaft
                translate([0, -1*mm-xaxis_pulley[1]-.1, 0])
                scale(1.03)
                bearing(bearing_MR105, override_h=6*mm, orient=[0,1,0], align=[0,-1,0]);

                xaxis_motor_thread=ThreadM3;
                xaxis_motor_nut=MHexNutM3;
                for(x=[-1,1])
                for(z=[-1,1])
                translate([x*screw_dist/2, -motor_mount_wall_thick, z*screw_dist/2])
                {
                    screw_cut(xaxis_motor_nut, h=motor_mount_wall_thick, with_nut=false, orient=[0,1,0], align=[0,1,0]);
                }
            }

        }

        // nut mount
        mirror([0,0,nut_top?1:0])
        translate([x_side*zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2])
        {
            union()
            {
                translate([0,0,-.1])
                {
                    // nut
                    fncylindera(h=nut_h+1, d=zaxis_nut[0]*1.05, align=[0,0,1]);

                    // lead screw
                    translate([0,0,-.1])
                    fncylindera(h=xaxis_end_wz+1, d=zaxis_nut[2]*1.5, align=[0,0,1]);

                    for(i=[-1,1])
                        translate([i*13.5, 0, 0])
                            fncylindera(h=5, r=1.6, align=[0,0,1]);
                }
            }
        }
    }

    if(with_motor && show_motor)
    {
            /*translate([0,5,0])*/
        translate(xaxis_end_motor_offset)
        {
            /*translate([0,-motor_mount_wall_thick,0])*/
            /*translate([0,-5,0])*/
            /*translate([0,-xaxis_pulley[0]/2,0])*/

            // 1mm due to motor offset
            translate([0,-1*mm,0])
            {
                // 1mm between pulley and motor
                /*translate([0,-1*mm,0])*/
                    /*pulley(xaxis_pulley, flip=false, orient=[0,1,0], align=[0,-1,0]);*/
                /*motor(xaxis_motor, NemaMedium, dualAxis=false, orientation=[-90,0,0]);*/
            }
        }
    }

    %if(show_nut)
    {
        mirror([0,0,nut_top?1:0])
        translate([x_side*zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2-zaxis_nut[3]])
        xaxis_end_znut();
    }

    %if(show_rods)
    {
        for(z=[-1,1])
            translate([0,0,z*xaxis_rod_distance/2])
            translate([0, -xaxis_zaxis_distance_y, 0])
            fncylindera(d=zaxis_rod_d, h=zaxis_rod_l, orient=[0,0,1]);
    }
}

xaxis_end_beltpath_height = xaxis_pulley_inner_d+5*mm;
xaxis_end_beltpath_width = max(belt_width+3*mm, xaxis_pulley[0]+3*mm);

module xaxis_end_beltpath(xaxis_end_beltpath_length=1000)
{
    diag = pythag_hyp(xaxis_end_beltpath_width,xaxis_end_beltpath_width)/2;

    hull()
    for(z=[-1,1])
    translate([0,0,z*xaxis_end_beltpath_height/2])
    translate([-diag/2,0,0])
    translate([diag/2,0,0])
    rotate([z*-45,0,0])
    cubea([xaxis_end_beltpath_length, diag, diag]);
}

module xaxis_end_idlerholder(xaxis_end_beltpath_length=10)
{
    diag = pythag_hyp(xaxis_end_beltpath_width,xaxis_end_beltpath_width)/2;

    difference()
    {
        union()
        {
            cubea([10*mm, xaxis_end_beltpath_width/sqrt(2), xaxis_rod_distance], align=[1,0,0]);

            translate([10*mm, 0,0])
                cubea([15*mm, xaxis_idler_pulley[0]+8*mm, xaxis_rod_distance+xaxis_rod_d*2], align=[1,0,0]);
        }

        // x smooth rods
        for(z=[-1,1])
            translate([0,0,z*(xaxis_rod_distance/2)])
                fncylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=[1,0,0]);

        translate([20,0,0])
            pulley(xaxis_idler_pulley, orient=[0,1,0]);

        translate([10*mm+15*mm/2,0,0])
        fncylindera(d=lookup(ThreadSize, ThreadM5), h=100, orient=[0,1,0]);

        xaxis_end_beltpath();
    }
}

module xaxis_end_znut()
{
    difference()
    {
        union()
        {
            fncylindera(d=zaxis_nut[1], h=zaxis_nut[3], orient=[0,0,1], align=[0,0,1]);
            fncylindera(d=zaxis_nut[0], h=zaxis_nut[4], orient=[0,0,1], align=[0,0,1]);
        }
        translate([0,0,-.1])
            fncylindera(d=zaxis_nut[2], h=zaxis_nut[4]+.2, orient=[0,0,1], align=[0,0,1]);
    }
}

/*if(false)*/
{
    // x smooth rods
    for(z=[-1,1])
        translate([0,0,z*(xaxis_rod_distance/2)])
            %fncylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=[1,0,0]);

    xaxis_end(with_motor=true, show_motor=false, nut_top=false, show_nut=true, show_rods=true);

    translate([150,0,0])
    {
        xaxis_end(with_motor=false, show_motor=true, nut_top=false, show_nut=true, show_rods=true);
        xaxis_end_idlerholder();
    }
}

if(false)
{
    translate([0,0,xaxis_end_wz/2])
    xaxis_end(with_motor=true, show_motor=true, show_nut=false);

    translate([100,0,xaxis_end_wz/2])
    xaxis_end(with_motor=false, show_nut=false);

    /*translate([50,30,25])*/
        /*rotate([0,90,0])*/
        /*xaxis_end_idlerholder();*/
}