sirens/designs/openscad/tests/siren_stator_custom.scad
Michael Winter 0fbf33b756 Restructure project with OpenSCAD redesign and v1 legacy code
- Move legacy FreeCAD files to v1/
- Add OpenSCAD programmatic CAD designs
- Add README and AGENTS.md documentation
- Add .gitignore
- Update firmware to v2 architecture
2026-03-29 14:24:42 +02:00

314 lines
12 KiB
OpenSCAD

/* [Stator Parameters] */
Outer_Diameter = 200; //[10:1:500] Outer diameter of the stator
Column_Height = 100; //[10:1:500] Height of the entire column
Base_Height = 5; //[1:0.1:50] Height of the base
Number_of_Ports = 7; //[3:1:20] Number of rectangular ports (works with odd or even)
Port_Height = 70; //[10:1:500] Height of the ports
Wall_Thickness = 5; //[1:0.1:50] Thickness of the column wall
Tolerance = 2; //[0:0.1:5]
/* [Hub Parameters] */
Hub_Diameter = 10; //[10:1:500] Diameter of the rotor hub
Shaft_Diameter = 5; //[1:0.1:50] Diameter of the motor shaft
/* [Blade Parameters] */
Blade_Thickness = 5; //[1:0.1:20] Thickness of each blade
module stator_core(outer_diameter, number_of_ports, column_height, port_height, base_height, wall_thickness, port_vertical_offset = 0) {
// Calculate port width based on equal arc length
port_width = (PI * outer_diameter) / (number_of_ports * 2);
// Calculate default vertical position to center the ports if no offset is provided
default_port_vertical_offset = (column_height - port_height) / 2;
// Use the provided offset or fall back to the centered position
final_port_vertical_offset = port_vertical_offset != 0 ?
default_port_vertical_offset - (port_vertical_offset / 2):
default_port_vertical_offset;
// Calculate inner diameter based on wall thickness
inner_diameter = outer_diameter - wall_thickness;
difference() {
union() {
// Base cylinder
cylinder(h = base_height, d = outer_diameter, $fn = 100);
// Main cylindrical body
translate([0, 0, base_height])
cylinder(h = column_height, d = outer_diameter, $fn = 100);
}
// Hollow out the center (open on top end)
translate([0, 0, base_height])
cylinder(h = column_height + 1, d = inner_diameter, $fn = 100);
// Create evenly spaced rectangular ports
for (i = [0 : number_of_ports - 1]) {
rotate([0, 0, i * (360 / number_of_ports)])
translate([outer_diameter/2 - wall_thickness * 2, -port_width/2, base_height + final_port_vertical_offset])
cube([wall_thickness * 2 + 1, port_width, port_height], center = false);
}
}
}
module stator() {
// Local variables set to global variables
outer_diameter = Outer_Diameter;
number_of_ports = Number_of_Ports;
column_height = Column_Height;
port_height = Port_Height;
base_height = Base_Height;
wall_thickness = Wall_Thickness;
// Use the module instead of calling it as a function
stator_core(outer_diameter, number_of_ports, column_height, port_height, base_height, wall_thickness);
}
module stator() {
// Local variables set to global variables
outer_diameter = Outer_Diameter;
number_of_ports = Number_of_Ports;
column_height = Column_Height;
port_height = Port_Height;
base_height = Base_Height;
wall_thickness = Wall_Thickness;
// Extension dimensions
extension_length = 20; // Length of extension
extension_width = 15; // Width of extension
fillet_radius = 2; // Fillet radius
screw_hole_diameter = 4; // M4 screw hole
support_ring_diameter = screw_hole_diameter + 6;
difference() {
union() {
// Original stator core
stator_core(outer_diameter, number_of_ports, column_height, port_height, base_height, wall_thickness);
// Top extensions at 4 cardinal points
translate([0, 0, base_height + column_height - wall_thickness])
for (i = [0 : 3]) {
rotate([0, 0, i * 90])
translate([outer_diameter/2, -extension_width/2, 0])
hull() {
// Corners with fillet
// Bottom left
translate([fillet_radius, fillet_radius, 0])
cylinder(r = fillet_radius, h = wall_thickness, $fn = 50);
// Bottom right
translate([extension_length - fillet_radius, fillet_radius, 0])
cylinder(r = fillet_radius, h = wall_thickness, $fn = 50);
// Top left
translate([fillet_radius, extension_width - fillet_radius, 0])
cylinder(r = fillet_radius, h = wall_thickness, $fn = 50);
// Top right
translate([extension_length - fillet_radius, extension_width - fillet_radius, 0])
cylinder(r = fillet_radius, h = wall_thickness, $fn = 50);
}
}
}
// M4 Screw holes through top extensions
translate([0, 0, base_height + column_height - wall_thickness])
for (i = [0 : 3]) {
rotate([0, 0, i * 90])
translate([outer_diameter/2 + extension_length/2, 0, -1])
cylinder(h = wall_thickness + 2, d = screw_hole_diameter, $fn = 50);
}
}
}
/*
module blade(outer_diameter, column_height, blade_thickness, blade_color) {
// Bezier curve function (cubic)
function bezier_cubic(p0, p1, p2, p3, t) =
pow(1-t, 3) * p0 +
3 * pow(1-t, 2) * t * p1 +
3 * (1-t) * pow(t, 2) * p2 +
pow(t, 3) * p3;
// Generate Bezier curve points
function generate_bezier_points(p0, p1, p2, p3, steps=20) =
[for (i = [0:steps]) bezier_cubic(p0, p1, p2, p3, i/steps)];
// Control points for the Bezier curve
p0 = [0, 0]; // Start point
p1 = [outer_diameter / 3, column_height];
p2 = [outer_diameter / 8, column_height];
p3 = [outer_diameter / 2, column_height]; // End point
// Generate curve points
curve_points = generate_bezier_points(p0, p1, p2, p3);
// Combine points to create polygon
points = concat(
curve_points,
[[outer_diameter/2, 0]] // Close the polygon
);
color(blade_color)
rotate([90, 0, 0]) // Rotate 90 degrees around X-axis
linear_extrude(height = blade_thickness, center = true)
polygon(points = points);
}
*/
module blade(outer_diameter, column_height, blade_thickness, blade_color) {
// Rectangular blade points
points = [
[outer_diameter * 0.5 / 2, 0], // Start at 40% of radius
[outer_diameter * 0.5 / 2, column_height],// Top left
[outer_diameter / 2, column_height],// Top right
[outer_diameter / 2, 0] // Bottom right
];
color(blade_color)
rotate([90, 0, 0]) // Rotate 90 degrees around X-axis
linear_extrude(height = blade_thickness, center = true)
polygon(points = points);
}
module rotor() {
// Local variables set to global variables
outer_diameter = Outer_Diameter - Wall_Thickness - Tolerance;
number_of_ports = Number_of_Ports;
column_height = Column_Height - Base_Height - (Tolerance * 2);
port_height = Port_Height;
base_height = Base_Height;
wall_thickness = Wall_Thickness;
port_vertical_offset = Tolerance * 2 + 1;
// Hub parameters from global variables
hub_diameter = Hub_Diameter;
shaft_diameter = Shaft_Diameter;
hub_height = base_height * 2;
// Blade parameters from global variables
number_of_blades = Number_of_Ports;
blade_thickness = Blade_Thickness;
rotation_offset = (360 / (number_of_ports * 4)) +
((blade_thickness / (PI * outer_diameter)) * 360 / 2);
difference() {
union() {
// Original stator_core module call
stator_core(outer_diameter, number_of_ports, column_height, port_height, base_height, wall_thickness, port_vertical_offset);
// Hub for motor attachment
translate([0, 0, 0])
cylinder(h = hub_height, d = hub_diameter, $fn = 100);
// Add blades
for (i = [0 : number_of_blades - 1]) {
rotate([0, 0, i * (360 / number_of_ports) + rotation_offset])
//rotate([0, 0, i * (360 / number_of_ports) + rotation_offset - 10])
mirror([0, 1, 0]) // Mirror along Z-axis
translate([0, 0, base_height])
//translate([40, 0, base_height])
//rotate([0, 0, -20])
//translate([-40, 0, 0])
blade(
outer_diameter - wall_thickness,
column_height,
blade_thickness,
"red" // Blade color
);
}
}
// Shaft hole for motor attachment
translate([0, 0, -1])
cylinder(h = hub_height + 2, d = shaft_diameter, $fn = 100);
}
}
module stator_cap() {
outer_diameter = Outer_Diameter;
wall_thickness = Wall_Thickness;
column_height = Column_Height;
base_height = Base_Height;
// Central hole diameter (60% of total diameter)
central_hole_diameter = outer_diameter * 0.6;
// M4 screw specifications
screw_hole_diameter = 4;
// Extension dimensions
extension_length = 20; // Length of extension
extension_width = 15; // Width of extension
fillet_radius = 2; // Fillet radius
// Screw hole support ring
support_ring_diameter = screw_hole_diameter + 6; // Adds extra material around screw hole
difference() {
union() {
// Base solid cylinder
cylinder(h = wall_thickness, d = outer_diameter, $fn = 100);
// Screw hole extensions at 4 cardinal points
for (i = [0 : 3]) {
rotate([0, 0, i * 90])
translate([outer_diameter/2 - wall_thickness, -extension_width/2, 0]) {
difference() {
// Filleted extension
hull() {
// Corners with fillet
// Bottom left
translate([fillet_radius, fillet_radius, 0])
cylinder(r = fillet_radius, h = wall_thickness, $fn = 50);
// Bottom right
translate([extension_length - fillet_radius, fillet_radius, 0])
cylinder(r = fillet_radius, h = wall_thickness, $fn = 50);
// Top left
translate([fillet_radius, extension_width - fillet_radius, 0])
cylinder(r = fillet_radius, h = wall_thickness, $fn = 50);
// Top right
translate([extension_length - fillet_radius, extension_width - fillet_radius, 0])
cylinder(r = fillet_radius, h = wall_thickness, $fn = 50);
}
// Centered screw hole support ring
translate([extension_length/2, extension_width/2, -1])
cylinder(h = wall_thickness + 2, d = support_ring_diameter, $fn = 100);
}
}
}
}
// Central hole
translate([0, 0, -1])
cylinder(h = wall_thickness + 2, d = central_hole_diameter, $fn = 100);
// M4 Screw holes through extensions
for (i = [0 : 3]) {
rotate([0, 0, i * 90])
translate([outer_diameter/2 + extension_length/2 - wall_thickness, 0, -1])
cylinder(h = wall_thickness + 2, d = screw_hole_diameter, $fn = 50);
}
}
}
// Render components separately
stator();
/*
translate([Outer_Diameter, 0, Base_Height + Tolerance])
rotor();
// Render cap separately and offset
translate([0, 0, Base_Height + Column_Height + Tolerance])
stator_cap();
*/