/frame builder.scad
// Standard preamble stuff $fn=$preview ? 20 : 64; // All dimensions in mm // width of the module boards module_w = 38.1; // 1.5 inches // height of the module boards module_h = 46.99; // 1.85 inches // Distance between the hole and the edge hole_inset = 3.175; // Extra space between module mounts margin = 1; // Breadboard width (not including tabs) bb_w = 35.5; // Breadboard height bb_h = 47.5; // Width of the breadboard tabs bb_tab_w = 5; // Outer retaining wall width bb_wall = 2; // Probably nothing configurable below here; skip to the bottom // Width of the hole peg hole_w = hole_inset * 2; // Distance between holes on adjacent modules inter_hole_distance = hole_w + margin; // Distance between mounting holes, horizontal hole_distance_x = module_w - hole_inset * 2; // Distance between mounting holes, vertical hole_distance_y = module_h - hole_inset * 2; // Distance between mounting holes, diagonal hole_distance_cross = sqrt(hole_distance_x^2 + hole_distance_y^2); // Angle between diagonal holes cross_angle = atan2(hole_distance_x, hole_distance_y); bb_outer_w = bb_w + bb_wall * 2; bb_outer_h = bb_h + bb_wall * 2; module hole(h) { difference() { cylinder(h=h, r=hole_inset); translate([0, 0, -0.5]) cylinder(h+1, 2.5/2, 2.5/2); } cylinder(h=3, r=hole_inset); } module vframe() { hole(7); translate([0, hole_distance_y/2, 1.5]) cube([hole_w, hole_distance_y, 3], center=true); translate([0, hole_distance_y, 0]) hole(7); } module frame() { vframe(); translate([hole_distance_x, 0, 0]) vframe(); translate([hole_distance_x/2, 0, 1.5]) cube([hole_distance_x, hole_w, 3], center=true); translate([hole_distance_x/2, hole_distance_y, 1.5]) cube([hole_distance_x, hole_w, 3], center=true); translate([hole_distance_x/2, hole_distance_y/2, 1.5]) rotate([0, 0, 90-cross_angle]) cube([hole_distance_cross, hole_w, 3], center=true); translate([hole_distance_x/2, hole_distance_y/2, 1.5]) rotate([0, 0, 90+cross_angle]) cube([hole_distance_cross, hole_w, 3], center=true); } module module_row(n, skip=0, row=0) { for (i = [skip:n-1+skip]) { translate([i * (module_w + margin) + hole_inset, row * (module_h + margin) + hole_inset, 0]) frame(); if (i > skip) { translate([i * (module_w + margin) - hole_inset - margin, row * (module_h + margin), 0]) cube([inter_hole_distance, module_h, 3]); } } if (row > 0) { translate([skip * (module_w + margin), row * (module_h + margin) - hole_inset - margin, 0]) cube([n * (module_w + margin) - margin, inter_hole_distance, 3]); } } module breadboard() { difference() { cube([bb_outer_w, bb_outer_h, 5]); translate([bb_wall, bb_wall, 1]) cube([bb_w, bb_h, 4.1]); translate([bb_w/2 - bb_tab_w/2 + bb_wall, bb_h + bb_wall - 0.1, 1]) cube([bb_tab_w, bb_wall + 0.2, 4.1]); translate([-0.1, bb_h/2 - bb_tab_w/2 + bb_wall, 1]) cube([bb_wall + 0.2, bb_tab_w+0.1, 4.1]); } } // Put a breadboard in the second row, first column translate([0, module_h, 0]) breadboard(); // Patch left edge where frame and breadboard meet translate([0, module_h - hole_inset, 0]) cube([bb_wall, 4, 5]); // A row of modules in the first row module_row(2); // One module in the second row, starting in the second column module_row(1, skip=1, row=1);