diff --git a/model/common.scad b/model/common.scad index 0a9b063..15bec72 100644 --- a/model/common.scad +++ b/model/common.scad @@ -1,45 +1,262 @@ +include + BASE_MODEL_SCALE = [1.1, 1, 1.1]; BASE_MODEL_TRANSLATE = [-0.4, 0, 16.978]; +EPS = 0.01; +$fn = 50; -module main_display(){ - // Outer dimensions, height currently unknown - cube([55.04, 89.3, 10]); +module pin_header(cols = 4, rows = 1, anchor = BOTTOM, spin = 0, orient = UP) { + // Standard pin header dimensions (in mm) + base_height = 2.54; // Height of the plastic base + pin_width = 0.64; // Width/thickness of the square pin + pin_length = 6.0; // Length of pin sticking up + pitch = 2.54; + + // 1. The Plastic Base is the Parent + // It directly receives your anchor, spin, and orient arguments. + color("darkgrey") + cuboid([cols * pitch, rows * pitch, base_height], anchor=anchor, spin=spin, orient=orient) { + + // 2. Metal Pins are the Children + // Placed relative to the center of the plastic base + color("silver") + xcopies(spacing=pitch, n=cols) { + ycopies(spacing=pitch, n=rows) { + up(base_height / 2) + cuboid([pin_width, pin_width, pin_length], anchor=BOTTOM); + } + } + + // Allows attaching other objects to this header if needed + children(); + } } -module pad(){ - // A button has 4.2 x 6 mm -> At least ~20x20 are required for the PCB - cube([20, 20, 10]); +module main_display(pin_header = false) { + // Outer dimensions + width = 55.04; + length = 89.35; + height = 2.7; + + display_height = 3; + display_length = 77.6; + display_inset = 5.7; + + sd_width = 26.6; + sd_height = 3; + sd_length = 16.6; + sd_inset = 29.4; + + hole_diameter = 3; + hole_inset = 1.5; + + difference() { + cuboid([length, width, height]) { + position(TOP + RIGHT) + left(display_inset) + color("black") + cuboid([display_length, width, display_height], anchor=BOTTOM + RIGHT); + + position(BOTTOM + RIGHT + FRONT) + left(sd_inset) + cuboid([sd_width, sd_length, sd_height], anchor=TOP + RIGHT + FRONT); + + position(TOP + LEFT) + pin_header(14, spin=90, anchor=BOTTOM + BACK); + // pin_header(); + } + + xcopies(length - (2 * hole_inset) - hole_diameter) { + ycopies(width - (2 * hole_inset) - hole_diameter) { + zcyl(d=hole_diameter, h=height + EPS); + } + } + } } -module small_display_below_main() -{ - // https://de.aliexpress.com/item/1005003753680706.html - cube([45.8, 20, 11.3]); - // old i2c variant: - //cube([43.5, 19.44, 4.5]); - - // initial dimension ideas - // cube([38,16,4]); - // translate([150,0,0]) cube([22,5.5,4]); +module pad() { + // A button has 4.2 x 6 mm -> At least ~20x20 are required for the PCB + cube([20, 20, 10]); } -module tertiary_display() -{ - // https://de.aliexpress.com/item/1005006034531826.html - cube([80, 36, 10]); +module secondary_display(pin_header = false) { + // https://de.aliexpress.com/item/1005003753680706.html + length = 45.8; + width = 20; + height = 3.7; + + hole_diameter = 2; + hole_inset = 1.5; + + difference() { + cuboid([length, width, height]) { + if (pin_header) + position(LEFT + TOP) + pin_header(7, spin=90, anchor=BACK + BOTTOM); + } + + right(length / 2 - hole_inset) { + ycopies(width - (2 * hole_inset) - hole_diameter) { + zcyl(d=hole_diameter, h=height + EPS, anchor=RIGHT); + } + } + } } -module battery() { - // 18650 - rotate([0,90,0]) cylinder(d=18, h=65); +module tertiary_display() { + // https://de.aliexpress.com/item/1005006034531826.html + cube([80, 36, 10]); } -module microcontroller() { - // width 32 including USB-C port - length = 91.5; - height = 20; - battery_length = 65; - delta = length - battery_length; - cube([length, 32, height]); - translate([delta / 2,16, 15]) battery(); +module battery(anchor = BOTTOM) { + // 18650 + rotate([0, 90, 0]) cylinder(d=18, h=65, anchor=anchor); +} + +/// USB-C port and switch not 100% dimensionally accurate, take care! +module micro_controller(battery_holder = false, battery = false) { + pcb_length = 91.5; + pcb_height = 6.5; // including components, highest point: jst connector, followed by uC + pcb_height_no_components = 1.1; + pcb_width = 28.8; + + hole_diameter = 2.5; + hole_inset = 1; + usb_protrusion = 1.7; + usb_width = 9; + usb_inset_from_pcb_end = 5; + power_switch_protrusion = 2.1; + power_switch_inset_from_pcb_end = 8.1; + power_switch_width = 4; + + battery_holder_height = 15; + battery_holder_width = 21; + battery_holder_length = 77.3; + + battery_length = 65; + battery_protrusion = 4.5; + + difference() { + cuboid([pcb_length, pcb_width, pcb_height], rounding=2, edges="Z") { + if (battery_holder) + position(TOP) + cube([battery_holder_length, battery_holder_width, battery_holder_height], anchor=BOTTOM + CENTER) { + if (battery) + position(TOP) + up(battery_protrusion) + battery(anchor=CENTER + LEFT); + } + position(RIGHT + BOTTOM) { + position(FRONT) + left(usb_inset_from_pcb_end) + cube([usb_width, usb_protrusion, pcb_height - pcb_height_no_components], orient=FRONT, anchor=RIGHT + BOTTOM + FRONT); + position(BACK) + left(power_switch_inset_from_pcb_end) + cube([power_switch_width, power_switch_protrusion, pcb_height - pcb_height_no_components], orient=FRONT, anchor=RIGHT + TOP + FRONT); + } + } + + xcopies(pcb_length - (2 * hole_inset) - hole_diameter) { + ycopies(pcb_width - (2 * hole_inset) - hole_diameter) { + cyl(d=hole_diameter, h=pcb_height + EPS, orient=UP); + } + } + } +} + +module nfc(pin_header = true) { + length = 43; + width = 40.5; + height = 4; + + pin_protrusion = 2.2; + + hole_diameter = 3; + hole_inset = 6; + + x_span = length - (2 * hole_inset) - hole_diameter; + y_span = width - (2 * hole_inset) - hole_diameter; + + color("red") + difference() { + cuboid([length, width, height], rounding=2, edges="Z") { + // pin header is lower than highest other component -> in the cube. + if (pin_header) + right(6 - pin_protrusion) // ugly: 6mm is the pin height + position(LEFT + TOP) + yrot(-90) + pin_header(7, spin=90, anchor=FRONT + TOP); + } + + move_copies( + [ + [x_span / 2, -y_span / 2], // Bottom-Left corner + [-x_span / 2, y_span / 2], // Top-Right corner + ] + ) { + zcyl(d=hole_diameter, h=height + EPS); + } + } +} + +include + +module tertiary_display(pin_headers = true) { + pcb_length = 81; + pcb_width = 36.1; + pcb_height = 3.7; + + hole_diameter = 2.8; + hole_inset = 1; + + display_length = 71.2; + display_width = 24.4; + display_height = 7; + + piggy_length = 41.8; + piggy_width = 19.1; + piggy_height = 8.5 - 2.6; + piggy_inset = 6.2; + + jumper_protrusion = 6.6; + pin_protrusion = 6.2; + + color("green") + difference() { + cuboid([pcb_length, pcb_width, pcb_height]) { + position(TOP) + cuboid([display_length, display_width, display_height], anchor=BOTTOM); + } + + xcopies(pcb_length - (2 * hole_inset) - hole_diameter) { + ycopies(pcb_width - (2 * hole_inset) - hole_diameter) { + zcyl(d=hole_diameter, h=pcb_height + 1); + } + } + } + + // Replaces position(BOTTOM + BACK + LEFT) so that difference cannot mess with color. + translate([-pcb_length / 2 + piggy_inset, pcb_width / 2, -pcb_height / 2]) { + color("black") + cuboid([piggy_length, piggy_width, piggy_height], anchor=TOP + BACK + LEFT); + + if (pin_headers) { + // Replaces position(LEFT + BOTTOM) so that parent child cannot mess with color. + translate([0, -piggy_width / 2, -piggy_height]) + right(6 - pin_protrusion) + yrot(-90) + pin_header(4, spin=90, anchor=BACK + TOP); + + // Replaces position(RIGHT + BOTTOM) so that parent child cannot mess with color. + translate([piggy_length, -piggy_width / 2, -piggy_height]) + left(6 - pin_protrusion) + yrot(90) + back(1.6) + pin_header(2, spin=-90, anchor=BACK + TOP); + + // Replaces position(BACK + TOP) so that parent child cannot mess with color. + translate([piggy_length / 2, -EPS, 0]) + pin_header(16, anchor=BACK + TOP); + } + } }