/* [Siren General Parameters] */ siren_diameter = 125; // Base diameter siren_height = 50; // Height of the rotor number_of_ports = 5; // Number of ports tolerance = 2; // Tolerance between stator and rotor pressure_zone = 0.4; // Percentage of diameter round_radius = 4; // Rounding of top/bottom $fn = $preview ? 32 : 128; // Number of fragments /* [Stator Parameters] */ stator_wall_thickness = 8; // Stator wall thickness number_of_mounting_holes = 4; // Number of mounting holes screw_diameter = 3.2; // Diameter of screws - M3 clearance hole (3.2mm diameter) screw_bore_diameter = 6.5; screw_insert_diameter = 4; screw_bore_depth = 3; screw_length = 10 - (stator_wall_thickness - screw_bore_depth); stator_screw_offset = siren_diameter/2 - stator_wall_thickness/2; //distance to screws /* [Rotor Parameters] */ rotor_wall_thickness = 3; // Rotor wall thickness hub_height = 5; hub_diameter = 12; blade_angle = 15; port_height = siren_height - (rotor_wall_thickness * 2) - (tolerance * 2); // Height of the port /* [Motor Parameters] */ motor_shaft_diameter = 8; // Diameter of the motor body motor_frame_diameter = 60; motor_diameter = 28; // Diameter of the motor body motor_height = 45; magnet_diameter = 7; motor_screw_x_offset = 9.5; motor_screw_y_offset = 8; motor_screw_offset = 8; motor_frame_screw_offset = motor_frame_diameter/2 - stator_wall_thickness/2; //distance to screws // helper functions module ports(diameter, height, ports) { radius = diameter / 2; angle = 180 / ports; rotate([0, 0, 180 / ports]) for (i = [0:360/ports:360]) { rotate([0, 0, i]) linear_extrude(height) polygon(concat( [[0, 0]], // Center point [for (j = [0 : $fn]) [radius * cos(angle * j / $fn), radius * sin(angle * j / $fn)]] )); } } module column(outer_diameter, inner_diameter, height) { difference(){ // Outer cylinder cylinder(d = outer_diameter, h = height); // Subtract inner cylinder cylinder(d = inner_diameter, h = height); } } // Linear Interpolation function lerp(a, b, t) = a * (1 - t) + b * t; // Arc between points function function arc_between_points(p1, p2, height, steps=20) = [for(t = [0:1/steps:1]) let( x = lerp(p1.x, p2.x, t), y = lerp(p1.y, p2.y, t), // Parabolic arc height calculation arc_height = height * (1 - pow(2*t-1, 2)) ) [x, y + arc_height] ]; function bezier_curve(t, p0, p1, p2, p3, p4) = pow(1-t, 4) * p0 + 4 * pow(1-t, 3) * t * p1 + 6 * pow(1-t, 2) * pow(t, 2) * p2 + 4 * (1-t) * pow(t, 3) * p3 + pow(t, 4) * p4; function curved_polygon(points, steps, x_shift, y_shift) = let( left_curve = [for (t = [0 : 1/steps : 1]) bezier_curve(t, points[0], points[1], points[2], points[3], points[4]) ], right_curve = [for (pt = left_curve) [pt[0] + x_shift, pt[1] + y_shift] ] ) concat(left_curve, [for (i = [len(right_curve)-1 : -1 : 0]) right_curve[i]]); module stator(diameter, height, p_height, ports) { difference() { // Create column column(diameter, diameter - (stator_wall_thickness * 2), height); // Subtract ports translate([0, 0, (height - p_height) / 2]) ports(diameter, p_height, number_of_ports); // 4 M3 mounting holes for (i = [0:360/number_of_mounting_holes:360]) { // Top rotate([0, 0, i]) translate([stator_screw_offset, 0, -1]) cylinder(d = screw_insert_diameter, h = screw_length + 1); // Bottom rotate([0, 0, i]) translate([stator_screw_offset, 0, height - screw_length]) // Adjust position as needed cylinder(d = screw_insert_diameter, h = screw_length + 1); } } } module impeller_blades_straight(rotor_inner_diameter, rotor_height) { difference() { intersection() { // Column with full diameter cylinder(d = rotor_inner_diameter, h = rotor_height); // Blades union() { for (i = [0:360/number_of_ports:360]) { rotate([0, 0, i - 90]) translate([0, rotor_inner_diameter / 2, 0]) rotate([0, 0, blade_angle]) translate([-rotor_wall_thickness, -(rotor_inner_diameter / 2), 0]) linear_extrude(height = rotor_height, twist = 0, slices=360) square([rotor_wall_thickness, diameter]); } } } // Subtract core cylinder translate([0, 0, -1]) cylinder(d = diameter * pressure_zone, h = height + 10); } } module impeller_blade(radius, rotor_height){ // Generate points points1 = arc_between_points([0, -hub_diameter / 2], [radius, 0], -blade_angle); points2 = [for(p = [len(points1)-1:-1:0]) points1[p] - [0, -rotor_wall_thickness]]; // Create the blade by combining top and bottom points linear_extrude(height = rotor_height) polygon(concat( points1, points2 )); } module impeller_blades_curved(radius, rotor_height){ difference() { union() { // Rotate and create blades for (i = [0:360/number_of_ports:360]) { rotate([0, 0, i]) impeller_blade(radius, rotor_height); } } // Subtract core cylinder /* rounding_radius = 25; translate([0, 0, rotor_wall_thickness + rounding_radius]) minkowski() { // Original cylinder, reduced by twice the rounding radius cylinder( d = diameter * pressure_zone - (2 * rounding_radius), h = 1000 ); // Sphere for rounding sphere(r = rounding_radius); } */ top_rounding_radius = 5; bottom_rounding_radius = rotor_height / 2 - 1; translate([0, 0, rotor_height - top_rounding_radius - 0]) union(){ difference() { // Column with diameter = 2 * top_rounding_radius cylinder(d = (diameter * pressure_zone) + (top_rounding_radius * 2), h = top_rounding_radius + 10); // Top torus rotate_extrude() translate([((diameter * pressure_zone) + (top_rounding_radius * 2)) / 2, 0, 0]) circle(r = top_rounding_radius); } rotate([180, 0, 0]) minkowski() { // Original cylinder, reduced by twice the rounding radius cylinder( d = (diameter * pressure_zone) - (2 * bottom_rounding_radius), h = rotor_height - bottom_rounding_radius - (top_rounding_radius * 2) + 2 ); // Sphere for rounding sphere(r = bottom_rounding_radius); } } } } module rotor() { rotor_diameter = diameter - (stator_wall_thickness * 2) - (tolerance * 2); rotor_height = height - (tolerance * 2); rotor_inner_diameter = rotor_diameter - (rotor_wall_thickness * 2); difference() { union(){ difference() { // Outer cylinder cylinder(d = rotor_diameter, h = rotor_height); // Subtract inner cylinder translate([0, 0, rotor_wall_thickness]) cylinder(d = rotor_inner_diameter, h = rotor_height + 2); // Subtract ports translate([0, 0, -tolerance]) ports(); } /* // Central column for hub added after subtraction translate([0, 0, rotor_wall_thickness]) cylinder(d = hub_diameter, h = hub_height); */ // Add blades impeller_blades_curved(rotor_inner_diameter / 2, rotor_height); } translate([0, 0, -10]) cylinder(d = hub_diameter, h = 100); translate([0, 0, 0]) hub_attachment(0.2); /* // Subtract motor shaft hole translate([0, 0, -10]) intersection(){ cylinder(d = motor_shaft_diameter, h = 100); cube([motor_shaft_diameter, motor_shaft_diameter-1, 100], center = true); } */ } } module hub() { // Subtract motor shaft hole difference(){ cylinder(d = hub_diameter, h = hub_height + 3); translate([0, 0, -1]) intersection(){ cylinder(d = motor_shaft_diameter, h = 100); cube([motor_shaft_diameter, motor_shaft_diameter-1, 100], center = true); }; cylinder(d = motor_shaft_diameter, h = 2); } hub_attachment(); } module hub_attachment(aug = 0) { outer_diameter = hub_diameter + (tolerance * 6) + (aug * 2); mid_diameter = hub_diameter + (tolerance * 2) + (aug * 2); inner_diameter = outer_diameter - (tolerance * 2) - (aug * 2); difference(){ column(outer_diameter, inner_diameter, rotor_wall_thickness); translate([0, 0, -10]) ports(); } translate([0, 0, rotor_wall_thickness]) column(outer_diameter, mid_diameter, rotor_wall_thickness); column(mid_diameter, hub_diameter - (aug * 2), rotor_wall_thickness * 2); } module stator_top() { difference() { // Rounded top intersection() { // Unrounded full cylinder cylinder(d = diameter, h = stator_wall_thickness); // Add Minkowski rounded version minkowski() { cylinder(h = stator_wall_thickness - round_radius, d = diameter - round_radius * 2); sphere(r = round_radius); } } // Subtract central opening for pressure zone translate([0, 0, -1]) cylinder(d = diameter * pressure_zone, h = stator_wall_thickness + 2); // Subtract mounting holes for stator for (i = [0:360/number_of_mounting_holes:360]) { // Subtract screw hole rotate([0, 0, i]) translate([stator_screw_offset, 0, -1]) // Adjusted position cylinder(d = screw_diameter, h = stator_wall_thickness + 2); // Subtract counterbore rotate([0, 0, i]) translate([stator_screw_offset, 0, stator_wall_thickness - screw_bore_depth]) // Adjusted position cylinder(d = screw_bore_diameter, h = stator_wall_thickness); } } } module stator_bottom() { difference() { // Rounded bottom intersection() { // Unrounded full cylinder cylinder(d = diameter, h = stator_wall_thickness); // Minkowski rounded version minkowski() { cylinder(h = stator_wall_thickness - round_radius, d = diameter - round_radius * 2); sphere(r = round_radius); } } // Subtract central hole for motor translate([0, 0, -1]) cylinder(d = motor_diameter + (tolerance * 2), h = stator_wall_thickness + 5); // Subtract mounting holes for stator for (i = [0:360/number_of_mounting_holes:360]) { // Subtract screw hole rotate([0, 0, i]) translate([stator_screw_offset, 0, -1]) // Adjusted position cylinder(d = screw_diameter, h = stator_wall_thickness + 2); // Subtract counterbore rotate([0, 0, i]) translate([stator_screw_offset, 0, stator_wall_thickness - screw_bore_depth]) // Adjusted position cylinder(d = screw_bore_diameter, h = stator_wall_thickness); } // Subtract mounting holes for motor frame rotate([180, 0, 0]) translate([0, 0, -stator_wall_thickness]) for (i = [0:360/number_of_mounting_holes:360]) { // Subtract screw hole rotate([0, 0, i]) translate([motor_frame_screw_offset, 0, -1]) // Adjusted position cylinder(d = screw_diameter, h = stator_wall_thickness + 2); // Subtract counterbore rotate([0, 0, i]) translate([motor_frame_screw_offset, 0, stator_wall_thickness - screw_bore_depth]) // Adjusted position cylinder(d = screw_bore_diameter, h = stator_wall_thickness); } } } module motor_frame() { difference() { intersection(){ union(){ // Rounded base rotate([180, 0, 0]) translate([0, 0, -stator_wall_thickness]) intersection() { // Unrounded full cylinder cylinder(d = motor_frame_diameter, h = stator_wall_thickness); // Minkowski rounded version minkowski() { cylinder(h = stator_wall_thickness - round_radius, d = motor_frame_diameter - round_radius * 2); sphere(r = round_radius); } } translate([0, 0, stator_wall_thickness]) // Outer cylinder cylinder(d = motor_frame_diameter, h = motor_height); } // Outer cylinder cylinder(d = motor_frame_diameter, h = motor_height); } // Subtract inner cylinder translate([0, 0, stator_wall_thickness]) cylinder(d = motor_frame_diameter - (stator_wall_thickness * 2), h = motor_height + 2); // Subtract ports rotate([0, 0, -90/number_of_mounting_holes]) ports(number_of_mounting_holes); intersection(){ difference() { // Inner cylinder (subtract) translate([0, 0, -1]) cylinder(d = (motor_frame_screw_offset * 2) - stator_wall_thickness, h = motor_height + 2); translate([0, 0, 0]) cylinder(d = (motor_screw_y_offset * 2) + stator_wall_thickness, h = motor_height + 2); } // Subtract ports translate([0, 0, -stator_wall_thickness - 2]) rotate([0, 0, -90/number_of_mounting_holes]) ports(number_of_mounting_holes); } // Subtract mounting holes for frame for (i = [0:360/number_of_mounting_holes:360]) { rotate([0, 0, i]) translate([motor_frame_screw_offset, 0, motor_height - screw_length - 5]) // Adjusted position cylinder(d = screw_insert_diameter, h = 15); } // Subtract magnet hole translate([0, 0, -10]) cylinder(d = magnet_diameter + (tolerance * 2), h = 100); // Subtract mounting holes for motor for (i = [0:360/number_of_mounting_holes:360]) { rotate([0, 0, i]) { // Use modulo to alternate between x and y offsets motor_screw_offset = (floor(i / (360/number_of_mounting_holes)) % 2 == 0) ? motor_screw_x_offset : motor_screw_y_offset; translate([motor_screw_offset, 0, -1]) cylinder(d = screw_diameter, h = 15); } } } } module base() { union(){ difference(){ rotate_extrude() { polygon(curved_polygon( points = [ [diameter / 3, motor_height], [motor_frame_diameter / 2, motor_height - 5], [motor_frame_diameter / 2, 0], [motor_frame_diameter / 2, -10], [diameter / 3, -15] ], steps = 100, x_shift = -stator_wall_thickness, y_shift = 0 )); } // Subtract ports translate([0, 0, -25]) rotate([0, 0, -90/number_of_mounting_holes]) ports(number_of_mounting_holes, 45); /* translate([0, 0, -19]) // Subtract mounting holes for stator for (i = [0:360/number_of_mounting_holes:360]) { // Subtract screw hole rotate([0, 0, i]) translate([stator_screw_offset, 0, -1]) // Adjusted position cylinder(d = screw_diameter, h = stator_wall_thickness + 2); // Subtract counterbore rotate([0, 0, i]) translate([stator_screw_offset, 0, stator_wall_thickness - screw_bore_depth]) // Adjusted position cylinder(d = screw_bore_diameter, h = stator_wall_thickness); } */ } motor_frame(); translate([0, 0, -23]) stator_top(); } } stator(siren_diameter, siren_height, port_height, number_of_ports); //translate([diameter - 10, 0, tolerance]) /* intersection(){ cylinder(h = 30, d = 30); rotor(); } */ rotor(); /* translate([diameter - 10, 0, height + 10]) hub_attachment(); */ /* translate([0, 0, height + 2]) stator_top(); rotate([180, 0, 0]) translate([0, 0, 2]) stator_bottom(); //translate([0, 0, -motor_height - 10]) //motor_frame(); translate([0, 0, -motor_height - 15]) base(); */ /* stator(); translate([diameter + 10, 0, tolerance]) rotor(); translate([diameter * 2 + 10, 0, height + 2]) stator_top(); rotate([180, 0, 0]) translate([-diameter - 10, 0, 2]) stator_bottom(); translate([-diameter * 2 - 10, 0, -motor_height - 10]) motor_frame(); translate([-diameter * 3 - 10, 0, -motor_height - 10]) base(); */ /* // for testing difference(){ cylinder(h=5.5, d=20); translate([-5, 0, -1]) cylinder(h=10, d=screw_diameter); translate([-5, 0, 3]) cylinder(h=5, d=screw_bore_diameter); translate([5, 0, -1]) cylinder(h=10, d=screw_insert_diameter); } */