$fn = 64; // --- Parameters --- // Width of the inside cavity (accommodates the meter body) inner_width = 56; // Depth of the inside cavity inner_depth = 36; // Height of the holding basket basket_height = 30; // Wall thickness for the basket wall_thickness = 3; // Thickness of the mounting backplate mount_thickness = 5; // Radius for rounded corners corner_radius = 4; // Width of the slot for the soil probes probe_slot_width = 30; // Depth of the slot for the soil probes probe_slot_depth = 16; // Height of the backplate extending above the basket mount_height = 35; // Diameter of the mounting screws screw_dia = 4.5; // Diameter of the screw heads (for countersink) screw_head_dia = 8.5; // --- Derived Variables --- outer_width = inner_width + 2 * wall_thickness; total_height = basket_height + mount_height; backplate_y = wall_thickness + inner_depth; module soil_moisture_meter_holder() { difference() { // --- Main Solid Body --- union() { // Basket Exterior hull() { // Front left corner translate([-outer_width/2 + corner_radius, corner_radius, 0]) cylinder(r=corner_radius, h=basket_height); // Front right corner translate([outer_width/2 - corner_radius, corner_radius, 0]) cylinder(r=corner_radius, h=basket_height); // Back face (meets backplate) translate([-outer_width/2, backplate_y, 0]) cube([outer_width, 0.1, basket_height]); } // Mounting Backplate hull() { // Base anchors translate([-outer_width/2, backplate_y, 0]) cube([outer_width, mount_thickness, 0.1]); // Top rounded corners translate([-outer_width/2 + corner_radius, backplate_y, total_height - corner_radius]) rotate([-90, 0, 0]) cylinder(r=corner_radius, h=mount_thickness); translate([outer_width/2 - corner_radius, backplate_y, total_height - corner_radius]) rotate([-90, 0, 0]) cylinder(r=corner_radius, h=mount_thickness); } } // --- Cutouts --- // Inner Cavity (Meter Rest) hull() { translate([-inner_width/2 + corner_radius, wall_thickness + corner_radius, wall_thickness]) cylinder(r=corner_radius, h=basket_height + 1); translate([inner_width/2 - corner_radius, wall_thickness + corner_radius, wall_thickness]) cylinder(r=corner_radius, h=basket_height + 1); translate([-inner_width/2, backplate_y - 0.1, wall_thickness]) cube([inner_width, 0.1, basket_height + 1]); } // Probe Slot (Bottom Hole) probe_y_start = wall_thickness + (inner_depth - probe_slot_depth) / 2; hull() { translate([-probe_slot_width/2 + corner_radius, probe_y_start + corner_radius, -1]) cylinder(r=corner_radius, h=wall_thickness + 2); translate([probe_slot_width/2 - corner_radius, probe_y_start + corner_radius, -1]) cylinder(r=corner_radius, h=wall_thickness + 2); translate([-probe_slot_width/2 + corner_radius, probe_y_start + probe_slot_depth - corner_radius, -1]) cylinder(r=corner_radius, h=wall_thickness + 2); translate([probe_slot_width/2 - corner_radius, probe_y_start + probe_slot_depth - corner_radius, -1]) cylinder(r=corner_radius, h=wall_thickness + 2); } // Screw Holes translate([-inner_width/3, backplate_y - 1, basket_height + mount_height/2]) rotate([-90, 0, 0]) cylinder(d=screw_dia, h=mount_thickness + 2); translate([inner_width/3, backplate_y - 1, basket_height + mount_height/2]) rotate([-90, 0, 0]) cylinder(d=screw_dia, h=mount_thickness + 2); // Screw Countersinks translate([-inner_width/3, backplate_y - 0.01, basket_height + mount_height/2]) rotate([-90, 0, 0]) cylinder(d1=screw_head_dia, d2=screw_dia, h=mount_thickness - 1); translate([inner_width/3, backplate_y - 0.01, basket_height + mount_height/2]) rotate([-90, 0, 0]) cylinder(d1=screw_head_dia, d2=screw_dia, h=mount_thickness - 1); } } // Render the object soil_moisture_meter_holder();