1
0
mirror of https://github.com/nophead/Mendel90.git synced 2025-01-16 20:38:15 +01:00
Mendel90/scad/direct.scad
Chris Palmer ad21323ec6 Mods to support e3d in the main branch.
Tweaks to the huxley extruder.
Now shows hot end filament diameter on the BOM.
Moved huxley spool holder back to give more room for lighting.
Updated README.md.
Added huxley to command line usage messages.
2016-01-16 10:47:25 +00:00

524 lines
20 KiB
OpenSCAD

//
// Mendel90
//
// GNU GPL v2
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// Direct drive extruder
//
include <conf/config.scad>
use <d-motor_bracket.scad>
use <hot_end.scad>
MiniHyena = [5, 8, 13, 4, 6.3, 5.3, 1.5, 9, M3_grub_screw, 3];
function hobbed_id(type) = type[0];
function hobbed_od(type) = type[1];
function hobbed_length(type) = type[2];
function hobbed_offset(type) = type[3];
function hobbed_hob_od(type) = type[4];
function hobbed_hob_id(type) = type[5];
function hobbed_hob_radius(type) = type[6];
function hobbed_screw_z(type) = type[7];
function hobbed_screw_type(type) = type[8];
function hobbed_screw_l(type) = type[9];
module hobbed_pulley(type) {
od = hobbed_od(type);
id = hobbed_id(type);
len = hobbed_length(type);
vitamin(str("HOB",od, id, len, ": hobbed pulley ", od, ,"x", id));
color("DarkGoldenrod") render() difference() {
cylinder(r = od / 2, h = len);
cylinder(r = id / 2, h = len * 2 + 1, center = true);
translate([0, 0, hobbed_offset(type)])
rotate_extrude(a = 360)
translate([hobbed_hob_od(type) / 2 + hobbed_hob_radius(type), 0])
circle(r = hobbed_hob_radius(type));
translate([0, 0, hobbed_screw_z(type)])
rotate([-90, 0, 0])
cylinder(r = screw_radius(hobbed_screw_type(type)), h = od / 2 + 1);
}
}
module hobbed_pulley_assembly(type) {
hobbed_pulley(type);
translate([0, hobbed_id(type) / 2 + hobbed_screw_l(type) - 0.5, hobbed_screw_z(type)])
rotate([-90, 0, 0])
screw(hobbed_screw_type(type), hobbed_screw_l(type));
}
peg_spring = [6.5, 0.96, 16, 8];
pulley = MiniHyena;
idler = BB624;
d_extruder = extruder == Direct14 || extruder == Direct17 ? extruder : Direct17;
motor = extruder_motor(d_extruder);
spring = peg_spring;
compressed_spring = 9.5;
motor_thickness = 5;
motor_screw_depth = 3;
min_base_thickness = 8;
extension_clearance = 0.5;
extension = max(extension_clearance, nozzle_length(hot_end) - hot_end_length(hot_end));
jhead_screw = M3_cap_screw;
jhead_screw_length = 16;
jhead_washer = M4_washer;
jhead_screw_pitch = max(hot_end_insulator_diameter(hot_end) / 2 + screw_head_radius(jhead_screw),
hot_end_groove_dia(hot_end) / 2 + washer_diameter(jhead_washer) / 2);
jhead_nut_slot = nut_thickness(screw_nut(jhead_screw)) + 0.3;
angle = 30;
jhead_screw_angles = [angle, -angle, 180 - angle, -180 + angle];
extension_width = extruder_hole(d_extruder)[0] - 1;
extension_rad = jhead_screw_pitch + 5;
width = extruder_width(d_extruder);
length = min(extruder_length(d_extruder), 64);
base_thickness = max(min_base_thickness, jhead_screw_length - extension - 2 * washer_thickness(M3_washer) - washer_thickness(M4_washer));
height = base_thickness + NEMA_width(motor) + 1;
jhead_nut_offset = -(extension + base_thickness - 2 - jhead_nut_slot); // offset of nut from screw head
filament_r = extruder_filament(d_extruder) / 2;
filament_x = 0;
filament_z = width / 2;
filament_path_r = filament_r + 0.125;
motor_y = height - NEMA_width(motor) / 2 - 1;
motor_x = filament_x + filament_r + hobbed_hob_id(pulley) / 2;
motor_z = 0;
motor_screw_length = 8;
motor_screw_z = motor_screw_length - 2 * washer_thickness(M3_washer) - motor_screw_depth;
motor_plate_width = NEMA_width(motor) + 2;
motor_plate_rad = (motor_plate_width - NEMA_hole_pitch(motor)) / 2;
idler_closed_x = motor_x - hobbed_od(pulley) / 2 - ball_bearing_diameter(idler) / 2;
idler_x = filament_x - filament_r - ball_bearing_diameter(idler) / 2;
idler_z = filament_z;
idler_y = motor_y;
idler_clearance = 1;
motor_screw_offset = NEMA_hole_pitch(motor) / 2;
idler_pivot_x = motor_x - motor_screw_offset;
idler_pivot_y = motor_y + motor_screw_offset;
idler_swing_r = sqrt(sqr(idler_x -idler_pivot_x) + sqr(idler_y - idler_pivot_y));
idler_max_swing = atan((idler_closed_x - idler_pivot_x) / idler_swing_r);
pivot_screw_length = 25;
pivot_screw_z = min(pivot_screw_length - washer_thickness(M3_washer) - motor_screw_depth, width + eta);
lever_bottom_y = base_thickness + 1;
lever_width = 2 * motor_plate_rad + 1;
spring_x = idler_pivot_x - lever_width / 2;
spring_z = filament_z + filament_path_r + 3 * layer_height + screw_clearance_radius(M3_cap_screw);
spring_y = lever_bottom_y + 5;
filament_top_guide_r = tubing_od(PF7) / 2 + 2;
function direct_extruder_connector_offset() = [-motor_x, -width / 2, motor_y] + d_motor_connector_offset();
idler_clearance_r = ball_bearing_diameter(idler) / 2 + idler_closed_x - idler_x;
filament_bottom_guide_w = 2 * (filament_path_r + layer_height / 4 + min_wall);
filament_lower_gap = sqrt(sqr(idler_clearance_r) - sqr(idler_x - filament_x + filament_bottom_guide_w / 2));
filament_bottom_guide_length = idler_y - filament_lower_gap;
filament_botton_guide_height = filament_z - hobbed_offset(pulley) + hobbed_screw_z(pulley) - screw_radius(hobbed_screw_type(pulley)) - 0.5;
filament_bottom_guide_x = filament_x - filament_bottom_guide_w / 2;
bulkhead_x = filament_bottom_guide_x;
bulkhead_depth = filament_x + cos(angle) * jhead_screw_pitch - nut_trap_flat_radius(screw_nut(jhead_screw)) - bulkhead_x;
spring_screw_length = screw_longer_than(compressed_spring + 2 * washer_thickness(M4_washer) - (spring_x - bulkhead_x) + bulkhead_depth);
grub_screw_clearance_r = NEMA_shaft_dia(motor) / 2 + hobbed_screw_l(pulley);
module keyhole(r, h, l) {
R = r + layer_height / 4;
waist = 2 * R - 1;
entrance = 2 * R + 0.5;
y = sqrt(R * R - waist * waist / 4);
teardrop(h = h, r = R, center = true);
}
module direct_block_stl(include_support = true) {
stl("direct_block");
feed_tube_socket = 5;
insulator = hot_end_insulator_diameter(hot_end);
screw_pitch = hot_end_screw_pitch(hot_end);
insulator_depth = hot_end_inset(hot_end);
base_rad = 10.6;
filament_top_guide_length = feed_tube_socket + 2;
filament_top_guide_top = height + filament_top_guide_length - eta;
nut_channel_width = 2 * nut_radius(M4_nut) + 0.2;
nut_channel_z = idler_z - ball_bearing_width(idler) / 2 - nut_thickness(M4_nut) - layer_height;
difference(){
union(){
//
// motor plate
//
translate([motor_x - motor_plate_width / 2, 0, 0]){
hull() {
cube([motor_plate_width, 1, motor_thickness]);
for(x = [motor_plate_rad, motor_plate_width - motor_plate_rad])
translate([x, height - motor_plate_rad, 0])
cylinder(r = motor_plate_rad, h = motor_thickness);
}
}
//
// Filament guide
//
translate([bulkhead_x, 0, 0])
cube([bulkhead_depth, motor_y - grub_screw_clearance_r, width]);
translate([filament_bottom_guide_x, 0, 0])
cube([filament_bottom_guide_w, filament_bottom_guide_length, filament_botton_guide_height]);
hull() {
translate([filament_x, filament_top_guide_top - filament_top_guide_length, filament_z])
rotate([-90, 0, 0])
cylinder(r = filament_top_guide_r, h = filament_top_guide_length);
translate([filament_x - filament_top_guide_r, filament_top_guide_top - filament_top_guide_length, 0])
cube([filament_top_guide_r * 2, filament_top_guide_length, 1]);
}
// base
hull()
for(end = [-1 , 1])
translate([end * (length / 2 - base_rad), min_base_thickness / 2, filament_z])
intersection() {
union()
for(a = [-90, 90])
rotate([a, 0, 0])
teardrop(r = base_rad, h = min_base_thickness, truncate = false, center = true);
cube([width * 2, base_thickness + 1, width], center = true);
}
if(base_thickness > min_base_thickness) // nut housing
translate([motor_x - motor_plate_width / 2, 1, 0])
cube([2 * (filament_x - (motor_x - motor_plate_width / 2)), base_thickness - 1, width]);
if(extension)
translate([filament_x - extension_width / 2, -extension + extension_clearance + eta, 0])
intersection() {
cube([extension_width, extension - extension_clearance, width]);
translate([extension_width / 2, extension / 2, filament_z])
rotate([-90, 0, 0])
teardrop(r = extension_rad, h = extension + 1, center = true);
}
}
// filament path
translate([filament_x, 0, filament_z])
rotate([90,0,0]) {
teardrop_plus(h = 2 * filament_top_guide_top + 1, r = filament_path_r, center=true); // filament
translate([0, 0, -filament_top_guide_top])
teardrop_plus(h = feed_tube_socket * 2, r = tubing_od(PF7) / 2, center = true); // feed tube
}
//
// idler tension screw
//
translate([bulkhead_x + bulkhead_depth, spring_y, spring_z])
rotate([90, 0, 90])
nut_trap(screw_clearance_radius(M4_cap_screw), nut_radius(M4_nut), nut_thickness(M4_nut), horizontal = true);
//
// Bearing nut channel
//
translate([idler_pivot_x, idler_pivot_y, nut_channel_z])
linear_extrude(height = 100)
hull() {
translate([0, -idler_swing_r])
circle(nut_channel_width / 2);
rotate([0, 0, idler_max_swing])
translate([0, -idler_swing_r])
circle(nut_channel_width / 2);
}
// mounting holes
translate([filament_x, min_base_thickness, filament_z])
extruder_mounting_holes(true);
//
// holes for motor
//
translate([motor_x, motor_y, 0]) {
hub_recess = round_to_layer(NEMA_boss_height(motor)) + layer_height;
poly_cylinder(r = NEMA_big_hole(motor), h = hub_recess * 2, center = true); // motor hub slot
translate([0, 0, hub_recess + (include_support ? layer_height : -1)])
poly_cylinder(r = hobbed_od(pulley) / 2 + 0.5, h = width, center = false); // hole for shaft and pulley
for(x = NEMA_holes(motor), y = NEMA_holes(motor)) // motor screw holes
translate([x, y, motor_screw_z]) {
poly_cylinder(r = M3_clearance_radius, h = 100, center = true);
if(x > 0 || y < 0)
poly_cylinder(r = washer_diameter(M3_washer) / 2 + 0.5, h = 100, center = false);
}
}
//
// Hole for hot end
//
translate([filament_x, -extension + eta, filament_z])
rotate([90,0,0]) {
relief = 0.5;
translate([0, 0, -insulator_depth + hot_end_inset(hot_end) / 2]) // slot for the flange
keyhole(insulator / 2, hot_end_inset(hot_end), width - filament_z);
*translate([0, 0, -insulator_depth + relief / 2])
keyhole(insulator / 2 + 0.5, relief, width - filament_z); // relief to avoid corner radius
//
// Screw holes and nut traps
//
for(i = [0 : len(jhead_screw_angles) - 1])
rotate([0, 0, jhead_screw_angles[i]])
translate([jhead_screw_pitch, 0, 0])
rotate([0, 0, -jhead_screw_angles[i]]) {
translate([0, 0, washer_thickness(M4_washer) + washer_thickness(M3_washer) - extension_clearance])
teardrop_plus(r = screw_clearance_radius(jhead_screw), h = jhead_screw_length * 2, center = true);
translate([0, 0, jhead_nut_offset - jhead_nut_slot / 2]) {
w = nut_flat_radius(screw_nut(jhead_screw));
rotate([0, 0, 90])
nut_trap(0, nut_radius(screw_nut(jhead_screw)), jhead_nut_slot / 2, horizontal = true);
rotate([0, 0, jhead_screw_angles[i] < 0 ? 180 : 0])
translate([-w, -1, -jhead_nut_slot / 2])
cube([w * 2, 100, jhead_nut_slot], center = false);
}
}
}
}
}
module direct_motor_assembly(show_connector = true, exploded = exploded) {
assembly("extruder_motor_assembly");
// motor and gear
rotate([0, 0, 180]) {
NEMA(motor);
translate([0, 0, filament_z - hobbed_offset(pulley) + exploded * 20])
rotate([0, 0, -90])
hobbed_pulley_assembly(pulley);
}
if(show_connector)
d_motor_bracket_assembly();
end("extruder_motor_assembly");
}
module direct_idler_lever_stl() {
stl("direct_idler_lever");
w = lever_width;
h = width - motor_thickness - nut_thickness(M3_nut) - 3 * washer_thickness(M3_washer);
h2 = width - idler_z - ball_bearing_width(idler) / 2 - washer_thickness(M4_washer);
//h3 = width - motor_thickness - screw_head_height(M3_cap_screw) - 3 * washer_thickness(M3_washer);
h4 = width / 2 - filament_path_r - 0.5;
difference() {
union() {
linear_extrude(height = h, convexity = 10) {
union() {
hull() {
circle(ball_bearing_diameter(idler) / 2 - 0.5); // idler boss
translate([idler_x - idler_pivot_x, idler_pivot_y - idler_y]) // pivot boss
circle(w / 2);
}
hull() {
translate([idler_x - idler_pivot_x, idler_pivot_y - idler_y]) // idler boss
circle(w / 2);
translate([idler_x - idler_pivot_x - w / 2, lever_bottom_y - idler_y]) // bottom of lever
square([w, 1]);
}
}
}
linear_extrude(height = h4) // release handle
hull() {
translate([idler_x - idler_pivot_x, idler_pivot_y - idler_y])
circle(w / 2 - 2);
translate([idler_x - idler_pivot_x - 2 * motor_screw_offset, idler_pivot_y - idler_y])
circle(w / 2 - 2);
}
}
translate([0, 0, h2])
poly_cylinder(r = ball_bearing_diameter(idler) / 2 + 0.5, h = 10); // bearing socket
rotate([0, 0, 90])
nut_trap(2, nut_trap_radius(M4_nut, horizontal = false, snug = false), nut_trap_depth(M4_nut), supported = true); // nut trap for axle
translate([idler_x - idler_pivot_x, idler_pivot_y - idler_y, width - pivot_screw_z]) {
translate([0, 0, width > pivot_screw_z ? layer_height : -1]) // support membrane if needed
poly_cylinder(r = 3/2, h = 100, center = false); // pivot hole
rotate([180, 0, 0])
poly_cylinder(r = washer_diameter(M3_washer) / 2 + 0.5, h = 10); // counterbore
}
translate([idler_closed_x - spring_x, spring_y - idler_y, width - spring_z])
rotate([90, 0, 90])
tearslot(100, M4_clearance_radius, 1, true); // Tension screw slot
translate([idler_x - motor_x,
motor_y - idler_y,
width - (filament_z - hobbed_offset(pulley) + hobbed_screw_z(pulley))]) // clearance for grub screw
cylinder(r =grub_screw_clearance_r,
h = 2 * screw_radius(hobbed_screw_type(pulley)) + 1, center = true);
}
}
module direct_idler_assembly() {
translate([-idler_x, idler_z - width / 2 + exploded * 50, idler_y]) {
rotate([90, 0, 0]) {
translate([0, 0, idler_z - width])
color("lime") render() direct_idler_lever_stl();
explode([0, 0, 20])
ball_bearing(idler)
screw(M4_hex_screw, 16);
translate([0, 0, -ball_bearing_width(idler) / 2 + exploded * 10])
rotate([180, 0, 0])
washer(M4_washer);
translate([0, 0, idler_z - width + nut_trap_depth(M4_nut)])
rotate([180, 0, 90])
nut(M4_nut, true);
}
}
translate([-spring_x, spring_z - width / 2, spring_y])
rotate([0, 90, 0])
washer(M4_washer)
comp_spring(spring, compressed_spring)
washer(M4_washer)
screw(M4_cap_screw, spring_screw_length);
}
module direct_assembly(show_connector = true, show_drive = true) {
assembly("extruder_assembly");
color(wades_block_color) render()
difference() {
translate([0, -filament_z, 0])
rotate([90, 0, 180])
direct_block_stl(false);
*translate([-1,-10, filament_z]) // cross section
cube([200,100,100]);
}
if(show_drive) {
// mounting screws
translate([filament_x, 0, min_base_thickness])
extruder_mounting_screws();
// motor
translate([0, -40 * exploded, 0])
translate([-motor_x, motor_z - width / 2, motor_y])
rotate([90,0,180])
direct_motor_assembly(show_connector, 0);
// motor screws
translate([-motor_x, -width / 2 + motor_screw_z, motor_y])
rotate([-90, 0, 0])
NEMA_screws(motor, 3, motor_screw_length, M3_pan_screw);
// idler axle
translate([-idler_pivot_x, -width / 2, idler_pivot_y])
rotate([-90, 0, 0]) {
translate([0, 0, pivot_screw_z])
explode([0, 0, 50])
screw_and_washer(M3_cap_screw, pivot_screw_length);
translate([0, 0, motor_thickness])
explode([0, 0, 5])
washer(M3_washer)
explode([0, 0, 2])
star_washer(M3_washer)
explode([0, 0, 2])
nut(M3_nut)
explode([0, 0, 2])
washer(M3_washer);
}
//
// Filament
//
color("lime") render() cylinder(r = filament_r, h = 100);
//
// Idler
//
direct_idler_assembly();
translate([-bulkhead_x - bulkhead_depth, spring_z - width / 2, spring_y])
rotate([0, 90, 0])
explode([0, 0, -5])
nut(M4_nut);
}
//
// Hot end
//
translate([filament_x, 0, -extension])
hot_end_assembly();
//
// Hot end screws
//
translate([filament_x, 0, -extension])
for(i = [0 : len(jhead_screw_angles) - 1]) {
a = jhead_screw_angles[i];
rotate([180, 0, a]) {
translate([jhead_screw_pitch, 0, 0])
washer(jhead_washer)
screw_and_washer(jhead_screw, jhead_screw_length, true);
translate([jhead_screw_pitch, 0, jhead_nut_offset - jhead_nut_slot / 2 + nut_thickness(screw_nut(jhead_screw)) / 2])
explode( [ 15 * sin(-a), 15 * cos(-a), 0] * [-1,1,-1,1][i])
rotate([180, 0, -a + 90])
nut(screw_nut(jhead_screw));
}
}
end("extruder_assembly");
}
module direct_extruder_stl() {
direct_block_stl();
translate([filament_x + filament_bottom_guide_w + (idler_pivot_x - idler_x) + 2 * motor_screw_offset + lever_width / 2,
height - (idler_pivot_y - idler_y) + lever_width / 2, 0])
direct_idler_lever_stl();
}
if(1)
direct_assembly(true, true);
else
direct_extruder_stl();