// ============================================ // RASKOG Magnetic Skadis Separator // ============================================ // A customizable divider for the IKEA RASKOG cart. The vertical wall is // itself an IKEA Skadis pegboard panel, so real Skadis accessories hang on // the divider. It stands on a wide magnetic foot whose magnets grab the // steel wire-mesh floor of the RASKOG basket to hold the divider in place. // // The Skadis hole pattern comes from the shared lib/skadis-board generator // (40mm grid + 20mm offset grid), with selectable standard/dense density — // both stay compatible with off-the-shelf Skadis accessories. // // Magnets are glued into pockets that open at the BOTTOM of the foot's two // flange wings, so each magnet sits flush against the steel mesh for the // strongest hold. Pick bigger/more magnets for an even stronger grip. // // Print standing exactly as modeled (foot flat on the bed, wall up) — it is // support-free apart from the few-mm ceiling each magnet pocket bridges over. // Use a brim for the tall thin wall if your printer needs one. // // RASKOG basket interior (measured at the floor; walls taper inward): // bottom 288 x 405, middle 284 x 397, top 278 x 389 mm. // The default wall_width spans the short axis with clearance for the taper. // // Coordinate system: // Origin (0, 0, 0) = center of the foot footprint, on the basket floor. // X = wall length (along the basket axis being divided) // Y = thin direction (foot width + wall thickness) // Z = up use <../lib/skadis-board/skadis-board.scad>; // ============================================ // CUSTOMIZABLE PARAMETERS // ============================================ /* [Separator Wall] */ // Wall length (X, mm). Default spans the RASKOG short axis with clearance. wall_width = 270; // [40:1:400] // Skadis board height above the foot (Z, mm) wall_height = 80; // [40:1:200] // Board thickness (mm). Keep ~5 for Skadis accessory compatibility. wall_thickness = 5.0; // [4:0.1:6] // Hole pattern: standard Skadis checkerboard, or denser full 20mm grid wall_density = "dense"; // [standard, dense] // Slot short axis (Skadis nominal 5mm) wall_slot_width = 5.0; // [4:0.1:8] // Slot long axis (Skadis nominal 15mm) wall_slot_height = 15.0; // [10:0.1:25] // Countersink at each slot mouth (mm); 0 = sharp slot wall_edge_chamfer = 1.0; // [0:0.1:3] // Outer board corner radius (mm) wall_corner_r = 4; // [0:0.5:15] /* [Magnetic Foot] */ // Foot flange total width (Y, mm) — the wide base that resists tipping foot_flange_w = 34; // [12:1:80] // Foot flange height (Z, mm) — must contain the magnet pocket + floor foot_flange_h = 6; // [3:0.5:20] // Central neck width (Y, mm) — must be >= wall_thickness neck_w = 6; // [3:0.5:20] // Top of the neck where the wall begins (Z, mm) foot_height = 12; // [6:1:40] // Chamfer on the foot's bottom edges to avoid an elephant-foot lip (mm) foot_edge_chamfer = 1.0; // [0:0.1:4] // Concave fillet where the neck meets the flange top (mm) — strength join_fillet_r = 2.0; // [0:0.5:8] // How far the wall base sinks into the neck for a solid union (mm) merge_overlap = 3; // [1:0.1:8] /* [Magnets] */ // Magnet disc diameter (mm) magnet_diameter = 6; // [3:0.5:20] // Magnet disc height/thickness (mm) magnet_height = 3; // [1:0.5:6] // Magnet rows: 2 = one per wing (default, anti-tip), 1 = single offset row magnet_rows = 2; // [1, 2] // Magnets along the foot in each row magnet_per_row = 6; // [1:1:30] // Radial clearance around each magnet (glue gap, mm) magnet_fit_clear = 0.2; // [0:0.05:0.6] // How far the magnet sits above the bottom face (mm) — 0 = flush with the // foot bottom for the strongest grip; raise to recess/protect the magnet magnet_recess = 0.0; // [0:0.1:3] // Distance from the foot ends to the first/last magnet (mm) magnet_inset = 18; // [5:1:80] /* [Resolution] */ $fn = 64; // ============================================ // DERIVED DIMENSIONS // ============================================ foot_length = wall_width; // foot runs the full length of the wall hf = foot_flange_w / 2; // flange half-width (Y) nf = neck_w / 2; // neck half-width (Y) pocket_r = magnet_diameter / 2 + magnet_fit_clear; // Y of each magnet row: centered in the wing region that is clear of the // neck-to-flange fillet, so the magnet never collides with the fillet. wing_center_y = (nf + join_fillet_r + hf) / 2; wall_z = foot_height - merge_overlap; // board base Z (sunk into the neck) total_height = wall_z + wall_height; // overall part height (info) // ============================================ // PARAMETER VALIDATION // ============================================ assert(wall_width > 0 && wall_height > 0, "wall_width and wall_height must be positive"); assert(wall_thickness >= 4 && wall_thickness <= 6, "wall_thickness should be ~5mm for Skadis accessory compatibility"); assert(foot_flange_w > neck_w, "foot_flange_w must be greater than neck_w"); assert(neck_w >= wall_thickness, "neck_w must be >= wall_thickness so the wall seats on the foot"); assert(foot_height > foot_flange_h, "foot_height must be greater than foot_flange_h (the neck rises above the flange)"); assert(magnet_recess >= 0, "magnet_recess must be non-negative"); assert(foot_flange_h >= magnet_recess + magnet_height + 0.8, "foot_flange_h too small: needs magnet_recess + magnet_height + >=0.8mm cap above the magnet"); assert(magnet_diameter > 0 && magnet_height > 0, "magnet dimensions must be positive"); assert(magnet_rows == 1 || magnet_rows == 2, "magnet_rows must be 1 or 2"); assert(magnet_per_row >= 1, "magnet_per_row must be >= 1"); assert(magnet_fit_clear >= 0, "magnet_fit_clear must be non-negative"); assert(wing_center_y - pocket_r >= nf + join_fillet_r, "magnet pocket overlaps the neck/fillet — widen the flange or shrink the magnet"); assert(wing_center_y + pocket_r <= hf - foot_edge_chamfer - 0.5, "magnet pocket too close to the flange edge — widen the flange or shrink the magnet"); assert(2 * magnet_inset < foot_length, "magnet_inset too large for the foot length"); assert(magnet_per_row == 1 || (foot_length - 2 * magnet_inset) >= (magnet_per_row - 1) * (magnet_diameter + 2 * magnet_fit_clear + 2), "not enough foot length to fit magnet_per_row pockets without overlap"); assert(merge_overlap > 0 && merge_overlap < foot_height && merge_overlap < wall_height, "merge_overlap must fit within both the neck and the wall"); assert(foot_edge_chamfer >= 0 && 2 * foot_edge_chamfer < foot_flange_w && foot_edge_chamfer < foot_flange_h, "foot_edge_chamfer must fit within the flange"); assert(join_fillet_r >= 0 && join_fillet_r <= (foot_flange_w - neck_w) / 2 && join_fillet_r <= (foot_height - foot_flange_h), "join_fillet_r must fit within the flange-to-neck step"); // ============================================ // MAIN ASSEMBLY // ============================================ separator(); module separator() { union() { magnetic_foot(); translate([-wall_width / 2, -wall_thickness / 2, wall_z]) skadis_board( width = wall_width, height = wall_height, thickness = wall_thickness, density = wall_density, slot_w = wall_slot_width, slot_h = wall_slot_height, edge_chamfer = wall_edge_chamfer, corner_r = wall_corner_r); } } // ============================================ // COMPONENT MODULES // ============================================ // Inverted-T foot: a wide flat flange (the basket-floor footprint) with a // narrow central neck the wall seats on. Magnet pockets are subtracted from // the flange wings. Built by extruding the Y-Z cross-section along X. module magnetic_foot() { difference() { rotate([90, 0, 90]) // map 2D (u,v) -> (Y, Z); extrude along X linear_extrude(height = foot_length, center = true) polygon(_foot_profile( hf = hf, nf = nf, ch = foot_edge_chamfer, fh = foot_flange_h, th = foot_height, jf = join_fillet_r)); magnet_pockets(); } } // 2D cross-section of the foot in the Y-Z plane (first coord = Y, second = Z). // Symmetric inverted-T: chamfered bottom flange + concave fillets where the // vertical neck meets the flange top. function _foot_profile(hf, nf, ch, fh, th, jf, n_arc = 12) = let ( // Left inside fillet: flange top (z=fh) up to neck wall (Y=-nf). left_fillet = [ for (i = [0 : n_arc]) let (a = -90 + 90 * i / n_arc) [(-nf - jf) + jf * cos(a), (fh + jf) + jf * sin(a)] ], // Right inside fillet: neck wall (Y=nf) down to flange top (z=fh). right_fillet = [ for (i = [0 : n_arc]) let (a = 180 + 90 * i / n_arc) [(nf + jf) + jf * cos(a), (fh + jf) + jf * sin(a)] ] ) concat( [[-(hf - ch), 0], [-hf, ch], [-hf, fh]], left_fillet, [[-nf, th], [nf, th]], right_fillet, [[hf, fh], [hf, ch], [hf - ch, 0]] ); // Glue-in magnet pockets: vertical bores opening at the BOTTOM of the flange // wings. The magnet is glued in from below, seating against the pocket // ceiling magnet_recess above the bottom face; the solid cap above it is // what the print bridges over. module magnet_pockets() { rows_y = (magnet_rows == 2) ? [-wing_center_y, wing_center_y] : [wing_center_y]; for (y = rows_y) for (x = _magnet_x_positions()) translate([x, y, -1]) cylinder(h = magnet_recess + magnet_height + 1, r = pocket_r); } // Evenly spaced magnet X positions within the inset span (centered if one). function _magnet_x_positions() = let (span = foot_length / 2 - magnet_inset) (magnet_per_row == 1) ? [0] : [ for (i = [0 : magnet_per_row - 1]) -span + 2 * span * i / (magnet_per_row - 1) ];