289 lines
6.0 KiB
OpenSCAD
289 lines
6.0 KiB
OpenSCAD
/*
|
|
FireFly tetrahedron adapter
|
|
Base STL: tetrahedron40mmC.stl
|
|
|
|
Purpose:
|
|
- Import original 40 mm foldable tetrahedron STL
|
|
- Scale it to 60 mm base geometry
|
|
- Add cable holes, vent/drain holes, and optional PCB mounting holes
|
|
|
|
Workflow:
|
|
1. Set PART = "upper"
|
|
2. Render with F6
|
|
3. Export STL
|
|
4. Set PART = "lower"
|
|
5. Render with F6
|
|
6. Export STL
|
|
|
|
Notes:
|
|
- Hole coordinates are defined on the original 40 mm STL coordinate system.
|
|
- The script scales them automatically to 60 mm.
|
|
- First export should be treated as v0.1 prototype.
|
|
*/
|
|
|
|
|
|
/* =========================
|
|
Main selection
|
|
========================= */
|
|
|
|
PART = "upper"; // "upper", "lower", or "both_preview"
|
|
|
|
|
|
/* =========================
|
|
Input file
|
|
========================= */
|
|
|
|
input_stl = "tetrahedron40mmC.stl";
|
|
|
|
|
|
/* =========================
|
|
Scaling
|
|
========================= */
|
|
|
|
// Original tetrahedron edge length
|
|
original_edge_mm = 40;
|
|
|
|
// Target mechanical base size
|
|
target_edge_mm = 60;
|
|
|
|
// XY scale from 40 mm to 60 mm
|
|
scale_xy = target_edge_mm / original_edge_mm; // 1.5
|
|
|
|
// Keep original thickness.
|
|
// Set to 1.2 or 1.3 if you want a slightly thicker part.
|
|
scale_z = 1.0;
|
|
|
|
|
|
/* =========================
|
|
General hole settings
|
|
========================= */
|
|
|
|
hole_fn = 40;
|
|
cut_height = 20;
|
|
|
|
|
|
/* =========================
|
|
Feature switches
|
|
========================= */
|
|
|
|
add_upper_cable_holes = true;
|
|
add_upper_hanger_hole = true;
|
|
|
|
add_lower_vent_holes = true;
|
|
add_lower_cable_holes = true;
|
|
add_lower_pcb_mount_holes = true;
|
|
|
|
// Keep this false for the first prototype.
|
|
// Standoffs may interfere with folding depending on print orientation.
|
|
add_lower_pcb_standoffs = false;
|
|
|
|
|
|
/* =========================
|
|
Hole sizes
|
|
========================= */
|
|
|
|
cable_hole_d = 3.2; // for small solar-panel wires
|
|
hanger_hole_d = 3.5; // for small ring / wire / eyelet
|
|
vent_hole_d = 2.0; // condensation vent / drain holes
|
|
pcb_screw_hole_d = 2.2; // M2 clearance-ish
|
|
pcb_standoff_d = 6.0;
|
|
pcb_standoff_h = 3.0;
|
|
|
|
|
|
/* =========================
|
|
Coordinate reference
|
|
=========================
|
|
|
|
The uploaded STL is approximately:
|
|
|
|
X: -34.64 to +34.64
|
|
Y: -20.00 to +60.00
|
|
Z: -0.10 to +2.00
|
|
|
|
The original model is a flat foldable tetrahedron net.
|
|
Coordinates below are before scaling.
|
|
*/
|
|
|
|
|
|
/* =========================
|
|
Upper part hole positions
|
|
========================= */
|
|
|
|
// Cable holes for three solar panels.
|
|
// Adjust after checking where your real panel wires exit.
|
|
upper_cable_points = [
|
|
[-18, 20],
|
|
[ 24, 7],
|
|
[ 24, 33]
|
|
];
|
|
|
|
// Optional hanger hole close to one upper fold/vertex area.
|
|
// If this weakens the corner too much, disable it and use an external loop instead.
|
|
upper_hanger_points = [
|
|
[0, 38]
|
|
];
|
|
|
|
|
|
/* =========================
|
|
Lower part hole positions
|
|
========================= */
|
|
|
|
// Cable transfer holes between upper solar section and lower electronics bay.
|
|
lower_cable_points = [
|
|
[-10, 20],
|
|
[ 12, 13],
|
|
[ 12, 27]
|
|
];
|
|
|
|
// Small vent/drain hole clusters near likely lower/edge areas.
|
|
// These are deliberately small.
|
|
lower_vent_centres = [
|
|
[ 0, 3],
|
|
[ 0, 37],
|
|
[-30, 20],
|
|
[ 31, 20]
|
|
];
|
|
|
|
// Approximate triangular PCB mounting pattern.
|
|
// Tune this after measuring your actual red triangle PCB.
|
|
lower_pcb_mount_points = [
|
|
[ 0, 8],
|
|
[ 25, 20],
|
|
[ 0, 32]
|
|
];
|
|
|
|
|
|
/* =========================
|
|
Basic modules
|
|
========================= */
|
|
|
|
module base_import_scaled()
|
|
{
|
|
scale([scale_xy, scale_xy, scale_z])
|
|
import(input_stl, convexity = 10);
|
|
}
|
|
|
|
|
|
module vertical_hole(p, d)
|
|
{
|
|
translate([p[0] * scale_xy, p[1] * scale_xy, 1])
|
|
cylinder(h = cut_height, d = d, center = true, $fn = hole_fn);
|
|
}
|
|
|
|
|
|
module vent_cluster(p)
|
|
{
|
|
// Small 2 x 3 vent/drain pattern.
|
|
// Pitch is in final millimetres, not original model coordinates.
|
|
pitch = 3.0;
|
|
|
|
for (ix = [-1, 0, 1])
|
|
for (iy = [0, 1])
|
|
translate([
|
|
p[0] * scale_xy + ix * pitch,
|
|
p[1] * scale_xy + iy * pitch,
|
|
1
|
|
])
|
|
cylinder(h = cut_height, d = vent_hole_d, center = true, $fn = hole_fn);
|
|
}
|
|
|
|
|
|
module pcb_standoff(p)
|
|
{
|
|
// Standoff added on top of the flat STL.
|
|
// Use only if you confirm it does not block folding.
|
|
translate([p[0] * scale_xy, p[1] * scale_xy, 2.1 * scale_z])
|
|
cylinder(h = pcb_standoff_h, d = pcb_standoff_d, center = false, $fn = hole_fn);
|
|
}
|
|
|
|
|
|
/* =========================
|
|
Upper tetrahedron
|
|
========================= */
|
|
|
|
module upper_part()
|
|
{
|
|
difference()
|
|
{
|
|
base_import_scaled();
|
|
|
|
if (add_upper_cable_holes)
|
|
{
|
|
for (p = upper_cable_points)
|
|
vertical_hole(p, cable_hole_d);
|
|
}
|
|
|
|
if (add_upper_hanger_hole)
|
|
{
|
|
for (p = upper_hanger_points)
|
|
vertical_hole(p, hanger_hole_d);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* =========================
|
|
Lower tetrahedron
|
|
========================= */
|
|
|
|
module lower_part()
|
|
{
|
|
difference()
|
|
{
|
|
union()
|
|
{
|
|
base_import_scaled();
|
|
|
|
if (add_lower_pcb_standoffs)
|
|
{
|
|
for (p = lower_pcb_mount_points)
|
|
pcb_standoff(p);
|
|
}
|
|
}
|
|
|
|
if (add_lower_cable_holes)
|
|
{
|
|
for (p = lower_cable_points)
|
|
vertical_hole(p, cable_hole_d);
|
|
}
|
|
|
|
if (add_lower_vent_holes)
|
|
{
|
|
for (p = lower_vent_centres)
|
|
vent_cluster(p);
|
|
}
|
|
|
|
if (add_lower_pcb_mount_holes)
|
|
{
|
|
for (p = lower_pcb_mount_points)
|
|
vertical_hole(p, pcb_screw_hole_d);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* =========================
|
|
Output
|
|
========================= */
|
|
|
|
if (PART == "upper")
|
|
{
|
|
upper_part();
|
|
}
|
|
else if (PART == "lower")
|
|
{
|
|
lower_part();
|
|
}
|
|
else if (PART == "both_preview")
|
|
{
|
|
translate([-80, 0, 0])
|
|
upper_part();
|
|
|
|
translate([80, 0, 0])
|
|
lower_part();
|
|
}
|
|
else
|
|
{
|
|
echo("Invalid PART setting. Use upper, lower, or both_preview.");
|
|
}
|