/** Parameters */ $camera_mount = true; $base = true; $arm_base = true; $arm_pieces = 1; $screws = 1; $nuts = 1; $nut_bumps = false; /** Code */ module __no_more_parameters() {}; /** Scale nuts up slightly for easier fit and less friction. */ $nut_scale = 1.05; $triangle_width = 65; $triangle_height = 40; $triangle_thickness = 5.87; $triangle_screw_hole_diameter = 4.7; $triangle_x_hole_gap = 40; $triangle_y_hole_gap = 20; $triangle_x_offset = 19; $triangle_y_offset = 5; $fn = $preview ? 8 : 360; $steps_per_turn = $preview ? 8 : 128; use if ($camera_mount) { translate([-90, -40, 0]) camera_mount(); } if ($base) { screen_and_attachment(); pi_bed(); } module pi_bed() { $slat_count = 10; $slat_gap = 10.4; $slat_width = 4; $side_width = 6; $bed_depth = 6; $bed_width = 70; // slats for (i = [0:1:$slat_count - 1]) { translate([$slat_gap * i, -70, -$bed_depth]) cube([4, $bed_width, 4]); } // sides for (i = [0:1:1]) { color("blue") translate([0, -$bed_width * i - $side_width, -$bed_depth]) cube([97.6, $side_width, $bed_depth]); } // railings color("orange") translate([0, -$side_width - $bed_width, -$bed_depth]) cube([$slat_width / 2, $bed_width, $bed_depth]); color("orange") translate([97.6, -$side_width - $bed_width, -$bed_depth]) cube([$slat_width / 2, $bed_width + $side_width, $bed_depth]); } module screen_and_attachment() { color("green") translate([-15, 0, 0]) rotate([90, 0, 0]) attachment_point(); color("blue") translate([-0.5, 0, 4.5]) rotate([45, 0, -90]) screen_mount(); $screen_mount_support_width = 6; difference() { color("red") translate([44.5, -$screen_mount_support_width, 27.4]) rotate([0, -45, 0]) cube([12, $screen_mount_support_width, 18]); translate([50, -$screen_mount_support_width * 1.5, 0]) cube([20, $screen_mount_support_width * 2, 60]); }; } $camera_mount_thickness = 1; $camera_screw_gap_y = 25.2; $camera_screw_diameter = 2.75; module camera_mount() { difference() { cylinder(h=$camera_mount_thickness, d=$camera_screw_gap_y); translate([0, 0, -0.1]) cylinder(h=3 * $camera_mount_thickness, d=$camera_screw_gap_y - $camera_screw_diameter * 3); rotate([0, 0, 90]) translate([$camera_screw_gap_y / 2 - $camera_screw_diameter / 1.33, 0, -0.1]) cylinder(h=3 * $camera_mount_thickness, d=$camera_screw_diameter); rotate([0, 0, -90]) translate([$camera_screw_gap_y / 2 - $camera_screw_diameter / 1.33, 0, -0.1]) cylinder(h=3 * $camera_mount_thickness, d=$camera_screw_diameter); translate([-1 * $camera_screw_gap_y - $camera_screw_diameter / 1.33, -1 * $camera_screw_gap_y / 2, -0.1]) cube([$camera_screw_gap_y, $camera_screw_gap_y, 3 * $camera_mount_thickness]); }; $width = 20; $thickness = 3; $attachment_offset = 8.475; difference() { union() { color("orange") translate([$width + $attachment_offset, $thickness / 2, $width / 2]) rotate([90, 0, 0]) cylinder(d=$width, h=$thickness); intersection() { translate([$width + $attachment_offset, $thickness / 2, 0]) rotate([90, 0, 0]) cylinder(h=$thickness, d=$width * 2); translate([$attachment_offset, -$thickness / 2, 0]) cube([$width, $thickness, $width]); }; }; translate([$width + $attachment_offset, $thickness / 2, $width / 2]) rotate([90, 0, 0]) thread_hole_punch(); }; } module attachment_point() { difference() { linear_extrude($triangle_thickness) polygon([[0, 0], [$triangle_width, $triangle_height], [$triangle_width, 0]]); translate([$triangle_x_offset, $triangle_y_offset, 0]) union() { hole_puncher(); translate([$triangle_x_hole_gap, 0, 0]) hole_puncher(); translate([$triangle_x_hole_gap, $triangle_y_hole_gap, 0]) hole_puncher(); }; translate([$rounded_nose, 4.234, -0.2]) rotate([0, 0, 120]) nose_rounding(); translate([0, $triangle_height - $triangle_y_offset * 1.2, -0.1]) cube([100, 100, $triangle_thickness * 3]); translate([45, 12, -0.1]) cylinder(h=100, r=10); translate([28, 8, -0.1]) cylinder(h=100, r=4); }; }; $screen_enter_diameter = 10; $screen_lock_diameter = 6.25; $screen_enter_gap = 30 + $screen_lock_diameter; $screen_enter_y_offset = 14; $screen_mount_width = 50; $screen_mount_height = 60; $screen_mount_thickness = 5; $screen_side_cutout_size = 36; module screen_mount() { difference() { cube([$screen_mount_width, $screen_mount_height, $screen_mount_thickness]); translate([$screen_mount_width / 2, $screen_enter_y_offset, -0.1]) cylinder(h=$screen_mount_thickness * 2, d=$screen_enter_diameter); translate([$screen_mount_width / 2, $screen_enter_y_offset + $screen_enter_gap, -0.1]) cylinder(h=$screen_mount_thickness * 2, d=$screen_enter_diameter); for (i = [0:1:7]) { mount_hole_puncher(i * -1); }; translate([$screen_mount_width, $screen_mount_height / 2, -0.1]) cylinder(h=$screen_mount_thickness * 2, d=$screen_side_cutout_size); translate([0, $screen_mount_height / 2, -0.1]) cylinder(h=$screen_mount_thickness * 2, d=$screen_side_cutout_size); }; }; module mount_hole_puncher($gap) { translate([$screen_mount_width / 2, $screen_enter_y_offset + $gap, -0.1]) cylinder(h=$screen_mount_thickness * 2, d=$screen_lock_diameter); translate([$screen_mount_width / 2, $screen_enter_y_offset + $screen_enter_gap + $gap, -0.1]) cylinder(h=$screen_mount_thickness * 2, d=$screen_lock_diameter); }; module hole_puncher() { translate([0, 0, $triangle_thickness * -1]) cylinder(h=$triangle_thickness * 3, d=$triangle_screw_hole_diameter); }; $rounded_nose = 25; module nose_rounding() { difference() { color("red") cube([$rounded_nose, $rounded_nose, $triangle_thickness * 2]); translate([-3, 0, $triangle_thickness / -2]) color("blue") cylinder(h=$triangle_thickness * 3, d=$rounded_nose); }; }; module thread(backlash=0.1) { scale([0.5, 0.5, 0.5]) trapezoidThread(length=35, backlash=backlash, stepsPerTurn=$steps_per_turn); } $screw_head_diameter = 25; $screw_head_thickness = 8; $nut_head_bump_thickness = 0.5; module nut_head(thickness=$screw_head_thickness) { union() { cylinder(d=$screw_head_diameter, h=thickness, $fn=6); if ($nut_bumps) translate([0, 0, thickness]) nut_bumps(); }; } module nut_bumps() { bump_length = $screw_head_diameter * 0.05; bump_count = 24; for (i = [0:1:bump_count - 1]) { rotate([0, 0, i * (360 / bump_count)]) translate([$screw_head_diameter / 2 - bump_length * 3, 0, 0]) color("red") cube([bump_length, $nut_head_bump_thickness, $nut_head_bump_thickness]); } } module screw() { union() { translate([0, 0, $screw_head_thickness - 4]) thread(); nut_head(); }; } for (i = [0:1:$screws - 1]) { translate([-$screw_head_diameter, i * ($screw_head_diameter + 5), 0]) screw(); } for (i = [0:1:$nuts - 1]) { translate([-$screw_head_diameter * 2 - 8, i * ($screw_head_diameter + 5), 0]) difference() { nut_head(); scale([$nut_scale, $nut_scale, 1]) translate([0, 0, -4]) thread(backlash=-0.2); }; } module arm_piece() { union() { $thickness = 3; $length = 60; $width = 20; difference() { union() { cube([$length, $width, $thickness]); translate([0, $width / 2, 0]) cylinder(h=$thickness, d=$width); translate([$length, $width / 2, 0]) cylinder(h=$thickness, d=$width); }; translate([0, $width / 2, 0]) thread_hole_punch(); translate([$length, $width / 2, 0]) thread_hole_punch(); } if ($nut_bumps) { translate([0, $width / 2, $thickness]) nut_bumps(); translate([$length, $width / 2, $thickness]) nut_bumps(); } } } for (i = [0:1:$arm_pieces - 1]) { translate([0, (i + 1) * -40, 0]) arm_piece(); } module thread_hole_punch(height=50) { translate([0, 0, -0.1]) cylinder(d=13, h=height); } module arm_base() { $width = 20; $thickness = 3; $screw_top = 24.46175; $hole_height = $screw_top + $width / 2 + 1; difference() { union() { translate([0, $thickness / 2, $hole_height]) rotate([90, 0, 0]) cylinder(d=$width, h=$thickness); color("gray") translate([-$width / 2, -$thickness / 2, $screw_top]) cube([$width, $thickness, $width / 2 + 1]); }; translate([0, 2, $hole_height]) rotate([90, 0, 0]) thread_hole_punch(); } color("brown") translate([0, 0, $screw_top]) rotate([-180, 0, 0]) screw(); } if ($arm_base) { translate([-30, -40, 0]) arm_base(); }