509 lines
15 KiB
OpenSCAD
509 lines
15 KiB
OpenSCAD
include <constants.scad>
|
|
include <lib.scad>
|
|
include <stock_parts.scad>
|
|
include <units.inc>
|
|
|
|
frame_size = 20;
|
|
wall_thickness = 2;
|
|
corner_size = 30;
|
|
// The length along each edge that the corner bracket takes. I.e., if
|
|
// you construct a frame of four corner brackets and 4 tubes of length
|
|
// $L-$corner_size, the distance between opposite tubes' centerlines
|
|
// will be $L.
|
|
corner_offset = frame_size / 2 + wall_thickness;
|
|
rail_diam = 8;
|
|
// distance between centerline of rail and centerline of frame Y tube.
|
|
yrail_offset = (frame_size + corner_size) / 2;
|
|
|
|
ysled_extralen = frame_size; // on each end
|
|
|
|
// Both of these are distance from frame centerline
|
|
belt_height1 = frame_size / 2 + wall_thickness + belt_width / 2 + 2;
|
|
belt_height2 = belt_height1 + belt_width + 2;
|
|
|
|
// calculated
|
|
|
|
ysled_rail_spacing = (sled_ysize);
|
|
motor_shaft_xoffset = (corner_size - wall_thickness) / 2 + 1;
|
|
motor_mount_length_adjustment = 4;
|
|
motor_mount_length = nema17_face + wall_thickness + motor_mount_length_adjustment;
|
|
|
|
// Generates bar of length $l, centered on origin extending in +Z
|
|
module tslot(l) {
|
|
bom_item(printable = false, label = str("tslot(", l, "mm)"));
|
|
colorize(stock_color) {
|
|
translate([ -frame_size / 2, -frame_size / 2, 0 ])
|
|
cube([ frame_size, frame_size, l ]);
|
|
}
|
|
}
|
|
|
|
// A corner, with tubes extending in +x and +y.
|
|
module corner_base() {
|
|
odim = frame_size / 2 + wall_thickness;
|
|
ldim = frame_size / 2 + corner_size;
|
|
|
|
cap_points = [
|
|
[ -odim, -odim ], [ -odim, ldim ], [ odim, ldim ],
|
|
[odim, odim], [ ldim, odim ],
|
|
[ ldim, -odim ]
|
|
];
|
|
difference() {
|
|
translate([ 0, 0, -odim ]) linear_extrude(odim * 2)
|
|
polygon(points = cap_points);
|
|
|
|
// two bars...
|
|
translate([ -frame_size / 2, corner_offset, -frame_size / 2 ])
|
|
cube([ frame_size, ldim, frame_size ]);
|
|
translate([ corner_offset, -frame_size / 2, -frame_size / 2 ])
|
|
cube([ ldim, frame_size, frame_size ]);
|
|
translate([ corner_offset, corner_offset, -frame_size / 2 ])
|
|
cube([ ldim, ldim, frame_size ]);
|
|
// translate([-odim - 1, -odim - 1, 0])
|
|
// cube(ldim*2);
|
|
}
|
|
}
|
|
|
|
module rail_holder(in_x) {
|
|
odim = frame_size / 2 + wall_thickness;
|
|
ldim = frame_size / 2 + corner_size;
|
|
tube_offset = (corner_size) / 2 + wall_thickness;
|
|
tube_rotation = in_x ? 90 : 0;
|
|
|
|
translated_rail_offset = yrail_offset - frame_size / 2 - wall_thickness;
|
|
|
|
|
|
translate([ frame_size / 2 + wall_thickness, frame_size / 2 + wall_thickness, -frame_size / 2 - wall_thickness ]) {
|
|
difference() {
|
|
cube([
|
|
!in_x ? corner_size - wall_thickness : 10,
|
|
!in_x ? 10 : corner_size - wall_thickness,
|
|
wall_thickness * 2 + frame_size
|
|
]);
|
|
translate(
|
|
[ translated_rail_offset, translated_rail_offset, frame_size / 2 + wall_thickness ])
|
|
rotate([ tube_rotation - 90, tube_rotation, 0 ])
|
|
translate([ 0, 0, -corner_size ])
|
|
cylinder(d = rail_diam, corner_size * 4);
|
|
}
|
|
}
|
|
}
|
|
|
|
// centered on the rail.
|
|
module ysled_slider(spread, associated_parts = $preview, is_left=true) {
|
|
bom_item(label = str("ysled_slider(", spread, ")"));
|
|
sled_len = spread + frame_size;
|
|
sled_height = frame_size;
|
|
idler_spacing = spread / 3;
|
|
|
|
local_idler_xoffset = pulley_sbend_offset - yrail_offset + motor_shaft_xoffset;
|
|
echo("LIX:", local_idler_xoffset)
|
|
colorize("green") translate([ 0, -sled_len / 2, 0 ])
|
|
rotate([ -90, 0, 0 ]) {
|
|
difference() {
|
|
union() {
|
|
translate([ -frame_size / 2, -frame_size / 2, 0 ])
|
|
cube([ frame_size + 5, frame_size, sled_len ]);
|
|
translate([
|
|
pulley_sbend_offset - yrail_offset + motor_shaft_xoffset -
|
|
pulley_clearance_rad - 4,
|
|
-frame_size / 2, 0
|
|
]) cube([ frame_size + 5, frame_size, sled_len ]);
|
|
}
|
|
|
|
for (y = [idler_spacing/2, -idler_spacing/2]) {
|
|
rotate([90, 0, 0])
|
|
translate([local_idler_xoffset, sled_len/2 + y, 0])
|
|
cylinder(d=3, h = frame_size);
|
|
}
|
|
cylinder(d = rail_diam * 1.5, h = sled_len);
|
|
translate([ 0, 0, -1 ]) cylinder(d = bushing_od, h = bushing_len + 1);
|
|
translate([ 0, 0, sled_len - bushing_len ])
|
|
cylinder(d = bushing_od, h = bushing_len + 1);
|
|
|
|
for (zpos = [ frame_size / 2, sled_len - frame_size / 2 ]) {
|
|
translate([ sled_height / 2, 0, zpos ]) rotate([ 0, 90, 0 ]) {
|
|
cylinder(h = sled_height + 1, d = rail_diam);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// TODO: add posts for the idlers
|
|
|
|
// color("#f00")
|
|
translate(
|
|
[ local_idler_xoffset, 0, frame_size/2 - 1 ]) {
|
|
translate([ 0, idler_spacing / 2, 0 ]) {
|
|
idler_post(belt_height = belt_height1 - frame_size/2 + 1, toothed = is_left);
|
|
}
|
|
translate([ 0, -idler_spacing / 2, 0 ]) {
|
|
rotate([ 0, 0, -90 ]) { idler_post(belt_height = belt_height2 - frame_size/2 + 1, toothed = !is_left); }
|
|
}
|
|
}
|
|
|
|
if ($preview) {
|
|
translate([ 0, -sled_len / 2, 0 ]) rotate([ -90, 0, 0 ])
|
|
bushing();
|
|
translate([ 0, sled_len / 2, 0 ]) rotate([ 90, 0, 0 ])
|
|
bushing();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
module nema17_housing() {
|
|
hwidth = corner_size + frame_size + wall_thickness;
|
|
hheight = nema17_face + wall_thickness * 2;
|
|
hdepth = frame_size + wall_thickness * 2;
|
|
|
|
screw_dxy = 31 / 2;
|
|
|
|
translate([ 0, -nema17_face / 2 - frame_size / 2 - wall_thickness, 0 ])
|
|
slotify([0, -motor_mount_length_adjustment, 0]) {
|
|
|
|
translate([ 0, 0, -2 ])
|
|
cube([ nema17_face + 1, nema17_face + 1, hdepth ], center = true);
|
|
cylinder(d = 23, frame_size);
|
|
|
|
translate([ -screw_dxy, -screw_dxy, frame_size / 2 + wall_thickness ])
|
|
rotate([ 180, 0, 0 ]) {
|
|
cylinder(d = 5, h = 3);
|
|
}
|
|
translate([ screw_dxy, -screw_dxy, frame_size / 2 + wall_thickness ])
|
|
rotate([ 180, 0, 0 ]) {
|
|
cylinder(d = 5, h = 3);
|
|
}
|
|
translate([ -screw_dxy, screw_dxy, frame_size / 2 + wall_thickness ])
|
|
rotate([ 180, 0, 0 ]) {
|
|
cylinder(d = 5, h = 3);
|
|
}
|
|
translate([ screw_dxy, screw_dxy, frame_size / 2 + wall_thickness ])
|
|
rotate([ 180, 0, 0 ]) {
|
|
cylinder(d = 5, h = 3);
|
|
}
|
|
}
|
|
}
|
|
|
|
// belt height is the center of the belt.
|
|
// Roration is in Z axis, from +x/+y
|
|
module idler_post(belt_height, toothed = true) {
|
|
gap = 0.5;
|
|
|
|
post_radius = pulley_clearance_rad + 4;
|
|
top_shelf_thickness = 4;
|
|
total_height = idler_zmargin.y + belt_height + top_shelf_thickness + gap;
|
|
slot_radius = pulley_clearance_rad;
|
|
slot_height = idler_zmargin.x + idler_zmargin.y + gap * 2;
|
|
|
|
difference() {
|
|
union() {
|
|
// outer shell
|
|
cylinder(h = total_height, r = post_radius);
|
|
translate([ 0, -post_radius, 0 ])
|
|
cube([ post_radius, post_radius, total_height ]);
|
|
translate([ -post_radius, 0, 0 ])
|
|
cube([ post_radius, post_radius, total_height ]);
|
|
}
|
|
|
|
translate([ 0, 0, belt_height - idler_zmargin.x - gap ]) {
|
|
cylinder(r = slot_radius, slot_height);
|
|
translate([ -slot_radius, 0, 0 ])
|
|
cube([ post_radius * 2, post_radius * 2, slot_height ]);
|
|
translate([ 0, -slot_radius, 0 ])
|
|
cube([ post_radius * 2, post_radius * 2, slot_height ]);
|
|
}
|
|
|
|
cylinder(d = 3, h = total_height + 1, $fn = 30);
|
|
translate([ 0, 0, total_height - 2 ]) cylinder(r = 3, h = 3);
|
|
}
|
|
if($preview) {
|
|
idler(height = belt_height, toothed=toothed);
|
|
}
|
|
}
|
|
|
|
module flcorner() {
|
|
bom_item();
|
|
render() {
|
|
rotate([ 0, 0, 0 ]) {
|
|
corner_base();
|
|
rail_holder(false);
|
|
}
|
|
difference() {
|
|
translate([
|
|
-frame_size/2 - wall_thickness,
|
|
-frame_size/2 - wall_thickness - motor_mount_length,
|
|
-frame_size/2 - wall_thickness
|
|
])
|
|
cube([
|
|
frame_size + wall_thickness + corner_size,
|
|
motor_mount_length,
|
|
frame_size + wall_thickness * 2
|
|
]);
|
|
translate([ motor_shaft_xoffset, 0, 0 ]) nema17_housing();
|
|
|
|
}
|
|
// translate([motor_shaft_xoffset, 0, 0 ]) nema17_housing();
|
|
}
|
|
if ($preview)
|
|
translate([
|
|
motor_shaft_xoffset,
|
|
-nema17_face / 2 - frame_size / 2 - wall_thickness, frame_size / 2
|
|
]) {
|
|
nema17();
|
|
translate([ 0, 0, -frame_size / 2 + belt_height2 ]) { active_pulley(); }
|
|
}
|
|
}
|
|
|
|
module frcorner() {
|
|
bom_item();
|
|
render() {
|
|
rotate([ 0, 0, 90 ]) {
|
|
corner_base();
|
|
rail_holder(true);
|
|
}
|
|
difference() {
|
|
translate([
|
|
-frame_size/2 - corner_size,
|
|
-frame_size/2 - wall_thickness - motor_mount_length,
|
|
-frame_size/2 - wall_thickness
|
|
])
|
|
cube([
|
|
frame_size + wall_thickness + corner_size,
|
|
motor_mount_length,
|
|
frame_size + wall_thickness * 2
|
|
]);
|
|
translate([ -motor_shaft_xoffset, 0, 0 ]) nema17_housing();
|
|
|
|
}
|
|
}
|
|
if ($preview)
|
|
translate([
|
|
-motor_shaft_xoffset,
|
|
-nema17_face / 2 - frame_size / 2 - wall_thickness, frame_size / 2
|
|
]) {
|
|
nema17();
|
|
translate([ 0, 0, belt_height1 - frame_size / 2 ]) {
|
|
rotate([ 180, 0, 0 ]) active_pulley();
|
|
}
|
|
}
|
|
}
|
|
|
|
module blcorner() {
|
|
bom_item();
|
|
render()
|
|
rotate([ 0, 0, 270 ]) {
|
|
corner_base();
|
|
rail_holder(true);
|
|
}
|
|
translate([motor_shaft_xoffset + pulley_sbend_offset, 0, 0])
|
|
rotate([0,0,-90])
|
|
idler_post(belt_height = belt_height1, toothed=true);
|
|
|
|
translate([0, -(motor_shaft_xoffset + pulley_sbend_offset), 0])
|
|
rotate([0,0,-90])
|
|
idler_post(belt_height = belt_height2, toothed=true);
|
|
}
|
|
|
|
module brcorner() {
|
|
bom_item();
|
|
render()
|
|
rotate([ 0, 0, 180 ]) {
|
|
corner_base();
|
|
rail_holder(false);
|
|
}
|
|
translate([-(motor_shaft_xoffset + pulley_sbend_offset), 0, 0])
|
|
rotate([0,0,180])
|
|
idler_post(belt_height = belt_height2, toothed=true);
|
|
|
|
translate([0, -(motor_shaft_xoffset + pulley_sbend_offset), 0])
|
|
rotate([0,0,180])
|
|
idler_post(belt_height = belt_height1, toothed=true);
|
|
}
|
|
|
|
module xsled_slider() {
|
|
slider_len = bushing_len + 10;
|
|
screw_tab_len = 20;
|
|
screw_tab_thickness = 10;
|
|
|
|
render()
|
|
// translate([screw_tab_len, 0, 0])
|
|
difference() {
|
|
union() {
|
|
rotate([ 0, 90, 0 ]) { cylinder(d = frame_size, h = slider_len); }
|
|
|
|
translate([ 0, -frame_size / 2, 0 ])
|
|
cube([ slider_len, frame_size, frame_size / 2 ]);
|
|
|
|
*translate([ -screw_tab_len, -frame_size / 2, frame_size / 2 ]) cube(
|
|
[ screw_tab_len * 2 + slider_len, frame_size, screw_tab_thickness ]);
|
|
}
|
|
rotate([ 0, 90, 0 ]) {
|
|
cylinder(d = bushing_od, h = bushing_len);
|
|
cylinder(d = rail_diam * 1.1, slider_len * 2);
|
|
}
|
|
}
|
|
if ($preview)
|
|
rotate([ 0, 90, 0 ]) bushing();
|
|
}
|
|
|
|
module sled_cornera() {
|
|
bom_item();
|
|
corner_base();
|
|
translate([ -frame_size / 2 - wall_thickness, 0, -frame_size ])
|
|
xsled_slider();
|
|
}
|
|
|
|
module sled_cornerb() {
|
|
bom_item();
|
|
corner_base();
|
|
rotate([ 0, 0, 90 ])
|
|
translate([ -frame_size / 2 - wall_thickness, 0, -frame_size ])
|
|
xsled_slider();
|
|
}
|
|
|
|
module xsled_frame() {
|
|
translate([ -sled_xsize / 2 + corner_offset, -ysled_rail_spacing / 2, 0 ])
|
|
rotate([ 0, 90, 0 ]) tslot(sled_xsize - corner_offset * 2);
|
|
translate([ -sled_xsize / 2 + corner_offset, ysled_rail_spacing / 2, 0 ])
|
|
rotate([ 0, 90, 0 ]) tslot(sled_xsize - corner_offset * 2);
|
|
translate([ -sled_xsize / 2, -ysled_rail_spacing / 2 + corner_offset, 0 ])
|
|
rotate([ -90, 0, 0 ]) tslot(sled_ysize - corner_offset * 2);
|
|
translate([ sled_xsize / 2, -ysled_rail_spacing / 2 + corner_offset, 0 ])
|
|
rotate([ -90, 0, 0 ]) tslot(sled_ysize - corner_offset * 2);
|
|
|
|
translate([ -sled_xsize / 2, -sled_ysize / 2, 0 ]) sled_cornera();
|
|
translate([ sled_xsize / 2, sled_ysize / 2, 0 ]) rotate([ 0, 0, 180 ])
|
|
sled_cornera();
|
|
|
|
translate([ sled_xsize / 2, -sled_ysize / 2, 0 ]) rotate([ 0, 0, 90 ])
|
|
sled_cornerb();
|
|
translate([ -sled_xsize / 2, sled_ysize / 2, 0 ]) rotate([ 0, 0, 270 ])
|
|
sled_cornerb();
|
|
|
|
// simulate a piece of film
|
|
if (false) {
|
|
color("#0008") cube([ 5 * inch, 4 * inch, 1 ], center = true);
|
|
}
|
|
}
|
|
|
|
module xsled2() {
|
|
bom_item();
|
|
|
|
tab_len = bushing_len * 2;
|
|
tab_thickness = bushing_od + wall_thickness * 2;
|
|
glass_thickness = 3; // TODO: Update when an actual size is available
|
|
|
|
inner_ysize = sled_ysize - tab_thickness;
|
|
|
|
film_height = belt_height2 + belt_width / 2;
|
|
ledge_width = 15;
|
|
inside_ledge_width = 8;
|
|
outside_ledge_width = ledge_width - inside_ledge_width;
|
|
|
|
|
|
film_thickness = 0.25;
|
|
|
|
finger_notch_diam = 25;
|
|
finger_notch_smdepth = 2;
|
|
|
|
glass_holder_points = [
|
|
[0, -tab_thickness/2],
|
|
[0, film_height + glass_thickness],
|
|
[wall_thickness, film_height + glass_thickness],
|
|
[wall_thickness, film_height],
|
|
[outside_ledge_width, film_height],
|
|
[outside_ledge_width, film_height - glass_thickness],
|
|
[ledge_width, film_height - glass_thickness],
|
|
[wall_thickness * 2, -tab_thickness / 2]
|
|
];
|
|
|
|
echo("Ledge width: ", ledge_width - outside_ledge_width);
|
|
for (xsign = [ 1, -1 ], ysign = [ 1, -1 ]) {
|
|
translate([ sled_xsize / 2 * xsign, sled_ysize / 2 * ysign, 0 ])
|
|
rotate([ 0, -90 * xsign, 0 ]) {
|
|
difference() {
|
|
union() {
|
|
cylinder(d = tab_thickness, h = tab_len);
|
|
translate(
|
|
[ -tab_thickness / 2, ysign > 0 ? -tab_thickness / 2 : 0, 0 ])
|
|
cube([ tab_thickness, tab_thickness / 2 + 1, tab_len ]);
|
|
}
|
|
translate([ 0, 0, -0.5 ]) {
|
|
cylinder(d = bushing_od, h = bushing_len + 0.5);
|
|
cylinder(d = rail_diam * 1.1, h = tab_len + 1);
|
|
}
|
|
}
|
|
if ($preview) {
|
|
bushing();
|
|
}
|
|
}
|
|
|
|
// cube([sled_xsize, inner_ysize, tab_thickness/2], center=true);
|
|
difference() {
|
|
union() {
|
|
translate([ -sled_xsize / 2, -inner_ysize / 2, 0])
|
|
rotate([ 0, 90, 0 ]) rotate([ 0, 0, 90 ]) linear_extrude(sled_xsize)
|
|
polygon(glass_holder_points);
|
|
|
|
translate([ sled_xsize / 2, inner_ysize / 2, 0 ])
|
|
rotate([ 0, 90, 180 ]) rotate([ 0, 0, 90 ])
|
|
linear_extrude(sled_xsize) polygon(glass_holder_points);
|
|
|
|
translate([ sled_xsize / 2, -inner_ysize / 2, 0 ])
|
|
rotate([ 0, 90, 90 ]) rotate([ 0, 0, 90 ])
|
|
linear_extrude(inner_ysize) polygon(glass_holder_points);
|
|
|
|
translate([ -sled_xsize / 2, inner_ysize / 2, 0 ])
|
|
rotate([ 0, 90, -90 ]) rotate([ 0, 0, 90 ])
|
|
linear_extrude(inner_ysize) polygon(glass_holder_points);
|
|
}
|
|
|
|
for (x = [ -1, 1],
|
|
y = [ -1, 1]) {
|
|
translate([x * (sled_xsize/2 - outside_ledge_width - inside_ledge_width / 2),
|
|
y * (inner_ysize/2 - outside_ledge_width - inside_ledge_width / 2),
|
|
film_height])
|
|
rotate([180,0,0]) {
|
|
cylinder(d=4, h = 50);
|
|
cylinder(d=5, h = 4 + glass_thickness );
|
|
}
|
|
}
|
|
translate([
|
|
-10, -inner_ysize / 2,
|
|
|
|
film_height - glass_thickness + 0.5 - finger_notch_smdepth + finger_notch_diam / 2
|
|
]) rotate([90, 0, 0])
|
|
cylinder(d=finger_notch_diam, h = ledge_width * 3, center=true);
|
|
}
|
|
}
|
|
|
|
color("#fff3") if ($preview) {
|
|
// draw glass sheets
|
|
translate(
|
|
[ 0, 0, film_height - glass_thickness / 2 + 0.5 ])
|
|
cube(
|
|
[
|
|
sled_xsize - outside_ledge_width * 2,
|
|
inner_ysize - outside_ledge_width * 2,
|
|
glass_thickness
|
|
],
|
|
center = true);
|
|
*translate(
|
|
[ 0, 0, film_height + film_thickness * 2 + glass_thickness / 2 + 0.5 ])
|
|
cube(
|
|
[
|
|
sled_xsize - wall_thickness * 2,
|
|
inner_ysize - wall_thickness * 2,
|
|
glass_thickness
|
|
],
|
|
center = true);
|
|
}
|
|
if($preview) {
|
|
color("#0003")
|
|
translate([0, 0, film_height + 0.5]) {
|
|
cube([5*inch, 4*inch, film_thickness], center=true);
|
|
}
|
|
}
|
|
}
|
|
|
|
// render()
|
|
// xsled2(); |