diff --git a/roundedcube.scad b/roundedcube.scad new file mode 100644 index 0000000..a362882 --- /dev/null +++ b/roundedcube.scad @@ -0,0 +1,61 @@ +// Higher definition curves +$fs = 0.01; + +module roundedcube(size = [1, 1, 1], center = false, radius = 0.5, apply_to = "all") { + // If single value, convert to [x, y, z] vector + size = (size[0] == undef) ? [size, size, size] : size; + + translate_min = radius; + translate_xmax = size[0] - radius; + translate_ymax = size[1] - radius; + translate_zmax = size[2] - radius; + + diameter = radius * 2; + + module build_point(type = "sphere", rotate = [0, 0, 0]) { + if (type == "sphere") { + sphere(r = radius); + } else if (type == "cylinder") { + rotate(a = rotate) + cylinder(h = diameter, r = radius, center = true); + } + } + + obj_translate = (center == false) ? + [0, 0, 0] : [ + -(size[0] / 2), + -(size[1] / 2), + -(size[2] / 2) + ]; + + translate(v = obj_translate) { + hull() { + for (translate_x = [translate_min, translate_xmax]) { + x_at = (translate_x == translate_min) ? "min" : "max"; + for (translate_y = [translate_min, translate_ymax]) { + y_at = (translate_y == translate_min) ? "min" : "max"; + for (translate_z = [translate_min, translate_zmax]) { + z_at = (translate_z == translate_min) ? "min" : "max"; + + translate(v = [translate_x, translate_y, translate_z]) + if ( + (apply_to == "all") || + (apply_to == "xmin" && x_at == "min") || (apply_to == "xmax" && x_at == "max") || + (apply_to == "ymin" && y_at == "min") || (apply_to == "ymax" && y_at == "max") || + (apply_to == "zmin" && z_at == "min") || (apply_to == "zmax" && z_at == "max") + ) { + build_point("sphere"); + } else { + rotate = + (apply_to == "xmin" || apply_to == "xmax" || apply_to == "x") ? [0, 90, 0] : ( + (apply_to == "ymin" || apply_to == "ymax" || apply_to == "y") ? [90, 90, 0] : + [0, 0, 0] + ); + build_point("cylinder", rotate); + } + } + } + } + } + } +} \ No newline at end of file diff --git a/soundslab_10000_v1.scad b/soundslab_10000_v1.scad index 3690bdb..aeb0410 100644 --- a/soundslab_10000_v1.scad +++ b/soundslab_10000_v1.scad @@ -8,24 +8,38 @@ include // parameters - all lengths in mm battery_width = 60; battery_length = 102; -battery_depth = 13; +battery_depth = 19; // battery + UPS HAT + external USB-A port -depth_of_circuit_boards = 6; // includes tallest component +pi_width = 64; +pi_length = 30; +pi_height = 13; // pi zero w and Pirate Audio Headphone Amp HAT stacked lcd_width = 23.4; lcd_height = 23.4; lcd_depth = 6; // how far to recess from top surface of case +headphone_offset_length = 20; // from "top" +headphone_offset_depth = 5; // from "front" + +usb_a_offset_length = 15; // from "bottom" +usb_a_offset_depth = 11; // from "back" + +micro_usb_offset_width = 18; // from "right" +micro_usb_offset_depth = 11; // from "back" + // build +case_width = pi_width + 2; // wider of battery_width and pi_width +case_length = battery_length + pi_length + 2 + 2; // extra 2mm for space between battery and pi +case_depth = battery_depth + 2; // deeper of battery_depth and pi_depth difference() { // case color("white", 0.4) { roundedcube( [ - battery_width + 1, - battery_length + 1, - depth_of_circuit_boards + battery_depth + 2 + case_width, + case_length, + case_depth ], false, 5 @@ -36,9 +50,9 @@ difference() { color("white", 0.0) { roundedcube( [ - battery_width - 1, - battery_length - 1, - depth_of_circuit_boards + battery_depth + case_width - 2, + case_length - 2, + case_depth - 2 ], false, 5 @@ -49,9 +63,9 @@ difference() { // active area of the LCD screen is 23.4mm x 23.4mm according to http://www.lcdwiki.com/1.3inch_IPS_Module // lcd cutout translate ([ - ((battery_width + 1) / 2) + 8 - (lcd_width / 2), - ((battery_length + 1) - 10) - (lcd_height), - battery_depth + 6 + (case_width / 2) + 8 - (lcd_width / 2), + (case_length - 10) - (lcd_height), + case_depth - 6 ]) { color ("blue") { cube( @@ -63,9 +77,9 @@ difference() { // lcd buttons translate ([ - ((battery_width + 1) / 2) + 21, - ((battery_length + 1) - 18), - battery_depth + 6 + (case_width / 2) + 21, + (case_length - 18), + case_depth - 6 ]) { color ("green") { cube( @@ -76,9 +90,9 @@ difference() { } translate ([ - ((battery_width + 1) / 2) + 21, - ((battery_length + 1) - 28), - battery_depth + 6 + (case_width / 2) + 21, + (case_length - 28), + case_depth - 6 ]) { color ("green") { cube( @@ -89,9 +103,9 @@ difference() { } translate ([ - ((battery_width + 1) / 2) - 8, - ((battery_length + 1) - 18), - battery_depth + 6 + (case_width / 2) - 8, + (case_length - 18), + case_depth - 6 ]) { color ("green") { cube( @@ -102,9 +116,9 @@ difference() { } translate ([ - ((battery_width + 1) / 2) - 8, - ((battery_length + 1) - 28), - battery_depth + 6 + (case_width / 2) - 8, + (case_length - 28), + case_depth - 6 ]) { color ("green") { cube( @@ -116,9 +130,9 @@ difference() { // joystick translate ([ - ((battery_width + 1) / 2) - 17, - ((battery_length + 1) - 27.5), - battery_depth + 6 + (case_width / 2) - 17, + (case_length - 27.5), + case_depth - 6 ]) { rotate(a=45,v=[0,0,1]) { color ("green") { @@ -130,4 +144,47 @@ difference() { } } + // headphone jack + translate([ + -1, // start far left of device + case_length - headphone_offset_length, // distance from "top" + case_depth - headphone_offset_depth // distance from "front" + ]) { + rotate(a=90,v=[0,1,0]) { + color ("yellow") { + cylinder( + h=3, + d=4 + ); + } + } + } + + // usb-a port (external storage) + translate([ + -1, // start far left of device + usb_a_offset_length, // distance from "bottom" + case_depth - usb_a_offset_depth // distance from "back" + ]) { + color ("red") { + cube( + [3, 14, 7], + false + ); + } + } + + // micro-usb port (power) + translate([ + case_width - micro_usb_offset_width, // distance from "right" + -1, // start far bottom of device + case_depth - micro_usb_offset_depth // distance from "back" + ]) { + color ("purple") { + cube( + [9, 3, 3], + false + ); + } + } } \ No newline at end of file