1
0
mirror of https://github.com/nophead/Mendel90.git synced 2025-01-17 04:48:15 +01:00
Mendel90/scad/spool_holder.scad
Chris Palmer e0ee0fa2da Cleaned up spool holder.
Now uses offset instead of Minkowski.
 Dowels stronger and better fit.
2016-01-04 21:00:27 +00:00

467 lines
15 KiB
OpenSCAD

//
// Mendel90
//
// GNU GPL v2
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// Filament spool holder
//
include <conf/config.scad>
include <positions.scad>
use <wade.scad>
small_bearing = false;
bearing = small_bearing ? BB624 : BB608;
spool_screw = small_bearing ? M4_cap_screw : M8_cap_screw;
spool_penny_washer = small_bearing ? M5_penny_washer : M8_penny_washer;
spool_nut = screw_nut(spool_screw);
spool_washer = screw_washer(spool_screw);
thickness = 6;
wall = 2;
angle = 45;
hook = 8;
hook_overlap = 3;
tube_r = 4;
socket_r = tube_r - min_wall;
dowel_r = socket_r;
hook_r = 3;
left = left_stay_x + sheet_thickness(frame) / 2;
right = right_stay_x - sheet_thickness(frame) / 2;
spool_x = (left + right) / 2;
spool_y = gantry_Y + sheet_thickness(frame) + 10 + spool_height(spool) / 2;
bearing_r = (spool_diameter(spool) + ball_bearing_diameter(bearing)) / 2;
bearing_x = cos(angle) * bearing_r;
bearing_z = spool_z - sin(angle) * bearing_r;
bearing_y = (spool_width(spool) + spool_rim_thickness(spool)) / 2;
bracket_width = right - (spool_x + bearing_x);
bracket_height = height - bearing_z;
top_tube_x = bracket_width - tube_r;
top_tube_y = bracket_height + hook - tube_r;
bottom_tube_y = -bracket_height + tube_r;
middle_tube_x = washer_diameter(spool_washer) / 2 + 1 + tube_r;
dx = top_tube_x - middle_tube_x;
dy = top_tube_y;
tube_spacing = sqrt(dx * dx + dy * dy);
width = bearing_y * 2 - 2 * (thickness + washer_thickness(spool_washer) + ball_bearing_width(bearing) / 2);
function spool_holder_gap() = spool_y - width / 2 - thickness - (gantry_Y + sheet_thickness(frame));
sponge_length = 15;
sponge_depth = 15;
sponge_height = 15;
sponge_wall = 2;
feed_clip_length = 2 * (tube_r + 3);
feed_clip_width = sponge_depth + sponge_wall;
feed_clip_thickness = 3;
module pie_slice(r, start_angle, end_angle) {
R = r * sqrt(2) + 1;
a0 = (4 * start_angle + 0 * end_angle) / 4;
a1 = (3 * start_angle + 1 * end_angle) / 4;
a2 = (2 * start_angle + 2 * end_angle) / 4;
a3 = (1 * start_angle + 3 * end_angle) / 4;
a4 = (0 * start_angle + 4 * end_angle) / 4;
if(end_angle > start_angle)
intersection() {
circle(r);
polygon([
[0,0],
[R * cos(a0), R * sin(a0)],
[R * cos(a1), R * sin(a1)],
[R * cos(a2), R * sin(a2)],
[R * cos(a3), R * sin(a3)],
[R * cos(a4), R * sin(a4)],
]);
}
}
//
// Tube clips
//
module tube_clip() {
angle = atan(0.6);
linear_extrude(height = feed_clip_width, convexity = 5)
union() {
difference() {
pie_slice(tube_r + feed_clip_thickness, -angle, 180 + angle);
circle(tube_r);
}
for(a = [-angle, 180 + angle])
rotate(a)
translate([tube_r + feed_clip_thickness / 2, 0])
circle(feed_clip_thickness / 2);
}
}
filament_y = tube_r + feed_clip_thickness + feed_tube_tape_rad + eta;
filament_z = sponge_wall + sponge_depth / 2;
box_length = sponge_length + 2 * sponge_wall;
box_height = sponge_height + 2 * sponge_wall;
box_depth = sponge_depth + sponge_wall;
box_x = tube_spacing - box_length - feed_clip_length / 2 - 2;
box_y = filament_y - box_height / 2;
module dust_filter_stl() {
stl("dust_filter");
filament_hole_r = 2;
difference() {
union() {
tube_clip(); // clips at each end
translate([tube_spacing, 0, 0])
tube_clip();
translate([0, tube_r + eta, 0])
cube([tube_spacing, feed_clip_thickness, box_depth]); // joining strip
translate([box_x, box_y, 0])
cube([box_length, box_height, box_depth]); // box for dust trap
translate([0, filament_y, filament_z])
hull() {
rotate([-90, 0, 90])
cylinder(r = feed_tube_tape_rad + wall, h = wall + feed_tube_tape, center = true);
translate([-feed_tube_tape / 2, - wall, - filament_z])
cube([feed_tube_tape, 2 * wall, 1]);
}
}
translate([box_x + sponge_wall, box_y + sponge_wall, sponge_wall])
cube([sponge_length, sponge_height, sponge_depth + 1]);
translate([box_x + box_length / 2, filament_y, filament_z])
rotate([90, 0, 90])
teardrop(r = filament_hole_r, h = box_length + 1, center = true);
translate([0, filament_y, filament_z])
rotate([90, 0, 90])
teardrop(r = feed_tube_rad, h = wall + feed_tube_tape + 1, center = true);
translate([wall, filament_y, filament_z])
rotate([90, 0, 90])
teardrop(r = feed_tube_tape_rad, h = wall + feed_tube_tape, center = true);
}
}
screw_tab = screw_boss_diameter(frame_screw);
tab_thickness = part_base_thickness + ((frame_nut_traps) ? nut_trap_depth(nut) : 0);
nut_offset = frame_nut_traps ? -screw_tab / 2 + nut_radius(frame_nut) + 0.5 : 0;
//
// Tube with a dowel on top
//
module tube(height) {
difference() {
union() {
cylinder(r = tube_r + 0.001, h = height);
hull() {
cylinder(r = dowel_r, h = height + thickness - wall - 2 * layer_height); // dowel
cylinder(r = dowel_r - layer_height, h = height + thickness - wall - layer_height); // chamferred end
}
}
translate([0, 0, wall])
cylinder(r = tube_r - wall, h = height - 2 * wall);
translate([0, 0, height - layer_height]) // small hole to force solid layers above
cylinder(r = 1, h = layer_height);
translate([0, 0, height + 3 * layer_height]) // small hole to force solid layers above
cylinder(r = dowel_r - min_wall, h = layer_height);
}
}
//
// The outline of the bracket, triangle with rounded corners
//
module shape(width, height) {
hull() {
circle(washer_diameter(spool_washer) / 2 + 1);
translate([top_tube_x, top_tube_y])
circle(tube_r);
translate([top_tube_x, bottom_tube_y])
circle(tube_r);
}
}
//
// Inset to remove most of the plastic leaving a frame
//
frame_bar_width = 8;
module inner_shape(width, height) {
rad = 4;
inset = frame_bar_width + rad;
offset(rad)
offset(-inset)
shape(width, height);
}
//
// A bisexual bracket
//
module spool_bracket(width, height, tube) {
hole_r = screw_clearance_radius(spool_screw);
difference() {
union() {
linear_extrude(height = thickness, convexity = 5)
difference() {
union() {
shape(width, height);
hull() {
translate([width - tube_r, height - hook_overlap])
square([1, hook + hook_overlap]);
translate([width + sheet_thickness(frame) + hook - hook_r, height - hook_overlap + hook_r])
circle(hook_r);
translate([width + sheet_thickness(frame) + hook - hook_r, height + hook - hook_r])
circle(hook_r);
}
}
difference() {
inner_shape(width, height);
circle(washer_diameter(spool_washer) / 2 + 1 + 2 * tube_r);
}
poly_circle(hole_r); // hole for axel screw
translate([width, height - hook])
square([sheet_thickness(frame) + 0.2, hook]); // slot for frame
}
if(tube > 0) {
for(v = [
[top_tube_x, bottom_tube_y, 0],
[top_tube_x, top_tube_y, 0],
[middle_tube_x, 0, 0],
]) translate(v)
tube(tube + thickness);
translate([width - tab_thickness, -height + tube_r, 0])
cube([tab_thickness, screw_tab + tube_r, screw_tab + thickness]);
}
}
translate([width - part_base_thickness, -height + 2 * tube_r + screw_tab / 2 + nut_offset, thickness + screw_tab / 2 + nut_offset])
rotate([90, 0, -90])
part_screw_hole(frame_screw, frame_nut, horizontal = true);
if(tube < 0)
for(v = [
[top_tube_x, bottom_tube_y, thickness],
[top_tube_x, top_tube_y, thickness],
[middle_tube_x, 0, thickness],
]) translate(v)
cylinder(r = socket_r, h = - 2 * tube, center = true); // socket for dowel
}
}
//
// Male and female versions
//
module spool_bracket_female_stl() {
stl("spool_bracket_female");
spool_bracket(bracket_width, bracket_height, wall - thickness);
}
module spool_bracket_male_stl() {
stl("spool_bracket_male");
mirror([0, 1, 0]) spool_bracket(bracket_width, bracket_height, width);
}
//
// One bearing and bracket
//
module spool_bracket_assembly(male)
{
rotate([-90, 0, 0]) {
translate([0, 0, exploded * 15]) {
ball_bearing(bearing);
translate([0, 0, ball_bearing_width(bearing) / 2 + exploded * 5])
washer(spool_washer)
translate([0, 0, exploded * 5])
washer(spool_penny_washer)
screw(spool_screw, 30);
}
rotate([180, 0, 0])
translate([0, 0, ball_bearing_width(bearing) / 2]) {
translate([0, 0, exploded * -10])
washer(spool_washer) translate([0, 0, exploded * 5]) group() {
if(male)
color(plastic_part_color("lime")) render() spool_bracket_male_stl();
else
color(plastic_part_color("red")) render() spool_bracket_female_stl();
translate([0, 0, thickness]) {
translate([0, 0, exploded * 5])
washer(spool_washer)
nut(spool_nut, true);
}
}
}
if(male)
translate([right - (spool_x + bearing_x), -height + bearing_z + tube_r, -bearing_y]) {
translate([-part_base_thickness, tube_r + screw_tab / 2 + nut_offset, width / 2 - screw_tab / 2 - nut_offset])
rotate([0, -90, 0])
rotate([0, 0, 30])
frame_screw(part_base_thickness);
}
}
}
//
// The full assembly
//
module spool_assembly(show_spool = true) {
angle = atan(dx / dy);
tube_length = 750;
truncated = show_spool ? 200 : 100;
sponge_scale = 0.75 + exploded * 0.25;
assembly("spool_holder_assembly");
if(show_spool)
translate([spool_x, spool_y, spool_z])
rotate([90, 0, 0])
spool(spool);
for(side = [-1, 1]) {
translate([spool_x + side * bearing_x, spool_y + side * bearing_y, bearing_z])
rotate([0, 0, 90 - side * 90])
spool_bracket_assembly(false);
translate([spool_x + side * bearing_x, spool_y - side * bearing_y, bearing_z])
rotate([0, 180, 90 + side * 90])
spool_bracket_assembly(true);
if(side == -1)
translate([spool_x + side * (bearing_x + top_tube_x), spool_y + feed_clip_width / 2 + sponge_wall / 2, bearing_z + top_tube_y])
rotate([90, 90 - angle, 0]) {
color("red") render() dust_filter_stl();
translate([box_x + box_length / 2, box_y + box_height / 2, sponge_height / 2 + sponge_wall])
explode([-30, 50, 70]) difference() {
scale([sponge_scale, sponge_scale, sponge_scale])
sheet(Foam20, 20, 20);
translate([0, 0, sponge_depth / 2])
cube([22, 1, sponge_depth], center = true);
}
rotate([90, 0, 90])
translate([filament_y, feed_clip_width / 2 + sponge_wall / 2, -tube_length / 2 + (wall + feed_tube_tape) / 2]) {
difference() {
tubing(PF7, tube_length);
translate([0, 0, -truncated + tube_length / 2])
rotate([180, 0, 0])
cylinder(r = 20, h = 1000);
translate([0, 0, -truncated /2 + tube_length / 2])
rotate([30, 0, 0])
cylinder(r = 40, h = 5);
}
}
}
}
vitamin("PLA3040: PLA sample 3mm ~50m");
end("spool_holder_assembly");
}
module spool_holder_holes()
for(side = [-1, 1])
translate([side < 0 ? left: right, spool_y + side * (-width / 2 + screw_tab / 2 + nut_offset), bearing_z - bracket_height + 2 * tube_r + screw_tab / 2 + nut_offset])
rotate([0, 90, 0])
frame_screw_hole();
//
// All four laid out for building
//
module spool_holder_brackets_stl() {
w = top_tube_y - bottom_tube_y;
gap = 2 * tube_r + 2;
h = w / 2 + gap / sqrt(2);
x = h - top_tube_x;
for(i = [0:3]) {
odd = i % 2;
rotate([0, 0, i * 90])
translate([x, (odd ? -1 : 1) * (top_tube_y + bottom_tube_y) / 2,0])
if(odd)
spool_bracket_female_stl();
else
spool_bracket_male_stl();
}
}
//
// A pair laid out for building
//
module spool_holder_short_brackets_stl() {
gap = sheet_thickness(frame) + hook + 2;
rotate([0, 0, 90]) {
spool_bracket_female_stl();
translate([2 * bracket_width + gap, hook, 0])
rotate([0, 0, 180])
spool_bracket_female_stl();
}
}
module spool_holder_tall_brackets_stl() {
rotate([0, 0, 90]) {
spool_bracket_male_stl();
translate([2 * bracket_width + 2, hook_overlap + 2, 0])
rotate([0, 0, 180])
spool_bracket_male_stl();
}
}
module spool_holder_tall_brackets_x4_stl() {
w = top_tube_y - bottom_tube_y;
gap = 2 * tube_r + 2;
h = w / 2 + gap / sqrt(2);
x = h - top_tube_x;
for(i = [0:3])
rotate([0, 0, i * 90])
translate([x, (top_tube_y + bottom_tube_y) / 2,0])
spool_bracket_male_stl();
}
if(1)
translate([0, 0, - spool_z])
spool_assembly();
else
if(1)
spool_holder_brackets_stl();
else
dust_filter_stl();