added openscad file for lens cover

added openscad file for lens cover

render stl, slice it and print it

/**
 *    Lamax x6 -- lens cover
 *
 *    @author        Karel Fiala
 *    @email         fiala.karel@gmail.com
 */

$fn=300;

module lamax_x6_lens_cover() {

    width = 21/2;
    heigh = 10;
    wall = 0.7;
    space = 0.3;

    inner = width + space;
    outer = inner + wall;

    difference() {
        translate([0, 0, -0.7]) cylinder(r1=outer, r2=outer, h=heigh + wall, center = true);
        cylinder(r1=inner, r2=inner, h=heigh + wall, center = true);
    }

}

// calling
lamax_x6_lens_cover();

error: pathspec 'improvements/lens-cover.scad' did not match any file(s) known to git


main: use fncylindera orient param

main: use fncylindera orient param

include <thing_libutils/metric-thread.scad>;
include <thing_libutils/metric-hexnut.scad>;
use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
use <thing_libutils/attach.scad>;
use <thing_libutils/triangles.scad>
use <thing_libutils/linear-extrusion.scad>;

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

include <config.scad>
include <extruder-direct.scad>

xaxis_pos_x = -225/2*mm;
xaxis_range_z=[85,350];
xaxis_pos_z = 350*mm;

main();

module main()
{
    color(extrusion_color)
    gantry_lower();

    color(extrusion_color)
    translate([0,0,-main_lower_dist_z])
    gantry_lower();

    color(extrusion_color)
    for(i=[-1,1])
    translate([0,i*(main_upper_dist_y/2),0])
    gantry_upper();

    // x axis
    translate([0,0,xaxis_pos_z])
    {
        translate([xaxis_pos_x,0,0])
        {
            xaxis_bearing_dist = 10;
            translate([0,xaxis_zaxis_distance_y,0])
            translate([0,xaxis_bearing[1]/2,0])
            cubea([xaxis_bearing[2]*2+xaxis_bearing_dist,5,xaxis_rod_distance+xaxis_bearing[1]], align=[0,1,0]);

            attach([[-8,-15,-16],[-1,0,0]],extruder_conn_xcarriage)
                extruder();

            // x carriage
            for(i=[-1,1])
                for(j=[-1,1])
                    translate([j*(xaxis_bearing_dist+xaxis_bearing[2])/2,xaxis_zaxis_distance_y,i*(xaxis_rod_distance/2)])
                        rotate([0,90,0])
                        bearing(xaxis_bearing);
        }

        // x smooth rods
        for(i=[-1,1])
            translate([0,xaxis_zaxis_distance_y,i*(xaxis_rod_distance/2)])
                rotate([0,90,0])
                fncylindera(h=xaxis_rod_l,d=xaxis_rod_d);
    }

    // y smooth rods
    for(i=[-1,1])
    translate([i*(yaxis_rod_distance/2),0,0])
    {
        rotate([90,0,0])
            fncylindera(h=yaxis_rod_l,d=yaxis_rod_d, align=[0,1,0]);
    }

    translate([0,0,yaxis_rod_d])
        cubea(ycarriage_size, align=[0,0,1]);

    // z axis
    for(i=[-1,1])
    translate([i*(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, zaxis_motor_offset_z])
    {
        mirror([i==-1?1:0,0,0])
        {
            zmotor_mount();

            attach([[0,0,0],[0,0,0]],zmotor_mount_conn_motor)
            {
                // z motor/leadscrews
                motor(zaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);
            }
        }

        // z smooth rods
        translate([i*zaxis_rod_screw_distance_x/2+zmotor_mount_motor_offset,0,0])
        {
            fncylindera(h=zaxis_rod_l,d=zaxis_rod_d,align=[0,0,1]);

            translate([0,0,xaxis_pos_z-zaxis_motor_offset_z])
                fncylindera(h=zaxis_bearing[2], d=zaxis_bearing[1], align=[0,0,0]);
        }
    }
}

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

module zmotor_mount()
{
    motor_w = lookup(NemaSideSize,zaxis_motor);

    mount_thickness = 5;
    mount_thickness_h = 8;
    mount_thread_dia = lookup(ThreadSize, extrusion_thread);
    mount_width = motor_w+mount_thickness*2 + mount_thread_dia*8;
    mount_h = main_lower_dist_z+extrusion_size+zaxis_motor_offset_z;

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

        translate([0, i*((motor_w/2)+mount_thickness/2), 0])
        cubea([mount_thickness, mount_thickness, mount_h], align=[1,0,-1]);
    }

    // top mount plate
    difference()
    {
        translate([-motor_w/2,0,-extrusion_size-zaxis_motor_offset_z])
            cubea([mount_thickness, mount_width, extrusion_size], align=[1,0,1]);

        for(i=[-1,1])
            translate([-motor_w/2,i*(motor_w/2+mount_thread_dia*3),-extrusion_size])
                fncylindera(h=mount_thickness*3,d=mount_thread_dia, orient=[1,0,0]);
    }

    // bottom mount plate
    difference()
    {
        translate([-motor_w/2,0,-main_lower_dist_z-extrusion_size-zaxis_motor_offset_z])
            cubea([mount_thickness, mount_width, extrusion_size], align=[1,0,1]);

        for(i=[-1,1])
            translate([-motor_w/2,i*(motor_w/2+mount_thread_dia*3),-extrusion_size-main_lower_dist_z])
                fncylindera(h=mount_thickness*3,d=mount_thread_dia,align=[0,0,0], orient=[1,0,0]);
    }

/*#    cubea([motor_w+mount_thickness,motor_w+mount_thickness,zaxis_motor_offset_z], align=[0,0,-1]);*/

    // top plate
    difference()
    {
        cubea([motor_w, motor_w+mount_thickness*2, mount_thickness_h], align=[0,0,1], extrasize=[5,0,0], extrasize_align=[1,0,0]);

        translate([zmotor_mount_motor_offset,0,-1])
        linear_extrude(mount_thickness_h+2)
        stepper_motor_mount(17, slide_distance=0, mochup=false);
    }
}

module gantry_upper()
{
    for(i=[-1,1])
    translate([i*(main_width/2), 0])
    linear_extrusion(h=main_height, align=[-i,0,1], orient=[0,0,1]);

    translate([0, 0, main_height])
    linear_extrusion(h=main_upper_width, align=[0,0,1], orient=[1,0,0]);
}

module gantry_lower()
{
    for(i=[-1,1])
    translate([0,  i*(main_depth/2), 0])
    linear_extrusion(h=main_width, align=[0,i,-1], orient=[1,0,0]);

    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    linear_extrusion(h=main_depth, align=[-i,0,-1], orient=[0,1,0]);
}

include <thing_libutils/metric-thread.scad>;
include <thing_libutils/metric-hexnut.scad>;
use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
use <thing_libutils/attach.scad>;
use <thing_libutils/triangles.scad>
use <thing_libutils/linear-extrusion.scad>;

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

include <config.scad>
include <extruder-direct.scad>

xaxis_pos_x = -225/2*mm;
xaxis_range_z=[85,350];
xaxis_pos_z = 350*mm;

main();

module main()
{
    color(extrusion_color)
    gantry_lower();

    color(extrusion_color)
    translate([0,0,-main_lower_dist_z])
    gantry_lower();

    color(extrusion_color)
    for(i=[-1,1])
    translate([0,i*(main_upper_dist_y/2),0])
    gantry_upper();

    // x axis
    translate([0,0,xaxis_pos_z])
    {
        translate([xaxis_pos_x,0,0])
        {
            xaxis_bearing_dist = 10;
            translate([0,xaxis_zaxis_distance_y,0])
            translate([0,xaxis_bearing[1]/2,0])
            cubea([xaxis_bearing[2]*2+xaxis_bearing_dist,5,xaxis_rod_distance+xaxis_bearing[1]], align=[0,1,0]);

            attach([[-8,-15,-16],[-1,0,0]],extruder_conn_xcarriage)
                extruder();

            // x carriage
            for(i=[-1,1])
                for(j=[-1,1])
                    translate([j*(xaxis_bearing_dist+xaxis_bearing[2])/2,xaxis_zaxis_distance_y,i*(xaxis_rod_distance/2)])
                        rotate([0,90,0])
                        bearing(xaxis_bearing);
        }

        // x smooth rods
        for(i=[-1,1])
            translate([0,xaxis_zaxis_distance_y,i*(xaxis_rod_distance/2)])
                rotate([0,90,0])
                fncylindera(h=xaxis_rod_l,d=xaxis_rod_d);
    }

    // y smooth rods
    for(i=[-1,1])
    translate([i*(yaxis_rod_distance/2),0,0])
    {
        rotate([90,0,0])
            fncylindera(h=yaxis_rod_l,d=yaxis_rod_d, align=[0,1,0]);
    }

    translate([0,0,yaxis_rod_d])
        cubea(ycarriage_size, align=[0,0,1]);

    // z axis
    for(i=[-1,1])
    translate([i*(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, zaxis_motor_offset_z])
    {
        mirror([i==-1?1:0,0,0])
        {
            zmotor_mount();

            attach([[0,0,0],[0,0,0]],zmotor_mount_conn_motor)
            {
                // z motor/leadscrews
                motor(zaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);
            }
        }

        // z smooth rods
        translate([i*zaxis_rod_screw_distance_x/2+zmotor_mount_motor_offset,0,0])
        {
            fncylindera(h=zaxis_rod_l,d=zaxis_rod_d,align=[0,0,1]);

            translate([0,0,xaxis_pos_z-zaxis_motor_offset_z])
                fncylindera(h=zaxis_bearing[2], d=zaxis_bearing[1], align=[0,0,0]);
        }
    }
}

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

module zmotor_mount()
{
    motor_w = lookup(NemaSideSize,zaxis_motor);

    mount_thickness = 5;
    mount_thickness_h = 8;
    mount_thread_dia = lookup(ThreadSize, extrusion_thread);
    mount_width = motor_w+mount_thickness*2 + mount_thread_dia*8;
    mount_h = main_lower_dist_z+extrusion_size+zaxis_motor_offset_z;

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

        translate([0, i*((motor_w/2)+mount_thickness/2), 0])
        cubea([mount_thickness, mount_thickness, mount_h], align=[1,0,-1]);
    }

    // top mount plate
    difference()
    {
        translate([-motor_w/2,0,-extrusion_size-zaxis_motor_offset_z])
            cubea([mount_thickness, mount_width, extrusion_size], align=[1,0,1]);

        for(i=[-1,1])
            translate([-motor_w/2,i*(motor_w/2+mount_thread_dia*3),-extrusion_size])
                rotate([0,90,0])
                    fncylindera(h=mount_thickness*3,d=mount_thread_dia);
    }

    // bottom mount plate
    difference()
    {
        translate([-motor_w/2,0,-main_lower_dist_z-extrusion_size-zaxis_motor_offset_z])
            cubea([mount_thickness, mount_width, extrusion_size], align=[1,0,1]);

        for(i=[-1,1])
            translate([-motor_w/2,i*(motor_w/2+mount_thread_dia*3),-extrusion_size-main_lower_dist_z])
                rotate([0,90,0])
                fncylindera(h=mount_thickness*3,d=mount_thread_dia);
    }

/*#    cubea([motor_w+mount_thickness,motor_w+mount_thickness,zaxis_motor_offset_z], align=[0,0,-1]);*/

    // top plate
    difference()
    {
        cubea([motor_w, motor_w+mount_thickness*2, mount_thickness_h], align=[0,0,1], extrasize=[5,0,0], extrasize_align=[1,0,0]);

        translate([zmotor_mount_motor_offset,0,-1])
        linear_extrude(mount_thickness_h+2)
        stepper_motor_mount(17, slide_distance=0, mochup=false);
    }
}

module gantry_upper()
{
    for(i=[-1,1])
    translate([i*(main_width/2), 0])
    linear_extrusion(h=main_height, align=[-i,0,1], orient=[0,0,1]);

    translate([0, 0, main_height])
    linear_extrusion(h=main_upper_width, align=[0,0,1], orient=[1,0,0]);
}

module gantry_lower()
{
    for(i=[-1,1])
    translate([0,  i*(main_depth/2), 0])
    linear_extrusion(h=main_width, align=[0,i,-1], orient=[1,0,0]);

    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    linear_extrusion(h=main_depth, align=[-i,0,-1], orient=[0,1,0]);
}


Add some components to the ArduinoPro

Add some components to the ArduinoPro

- Approximate locations; only main components shown

/*
    Vitamin: ArduinoPro
    Model of an Arduino Pro Mini/Micro

    Derived from: https://github.com/sparkfun/Pro_Micro/
                     and: https://github.com/sparkfun/Arduino_Pro_Mini_328/

    Authors:
        Jamie Osborne (@jmeosbn)

    Local Frame:
        Point of origin is the centre of the bottom left pin (9)

    Parameters:
        type: can be "mini", or "micro";
                    otherwise returns a blank board with header pin holes

    Returns:
        Model of an Arduino Pro Mini/Micro with header holes
*/

// ArduinoPro Model Variants
ArduinoPro_Mini             = 1;            // default
ArduinoPro_Micro            = 2;

// ArduinoPro Without Programming Port
ArduinoPro_No_Port          = 0;

// Show Header Pins
ArduinoPro_Pins_Normal      = 1;
ArduinoPro_Pins_Opposite    = 2;

// ArduinoPro Without Header Pins
ArduinoPro_No_Pins          = 0;            // default

// ArduinoPro PCB Variables
ArduinoPro_PCB_Pitch    = 2.54;                         // spacing of the holes
ArduinoPro_PCB_Inset    = ArduinoPro_PCB_Pitch /2;      // inset from board edge
ArduinoPro_PCB_Type     = 0.047 * 25.4; // .047 .063    // standard PCB thickness
ArduinoPro_PCB_Layers   = 0.035 * 2;                    // total copper layer thickness
ArduinoPro_PCB_Height   = ArduinoPro_PCB_Type +
                          ArduinoPro_PCB_Layers;        // height of the PCB (along z)
ArduinoPro_PCB_Length   = 1.3 * 25.4;                   // length of the PCB (along y)
ArduinoPro_PCB_Width    = 0.7 * 25.4;                   //  width of the PCB (along x)
ArduinoPro_PCB_Colour   = [26/255, 90/255, 160/255];    // colour of solder mask

// Show board clearance area for components
ArduinoPro_PCB_Clearance      = 3;
ArduinoPro_PCB_Clearance_Show = true;

module ArduinoPro_MicroUSB() {
    include <MicroUSB.scad>
    // Subtracting `ArduinoPro_PCB_Inset` compansates for board origin
    //-: Not sure if board origin would be better set after creation
    move_x  = ArduinoPro_PCB_Width / 2 - ArduinoPro_PCB_Inset;
    move_y  = ArduinoPro_PCB_Length - ArduinoPro_PCB_Inset;
    move_z  = ArduinoPro_PCB_Height;

    // Add USB header and move to top of board (along x)
    translate([move_x, move_y, move_z])
        MicroUSB_Receptacle();
}

module ArduinoPro_PCB() {
    // Bare PCB, origin through location for bottom left hole
    translate([-ArduinoPro_PCB_Inset, -ArduinoPro_PCB_Inset, 0])
        square(size = [ArduinoPro_PCB_Width, ArduinoPro_PCB_Length]);
}

module ArduinoPro_Header_Hole() {
    // Standard PCB hole
    holediameter        = 1.25;         // diameter of PCB hole
    circle(d = holediameter);
}

module ArduinoPro_Header_Pin() {
    // Standard PCB header pin
    pcbholepitch        = 2.54;         // spacing of PCB holes
    holediameter        = 1.25;         // diameter of PCB hole
    pinheight           =   11;         // length of PCB pins
    pinoffset           =    3;         // offset of PCB pins
    pinwidth            = 0.63;         // width/gauge of PCB pins
    spacerwidth         = 2.25;         // height of breakaway pin frame
    spacerheight        = 2.54;         // height of breakaway pin frame

    // Header Pins
    color("white")
    translate([0, 0, -pinoffset])
    linear_extrude(pinheight)
        square(pinwidth, center = true);

    // Pin Spacers
    color("black")
    linear_extrude(spacerheight)
        square(spacerwidth, center = true);

    // Break-Away Material
    color("black")
    translate([0, pcbholepitch/2, 0])
    linear_extrude(spacerheight)
        square([spacerwidth * 0.85, pcbholepitch - spacerwidth], center = true);
}

module ArduinoPro_Headers_Layout() {
    // distance between the two header rows
    // FIXME: improve this to be a multiple of 0.1 inch
    rowpitch  = ArduinoPro_PCB_Width - ArduinoPro_PCB_Inset*2;
    // length for holes, leaving room for end header and insets
    rowlength = ArduinoPro_PCB_Length - ArduinoPro_PCB_Pitch - ArduinoPro_PCB_Inset*2;

    // Add headers to either side (along y)
    for (x = [0, rowpitch], y = [0 : ArduinoPro_PCB_Pitch : rowlength]) {
        translate([x, y, 0]) children();
    }
}

module ArduinoPro_Serial_Header_Layout() {
    // y position for header
    header_y = ArduinoPro_PCB_Length - ArduinoPro_PCB_Inset*2;
    // width for holes, leaving room for insets
    rowwidth = ArduinoPro_PCB_Width - ArduinoPro_PCB_Inset*2;

    // Add serial header along top of board (along x)
    for (x = [ArduinoPro_PCB_Inset : ArduinoPro_PCB_Pitch : rowwidth]) {
        translate([x, header_y, 0]) children();
    }
}

module ArduinoPro(type = ArduinoPro_Mini, headerpins = 0, serialpins = 0) {
    color(ArduinoPro_PCB_Colour)
    linear_extrude(height=ArduinoPro_PCB_Height)
    difference() {
        // Base PCB
        ArduinoPro_PCB();

        // Common Headers for Pro Mini/Micro
        ArduinoPro_Headers_Layout()
            ArduinoPro_Header_Hole();

        // Pro Mini Serial Header
        if (type == ArduinoPro_Mini) {
            ArduinoPro_Serial_Header_Layout()
                ArduinoPro_Header_Hole();
        }
    }

    // Distance to middle from origin
    moveX = ArduinoPro_PCB_Width/2 - ArduinoPro_PCB_Inset;

    // Controller IC
    color(Grey20)
    translate([moveX, 0.5*25.4, ArduinoPro_PCB_Height])
    rotate([0,0,45])
    linear_extrude(height=1)
      square(2*sqrt(.4*25.4), center=true);

    // Reset switch (or crystal for Pro Micro)
    color("silver")
    translate([moveX, 0.15*25.4, ArduinoPro_PCB_Height])
    linear_extrude(height=1)
        square([5, 3.5], center=true);

    // Capacitors
    moveY = (type == ArduinoPro_Mini ? 0.9 : 0.8) * 25.4;
    color("silver")
    translate([moveX/2, moveY, ArduinoPro_PCB_Height])
    linear_extrude(height=2)
    union() {
        square([1.5, 3.5], center=true);
        translate([7.5, 0, 0])
          square([1.5, 3.5], center=true);
    }

    // Other components
    color("silver")
    translate([moveX, moveY, ArduinoPro_PCB_Height])
    linear_extrude(height=1)
    union() {
        square([1, 2.5], center=true);
        translate([0, 3, 0])
            square([2.5, 1.5], center=true);
    }

    // Pro Mini Serial Header Pins
    serialontop = (serialpins != ArduinoPro_Pins_Opposite);
    if (serialpins > 0 && type == ArduinoPro_Mini) {
        // Offset for board height if located on top
        translate([0, 0, serialontop ? ArduinoPro_PCB_Height : 0])
            mirror([0, 0, serialontop ? 0 : 1 ])
            ArduinoPro_Serial_Header_Layout()
                ArduinoPro_Header_Pin();
    }

    // Common Header Pins
    headerontop = (headerpins == ArduinoPro_Pins_Opposite);
    if (headerpins > 0) {
        // Offset for board height located on top
        translate([0, 0, headerontop ? ArduinoPro_PCB_Height : 0])
            mirror([0, 0, headerontop ? 0 : 1 ])
            ArduinoPro_Headers_Layout()
                ArduinoPro_Header_Pin();
    }

    // Pro Micro USB port
    if (type == ArduinoPro_Micro) ArduinoPro_MicroUSB();

    // Indicate area for minimum board clearance
    if (ArduinoPro_PCB_Clearance_Show && !headerpins) {
        color(ArduinoPro_PCB_Colour, 0.1)
        translate([-ArduinoPro_PCB_Inset, -ArduinoPro_PCB_Inset, 0.5])
        linear_extrude(height=ArduinoPro_PCB_Clearance)
            square(size = [ArduinoPro_PCB_Width, ArduinoPro_PCB_Length]);
    }
}

// Example Usage
// ArduinoPro(ArduinoPro_Mini, ArduinoPro_Serial_Pins);
// ArduinoPro(ArduinoPro_Micro, ArduinoPro_Header_Pins);

/*
    Vitamin: ArduinoPro
    Model of an Arduino Pro Mini/Micro

    Derived from: https://github.com/sparkfun/Pro_Micro/
                     and: https://github.com/sparkfun/Arduino_Pro_Mini_328/

    Authors:
        Jamie Osborne (@jmeosbn)

    Local Frame:
        Point of origin is the centre of the bottom left pin (9)

    Parameters:
        type: can be "mini", or "micro";
                    otherwise returns a blank board with header pin holes

    Returns:
        Model of an Arduino Pro Mini/Micro with header holes
*/

// ArduinoPro Model Variants
ArduinoPro_Mini             = 1;            // default
ArduinoPro_Micro            = 2;

// ArduinoPro Without Programming Port
ArduinoPro_No_Port          = 0;

// Show Header Pins
ArduinoPro_Pins_Normal      = 1;
ArduinoPro_Pins_Opposite    = 2;

// ArduinoPro Without Header Pins
ArduinoPro_No_Pins          = 0;            // default

// ArduinoPro PCB Variables
ArduinoPro_PCB_Pitch    = 2.54;                         // spacing of the holes
ArduinoPro_PCB_Inset    = ArduinoPro_PCB_Pitch /2;      // inset from board edge
ArduinoPro_PCB_Type     = 0.047 * 25.4; // .047 .063    // standard PCB thickness
ArduinoPro_PCB_Layers   = 0.035 * 2;                    // total copper layer thickness
ArduinoPro_PCB_Height   = ArduinoPro_PCB_Type +
                          ArduinoPro_PCB_Layers;        // height of the PCB (along z)
ArduinoPro_PCB_Length   = 1.3 * 25.4;                   // length of the PCB (along y)
ArduinoPro_PCB_Width    = 0.7 * 25.4;                   //  width of the PCB (along x)
ArduinoPro_PCB_Colour   = [26/255, 90/255, 160/255];    // colour of solder mask

// Show board clearance area for components
ArduinoPro_PCB_Clearance      = 3;
ArduinoPro_PCB_Clearance_Show = true;

module ArduinoPro_MicroUSB() {
    include <MicroUSB.scad>
    // Subtracting `ArduinoPro_PCB_Inset` compansates for board origin
    //-: Not sure if board origin would be better set after creation
    move_x  = ArduinoPro_PCB_Width / 2 - ArduinoPro_PCB_Inset;
    move_y  = ArduinoPro_PCB_Length - ArduinoPro_PCB_Inset;
    move_z  = ArduinoPro_PCB_Height;

    // Add USB header and move to top of board (along x)
    translate([move_x, move_y, move_z])
        MicroUSB_Receptacle();
}

module ArduinoPro_PCB() {
    // Bare PCB, origin through location for bottom left hole
    translate([-ArduinoPro_PCB_Inset, -ArduinoPro_PCB_Inset, 0])
        square(size = [ArduinoPro_PCB_Width, ArduinoPro_PCB_Length]);
}

module ArduinoPro_Header_Hole() {
    // Standard PCB hole
    holediameter        = 1.25;         // diameter of PCB hole
    circle(d = holediameter);
}

module ArduinoPro_Header_Pin() {
    // Standard PCB header pin
    pcbholepitch        = 2.54;         // spacing of PCB holes
    holediameter        = 1.25;         // diameter of PCB hole
    pinheight           =   11;         // length of PCB pins
    pinoffset           =    3;         // offset of PCB pins
    pinwidth            = 0.63;         // width/gauge of PCB pins
    spacerwidth         = 2.25;         // height of breakaway pin frame
    spacerheight        = 2.54;         // height of breakaway pin frame

    // Header Pins
    color("white")
    translate([0, 0, -pinoffset])
    linear_extrude(pinheight)
        square(pinwidth, center = true);

    // Pin Spacers
    color("black")
    linear_extrude(spacerheight)
        square(spacerwidth, center = true);

    // Break-Away Material
    color("black")
    translate([0, pcbholepitch/2, 0])
    linear_extrude(spacerheight)
        square([spacerwidth * 0.85, pcbholepitch - spacerwidth], center = true);
}

module ArduinoPro_Headers_Layout() {
    // distance between the two header rows
    // FIXME: improve this to be a multiple of 0.1 inch
    rowpitch  = ArduinoPro_PCB_Width - ArduinoPro_PCB_Inset*2;
    // length for holes, leaving room for end header and insets
    rowlength = ArduinoPro_PCB_Length - ArduinoPro_PCB_Pitch - ArduinoPro_PCB_Inset*2;

    // Add headers to either side (along y)
    for (x = [0, rowpitch], y = [0 : ArduinoPro_PCB_Pitch : rowlength]) {
        translate([x, y, 0]) children();
    }
}

module ArduinoPro_Serial_Header_Layout() {
    // y position for header
    header_y = ArduinoPro_PCB_Length - ArduinoPro_PCB_Inset*2;
    // width for holes, leaving room for insets
    rowwidth = ArduinoPro_PCB_Width - ArduinoPro_PCB_Inset*2;

    // Add serial header along top of board (along x)
    for (x = [ArduinoPro_PCB_Inset : ArduinoPro_PCB_Pitch : rowwidth]) {
        translate([x, header_y, 0]) children();
    }
}

module ArduinoPro(type = ArduinoPro_Mini, headerpins = 0, serialpins = 0) {
    color(ArduinoPro_PCB_Colour)
    linear_extrude(height=ArduinoPro_PCB_Height)
    difference() {
        // Base PCB
        ArduinoPro_PCB();

        // Common Headers for Pro Mini/Micro
        ArduinoPro_Headers_Layout()
            ArduinoPro_Header_Hole();

        // Pro Mini Serial Header
        if (type == ArduinoPro_Mini) {
            ArduinoPro_Serial_Header_Layout()
                ArduinoPro_Header_Hole();
        }
    }

    // Pro Mini Serial Header Pins
    serialontop = (serialpins != ArduinoPro_Pins_Opposite);
    if (serialpins > 0 && type == ArduinoPro_Mini) {
        // Offset for board height if located on top
        translate([0, 0, serialontop ? ArduinoPro_PCB_Height : 0])
            mirror([0, 0, serialontop ? 0 : 1 ])
            ArduinoPro_Serial_Header_Layout()
                ArduinoPro_Header_Pin();
    }

    // Common Header Pins
    headerontop = (headerpins == ArduinoPro_Pins_Opposite);
    if (headerpins > 0) {
        // Offset for board height located on top
        translate([0, 0, headerontop ? ArduinoPro_PCB_Height : 0])
            mirror([0, 0, headerontop ? 0 : 1 ])
            ArduinoPro_Headers_Layout()
                ArduinoPro_Header_Pin();
    }

    // Pro Micro USB port
    if (type == ArduinoPro_Micro) ArduinoPro_MicroUSB();

    // Indicate area for minimum board clearance
    if (ArduinoPro_PCB_Clearance_Show && !headerpins) {
        color(ArduinoPro_PCB_Colour, 0.1)
        translate([-ArduinoPro_PCB_Inset, -ArduinoPro_PCB_Inset, 0.5])
        linear_extrude(height=ArduinoPro_PCB_Clearance)
            square(size = [ArduinoPro_PCB_Width, ArduinoPro_PCB_Length]);
    }
}

// Example Usage
// ArduinoPro(ArduinoPro_Mini, ArduinoPro_Serial_Pins);
// ArduinoPro(ArduinoPro_Micro, ArduinoPro_Header_Pins);


Tweak measurement after hardboard cut test.

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

// Set thickness to account for thickness of material
// PLUS needed clearance for cuts into which material should fit.

// 0.100" Acrylic:
window_thickness = 2.4;  // 2.4mm = 0.094" (looks good based on cut test piece for acrylic slotting into itself)

// 1/8" Hardboard:
thickness = 2.8;  // 2.8mm = 0.110" (looks good based on cut test piece for hardboard slotting into hardboard)

// Interior box dimensions
// The variables are used below to control placement of **centerpoints** centerpoints of walls,
// so material thickness is added to account for that.
width = 290 + thickness;    // x = 29cm wall-to-wall
depth = 348 + thickness;    // y = 34.8cm to accomodate 34.8cm tank length
i_height = 190 + thickness; // z = 19cm to accomodate 16cm tank height plus light holder, plus cover
                            // (i_height because 'height' is used for height of entire box)

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

// amount horizontal support tabs extend past side supports (technically, it will go this distance minus thickness/2)
outset = thickness+2;

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

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

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

// hanging support thickness and drop (distance it "sits down" after in place)
support_w = 10;
support_drop = support_w/2;

// for slight offsets/tweaks
epsilon = 1;

// vars to control projection for DXF export (see makefile)
if (DXF_TOP) {
    projection() top_cover();
} else if (DXF_BOTTOM) {
    projection() tank_base();
} else if (DXF_SIDE1) {
    projection() rotate(a=[90,0,0]) side(y=0);
} else if (DXF_SIDE2) {
    projection() rotate(a=[90,0,0]) side(y=depth);
} else if (DXF_END1) {
    projection() rotate(a=[0,90,0]) vert_face(x=0);
} else if (DXF_END2) {
    projection() rotate(a=[0,90,0]) vert_face(x=width);
} else if (DXF_LIGHT_BAR) {
    projection() light_bar();
} else if (DXF_CAMERA_SUPPORT) {
    projection() rotate(a=[90,0,0]) camera_supports(justone=true);
} else if (DXF_RPI_SUPPORT) {
    projection() rotate(a=[90,0,0]) rpi_support();
}
else {
    // 3D model
    // components to include (comment out unwanted)
    vert_face(x=0);      // "near face, transparent for monitor
    vert_face(x=width);  // "far" face, with camera, rpi, etc.
    side(y=0);
    side(y=depth);
    tank_base();
    light_bar();
    camera_supports(x=width, y=depth/2, z=height/2);
    rpi_support(x=width, y=depth/2-50, z=height/2);
    mock_rpi(x=width, y=depth/2-60, z=height/2);
    top_cover();
}

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

module vert_face(x=0) {
    difference() {
        if (x == 0) {
            vert_face_base(0, window_thickness);
        }
        else {
            vert_face_base(x);
            camera_opening();
            camera_supports(x=width+thickness*2, y=depth/2, z=height/2+support_drop);
            rpi_support(x=width+thickness*2, y=depth/2-50, z=height/2+support_drop);
        }
        // CAUTION: OpenSCAD won't let me make a projection of vert_face(x=0)
        //   if tank_base is put after side(y=depth) here... bug.  :(
        tank_base();
        top_cover();
        side(y=0);
        side(y=depth);
    }
}

module vert_face_base(x, face_thickness=thickness) {
    translate([x-face_thickness/2,-overhang, 0])
    difference() {
        cube([face_thickness,depth+overhang*2,height]);
        translate([0, depth+overhang+thickness/2, 3/4*height])
            rounded_truncation(up=true);
        translate([0, 0, 3/4*height])
            rounded_truncation(up=true);
    }
}

module rounded_truncation(up, rot=[0,0,0]) {
    real_overhang=overhang-thickness/2;
    truncation_height=height/4;
    rotate(a=rot)
    difference() {
        translate([-50,0,0])
            cube([100, real_overhang, truncation_height]);
        if (up) {
            translate([-50, real_overhang/2, 0])
            rotate(a=[0, 90, 0])
                cylinder(d=real_overhang, h=100);
        }
        else {
            translate([-50, real_overhang/2, truncation_height])
            rotate(a=[0, 90, 0])
                cylinder(d=real_overhang, h=100);
        }
    }
}

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

module camera_supports(x, y, z, justone=false) {
    spacing = 20;
    out = 10;
    up = 36;
    hanging_support(x, y + spacing/2, z, out, up);
    if (!justone) {
        hanging_support(x, y - spacing/2, z, out, up);
    }
}

module rpi_support(x, y, z) {
    hanging_support(x, y, z, out=3.2, up=85);
}

module hanging_support(x, y, z, out, up) {
    inner_w = out+thickness;
    inner_h = up;
    color("Red", alpha=0.5)
    translate([x,y,z])
    // push inner opening up against vert face
    translate([inner_w/2,0,0])
    difference() {
        cube([inner_w+support_w*2, thickness, inner_h+support_w*2], center=true);
        // cutout for object
        cube([inner_w, thickness*2, inner_h], center=true);
        // cutout for passing through vertface
        translate([-(inner_w/2+support_w/2),0,-support_drop/2])
            cube([support_w+2*epsilon, thickness*2, inner_h-support_drop], center=true);
        // bottom cutout
        translate([-inner_w/2,0,-(inner_h/2+support_w-support_drop/2)])
            cube([thickness, thickness*2, support_drop], center=true);
    }
}

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

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

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

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

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

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

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

module side_base(y) {
    translate([-overhang,y-thickness/2,overhang/2])
    difference() {
        cube([width+overhang*2, thickness, height-overhang/2]);
        translate([width+overhang+thickness/2, 0, 0])
            rounded_truncation(up=false, rot=[0,0,-90]);
        translate([0, 0, 0])
            rounded_truncation(up=false, rot=[0,0,-90]);
    }
}

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

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

// Set thickness to account for thickness of material
// PLUS needed clearance for cuts into which material should fit.

// 0.100" Acrylic:
window_thickness = 2.4;  // 2.4mm = 0.094" (looks good based on cut test piece)

// 1/8" Hardboard:
thickness = 3.1;  // 3.1mm = 0.122" (best guess for hardboard for now)

// Interior box dimensions
// The variables are used below to control placement of **centerpoints** centerpoints of walls,
// so material thickness is added to account for that.
width = 290 + thickness;    // x = 29cm wall-to-wall
depth = 348 + thickness;    // y = 34.8cm to accomodate 34.8cm tank length
i_height = 190 + thickness; // z = 19cm to accomodate 16cm tank height plus light holder, plus cover
                            // (i_height because 'height' is used for height of entire box)

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

// amount horizontal support tabs extend past side supports (technically, it will go this distance minus thickness/2)
outset = thickness+2;

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

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

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

// hanging support thickness and drop (distance it "sits down" after in place)
support_w = 10;
support_drop = support_w/2;

// for slight offsets/tweaks
epsilon = 1;

// vars to control projection for DXF export (see makefile)
if (DXF_TOP) {
    projection() top_cover();
} else if (DXF_BOTTOM) {
    projection() tank_base();
} else if (DXF_SIDE1) {
    projection() rotate(a=[90,0,0]) side(y=0);
} else if (DXF_SIDE2) {
    projection() rotate(a=[90,0,0]) side(y=depth);
} else if (DXF_END1) {
    projection() rotate(a=[0,90,0]) vert_face(x=0);
} else if (DXF_END2) {
    projection() rotate(a=[0,90,0]) vert_face(x=width);
} else if (DXF_LIGHT_BAR) {
    projection() light_bar();
} else if (DXF_CAMERA_SUPPORT) {
    projection() rotate(a=[90,0,0]) camera_supports(justone=true);
} else if (DXF_RPI_SUPPORT) {
    projection() rotate(a=[90,0,0]) rpi_support();
}
else {
    // 3D model
    // components to include (comment out unwanted)
    vert_face(x=0);      // "near face, transparent for monitor
    vert_face(x=width);  // "far" face, with camera, rpi, etc.
    side(y=0);
    side(y=depth);
    tank_base();
    light_bar();
    camera_supports(x=width, y=depth/2, z=height/2);
    rpi_support(x=width, y=depth/2-50, z=height/2);
    mock_rpi(x=width, y=depth/2-60, z=height/2);
    top_cover();
}

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

module vert_face(x=0) {
    difference() {
        if (x == 0) {
            vert_face_base(0, window_thickness);
        }
        else {
            vert_face_base(x);
            camera_opening();
            camera_supports(x=width+thickness*2, y=depth/2, z=height/2+support_drop);
            rpi_support(x=width+thickness*2, y=depth/2-50, z=height/2+support_drop);
        }
        // CAUTION: OpenSCAD won't let me make a projection of vert_face(x=0)
        //   if tank_base is put after side(y=depth) here... bug.  :(
        tank_base();
        top_cover();
        side(y=0);
        side(y=depth);
    }
}

module vert_face_base(x, face_thickness=thickness) {
    translate([x-face_thickness/2,-overhang, 0])
    difference() {
        cube([face_thickness,depth+overhang*2,height]);
        translate([0, depth+overhang+thickness/2, 3/4*height])
            rounded_truncation(up=true);
        translate([0, 0, 3/4*height])
            rounded_truncation(up=true);
    }
}

module rounded_truncation(up, rot=[0,0,0]) {
    real_overhang=overhang-thickness/2;
    truncation_height=height/4;
    rotate(a=rot)
    difference() {
        translate([-50,0,0])
            cube([100, real_overhang, truncation_height]);
        if (up) {
            translate([-50, real_overhang/2, 0])
            rotate(a=[0, 90, 0])
                cylinder(d=real_overhang, h=100);
        }
        else {
            translate([-50, real_overhang/2, truncation_height])
            rotate(a=[0, 90, 0])
                cylinder(d=real_overhang, h=100);
        }
    }
}

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

module camera_supports(x, y, z, justone=false) {
    spacing = 20;
    out = 10;
    up = 36;
    hanging_support(x, y + spacing/2, z, out, up);
    if (!justone) {
        hanging_support(x, y - spacing/2, z, out, up);
    }
}

module rpi_support(x, y, z) {
    hanging_support(x, y, z, out=3.2, up=85);
}

module hanging_support(x, y, z, out, up) {
    inner_w = out+thickness;
    inner_h = up;
    color("Red", alpha=0.5)
    translate([x,y,z])
    // push inner opening up against vert face
    translate([inner_w/2,0,0])
    difference() {
        cube([inner_w+support_w*2, thickness, inner_h+support_w*2], center=true);
        // cutout for object
        cube([inner_w, thickness*2, inner_h], center=true);
        // cutout for passing through vertface
        translate([-(inner_w/2+support_w/2),0,-support_drop/2])
            cube([support_w+2*epsilon, thickness*2, inner_h-support_drop], center=true);
        // bottom cutout
        translate([-inner_w/2,0,-(inner_h/2+support_w-support_drop/2)])
            cube([thickness, thickness*2, support_drop], center=true);
    }
}

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

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

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

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

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

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

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

module side_base(y) {
    translate([-overhang,y-thickness/2,overhang/2])
    difference() {
        cube([width+overhang*2, thickness, height-overhang/2]);
        translate([width+overhang+thickness/2, 0, 0])
            rounded_truncation(up=false, rot=[0,0,-90]);
        translate([0, 0, 0])
            rounded_truncation(up=false, rot=[0,0,-90]);
    }
}

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


SD-card reader board

SD-card reader board


change buttons height

change buttons height

$fn = 50;
button_h = 13;
overlap = 5;
total_height = 22.5;
th = 2; // enclosure thickness
eps = 1e-1;

cap_r = 6.5 / 2;
cap_h = total_height - button_h + overlap;

border_offset = 5.5 + th;
border_h = 3;
border_r = cap_r + 3;

socket_r = 3.2 / 2;

difference() {
  union() {
    cylinder(r=cap_r, h=cap_h);
    translate([0, 0, cap_h - border_h - border_offset]) {
      cylinder(r=border_r, h=border_h);
    }
  }
  translate([0, 0, -eps]) {
    cylinder(r=socket_r, h=overlap+eps);
  }
}

$fn = 50;
button_h = 13;
overlap = 5;
total_height = 23;
th = 2; // enclosure thickness
eps = 1e-1;

cap_r = 6.5 / 2;
cap_h = total_height - button_h + overlap;

border_offset = 5.5 + th;
border_h = 3;
border_r = cap_r + 3;

socket_r = 3.2 / 2;

difference() {
  union() {
    cylinder(r=cap_r, h=cap_h);
    translate([0, 0, cap_h - border_h - border_offset]) {
      cylinder(r=border_r, h=border_h);
    }
  }
  translate([0, 0, -eps]) {
    cylinder(r=socket_r, h=overlap+eps);
  }
}


added panel ammeter bracket

added panel ammeter bracket

// adapter plate for panel ammeter

2_56 = .07; // drill tap diameter
T_PLATE = .1;

MOUNT_X = 1.626;
MOUNT_Y = 1.07;

module hole(x, y, height, d) {
    translate([x, y, height/2])
        cylinder(h=2 * height,d=d,center=true,$fn=50);
}

difference() {
    linear_extrude(height = T_PLATE)
        square([MOUNT_X + .25, MOUNT_Y + .25], center = true);
    union() {

        // mounting holes for agc
        hole(-MOUNT_X/2, +MOUNT_Y/2, T_PLATE, 2_56);
        hole(-MOUNT_X/2, -MOUNT_Y/2, T_PLATE, 2_56);
        hole(+MOUNT_X/2, +MOUNT_Y/2, T_PLATE, 2_56);
        hole(+MOUNT_X/2, -MOUNT_Y/2, T_PLATE, 2_56);

        // cutout unused space in middle
        translate([0,0,-.5])
            linear_extrude(height = 1)
                square([1.336, .838], center = true);

        };
}

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


Partial FTC phone strain relief

Partial FTC phone strain relief

//
//  Strain relief for FTC robot phones - driver station and robot controller
//

use <../common/extrusions.scad>

$fn = 20;

thick = 3; // thickness of walls and base
LARGE = 100; // Something larger than any demension - for O to become U
EPSILON = 0.1; // Small emount to extend so that unions and intersections are clean

// Phone side - just the bottom
module phone_part(base_w) {
    //base_w = 29; // width - x
    base_d = 20; // depth - y
    ro = 1; // outside-facing radii
    cube([base_w, base_d, thick]);
}

// Support below usb cable - depth - in y-direction -  is {d}
module cable_support(cable_w, d) {
    //cable_w = 13; // width - x
    cable_h = 11; // height - z
    cable_center_w = 5; // width of center protrusion
    cable_r = 1; // radii of curve in center protrusion
    cable_pad_h = 5; // the base of the lug is slightly elevated (z) from the switch base
    cable_gap_d = 10; // a small gap in x between the start of the center protrusion.
                     // This is because the lugs are slightly taller (z) where they
                     // attach to the switch

    // The difference is to round the base of the lug - so that tape does not have to
    // wrap around a sharp corner.
    difference() {
        union() {
            cube([cable_w, d+EPSILON, thick]);
            translate([0, d-cable_gap_d, 0]) rotate([90, 0, 0])
                O_channel(cable_w, cable_h, cable_center_w, LARGE,
                (cable_w - cable_center_w)/2, cable_pad_h+thick,
                cable_r, cable_r,
                d - cable_gap_d);
        }
        translate([-thick, d+EPSILON, -thick]) rotate([90, 0, 0])
            O_channel(cable_w+2*thick, thick+thick, cable_w, LARGE,
                thick, thick,
                0, cable_r, d+2*EPSILON);
    }
}

module switch_strain_relief() {
    base_w = 55;
    cable_w = 10;
    cable_d = 30; // depth - y - of lug
    cable_off = (base_w - cable_w)/2; // offset in x of lug position
    translate([0, cable_d, 0]) phone_part(base_w);
    translate([cable_off, 0, 0]) cable_support(cable_w, cable_d);
}

switch_strain_relief();

error: pathspec 'openscad/strain-relief/phone-sr-v1.scad' did not match any file(s) known to git


tweaked dimensions to matched actual measurements

//
//  Strain relief for FTC robot main power switch
//

use <../common/extrusions.scad>

$fn = 20;

thick = 3; // thickness of walls and base
LARGE = 100; // Something larger than any demension - for O to become U
EPSILON = 0.1; // Small emount to extend so that unions and intersections are clean

// Switch side and walls
module switch_part() {
    switch_w = 29; // width - x
    wall_h = 10; // height - z - of walls - will be slightly less than switch walls
                 // so that tape or ziptie is firm against top of the switch
    switch_d = 15; // depth - y
    ro = 1; // outside-facing radii
    ri = 0.2; // radii of switch channel inside walls
    side_w = 6; // side part of base without hole
    front_d = 6; // front part of base without hole
    hole_r = 5;
    hole_w = switch_w - 2 * side_w; // width of hole
    base_w = switch_w + 2*thick;
    difference() {
        translate([0, switch_d, 0]) rotate([90, 0, 0])
            O_channel(base_w, wall_h+thick, switch_w, LARGE,
                thick, thick,
                ro, ri,switch_d);
        translate([thick + side_w, front_d, -EPSILON])
            oblong(hole_w, LARGE, hole_r, thick + 2*EPSILON);
    }
}

// Support below lugs - depth - in y-direction -  is {lug_d}
module lugs_support(lug_d) {
    lug_w = 13; // width - x
    lug_h = 6; // height - z
    lug_center_w = 5; // width of center protrusion
    lug_r = 1; // radii of curve in center protrusion
    lug_pad_h = 0.6; // the base of the lug is slightly elevated (z) from the switch base
    lug_gap_d = 0.5; // a small gap in x between the start of the center protrusion.
                     // This is because the lugs are slightly taller (z) where they
                     // attach to the switch

    // The difference is to round the base of the lug - so that tape does not have to
    // wrap around a sharp corner.
    difference() {
        union() {
            cube([lug_w, lug_d+EPSILON, thick]);
            translate([lug_w, lug_d-lug_gap_d, lug_h+thick+lug_pad_h])
                rotate([90, 180, 0])
                    T_channel(lug_center_w, lug_h, lug_w, thick+lug_pad_h,
                        (lug_w-lug_center_w)/2,
                        lug_r, lug_d-lug_gap_d);
        }
        translate([-thick, lug_d+EPSILON, -thick]) rotate([90, 0, 0])
            O_channel(lug_w+2*thick, thick+thick, lug_w, LARGE,
                thick, thick,
                0, lug_r, lug_d+2*EPSILON);
    }
}

module switch_strain_relief() {
    lug_d = 10; // depth - y - of lug
    lug_off = 6; // offset in x of lug position
    translate([0, lug_d, 0]) switch_part();
    translate([lug_off, 0, 0]) lugs_support(lug_d);
}

switch_strain_relief();

//
//  Strain relief for FTC robot main power switch
//

use <../common/extrusions.scad>

$fn = 20;

thick = 3; // thickness of walls and base
LARGE = 100; // Something larger than any demension - for O to become U
EPSILON = 0.1; // Small emount to extend so that unions and intersections are clean

// Switch side and walls
module switch_part() {
    switch_w = 30; // width - x
    wall_h = 10; // height - z - of walls - will be slightly less than switch walls
                 // so that tape or ziptie is firm against top of the switch
    switch_d = 30; // depth - y
    ro = 1; // outside-facing radii
    ri = 0.2; // radii of switch channel inside walls
    side_w = 5; // side part of base without hole
    front_d = 5; // front part of base without hole
    hole_r = 5;
    hole_w = switch_w - 2 * side_w; // width of hole
    base_w = switch_w + 2*thick;
    difference() {
        translate([0, switch_d, 0]) rotate([90, 0, 0])
            O_channel(base_w, wall_h+thick, switch_w, LARGE,
                thick, thick,
                ro, ri,switch_d);
        translate([thick + side_w, front_d, -EPSILON])
            oblong(hole_w, LARGE, hole_r, thick + 2*EPSILON);
    }
}

// Support below lugs - depth - in y-direction -  is {lug_d}
module lugs_support(lug_d) {
    lug_w = 10; // width - x
    lug_h = 5; // height - z
    lug_center_w = 5; // width of center protrusion
    lug_r = 1; // radii of curve in center protrusion
    lug_pad_h = 0.5; // the base of the lug is slightly elevated (z) from the switch base
    lug_gap_d = 0.5; // a small gap in x between the start of the center protrusion.
                     // This is because the lugs are slightly taller (z) where they
                     // attach to the switch

    // The difference is to round the base of the lug - so that tape does not have to
    // wrap around a sharp corner.
    difference() {
        union() {
            cube([lug_w, lug_d+EPSILON, thick]);
            translate([lug_w, lug_d-lug_gap_d, lug_h+thick+lug_pad_h])
                rotate([90, 180, 0])
                    T_channel(lug_center_w, lug_h, lug_w, thick+lug_pad_h,
                        (lug_w-lug_center_w)/2,
                        lug_r, lug_d-lug_gap_d);
        }
        translate([-thick, lug_d+EPSILON, -thick]) rotate([90, 0, 0])
            O_channel(lug_w+2*thick, thick+thick, lug_w, LARGE,
                thick, thick,
                0, lug_r, lug_d+2*EPSILON);
    }
}

module switch_strain_relief() {
    lug_d = 10; // depth - y - of lug
    lug_off = 5; // offset in x of lug position
    translate([0, lug_d, 0]) switch_part();
    translate([lug_off, 0, 0]) lugs_support(lug_d);
}

switch_strain_relief();


main: reformatting

main: reformatting

include <config.scad>

include <thing_libutils/materials.scad>

use <thing_libutils/screws.scad>
use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
use <thing_libutils/transforms.scad>;
use <thing_libutils/attach.scad>;
use <thing_libutils/linear-extrusion.scad>;
use <thing_libutils/timing-belts.scad>;

use <x-end.scad>
include <x-end.h>

use <x-carriage.scad>
include <x-carriage.h>

use <y-motor-mount.scad>
include <y-motor-mount.h>

use <y-carriage-bearing-mount.scad>
include <y-carriage-bearing-mount.h>

use <y-carriage-belt-clamp.scad>
include <y-carriage-belt-clamp.h>

use <y-idler.scad>
include <y-idler.h>

/*use <z-motor-mount.scad>*/
/*include <z-motor-mount.h>*/

use <gantry-upper-connector.scad>
use <gantry-lower-connector.scad>

use <rod-clamps.scad>
include <rod-clamps.h>

/*use <psu.scad>*/
/*include <psu.h>*/

/*use <lcd2004.scad>*/
/*use <power-panel-iec320.scad>*/

// x carriage
axis_range_x_ = main_width/2 + zmotor_mount_rod_offset_x - xaxis_end_width(true) - x_carriage_w/2 - .5*mm;
axis_range_x = [-1,1] *  axis_range_x_;
axis_printrange_x = [-1/2, 1/2] * printbed_size[0];
axis_x_parked = [false, true];

axis_range_y=[0*mm,200*mm];
axis_pos_y = axis_range_y[0];
axis_range_z=[90*mm,353*mm];
axis_pos_z = axis_range_z[0];

echo(str("Axis range X: " , axis_range_x[0], " ", axis_range_x[1]," mm"));
echo(str("Axis range Y: " , axis_range_y[0], " ", axis_range_y[1]," mm"));
echo(str("Axis range Z: " , axis_range_z[0], " ", axis_range_z[1]," mm"));

echo(str("Build area Z: " , axis_range_z[1]-axis_range_z[0] , " mm"));

home_offset_x0 = axis_range_x[0] - axis_printrange_x[0] + v_x(extruder_filapath_offset)[0];
echo(str("Home offset X0: " , home_offset_x0));
echo(str("Tool offset X: " , axis_range_x_+x_carriage_w/2));

module x_axis()
{
    // x axis
    translate([0,0,axis_pos_z])
    {
        zrod_offset = zmotor_mount_rod_offset_x;
        for(z=[-1,1])
        for(z=xaxis_beltpath_z_offsets)
        translate([-main_width/2-zrod_offset+xaxis_end_motor_offset[0], xaxis_zaxis_distance_y, z])
        rotate(90*X)
        belt_path(
            len=main_width+2*(zrod_offset)+xaxis_end_motor_offset[0],
            belt_width=xaxis_belt_width,
            belt=xaxis_belt,
            pulley_d=xaxis_pulley_inner_d,
            orient=X, align=X);

        for(x=[0:len(axis_range_x)-1])
        {
            /*#cubea(size=[x_carriage_w,10,100]);*/

            pos = axis_x_parked[x] ? axis_range_x[x] : -axis_printrange_x[x];

            translate([pos,0,0])
            mirror([x==0?0:1,0,0])
            attach(xaxis_carriage_conn, [[0,-xaxis_zaxis_distance_y,0],N])
            {
                x_carriage_withmounts(show_vitamins=true, beltpath_offset=x==0?-1:1);

                x_carriage_extruder(show_vitamins=true, with_sensormount=x==0);
            }
        }

        // x smooth rods
        color(color_rods)
        for(z=[-1,1])
        translate([xaxis_rod_offset_x,xaxis_zaxis_distance_y,z*(xaxis_rod_distance/2)])
        cylindera(h=xaxis_rod_l,d=xaxis_rod_d+.1, orient=X);

        for(x=[-1,1])
        translate([x*(main_width/2), 0, 0])
        translate([0, xaxis_zaxis_distance_y, 0])
        translate([x*zmotor_mount_rod_offset_x, 0, 0])
        mirror([max(0,x),0,0])
        {
            xaxis_end(with_motor=true, beltpath_index=max(0,x), show_nut=true, show_motor=true, show_nut=true);

            xaxis_end_bucket();
        }
    }
}

module y_axis()
{
    // y axis
    color(color_part)
    attach([[yaxis_belt_path_offset_x,main_depth/2,yaxis_motor_offset_z], [0,-1,0]], yaxis_motor_mount_conn)
    yaxis_motor_mount(show_motor=true);

    extrusion_idler_conn = [[yaxis_belt_path_offset_x, -main_depth/2-extrusion_size, -extrusion_size+yaxis_idler_offset_z], [0,-1,0]];
    attach(extrusion_idler_conn, yaxis_idler_conn)
    {
        color(color_part)
        yaxis_idler();

        attach(yaxis_idler_conn_pulleyblock, yaxis_idler_pulleyblock_conn)
        color(color_part)
        yaxis_idler_pulleyblock(show_pulley=true);
    }

    translate([yaxis_belt_path_offset_x,0,yaxis_belt_path_offset_z])
    translate([0,main_depth/2-yaxis_motor_offset_x,0])
    rotate(90*Y)
    belt_path(
        len=main_depth-yaxis_motor_offset_x-yaxis_idler_pulley_offset_y,
        belt_width=yaxis_belt_width,
        pulley_d=yaxis_pulley_inner_d,
        belt=yaxis_belt,
        align=-Y, orient=Y);

    color(color_part)
    translate([0,-axis_pos_y,get(LinearBearingInnerDiameter, yaxis_bearing)/2])
    attach(yaxis_carriage_bearing_mount_conn_bearing, yaxis_belt_mount_conn)
    yaxis_belt_holder();

    translate([0,0,get(LinearBearingInnerDiameter, yaxis_bearing)/2])
    {
        // y smooth rod clamps to frame
        for(x=[-1,1])
        for(y=[-1,1])
        attach([[x*(yaxis_rod_distance/2),y*(main_depth/2+extrusion_size/2),0],Z],mount_rod_clamp_conn_rod)
        mount_rod_clamp_full(rod_d=zaxis_rod_d, thick=4, width=extrusion_size, thread=zmotor_mount_clamp_thread, orient=Y);

        // y smooth rods
        for(x=[-1,1])
        translate([x*(yaxis_rod_distance/2), 0, 0])
        {
            color(color_rods)
            cylindera(h=yaxis_rod_l,d=yaxis_rod_d, orient=Y);

            for(y=[-1,1])
            attach([[0,y*(yaxis_bearing_distance_y/2)-axis_pos_y,0],[0,0,-1]], yaxis_carriage_bearing_mount_conn_bearing)
            {
                yaxis_carriage_bearing_mount();
                %yaxis_carriage_bearing_mount(part="vit");
            }
        }

        attach(yaxis_carriage_bearing_mount_conn_bearing, [[0,axis_pos_y,0],Z])
        {
            yaxis_carriage_size_inner = [32*mm,32*mm,0];

            // y axis plate "arms"
            for(x=[-1,1])
            for(y=[-1,1])
            hull()
            {
                translate([x*yaxis_carriage_size[0]/2, y*yaxis_carriage_size[1]/2, 0])
                cylindera(d=10*mm, h=yaxis_carriage_size[2], align=[-x,-y,1]);

                translate([x*(yaxis_carriage_size[0]/2-yaxis_carriage_size_inner[0]/2), y*(yaxis_carriage_size[1]/2-yaxis_carriage_size_inner[1]/2*mm), 0])
                cylindera(d=10*mm, h=yaxis_carriage_size[2], align=[-x,-y,1]);
            }

            // y axis plate
            cubea(yaxis_carriage_size - yaxis_carriage_size_inner, align=Z);

            translate([0,0,10*mm])
            cubea(printbed_size, align=Z);
        }
    }

}

module z_axis()
{
    // z axis
    for(x=[-1,1])
    {
        translate([x*(main_width/2),0,main_height])
        mirror([x==-1?1:0,0,0])
        color(color_part)
        translate([zmotor_mount_rod_offset_x, 0, extrusion_size/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);

        translate([x*(main_width/2), 0, 0])
        {
            translate([0,0,zaxis_motor_offset_z])
            mirror([x==-1?1:0,0,0])
            {
                color(color_part)
                zaxis_motor_mount(show_motor=true);

                color(color_part)
                translate([zmotor_mount_rod_offset_x, 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);
            }

            // z smooth rods
            translate([x*(zmotor_mount_rod_offset_x),0,0])
            color(color_rods)
            translate([0,0,zaxis_motor_offset_z-80*mm])
            cylindera(h=zaxis_rod_l,d=zaxis_rod_d, align=Z);
        }
    }

}

module gantry_upper()
{
    color(color_extrusion)
    for(y=[-1,1])
    translate([0,y*(main_upper_dist_y/2),0])
    {
        for(x=[-1,1])
        translate([x*(main_width/2), 0, 0])
        linear_extrusion(h=main_height, align=[-x,0,1], orient=Z);

        translate([0, 0, main_height])
        linear_extrusion(h=main_upper_width, align=Z, orient=X);
    }

    // upper gantry connectors
    for(x=[-1,1])
    translate([x*(main_width/2),0,main_height])
    mirror([x==-1?1:0,0,0])
    color(color_gantry_connectors)
    gantry_upper_connector();

}

module gantry_lower()
{
    color(color_extrusion)
    for(z=[-1,1])
    translate([0,0,z*-main_lower_dist_z/2])
    {
        for(y=[-1,1])
        translate([0, y*(main_depth/2), 0])
        linear_extrusion(h=main_width, align=[0,y,-1], orient=X);

        for(x=[-1,1])
        translate([x*(main_width/2), 0, 0])
        cubea([extrusion_size, main_depth, extrusion_size], align=[-x,0,-1]);
    }

    // lower gantry connectors
    for(x=[-1,1])
    for(y=[-1,1])
    translate([x*(main_width/2),y*(main_depth/2),-extrusion_size/2])
    mirror([x==1?0:-1,0,0])
    mirror([0,y==1?1:0,0])
    color(color_gantry_connectors)
    gantry_lower_connector();

}

module enclosure()
{
    // inner
    w=56*cm;
    h=56*cm;
    d=58*cm;
    wallthick=2*cm;
    backthick=0.5*cm;

    translate([0, 0, h/2+wallthick])
    {
        // left/right walls
        for(x=[-1,1])
        translate([x*w/2,0,0])
        cubea([wallthick,d,h], align=[x, 0, 0]);

        // back plate
        translate([0,d/2,0])
        cubea([w,backthick,h], align=[0,-1, 0]);

        // top/bottom plate
        for(z=[-1,1])
        translate([0,0,z*h/2])
        cubea([w+wallthick*2,d,wallthick], align=[0,0, z]);
    }
}

module main()
{
    translate([0,0,-main_lower_dist_z/2])
    gantry_lower();

    translate(-zaxis_rod_offset)
    gantry_upper();

    x_axis();
    y_axis();
    z_axis();

    translate([-75*mm,0,0])
    translate([0,main_depth/2,0])
    translate([0,extrusion_size,0])
    translate([0,0,-main_lower_dist_z/2-extrusion_size/2])
    power_panel_iec320(orient=[0,-1,0], align=Y);

    if(!$preview_mode)
    {
        translate([0,-main_depth/2,0])
        translate([0,-extrusion_size/2,0])
        translate([0,0,-main_lower_dist_z/2])
        mount_lcd2004(show_gantry=true);

        for(x=[-1,1])
        translate([x*(main_width/2-extrusion_size),main_depth/2,-main_lower_dist_z-extrusion_size])
        translate([-x*psu_a_w/2, -psu_a_d/2, psu_a_h/2])
        {
            psu_a();

            mirror([x==-1?1:0,0,0])
            translate([0, -psu_a_screw_dist_y/2, 0])
            psu_a_extrusion_bracket_side();

            translate([0, psu_a_screw_dist_y/2, 0])
            psu_a_extrusion_bracket_back();
        }

        translate([0,-main_depth/2,-main_lower_dist_z-extrusion_size])
        translate([-100,100,0])
        rotate([0,0,270])
        import("stl/RAMPS1_4.STL");
    }
}

feet_height = 8*mm;
translate([0, 0, main_lower_dist_z+extrusion_size*2+feet_height])
main();

/*psu();*/

/*%enclosure();*/

include <config.scad>
use <thing_libutils/screws.scad>
use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
use <thing_libutils/transforms.scad>;
use <thing_libutils/attach.scad>;
use <thing_libutils/linear-extrusion.scad>;
use <thing_libutils/timing-belts.scad>;

use <x-end.scad>
include <x-end.h>

use <x-carriage.scad>
include <x-carriage.h>

use <y-motor-mount.scad>
include <y-motor-mount.h>

use <y-carriage-bearing-mount.scad>
include <y-carriage-bearing-mount.h>

use <y-carriage-belt-clamp.scad>
include <y-carriage-belt-clamp.h>

use <y-idler.scad>
include <y-idler.h>

/*use <z-motor-mount.scad>*/
/*include <z-motor-mount.h>*/

use <gantry-upper-connector.scad>
use <gantry-lower-connector.scad>

use <rod-clamps.scad>
include <rod-clamps.h>

/*use <psu.scad>*/
/*include <psu.h>*/

/*use <lcd2004.scad>*/
/*use <power-panel-iec320.scad>*/

// x carriage
axis_range_x_ = main_width/2 + zmotor_mount_rod_offset_x - xaxis_end_width(true) - x_carriage_w/2 - .5*mm;
axis_range_x = [-1,1] *  axis_range_x_;
axis_printrange_x = [-1/2, 1/2] * printbed_size[0];
axis_x_parked = [false, true];

axis_range_y=[0*mm,200*mm];
axis_pos_y = axis_range_y[0];
axis_range_z=[90*mm,353*mm];
axis_pos_z = axis_range_z[0];

echo(str("Axis range X: " , axis_range_x[0], " ", axis_range_x[1]," mm"));
echo(str("Axis range Y: " , axis_range_y[0], " ", axis_range_y[1]," mm"));
echo(str("Axis range Z: " , axis_range_z[0], " ", axis_range_z[1]," mm"));

echo(str("Build area Z: " , axis_range_z[1]-axis_range_z[0] , " mm"));

home_offset_x0 = axis_range_x[0] - axis_printrange_x[0] + v_x(extruder_filapath_offset)[0];
echo(str("Home offset X0: " , home_offset_x0));
echo(str("Tool offset X: " , axis_range_x_+x_carriage_w/2));

module x_axis()
{
    // x axis
    translate([0,0,axis_pos_z])
    {
        zrod_offset = zmotor_mount_rod_offset_x;
        for(z=[-1,1])
        for(z=xaxis_beltpath_z_offsets)
        translate([-main_width/2-zrod_offset+xaxis_end_motor_offset[0], xaxis_zaxis_distance_y, z])
        rotate(90*X)
        belt_path(
            len=main_width+2*(zrod_offset)+xaxis_end_motor_offset[0],
            belt_width=xaxis_belt_width,
            belt=xaxis_belt,
            pulley_d=xaxis_pulley_inner_d,
            orient=X, align=X);

        for(x=[0:len(axis_range_x)-1])
        {
            /*#cubea(size=[x_carriage_w,10,100]);*/

            pos = axis_x_parked[x] ? axis_range_x[x] : -axis_printrange_x[x];

            translate([pos,0,0])
            mirror([x==0?0:1,0,0])
            attach(xaxis_carriage_conn, [[0,-xaxis_zaxis_distance_y,0],N])
            {
                x_carriage_withmounts(show_vitamins=true, beltpath_offset=x==0?-1:1);

                x_carriage_extruder(show_vitamins=true, with_sensormount=x==0);
            }
        }

        // x smooth rods
        color(color_rods)
        for(z=[-1,1])
            translate([xaxis_rod_offset_x,xaxis_zaxis_distance_y,z*(xaxis_rod_distance/2)])
                cylindera(h=xaxis_rod_l,d=xaxis_rod_d+.1, orient=X);

        for(x=[-1,1])
        {
            translate([x*(main_width/2), 0, 0])
            translate([0, xaxis_zaxis_distance_y, 0])
            translate([x*zmotor_mount_rod_offset_x, 0, 0])
            mirror([max(0,x),0,0])
            {
                xaxis_end(with_motor=true, beltpath_index=max(0,x), show_nut=true, show_motor=true, show_nut=true);

                xaxis_end_bucket();
            }
        }
    }
}

module y_axis()
{
    // y axis
    color(color_part)
    attach([[yaxis_belt_path_offset_x,main_depth/2,yaxis_motor_offset_z], [0,-1,0]], yaxis_motor_mount_conn)
    {
        yaxis_motor_mount(show_motor=true);
    }

    extrusion_idler_conn = [[yaxis_belt_path_offset_x, -main_depth/2-extrusion_size, -extrusion_size+yaxis_idler_offset_z], [0,-1,0]];
    attach(extrusion_idler_conn, yaxis_idler_conn)
    {
        color(color_part)
        yaxis_idler();

        attach(yaxis_idler_conn_pulleyblock, yaxis_idler_pulleyblock_conn)
        {
            color(color_part)
            yaxis_idler_pulleyblock(show_pulley=true);
        }
    }

    translate([yaxis_belt_path_offset_x,0,yaxis_belt_path_offset_z])
    {
        translate([0,main_depth/2-yaxis_motor_offset_x,0])
        {
            rotate(90*Y)
            belt_path(
                len=main_depth-yaxis_motor_offset_x-yaxis_idler_pulley_offset_y,
                belt_width=yaxis_belt_width,
                pulley_d=yaxis_pulley_inner_d,
                belt=yaxis_belt,
                align=-Y, orient=Y);
        }
    }

    color(color_part)
    translate([0,-axis_pos_y,get(LinearBearingInnerDiameter, yaxis_bearing)/2])
    attach(yaxis_carriage_bearing_mount_conn_bearing, yaxis_belt_mount_conn)
    {
        yaxis_belt_holder();
    }

    translate([0,0,get(LinearBearingInnerDiameter, yaxis_bearing)/2])
    {
        // y smooth rod clamps to frame
        for(x=[-1,1])
        for(y=[-1,1])
        {
            attach([[x*(yaxis_rod_distance/2),y*(main_depth/2+extrusion_size/2),0],Z],mount_rod_clamp_conn_rod)
            {
                mount_rod_clamp_full(rod_d=zaxis_rod_d, thick=4, width=extrusion_size, thread=zmotor_mount_clamp_thread, orient=Y);
            }
        }

        // y smooth rods
        for(x=[-1,1])
        translate([x*(yaxis_rod_distance/2), 0, 0])
        {
            color(color_rods)
            cylindera(h=yaxis_rod_l,d=yaxis_rod_d, orient=Y);

            for(y=[-1,1])
            {
                attach([[0,y*(yaxis_bearing_distance_y/2)-axis_pos_y,0],[0,0,-1]], yaxis_carriage_bearing_mount_conn_bearing)
                {
                    yaxis_carriage_bearing_mount();
                    %yaxis_carriage_bearing_mount(part="vit");
                }
            }
        }

        attach(yaxis_carriage_bearing_mount_conn_bearing, [[0,axis_pos_y,0],Z])
        {
            yaxis_carriage_size_inner = [32*mm,32*mm,0];

            // y axis plate "arms"
            for(x=[-1,1])
            for(y=[-1,1])
            hull()
            {
                translate([x*yaxis_carriage_size[0]/2, y*yaxis_carriage_size[1]/2, 0])
                {
                    cylindera(d=10*mm, h=yaxis_carriage_size[2], align=[-x,-y,1]);
                }
                translate([x*(yaxis_carriage_size[0]/2-yaxis_carriage_size_inner[0]/2), y*(yaxis_carriage_size[1]/2-yaxis_carriage_size_inner[1]/2*mm), 0])
                {
                    cylindera(d=10*mm, h=yaxis_carriage_size[2], align=[-x,-y,1]);
                }
            }

            // y axis plate
            cubea(yaxis_carriage_size - yaxis_carriage_size_inner, align=Z);

            translate([0,0,10*mm])
                cubea(printbed_size, align=Z);
        }
    }

}

module z_axis()
{
    // z axis
    for(x=[-1,1])
    {
        translate([x*(main_width/2),0,main_height])
        {
            mirror([x==-1?1:0,0,0])
            {
                color(color_part)
                translate([zmotor_mount_rod_offset_x, 0, extrusion_size/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);
                }
            }
        }

        translate([x*(main_width/2), 0, 0])
        {
            translate([0,0,zaxis_motor_offset_z])
                mirror([x==-1?1:0,0,0])
                {
                    color(color_part)
                    zaxis_motor_mount(show_motor=true);

                    color(color_part)
                    translate([zmotor_mount_rod_offset_x, 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);
                    }
                }

            // z smooth rods
            translate([x*(zmotor_mount_rod_offset_x),0,0])
            {
                // z rods
                color(color_rods)
                translate([0,0,zaxis_motor_offset_z-80*mm])
                    cylindera(h=zaxis_rod_l,d=zaxis_rod_d, align=Z);

            }
        }
    }

}

module gantry_upper()
{
    color(color_extrusion)
    for(y=[-1,1])
    translate([0,y*(main_upper_dist_y/2),0])
    {
        for(x=[-1,1])
        translate([x*(main_width/2), 0, 0])
        {
            linear_extrusion(h=main_height, align=[-x,0,1], orient=Z);
        }

        translate([0, 0, main_height])
        {
            linear_extrusion(h=main_upper_width, align=Z, orient=X);
        }
    }

    // upper gantry connectors
    for(x=[-1,1])
    {
        translate([x*(main_width/2),0,main_height])
        {
            mirror([x==-1?1:0,0,0])
            {
                color(color_gantry_connectors)
                    gantry_upper_connector();
            }

        }
    }
}

module gantry_lower()
{
    color(color_extrusion)
    for(z=[-1,1])
    {
        translate([0,0,z*-main_lower_dist_z/2])
        {
            for(y=[-1,1])
            translate([0, y*(main_depth/2), 0])
            {
                linear_extrusion(h=main_width, align=[0,y,-1], orient=X);
            }

            for(x=[-1,1])
            translate([x*(main_width/2), 0, 0])
            {
                cubea([extrusion_size, main_depth, extrusion_size], align=[-x,0,-1]);
            }
        }

    }

    // lower gantry connectors
    for(x=[-1,1])
    for(y=[-1,1])
    {
        translate([x*(main_width/2),y*(main_depth/2),-extrusion_size/2])
        {
            mirror([x==1?0:-1,0,0])
            mirror([0,y==1?1:0,0])
            {
                color(color_gantry_connectors)
                    gantry_lower_connector();
            }

        }
    }
}

module enclosure()
{
    // inner
    w=56*cm;
    h=56*cm;
    d=58*cm;
    wallthick=2*cm;
    backthick=0.5*cm;

    translate([0, 0, h/2+wallthick])
    {
        // left/right walls
        for(x=[-1,1])
        translate([x*w/2,0,0])
        cubea([wallthick,d,h], align=[x, 0, 0]);

        // back plate
        translate([0,d/2,0])
        cubea([w,backthick,h], align=[0,-1, 0]);

        // top/bottom plate
        for(z=[-1,1])
        translate([0,0,z*h/2])
        cubea([w+wallthick*2,d,wallthick], align=[0,0, z]);
    }
}

module main()
{
    translate([0,0,-main_lower_dist_z/2])
    gantry_lower();

    translate(-zaxis_rod_offset)
    gantry_upper();

    x_axis();
    y_axis();
    z_axis();

    translate([-75*mm,0,0])
    translate([0,main_depth/2,0])
    translate([0,extrusion_size,0])
    translate([0,0,-main_lower_dist_z/2-extrusion_size/2])
    power_panel_iec320(orient=[0,-1,0], align=Y);

    if(!$preview_mode)
    {
        translate([0,-main_depth/2,0])
        translate([0,-extrusion_size/2,0])
        translate([0,0,-main_lower_dist_z/2])
        mount_lcd2004(show_gantry=true);

        for(x=[-1,1])
        translate([x*(main_width/2-extrusion_size),main_depth/2,-main_lower_dist_z-extrusion_size])
        {
            translate([-x*psu_a_w/2, -psu_a_d/2, psu_a_h/2])
            {
                psu_a();

                mirror([x==-1?1:0,0,0])
                    translate([0, -psu_a_screw_dist_y/2, 0])
                    psu_a_extrusion_bracket_side();

                translate([0, psu_a_screw_dist_y/2, 0])
                    psu_a_extrusion_bracket_back();
            }
        }

        translate([0,-main_depth/2,-main_lower_dist_z-extrusion_size])
            translate([-100,100,0])
            rotate([0,0,270])
            import("stl/RAMPS1_4.STL");
    }
}

feet_height = 8*mm;
translate([0, 0, main_lower_dist_z+extrusion_size*2+feet_height])
main();

/*psu();*/

/*%enclosure();*/


z-axis/motor-mount: add some more reinforcement

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;

xaxis_zaxis_distance_y = xaxis_rod_d/2 + zaxis_bearing[1]/2;

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;

zaxis_leadscrew_offset_x = zmotor_w/2 + zmotor_mount_motor_offset;

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

module zaxis_motor_mount()
{

    difference()
    {
        // top plate
        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
            difference()
            {
                cubea([zmotor_mount_thickness, zmotor_w, zmotor_h], align=[1,0,-1]);
                // cutout for motor cables
                translate([0,0,-20*mm])
                cubea([zmotor_mount_thickness*3, 20*mm, zmotor_h], align=[0,0,-1]);
            }

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

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

            // bottom mount plate
            difference()
            {
                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]);

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

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

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

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;

xaxis_zaxis_distance_y = xaxis_rod_d/2 + zaxis_bearing[1]/2;

zmotor_w = lookup(NemaSideSize,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_conn_motor=[[-zmotor_mount_motor_offset, 0, 0],[0,1,0]];
zmotor_mount_clamp_width = zmotor_mount_clamp_dist+zmotor_mount_clamp_thread_dia*3;

zaxis_leadscrew_offset_x = zmotor_w/2 + zmotor_mount_motor_offset;

module zaxis_motor_mount()
{

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

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

            // bottom mount plate
            difference()
            {
                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]);

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

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

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

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