diff --git a/hardware/portapack_h1/case/pp_h1_case_2.scad b/hardware/portapack_h1/case/pp_h1_case_2.scad new file mode 100644 index 000000000..838800190 --- /dev/null +++ b/hardware/portapack_h1/case/pp_h1_case_2.scad @@ -0,0 +1,80 @@ +use +//use +use +include + +module case() { + difference() { + if( case_radiused ) { + case_outer_volume_radiused(); + } else { + case_outer_volume_squared(); + } + + union() { + if( case_radiused ) { + case_bottom_void_tool_volume_ball(); + } else { + case_bottom_void_tool_volume_end(); + } + + case_pcb_plane_void_tool_volume(); + pcb_attach_drills_volume(); + case_bumpers_emboss(); + translate([0, 0, h1_pcb_thickness]) portapack_h1_stack_drills(); + } + } +} + +/* Cross section */ +module case_cross_section() { + difference() { + case(); + translate([70, -10, -10]) cube([100, 100, 100]); + } +} + +module case_and_h1() { + case(); + translate([0, 0, h1_pcb_thickness]) hackrf_one(); +} + +module case_and_stack() { + case(); + translate([0, 0, h1_pcb_thickness]) portapack_h1_stack(); +} + +module stack_case_interference() { + intersection() { + case(); + translate([0, 0, h1_pcb_thickness]) portapack_h1_stack(); + } +} + +module stack_stack_interference() { + // Ensure stack and spacers do not interfere. + intersection() { + union() { + portapack_h1_stack_hackrf_one(); + portapack_h1_stack_portapack(); + } + portapack_h1_stack_spacers(); + } + + // Ensure screws do not interfere with stack. + intersection() { + union() { + portapack_h1_stack_hackrf_one(); + portapack_h1_stack_spacers(); + portapack_h1_stack_portapack(); + } + portapack_h1_stack_screws(); + } +} + +case(); +//case_and_h1(); +//case_and_stack(); +//case_cross_section(); +//stack_case_interference(); +//stack_stack_interference(); diff --git a/hardware/portapack_h1/case/pp_h1_parameters.scad b/hardware/portapack_h1/case/pp_h1_parameters.scad new file mode 100644 index 000000000..fa86fa9f8 --- /dev/null +++ b/hardware/portapack_h1/case/pp_h1_parameters.scad @@ -0,0 +1,64 @@ +pcb_l = 120; +pcb_w = 75; +pcb_corner_r = 4; +pcb_hole_r = 3.2 / 2; +pcb_hole_pad_r = 5.6 / 2; + +h1_pcb_thickness = 1.64; +pp_h1_pcb_thickness = 1.56; + +spacer_height = 0.5 * 25.4; + +bolt_drill_d = 3.0; +pcb_attach_drills_depth = 4.0; + +pcb_case_clearance = 0.5; +case_thickness = 1.5; +case_bottom_thickness = case_thickness * 2; +h1_pcb_bottom_clearance = 4.0; +case_bottom_tool_r = 3.0; +case_lid_thickness = 0.125 * 25.4; + +case_height_above_datum = h1_pcb_thickness + spacer_height + pp_h1_pcb_thickness + case_lid_thickness; +case_height_below_datum = case_bottom_thickness + h1_pcb_bottom_clearance; +case_height = case_height_below_datum + case_height_above_datum; + +attach_foot_r = pcb_hole_pad_r; +attach_drill_r = bolt_drill_d / 2.0; + +case_bumper_d = 0.5 * 25.4; +case_bumper_clearance = 0.5; +case_bumper_emboss_depth = 1.0; + +case_radiused = true; + +case_bumper_inset_from_pcb_edge = case_radiused ? 10.0 : 8.0; + +mounting_drills = [ + [4, 4], + [66, pcb_w - 4], + [116, 4], + [4, pcb_w - 4], + [71, pcb_w - 44], + [116, pcb_w - 4] +]; + +module pcb_extents() { + square([pcb_l, pcb_w]); +} + +module pcb_outline() { + minkowski() { + offset(r=-pcb_corner_r) { + pcb_extents(); + } + circle(r=pcb_corner_r); + } +} + +module pcb_outline_clearance() { + minkowski() { + pcb_outline(); + circle(r=pcb_case_clearance); + } +} diff --git a/hardware/portapack_h1/case/pp_h1_shell.scad b/hardware/portapack_h1/case/pp_h1_shell.scad new file mode 100644 index 000000000..86241a336 --- /dev/null +++ b/hardware/portapack_h1/case/pp_h1_shell.scad @@ -0,0 +1,152 @@ +include + +$fs=0.1; + +module attach_corner() { + circle(attach_foot_r); + polygon([[-10, -10],[attach_foot_r, -10],[attach_foot_r, 0],[0, attach_foot_r],[-10, attach_foot_r]]); +} + +module attach_side() { + circle(attach_foot_r); + translate([0, -attach_foot_r]) square([10, attach_foot_r * 2]); +} + +module attach_center() { + circle(attach_foot_r); +} + +module pcb_supports() { + translate(mounting_drills[0]) attach_corner(); + translate(mounting_drills[1]) rotate(90) attach_side(); + translate(mounting_drills[2]) rotate(90) attach_corner(); + translate(mounting_drills[3]) rotate(270) attach_corner(); + translate(mounting_drills[4]) attach_center(); + translate(mounting_drills[5]) rotate(180) attach_corner(); +} + +module pcb_attach_drill_outline() { + circle(r=attach_drill_r); +} + +module pcb_attach_drills_outline() { + for(p = mounting_drills) { + translate(p) pcb_attach_drill_outline(); + } +} + +module pcb_attach_drills_volume() { + translate([0, 0, -pcb_attach_drills_depth]) linear_extrude(height=30) { + pcb_attach_drills_outline(); + } +} + +module case_bottom_void_edge() { + // Edge of PCB, plus case clearance, minus board supports. + difference() { + pcb_outline_clearance(); + pcb_supports(); + } +} + +module case_bottom_void_tool_path() { + // Tool path to cut bottom of case. + offset(r=-case_bottom_tool_r) { + case_bottom_void_edge(); + } +} + +module case_bottom_void_tool_volume_ball() { + $fs=2; + $fn=18; + // Tool cut volume for bottom of case. + // Z=0 at bottom plane of H1 PCB + translate([0, 0, -h1_pcb_bottom_clearance + case_bottom_tool_r]) minkowski() { + linear_extrude(height=50, convexity=10) { + case_bottom_void_tool_path(); + } + sphere(r=case_bottom_tool_r); + } +} + +module case_outer_volume_radiused() { + $fs=2; + $fn=18; + tool_r = case_bottom_tool_r + case_thickness; + tz = h1_pcb_bottom_clearance + case_bottom_thickness - tool_r; + difference() { + // Rounded volume + translate([0, 0, -tz]) { + minkowski() { + linear_extrude(height=30, convexity=10) { + offset(r=-case_bottom_tool_r) { + pcb_outline_clearance(); + } + } + sphere(r=tool_r); + } + } + + // Cut off the top. + translate([-10, -10, case_height_above_datum]) cube([200, 200, 200]); + } +} + +module case_bottom_void_tool_volume_end() { + // Tool cut volume for bottom of case. + // Z=0 at bottom plane of H1 PCB + translate([0, 0, -h1_pcb_bottom_clearance]) { + linear_extrude(height=50) { + minkowski() { + case_bottom_void_tool_path(); + circle(r=case_bottom_tool_r); + } + } + } +} + +module case_bumper_emboss_outline() { + circle(r=case_bumper_d / 2 + case_bumper_clearance); +} + +module case_bumper_emboss_tool() { + height = 10; + translate([0, 0, -height]) linear_extrude(height=height) { + case_bumper_emboss_outline(); + } +} + +module case_bumpers_emboss() { + tz = case_height_below_datum - case_bumper_emboss_depth; + translate([0, 0, -tz]) { + translate([case_bumper_inset_from_pcb_edge, case_bumper_inset_from_pcb_edge, 0]) case_bumper_emboss_tool(); + translate([pcb_l - case_bumper_inset_from_pcb_edge, case_bumper_inset_from_pcb_edge, 0]) case_bumper_emboss_tool(); + translate([case_bumper_inset_from_pcb_edge, pcb_w - case_bumper_inset_from_pcb_edge, 0]) case_bumper_emboss_tool(); + translate([pcb_l - case_bumper_inset_from_pcb_edge, pcb_w - case_bumper_inset_from_pcb_edge, 0]) case_bumper_emboss_tool(); + } +} + +module case_pcb_plane_void_tool_edge() { + offset(r=-pcb_corner_r) { + pcb_outline_clearance(); + } +} + +module case_pcb_plane_void_tool_volume() { + linear_extrude(height=30, convexity=10) { + minkowski() { + case_pcb_plane_void_tool_edge(); + circle(r=pcb_corner_r); + } + } +} + +module case_outer_volume_squared() { + t = case_bottom_thickness + h1_pcb_bottom_clearance; + translate([0, 0, -t]) linear_extrude(height=t + case_height_above_datum) { + minkowski() { + pcb_outline(); + circle(r=pcb_case_clearance + case_thickness); + } + } +} diff --git a/hardware/portapack_h1/case/pp_h1_stack.scad b/hardware/portapack_h1/case/pp_h1_stack.scad new file mode 100644 index 000000000..d028c9d10 --- /dev/null +++ b/hardware/portapack_h1/case/pp_h1_stack.scad @@ -0,0 +1,846 @@ +include + +$fs=0.1; + +module pcb_mounting_hole_drill() { + circle(r=pcb_hole_r); +} + +module pcb_mounting_hole_drills() { + translate([ 64, 104]) pcb_mounting_hole_drill(); + translate([126, 104]) pcb_mounting_hole_drill(); + translate([176, 104]) pcb_mounting_hole_drill(); + translate([ 64, 171]) pcb_mounting_hole_drill(); + translate([131, 144]) pcb_mounting_hole_drill(); + translate([176, 171]) pcb_mounting_hole_drill(); +} + +//////////////////////////////////////////////////////// + +module pcb_cutout_antenna_pos() { + x = 61.5; + y1 = 154.75; + y2 = 167.25; + r = 1.5; + minkowski() { + polygon( + points=[[x+8,y1-4],[x,y1-4],[x,y1],[x+4,y1],[x+4,y2],[x,y2],[x,y2+4],[x+8,y2+4]] + ); + circle(r=r); + }; +} + +module pcb_cutout_antenna_neg_curve() { + x = 59.5; + y1 = 157; + y2 = 165; + r = 1.5; + minkowski() { + polygon( + points=[[x-2,y1],[x,y1],[x,y2],[x-2,y2]] + ); + circle(r=r); + }; +} + +module pcb_cutout_antenna_neg() { + x = 60.5; + y1 = 157; + y2 = 165; + w = -4; + union() { + polygon( + points=[[x+w,y1-3],[x,y1-3],[x,y2+3],[x+w,y2+3]] + ); + pcb_cutout_antenna_neg_curve(); + } +} + +module pcb_cutout_antenna() { + difference() { + pcb_cutout_antenna_neg(); + pcb_cutout_antenna_pos(); + } +} + +//////////////////////////////////////////////////////// + +module pcb_cutout_clocks_pos() { + x = 178.5; + y1 = 138.75; + y2 = 169.25; + r = 1.5; + w = 8; + w2 = 4; + minkowski() { + polygon( + points=[[x-w,y1-4],[x,y1-4],[x,y1],[x-w2,y1],[x-w2,y2],[x,y2],[x,y2+4],[x-w,y2+4]] + ); + circle(r=r); + }; +} + +module pcb_cutout_clock_neg_curve() { + x = 180.5; + y1 = 141; + y2 = 167; + r = 1.5; + w = 2; + minkowski() { + polygon( + points=[[x,y1],[x+w,y1],[x+w,y2],[x,y2]] + ); + circle(r=r); + }; +} + +module pcb_cutout_clocks_neg() { + x = 179.5; + y1 = 141; + y2 = 167; + w = 6; + union() { + polygon( + points=[[x,y1-3],[x+w,y1-3],[x+w,y2+3],[x,y2+3]] + ); + pcb_cutout_clock_neg_curve(); + } +} + +module pcb_cutout_clocks() { + difference() { + pcb_cutout_clocks_neg(); + pcb_cutout_clocks_pos(); + } +} + +//////////////////////////////////////////////////////// + +bulkhead_w = 6.35; +bulkhead_h = 6.35; +bulkhead_thickness = 1.02; + +barrel_d = 6.2; +barrel_clip_d = 5.5; +barrel_l = 12.45 - bulkhead_thickness; + +barrel_r = barrel_d / 2; +barrel_clip_r = barrel_clip_d / 2; + +peg_l = 3.81; +peg_w = 1.02; +peg_bottom_h = 0.76; +peg_top_h = 1.27; +peg_space = 1.78; + +module sma_73251_2120_pegs() { + peg_top_ty = bulkhead_h/2 - peg_bottom_h - peg_space - peg_top_h; + linear_extrude(height=peg_l) + { + translate([-bulkhead_w/2, peg_top_ty]) + square([peg_w, peg_top_h]); + translate([bulkhead_w/2 - peg_w, peg_top_ty]) + square([peg_w, peg_top_h]); + translate([-bulkhead_w/2, bulkhead_h/2 - peg_bottom_h]) + square([peg_w, peg_bottom_h]); + translate([bulkhead_w/2 - peg_w, bulkhead_h/2 - peg_bottom_h]) + square([peg_w, peg_bottom_h]); + } +} + +module sma_73251_2120_barrel_outline_circle() { + circle(r=barrel_r); +} + +module sma_73251_2120_barrel_outline() { + intersection() { + sma_73251_2120_barrel_outline_circle(); + square([barrel_clip_d, barrel_d + 1], center=true); + } +} + +module sma_73251_2120_barrel() { + linear_extrude(height=barrel_l) { + sma_73251_2120_barrel_outline(); + } +} + +module sma_73251_2120_bulkhead() { + linear_extrude(height=bulkhead_thickness) { + square([bulkhead_w, bulkhead_h], center=true); + } +} + +module sma_73251_2120_union() { + union() { + translate([0, 0, -peg_l]) sma_73251_2120_pegs(); + sma_73251_2120_bulkhead(); + translate([0, 0, bulkhead_thickness]) sma_73251_2120_barrel(); + } +} +/* +module sma_73251_2120() { + ty = bulkhead_h/2 - peg_bottom_h - peg_space/2; + rotate([90, 0, 0]) translate([0, -ty, 0]) { + union() { + translate([0, 0, -peg_l]) sma_73251_2120_pegs(); + sma_73251_2120_bulkhead(); + translate([0, 0, bulkhead_thickness]) sma_73251_2120_barrel(); + } + } +} +*/ +module sma_73251_2120_orient(board_thickness) { + // Align so that top surface of bottom peg is at z=0 (bottom of PCB). + t = peg_top_h / 2 + (peg_space - board_thickness) / 2; + translate([0, 0, -t]) rotate([90, 0, -90]) { + children(); + } +} + +module sma_73251_2120(refdes, board_thickness) { + sma_73251_2120_orient(board_thickness) { + sma_73251_2120_union(); + } +} + +module sma_73251_2120_drill(tolerance, board_thickness) { + sma_73251_2120_orient(board_thickness) { + linear_extrude(height=30) { + minkowski() { + sma_73251_2120_barrel_outline_circle(); + circle(r=tolerance); + } + } + } +} + +//////////////////////////////////////////////////////// + +module led(refdes, c) { + rotate(90) translate([-0.25, -2.15/2, -0.60]) { + color("gray") linear_extrude(height=0.60) { + square([0.50, 2.15]); + translate([0, 2.15/2]) circle(r=0.5); + } + } +} + +module led_drill() { + hole_diameter = 2; + + translate([0, -0.25, -0.3]) { + rotate([90, 0, 0]) { + cylinder(d=hole_diameter, h=10); + } + } +} + +//////////////////////////////////////////////////////// + +module sw_outline() { + circle(d=3.51, center=true); +} + +sw_a = 3.25; +sw_l = 5.85; +sw_tz = sw_l - sw_a; + +sw_large_hole_spacing = 7.01; +sw_large_hole_diameter = 1.30; +sw_small_hole_spacing = 4.50; +sw_small_hole_diameter = 0.99; +sw_large_small_hole_spacing = 2.49; +sw_pin_length_below_datum = 3.51; + +sw_button_z_offset = 4.01; + +module sw() { + rotate([180, 0, 90]) { + rotate([90, 0, 0]) { + translate([0, 4.01, sw_tz]) { + color("gray") translate([-7.11/2, -sw_button_z_offset, -3.68]) linear_extrude(height=3.68) square([7.11, 7.01]); + color("blue") linear_extrude(height=sw_a) sw_outline(); + } + } + + rotate([180, 0, 180]) linear_extrude(height=sw_pin_length_below_datum) { + translate([-sw_large_hole_spacing/2, sw_large_small_hole_spacing]) circle(d=sw_large_hole_diameter); + translate([ sw_large_hole_spacing/2, sw_large_small_hole_spacing]) circle(d=sw_large_hole_diameter); + translate([-sw_small_hole_spacing/2, 0]) circle(d=sw_small_hole_diameter); + translate([ sw_small_hole_spacing/2, 0]) circle(d=sw_small_hole_diameter); + } + } +} + +module sw_drill(clearance) { + translate([0, 0, -sw_button_z_offset]) { + rotate([0, -90, 0]) { + linear_extrude(h=10) { + minkowski() { + sw_outline(); + circle(r=clearance); + } + } + } + } +} + +//////////////////////////////////////////////////////// + +module header_x2(nx, b) { + ny = 2; + + w = 5.08; + d = 8.50; + + pin_spacing_x = 2.54; + pin_spacing_y = 2.54; + pin_d = 1.02; + pin_length = 3.2; + + rotate([180, 0, 0]) { + color("gray") translate([-b/2, -w/2, 0]) linear_extrude(height=d) square([b, w]); + + pin_tx = nx * pin_spacing_x / -2; + pin_ty = ny * pin_spacing_y / -2; + translate([pin_tx, pin_ty]) { + for(y = [1 : ny]) { + for(x = [1 : nx]) { + tx = (x - 0.5) * pin_spacing_x; + ty = (y - 0.5) * pin_spacing_y; + translate([tx, ty]) { + rotate([180, 0]) { + linear_extrude(height=pin_length) { + circle(d=pin_d); + } + } + } + } + } + } + } +} + +module header_11x2() { + nx = 11; + b = 28.44; + header_x2(nx, b); +} + +module header_13x2() { + nx = 13; + b = 33.52; + header_x2(nx, b); +} + +//////////////////////////////////////////////////////// + +module usb_plug_poly() { + inner_w1 = 6.9; + inner_h1 = 1.1; + inner_h = 1.85; + inner_w2 = 5.4; + inner_dw = inner_w1 - inner_w2; + + translate([-inner_w1/2, 0]) + polygon(points=[ + [0, 0], + [inner_w1, 0], + [inner_w1, inner_h1], + [inner_w1 - inner_dw/2, inner_h], + [inner_dw/2, inner_h], + [0, inner_h1] + ]); +} + +module usb_body_outline() { + body_buffer_r = 0.3; + + translate([0, body_buffer_r]) { + minkowski() { + usb_plug_poly(); + circle(r=body_buffer_r); + } + } +} + +module usb_plug_outline() { + outer_h = 3; + outer_ty = (outer_h - 2.45) / 2; + outer_buffer_r = 0.6; + + translate([0, outer_ty]) { + minkowski() { + usb_plug_poly(); + circle(r=outer_buffer_r); + } + } +} + +usb_body_h = 2.45; +usb_body_depth = 5.0; + +//usb_outer_w1 = 8; +usb_outer_depth = 0.63; + +module usb_transform() { + rotate([90, 180, 270]) translate([0, 0, -usb_outer_depth - 2.15 + 1.65]) children(); +} + +module usb() { + color("lightgray") usb_transform() { + translate([0, 0, usb_outer_depth]) { + linear_extrude(height=usb_body_depth) { + usb_body_outline(); + } + } + + linear_extrude(height=usb_outer_depth) { + usb_plug_outline(); + } + } +} + +module usb_drill(clearance) { + usb_transform() { + translate([0, 0, -usb_outer_depth - 10]) { + linear_extrude(height=20) { + minkowski() { + usb_plug_outline(); + circle(r=clearance); + } + } + } + } +} + +//////////////////////////////////////////////////////// + +module pcb_outline() { + minkowski() { + polygon( + points=[[64,104], [176,104], [176,171], [64,171]] + ); + circle(r=pcb_corner_r); + } +} + +module pcb_shape() { + difference() { + pcb_outline(); + pcb_cutout_antenna(); + pcb_cutout_clocks(); + pcb_mounting_hole_drills(); + } +} + +//////////////////////////////////////////////////////// + +module hackrf_one_components() { + color("green") linear_extrude(height=h1_pcb_thickness) pcb_shape(); + + translate([ 61.00, 161.00]) rotate( 0) sma_73251_2120("p4" , h1_pcb_thickness); + translate([179.00, 145.00]) rotate(180) sma_73251_2120("p2" , h1_pcb_thickness); + translate([179.00, 163.00]) rotate(180) sma_73251_2120("p16", h1_pcb_thickness); + + translate([ 61.00, 117.90]) rotate(-90) led("d7", "green"); + translate([ 61.27, 130.55]) rotate(-90) led("d8", "yellow"); + translate([ 61.27, 135.12]) rotate(-90) led("d2", "red"); + translate([ 61.27, 139.69]) rotate(-90) led("d4", "green"); + translate([ 61.27, 144.27]) rotate(-90) led("d5", "yellow"); + translate([ 61.27, 148.84]) rotate(-90) led("d6", "red"); + + translate([ 62.70, 111.40]) sw(); + translate([ 62.70, 124.40]) sw(); + + translate([171.76, 143.25]) rotate([0, 0, 90]) header_11x2("p20"); + translate([152.71, 164.84]) rotate([0, 0, 180]) header_13x2("p22"); + translate([123.50, 143.25]) rotate([0, 0, 90]) header_11x2("p28"); + + translate([180.00, 124.00]) usb(); +} + +module hackrf_one_transform() { + rotate([180, 0, 0]) translate([-60, -100 - pcb_w]) + children(); +} + +module hackrf_one() { + hackrf_one_transform() hackrf_one_components(); +} + +//////////////////////////////////////////////////////// + +module spacer() { + outer_d = 0.25 * 25.4; + inner_d = 0.140 * 25.4; + + //inner_d = ? + rotate([0, 180, 0]) { + color("lightgray") { + difference() { + linear_extrude(height=spacer_height) { + circle(d=outer_d); + } + translate([0, 0, -0.5]) { + linear_extrude(height=spacer_height + 1) { + circle(d=inner_d); + } + } + } + } + } +} + +module screw() { + wrench_sides = 6; + wrench_diameter = 2.0 / cos(360 / wrench_sides / 2); + + head_height = 2.0; + head_d = 5.5; + + shaft_length = 20.0; + threaded_d = 3.0; + + color("gray") { + translate([0, 0, -head_height]) difference() { + linear_extrude(height=head_height) + circle(d=head_d); + translate([0, 0, -0.5]) linear_extrude(height=head_height + 1) + circle(d=wrench_diameter, $fn=wrench_sides); + } + linear_extrude(height=shaft_length) + circle(d=threaded_d); + } +} + +//////////////////////////////////////////////////////// + +module header_mle_dual(name, nx) { + w = nx * 2.54; + h = 5; + d = 2.54; + offset = 3.81 - d; + + base_h = 7.44; + + translate([-w/2, -h/2, offset]) { + color("gray") linear_extrude(height=d) square([w, h]); + } + translate([-w/2, -base_h/2]) { + color("lightgray") { + linear_extrude(height=offset) square([w, base_h]); + } + } +} + +module lcd_kingtech() { + body_w = 42.72; + body_h = 60.26; + body_d = 2.50; + + touch_d = 0.7; + + tape_d = 0.1; + + view_w = 36.72; + view_h = 48.96; + view_tx = (body_w - view_w) / 2; + view_ty = 1.25 + 2.95; + + tab_w = 0.7; + tab_h = 2.5; + tab_d = 0.9; + tab_tz = body_d - tab_d; + tab_bot_ty = body_h - tab_h; + + translate([-body_w / 2, -view_ty - view_h/2, -(body_d + touch_d)]) { + translate([0, 0, touch_d]) { + color("beige") difference() { + linear_extrude(height=body_d) { + square([body_w, body_h]); + } + + translate([view_tx, view_ty, -1]) { + linear_extrude(height=2) { + square([view_w, view_h]); + } + } + } + + color("beige") translate([0, 0, tab_tz]) { + linear_extrude(height=tab_d) { + translate([-tab_w, 0]) square([tab_w, tab_h]); + translate([-tab_w, tab_bot_ty]) square([tab_w, tab_h]); + translate([body_w, 0]) square([tab_w, tab_h]); + translate([body_w, tab_bot_ty]) square([tab_w, tab_h]); + } + } + + color("black") translate([view_tx, view_ty]) { + linear_extrude(height=1) { + square([view_w, view_h]); + } + } + } + + color("lightgray", alpha=0.5) { + linear_extrude(height=touch_d) { + square([body_w, body_h]); + } + } + } +} + +module control_wheel() { + h = 6.0; + + top_d = 32.0; + top_h = 3.0; + + ring_d = 34.4; + ring_h = 0.2; + + bot_d = ring_d; + bot_h = h - ring_h - top_h; + + translate([0, 0, -h]) + color("white") + linear_extrude(height=top_h) + circle(d=top_d); + + translate([0, 0, -(h - top_h)]) + color("white") + linear_extrude(height=ring_h) + circle(d=ring_d); + + translate([0, 0, -(h - top_h - ring_h)]) + color("black") + linear_extrude(height=bot_h) + circle(d=bot_d); +} + +module audio_jack_hole() { + hole_outer_d = 5.00; + + circle(d=hole_outer_d); +} + +audio_jack_body_w = 6.00; +audio_jack_body_h = 5.00; +audio_jack_body_depth = 15.5; + +audio_jack_hole_inner_d = 3.600; +audio_jack_hole_depth = 1.5; + +audio_jack_mounting_offset = 7; + +module audio_jack() { + color("gray") rotate([90, 0, 0]) { + translate([0, audio_jack_body_h/2, -audio_jack_hole_depth - audio_jack_mounting_offset]) { + translate([0, 0, audio_jack_hole_depth]) + linear_extrude(height=audio_jack_body_depth) + square([audio_jack_body_w, audio_jack_body_h], center=true); + difference() { + linear_extrude(height=audio_jack_hole_depth) + audio_jack_hole(); + translate([0, 0, -0.5]) + linear_extrude(height=audio_jack_hole_depth + 1) + circle(d=audio_jack_hole_inner_d); + } + } + } +} + +module audio_jack_drill(diameter) { + translate([0, audio_jack_mounting_offset, audio_jack_body_h/2]) { + rotate([-90, 0, 0]) { + linear_extrude(height=10) { + circle(r=diameter / 2.0); + } + } + } +} + +micro_sd_body_h = 1.32; +micro_sd_body_w = 13.825; +micro_sd_body_depth = 15.25; + +micro_sd_card_w = 11.0; +micro_sd_card_h = 1.0; +micro_sd_card_depth = 15.0; + +micro_sd_card_tx = 0.9; +micro_sd_card_ty = (micro_sd_body_h - micro_sd_card_h) / 2; +micro_sd_card_insert_depth = micro_sd_card_depth - 2.3; + +micro_sd_card_eject_depth = micro_sd_card_depth - (2.3 + 3.3); + +module micro_sd() { + translate([-micro_sd_body_w/2, -micro_sd_body_depth/2]) { + rotate([90, 0, 0]) { + color("lightgray") difference() { + translate([0, 0, -micro_sd_body_depth]) + linear_extrude(height=micro_sd_body_depth) + square([micro_sd_body_w, micro_sd_body_h]); + translate([micro_sd_card_tx, micro_sd_card_ty, -micro_sd_card_insert_depth]) + linear_extrude(height=micro_sd_card_depth) + square([micro_sd_card_w, micro_sd_card_h]); + } + + color("black") + translate([micro_sd_card_tx, micro_sd_card_ty, -micro_sd_card_eject_depth]) + linear_extrude(height=micro_sd_card_depth) + square([micro_sd_card_w, micro_sd_card_h]); + } + } +} + +module micro_sd_drill(clearance) { + extra_width = 2; + translate([-micro_sd_body_w/2, 0]) { + rotate([90, 0, 0]) { + translate([micro_sd_card_tx - clearance - extra_width, micro_sd_card_ty - clearance, micro_sd_body_depth/2]) { + cube([micro_sd_card_w + 2 * clearance + extra_width, micro_sd_card_h + 2 * clearance, 10]); + } + } + } +} + +//////////////////////////////////////////////////////// + +module portapack_h1_pcb_mounting_hole_drills() { + translate([ 64, 104]) pcb_mounting_hole_drill(); + translate([126, 104]) pcb_mounting_hole_drill(); + translate([176, 104]) pcb_mounting_hole_drill(); + translate([ 64, 171]) pcb_mounting_hole_drill(); + translate([176, 171]) pcb_mounting_hole_drill(); +} + +module portapack_h1_pcb_shape() { + difference() { + pcb_outline(); + portapack_h1_pcb_mounting_hole_drills(); + } +} + +module portapack_h1_pcb() { + color("green") linear_extrude(height=pp_h1_pcb_thickness) { + portapack_h1_pcb_shape(); + } +} + +module portapack_h1_components_top() { + translate([ 94.83, 137.50]) rotate(90) lcd_kingtech(); + translate([147.50, 137.50]) control_wheel(); +} + +module portapack_h1_components_bottom() { + translate([0, 0, pp_h1_pcb_thickness]) { + translate([171.76, 143.25]) rotate( 90) header_mle_dual("p20", 11); + translate([152.71, 164.84]) rotate(180) header_mle_dual("p22", 13); + translate([123.50, 143.25]) rotate( 90) header_mle_dual("p28", 11); + translate([172.10, 114.80]) rotate(270) audio_jack(); + translate([ 68.40, 114.60]) rotate(270) micro_sd(); + } +} + +module portapack_h1_assembly() { + portapack_h1_pcb(); + portapack_h1_components_top(); + portapack_h1_components_bottom(); +} + +module portapack_h1_transform() { + rotate([180, 0, 0]) translate([-60, -100 - pcb_w]) + children(); +} + +module portapack_h1() { + portapack_h1_transform() portapack_h1_assembly(); +} + +//////////////////////////////////////////////////////// + +module slot() { + hull() { + children(); + translate([0, 0, -20]) children(); + } +} + +module portapack_h1_drills() { + micro_sd_clearance = 0.5; + audio_jack_hole_diameter = 7.0; // 6.5mm + 0.25mm clearance. + + portapack_h1_transform() { + translate([172.10, 114.80, pp_h1_pcb_thickness]) rotate(270) audio_jack_drill(audio_jack_hole_diameter); + slot() translate([ 68.40, 114.60, pp_h1_pcb_thickness]) rotate(270) micro_sd_drill(micro_sd_clearance); + } +} + +module hackrf_one_drills() { + clearance = 0.5; + sw_clearance = 0.6; + + hackrf_one_transform() { + slot() translate([ 61.00, 161.00]) rotate( 0) sma_73251_2120_drill(clearance, h1_pcb_thickness); + translate([179.00, 145.00]) rotate(180) sma_73251_2120_drill(clearance, h1_pcb_thickness); + translate([179.00, 163.00]) rotate(180) sma_73251_2120_drill(clearance, h1_pcb_thickness); + + translate([ 61.00, 117.90]) rotate(-90) led_drill(); + translate([ 61.27, 130.55]) rotate(-90) led_drill(); + translate([ 61.27, 135.12]) rotate(-90) led_drill(); + translate([ 61.27, 139.69]) rotate(-90) led_drill(); + translate([ 61.27, 144.27]) rotate(-90) led_drill(); + translate([ 61.27, 148.84]) rotate(-90) led_drill(); + + slot() translate([ 62.70, 111.40]) sw_drill(sw_clearance); + slot() translate([ 62.70, 124.40]) sw_drill(sw_clearance); + + translate([180.00, 124.00]) usb_drill(clearance); + } +} + +module portapack_h1_stack_hackrf_one() { + hackrf_one(); +} + +module portapack_h1_stack_spacers() { + hackrf_one_transform() { + translate([ 64, 104]) spacer(); + translate([126, 104]) spacer(); + translate([176, 104]) spacer(); + translate([ 64, 171]) spacer(); + translate([176, 171]) spacer(); + } +} + +module portapack_h1_stack_portapack() { + translate([0, 0, spacer_height + pp_h1_pcb_thickness]) portapack_h1(); +} + +module portapack_h1_stack_screws() { + screw_tz = spacer_height + pp_h1_pcb_thickness; + translate([0, 0, screw_tz]) portapack_h1_transform() { + translate([ 64, 104]) screw(); + translate([126, 104]) screw(); + translate([176, 104]) screw(); + translate([ 64, 171]) screw(); + translate([176, 171]) screw(); + } +} + +module portapack_h1_stack() { + portapack_h1_stack_hackrf_one(); + portapack_h1_stack_spacers(); + portapack_h1_stack_portapack(); + portapack_h1_stack_screws(); +} + +module portapack_h1_stack_drills() { + hackrf_one_drills(); + + translate([0, 0, spacer_height + pp_h1_pcb_thickness]) portapack_h1_drills(); +}