1.1 --- a/cartridge.scad Thu Dec 11 20:03:01 2014 +0100
1.2 +++ b/cartridge.scad Fri Dec 12 01:41:27 2014 +0100
1.3 @@ -28,7 +28,12 @@
1.4
1.5 /* Model configurations. */
1.6
1.7 - ROM_CARTRIDGE = 1;
1.8 + ROM_CARTRIDGE = 0;
1.9 + WIDE_CARTRIDGE = 1;
1.10 +
1.11 + /* Set this to the desired model type. */
1.12 +
1.13 + MODEL = ROM_CARTRIDGE;
1.14
1.15 /*
1.16 Options for checking. Some useful combinations...
1.17 @@ -142,9 +147,19 @@
1.18 cube([width, depth, height], center = true);
1.19 }
1.20
1.21 + /* Model widths. */
1.22 +
1.23 + ROM_CARTRIDGE_int_payload_width = 86.0;
1.24 + WIDE_CARTRIDGE_int_payload_width = 140.0;
1.25 +
1.26 /* Internal dimensions. */
1.27
1.28 - int_payload_width = 86.0; /* internal width in the payload section */
1.29 + /* internal width in the payload section */
1.30 + int_payload_width =
1.31 + MODEL == ROM_CARTRIDGE ? ROM_CARTRIDGE_int_payload_width :
1.32 + MODEL == WIDE_CARTRIDGE ? WIDE_CARTRIDGE_int_payload_width :
1.33 + ROM_CARTRIDGE_int_payload_width;
1.34 +
1.35 int_connector_width = 86.0; /* limited to the Plus 1 socket dimensions */
1.36 int_payload_depth = 12.5; /* maximum depth in the payload section */
1.37 int_connector_depth = 11.0; /* maximum depth in the connector section */
1.38 @@ -360,6 +375,44 @@
1.39 pow(pcb_lug_cross_height / 2, 2),
1.40 0.5);
1.41
1.42 + wide_pcb_lug_offset_from_inside = 6.0;
1.43 + wide_pcb_lug_offset_from_bottom = 6.0;
1.44 +
1.45 + /* PCBs for checking. */
1.46 +
1.47 + pcb_width = 84.85; pcb_height = 62.5; pcb_depth = 1;
1.48 + edge_connector_width = 56.5; edge_connector_height = 11.85;
1.49 +
1.50 + /*
1.51 + The rectangular part of the narrow left and right holes is smaller
1.52 + than the "bump" in the case, but the circular parts make the overall
1.53 + hole larger than the "bump". An extra depth is used for holes to avoid
1.54 + surface definition problems.
1.55 + */
1.56 +
1.57 + pcb_hole_margin = 0.55;
1.58 + pcb_hole_width = 2.2;
1.59 + pcb_hole_extra_depth = 0.1;
1.60 + pcb_lug_hole_radius = 3.75;
1.61 +
1.62 + pcb_left_hole_offset = pcb_back_support_left_bump_offset_from_bottom + pcb_hole_margin;
1.63 + pcb_left_hole_height = pcb_back_support_left_bump_height - pcb_hole_margin * 2;
1.64 + pcb_left_hole_offset_from_centre = pcb_support_offset_from_centre +
1.65 + pcb_back_support_width / 2 - pcb_hole_width / 2;
1.66 +
1.67 + pcb_right_hole_offset = pcb_back_support_right_bump_offset_from_bottom + pcb_hole_margin;
1.68 + pcb_right_hole_height = pcb_back_support_right_bump_height - pcb_hole_margin * 2;
1.69 + pcb_right_hole_offset_from_centre = -pcb_left_hole_offset_from_centre;
1.70 +
1.71 + pcb_hole_depth = pcb_depth + 2 * pcb_hole_extra_depth;
1.72 + pcb_hole_start_depth = -pcb_hole_extra_depth;
1.73 +
1.74 + wide_pcb_width = 138.0; wide_pcb_height = pcb_height; wide_pcb_depth = pcb_depth;
1.75 + wide_pcb_hole_depth = pcb_hole_depth;
1.76 + wide_pcb_hole_start_depth = pcb_hole_start_depth;
1.77 +
1.78 + wide_pcb_lug_hole_radius = 4.0;
1.79 +
1.80 /* Repeated constructs. */
1.81
1.82 module pcb_support(xdir, bump_height, bump_offset) {
1.83 @@ -411,13 +464,27 @@
1.84 }
1.85
1.86 module pcb_lug(xdir) {
1.87 - translate([xdir *
1.88 - (int_connector_width / 2 - pcb_lug_offset_from_inside),
1.89 + pcb_lug_explicit(xdir, int_connector_width / 2 - pcb_lug_offset_from_inside,
1.90 + pcb_lug_offset_from_bottom);
1.91 + }
1.92 +
1.93 + module pcb_lug_wide(xdir) {
1.94 + pcb_lug_explicit(xdir, int_payload_width / 2 - wide_pcb_lug_offset_from_inside,
1.95 + wide_pcb_lug_offset_from_bottom);
1.96 + pcb_lug_explicit(xdir, int_payload_width / 2 - wide_pcb_lug_offset_from_inside,
1.97 + wide_pcb_height - edge_connector_height - wide_pcb_lug_offset_from_bottom);
1.98 + }
1.99 +
1.100 + module pcb_lug_explicit(xdir, pcb_lug_offset_from_centre, pcb_lug_offset_from_bottom) {
1.101 + translate([payload_centre + xdir * pcb_lug_offset_from_centre,
1.102 back_depth,
1.103 int_payload_lower_extent + pcb_lug_offset_from_bottom
1.104 ])
1.105 rotate([90, 0, 0])
1.106 difference() {
1.107 +
1.108 + /* Cylinder with cross. */
1.109 +
1.110 union() {
1.111 cylinder(h=pcb_lug_depth, r=pcb_lug_outer_radius);
1.112 cube_at(pcb_lug_cross_width,
1.113 @@ -429,15 +496,32 @@
1.114 0, 0, 1,
1.115 0, 0, 0);
1.116 }
1.117 +
1.118 + /* Hollowed out by a cylinder. */
1.119 +
1.120 cylinder(h=pcb_lug_depth, r=pcb_lug_inner_radius);
1.121 +
1.122 + /* Tapered off for easier connection. */
1.123 +
1.124 translate([0, 0, pcb_lug_depth - pcb_lug_ro])
1.125 fillet_torus(pcb_lug_outer_radius, pcb_lug_rr);
1.126 }
1.127 }
1.128
1.129 module pcb_front_lug(xdir) {
1.130 - translate([xdir *
1.131 - (int_connector_width / 2 - pcb_lug_offset_from_inside),
1.132 + pcb_front_lug_explicit(xdir, int_connector_width / 2 - pcb_lug_offset_from_inside,
1.133 + pcb_lug_offset_from_bottom);
1.134 + }
1.135 +
1.136 + module pcb_front_lug_wide(xdir) {
1.137 + pcb_front_lug_explicit(xdir, int_payload_width / 2 - wide_pcb_lug_offset_from_inside,
1.138 + wide_pcb_lug_offset_from_bottom);
1.139 + pcb_front_lug_explicit(xdir, int_payload_width / 2 - wide_pcb_lug_offset_from_inside,
1.140 + wide_pcb_height - edge_connector_height - wide_pcb_lug_offset_from_bottom);
1.141 + }
1.142 +
1.143 + module pcb_front_lug_explicit(xdir, pcb_lug_offset_from_centre, pcb_lug_offset_from_bottom) {
1.144 + translate([payload_centre + xdir * pcb_lug_offset_from_centre,
1.145 -int_front_depth + pcb_front_lug_depth,
1.146 int_payload_lower_extent + pcb_lug_offset_from_bottom
1.147 ])
1.148 @@ -541,7 +625,7 @@
1.149
1.150 /* PCB supports. */
1.151
1.152 - if (ROM_CARTRIDGE) {
1.153 + if (MODEL == ROM_CARTRIDGE) {
1.154 cube_at(pcb_front_support_width,
1.155 pcb_front_support_depth,
1.156 pcb_front_support_height,
1.157 @@ -563,6 +647,12 @@
1.158 pcb_front_lug(-1);
1.159 pcb_front_lug(1);
1.160 }
1.161 +
1.162 + if (MODEL == WIDE_CARTRIDGE) {
1.163 +
1.164 + pcb_front_lug_wide(-1);
1.165 + pcb_front_lug_wide(1);
1.166 + }
1.167 }
1.168
1.169 /* Label insets. */
1.170 @@ -682,460 +772,487 @@
1.171
1.172 if (BACK)
1.173 translate([back_displacement, 0, 0])
1.174 - rotate([0, 0, back_rotation])
1.175 - difference() {
1.176 + rotate([0, 0, back_rotation]) {
1.177 + difference() {
1.178 +
1.179 + /* The cartridge surfaces. */
1.180
1.181 - /* The cartridge surfaces. */
1.182 + union() {
1.183 +
1.184 + /* Back portion. */
1.185 +
1.186 + if (BACK_SURFACE) {
1.187 +
1.188 + /* Surfaces surrounding the payload. */
1.189
1.190 - union() {
1.191 + /* Payload section of back surface. */
1.192
1.193 - /* Back portion. */
1.194 + cube_at(payload_width, payload_back, payload_height,
1.195 + 0, 1, 1,
1.196 + payload_centre, int_payload_back_depth, int_payload_lower_extent);
1.197
1.198 - if (BACK_SURFACE) {
1.199 + cube_at(back_left, back_depth, payload_height,
1.200 + -1, 1, 1,
1.201 + int_payload_left_extent, 0, int_payload_lower_extent);
1.202
1.203 - /* Surfaces surrounding the payload. */
1.204 + cube_at(back_right, back_depth, payload_height,
1.205 + 1, 1, 1,
1.206 + int_payload_right_extent, 0, int_payload_lower_extent);
1.207 +
1.208 + /* Surfaces surrounding the connector. */
1.209
1.210 - /* Payload section of back surface. */
1.211 + /* Connector section of back surface overlapping the floor. */
1.212 +
1.213 + cube_at(connector_width, connector_back, connector_height,
1.214 + 0, 1, -1,
1.215 + 0, int_connector_back_depth, int_payload_lower_extent);
1.216
1.217 - cube_at(payload_width, payload_back, payload_height,
1.218 - 0, 1, 1,
1.219 - payload_centre, int_payload_back_depth, int_payload_lower_extent);
1.220 + cube_at(back_left, back_depth, connector_height,
1.221 + -1, 1, -1,
1.222 + -int_connector_width / 2, 0, int_payload_lower_extent);
1.223 +
1.224 + cube_at(back_right, back_depth, connector_height,
1.225 + 1, 1, -1,
1.226 + int_connector_width / 2, 0, int_payload_lower_extent);
1.227
1.228 - cube_at(back_left, back_depth, payload_height,
1.229 - -1, 1, 1,
1.230 - int_payload_left_extent, 0, int_payload_lower_extent);
1.231 + /* Top of back piece. */
1.232 +
1.233 + cube_at(payload_width, back_depth, top,
1.234 + 0, 1, 1,
1.235 + payload_centre, 0, int_payload_upper_extent);
1.236
1.237 - cube_at(back_right, back_depth, payload_height,
1.238 - 1, 1, 1,
1.239 - int_payload_right_extent, 0, int_payload_lower_extent);
1.240 + /*
1.241 + The extension of the back to connect with the front. Here, the inside
1.242 + edges are rounded. The outside edges are rounded later.
1.243
1.244 - /* Surfaces surrounding the connector. */
1.245 + An extra overlapping measure is employed so that the filleting is
1.246 + continuous between the payload and connector portions. On the inside
1.247 + edges, the connector filleting is extended upwards.
1.248 + */
1.249 +
1.250 + /* Left side of payload. */
1.251
1.252 - /* Connector section of back surface overlapping the floor. */
1.253 + difference() {
1.254 + cube_at(back_left - groove_depth, groove_width_extra, inner_payload_front_cutout_height,
1.255 + -1, 1, 1,
1.256 + int_payload_left_extent, -groove_width_extra, int_payload_lower_extent);
1.257 + translate([int_payload_left_extent - groove_ro, -groove_width_extra + groove_ro,
1.258 + int_payload_lower_extent])
1.259 + rotate([0, 0, -90])
1.260 + fillet_justified(groove_rr, inner_payload_front_cutout_height);
1.261 + }
1.262
1.263 - cube_at(connector_width, connector_back, connector_height,
1.264 - 0, 1, -1,
1.265 - 0, int_connector_back_depth, int_payload_lower_extent);
1.266 + /* Right side of payload. */
1.267
1.268 - cube_at(back_left, back_depth, connector_height,
1.269 - -1, 1, -1,
1.270 - -int_connector_width / 2, 0, int_payload_lower_extent);
1.271 + difference() {
1.272 + cube_at(back_right - groove_depth, groove_width_extra, inner_payload_front_cutout_height,
1.273 + 1, 1, 1,
1.274 + int_payload_right_extent, -groove_width_extra, int_payload_lower_extent);
1.275 + translate([int_payload_right_extent + groove_ro, -groove_width_extra + groove_ro,
1.276 + int_payload_lower_extent])
1.277 + rotate([0, 0, 180])
1.278 + fillet_justified(groove_rr, inner_payload_front_cutout_height);
1.279 + }
1.280
1.281 - cube_at(back_right, back_depth, connector_height,
1.282 - 1, 1, -1,
1.283 - int_connector_width / 2, 0, int_payload_lower_extent);
1.284 + /* Left side of connector. */
1.285
1.286 - /* Top of back piece. */
1.287 + difference() {
1.288 + cube_at(back_left - groove_depth, groove_width_extra, inner_connector_front_cutout_height,
1.289 + -1, 1, -1,
1.290 + -int_connector_width / 2, -groove_width_extra, int_payload_lower_extent);
1.291 + translate([-int_connector_width / 2 - groove_ro, -groove_width_extra + groove_ro,
1.292 + lower_extent])
1.293 + rotate([0, 0, -90])
1.294 + fillet_partitioned(groove_rr, inner_connector_front_cutout_height + extra);
1.295 + }
1.296
1.297 - cube_at(payload_width, back_depth, top,
1.298 - 0, 1, 1,
1.299 - payload_centre, 0, int_payload_upper_extent);
1.300 + /* Right side of connector. */
1.301
1.302 - /*
1.303 - The extension of the back to connect with the front. Here, the inside
1.304 - edges are rounded. The outside edges are rounded later.
1.305 + difference() {
1.306 + cube_at(back_right - groove_depth, groove_width_extra, inner_connector_front_cutout_height,
1.307 + 1, 1, -1,
1.308 + int_connector_width / 2, -groove_width_extra, int_payload_lower_extent);
1.309 + translate([int_connector_width / 2 + groove_ro, -groove_width_extra + groove_ro,
1.310 + lower_extent])
1.311 + rotate([0, 0, 180])
1.312 + fillet_partitioned(groove_rr, inner_connector_front_cutout_height + extra);
1.313 + }
1.314 +
1.315 + /* Top side. */
1.316
1.317 - An extra overlapping measure is employed so that the filleting is
1.318 - continuous between the payload and connector portions. On the inside
1.319 - edges, the connector filleting is extended upwards.
1.320 - */
1.321 -
1.322 - /* Left side of payload. */
1.323 + difference() {
1.324 + cube_at(payload_width - groove_depth * 2, groove_width_extra, top - top_groove_depth,
1.325 + 0, 1, 1,
1.326 + payload_centre, -groove_width_extra, int_payload_upper_extent);
1.327 + translate([payload_centre, -groove_width_extra + groove_ro,
1.328 + int_payload_upper_extent + groove_ro])
1.329 + rotate([0, 0, 180])
1.330 + rotate([0, 90, 0])
1.331 + fillet(groove_rr, payload_width - groove_depth * 2);
1.332 + }
1.333 + }
1.334
1.335 difference() {
1.336 - cube_at(back_left - groove_depth, groove_width_extra, inner_payload_front_cutout_height,
1.337 - -1, 1, 1,
1.338 - int_payload_left_extent, -groove_width_extra, int_payload_lower_extent);
1.339 - translate([int_payload_left_extent - groove_ro, -groove_width_extra + groove_ro,
1.340 - int_payload_lower_extent])
1.341 - rotate([0, 0, -90])
1.342 - fillet_justified(groove_rr, inner_payload_front_cutout_height);
1.343 - }
1.344 +
1.345 + /* Floor of cartridge. */
1.346 +
1.347 + cube_at(int_connector_width, int_connector_back_depth, bottom,
1.348 + 0, 1, 1,
1.349 + 0, 0, lower_extent + int_connector_height);
1.350
1.351 - /* Right side of payload. */
1.352 + /* Edge connector cutout. */
1.353
1.354 - difference() {
1.355 - cube_at(back_right - groove_depth, groove_width_extra, inner_payload_front_cutout_height,
1.356 - 1, 1, 1,
1.357 - int_payload_right_extent, -groove_width_extra, int_payload_lower_extent);
1.358 - translate([int_payload_right_extent + groove_ro, -groove_width_extra + groove_ro,
1.359 - int_payload_lower_extent])
1.360 - rotate([0, 0, 180])
1.361 - fillet_justified(groove_rr, inner_payload_front_cutout_height);
1.362 + cube_at(edge_connector_cutout_back_width,
1.363 + edge_connector_cutout_back_depth,
1.364 + bottom,
1.365 + 0, 1, 1,
1.366 + 0, 0, lower_extent + int_connector_height);
1.367 }
1.368
1.369 - /* Left side of connector. */
1.370 + /* Extended floor. */
1.371 +
1.372 + if (payload_width > connector_width) {
1.373 +
1.374 + difference() {
1.375
1.376 - difference() {
1.377 - cube_at(back_left - groove_depth, groove_width_extra, inner_connector_front_cutout_height,
1.378 - -1, 1, -1,
1.379 - -int_connector_width / 2, -groove_width_extra, int_payload_lower_extent);
1.380 - translate([-int_connector_width / 2 - groove_ro, -groove_width_extra + groove_ro,
1.381 - lower_extent])
1.382 - rotate([0, 0, -90])
1.383 - fillet_partitioned(groove_rr, inner_connector_front_cutout_height + extra);
1.384 + cube_at(payload_width - connector_width, back_depth, bottom,
1.385 + 1, 1, 1,
1.386 + payload_left_extent, 0, lower_extent + int_connector_height);
1.387 +
1.388 + cube_at(payload_width - connector_width, edge_connector_cutout_front_depth, bottom,
1.389 + 1, 1, 1,
1.390 + payload_left_extent, 0, lower_extent + int_connector_height);
1.391 + }
1.392 }
1.393
1.394 - /* Right side of connector. */
1.395 + /* PCB supports. */
1.396
1.397 - difference() {
1.398 - cube_at(back_right - groove_depth, groove_width_extra, inner_connector_front_cutout_height,
1.399 - 1, 1, -1,
1.400 - int_connector_width / 2, -groove_width_extra, int_payload_lower_extent);
1.401 - translate([int_connector_width / 2 + groove_ro, -groove_width_extra + groove_ro,
1.402 - lower_extent])
1.403 - rotate([0, 0, 180])
1.404 - fillet_partitioned(groove_rr, inner_connector_front_cutout_height + extra);
1.405 + if (MODEL == ROM_CARTRIDGE) {
1.406 + pcb_support(-1, pcb_back_support_left_bump_height,
1.407 + pcb_back_support_left_bump_offset_from_bottom);
1.408 + pcb_support(1, pcb_back_support_right_bump_height,
1.409 + pcb_back_support_right_bump_offset_from_bottom);
1.410 +
1.411 + /* Circular "lugs" to hold PCBs in place. */
1.412 +
1.413 + pcb_lug(-1);
1.414 + pcb_lug(1);
1.415 }
1.416
1.417 - /* Top side. */
1.418 + if (MODEL == WIDE_CARTRIDGE) {
1.419
1.420 - difference() {
1.421 - cube_at(payload_width - groove_depth * 2, groove_width_extra, top - top_groove_depth,
1.422 - 0, 1, 1,
1.423 - payload_centre, -groove_width_extra, int_payload_upper_extent);
1.424 - translate([payload_centre, -groove_width_extra + groove_ro,
1.425 - int_payload_upper_extent + groove_ro])
1.426 - rotate([0, 0, 180])
1.427 - rotate([0, 90, 0])
1.428 - fillet(groove_rr, payload_width - groove_depth * 2);
1.429 + pcb_lug_wide(1);
1.430 + pcb_lug_wide(-1);
1.431 }
1.432 }
1.433
1.434 - difference() {
1.435 + /* Label insets. */
1.436
1.437 - /* Floor of cartridge. */
1.438 + union() {
1.439 +
1.440 + /* Top label. See also the front piece. */
1.441
1.442 - cube_at(int_connector_width, int_connector_back_depth, bottom,
1.443 - 0, 1, 1,
1.444 - 0, 0, lower_extent + int_connector_height);
1.445 + if (TOP_LABEL_INSET)
1.446 + translate([top_label_left_extent,
1.447 + -front_depth + top_label_offset_from_front,
1.448 + upper_extent - top_label_depth])
1.449 + cube([top_label_width, top_label_height,
1.450 + top_label_depth]);
1.451 + }
1.452 +
1.453 + /* Top and side grooves, positioned in the back portion. */
1.454 +
1.455 + union() {
1.456 +
1.457 + /* Left groove. */
1.458
1.459 - /* Edge connector cutout. */
1.460 + cube_at(groove_depth, groove_width_normal, height,
1.461 + 1, 1, 0,
1.462 + payload_left_extent, 0, 0);
1.463 +
1.464 + /* Right groove. */
1.465 +
1.466 + cube_at(groove_depth, groove_width_normal, height,
1.467 + -1, 1, 0,
1.468 + payload_right_extent, 0, 0);
1.469
1.470 - cube_at(edge_connector_cutout_back_width,
1.471 - edge_connector_cutout_back_depth,
1.472 - bottom,
1.473 - 0, 1, 1,
1.474 - 0, 0, lower_extent + int_connector_height);
1.475 + /* Top grooves. */
1.476 +
1.477 + cube_at(payload_width, groove_width_normal, groove_depth,
1.478 + 0, 1, -1,
1.479 + payload_centre, 0, upper_extent);
1.480 +
1.481 + cube_at(payload_width, top_groove_width, top_groove_depth,
1.482 + 0, 1, -1,
1.483 + payload_centre, -groove_width_extra, upper_extent);
1.484 }
1.485
1.486 - /* Extended floor. */
1.487 + /* Back cavity. */
1.488
1.489 - if (payload_width > connector_width) {
1.490 + if (BACK_CAVITY)
1.491 + intersection() {
1.492
1.493 - difference() {
1.494 + /* From the bottom upwards. */
1.495
1.496 - cube_at(payload_width - connector_width, back_depth, bottom,
1.497 - 1, 1, 1,
1.498 - payload_left_extent, 0, lower_extent + int_connector_height);
1.499 + translate([0, back_depth, lower_extent])
1.500 + linear_extrude(height = back_cavity_height)
1.501 + translate([-int_connector_width / 2, 0, 0])
1.502 + polygon([
1.503 + [back_cavity_offset_from_inner_left, 0],
1.504 + [back_cavity_inner_offset_from_inner_left,
1.505 + -back_cavity_depth],
1.506 + [back_cavity_inner_offset_from_inner_left +
1.507 + back_cavity_inner_width,
1.508 + -back_cavity_depth],
1.509 + [back_cavity_offset_from_inner_left +
1.510 + back_cavity_width, 0]
1.511 + ]);
1.512
1.513 - cube_at(payload_width - connector_width, edge_connector_cutout_front_depth, bottom,
1.514 - 1, 1, 1,
1.515 - payload_left_extent, 0, lower_extent + int_connector_height);
1.516 + /* From left to right. */
1.517 +
1.518 + translate([back_cavity_width / 2, back_depth, lower_extent])
1.519 + rotate([0, -90, 0])
1.520 + linear_extrude(height = back_cavity_width)
1.521 + polygon([
1.522 + [-extra, -back_cavity_depth],
1.523 + [back_cavity_inner_height,
1.524 + -back_cavity_depth],
1.525 + [back_cavity_height, 0],
1.526 + [-extra, 0]
1.527 + ]);
1.528 }
1.529 - }
1.530 +
1.531 + /* Inner back cavities. */
1.532 +
1.533 + translate([0, int_connector_back_depth, lower_extent])
1.534 + linear_extrude(height = int_connector_height)
1.535 + translate([-int_connector_width / 2, 0, 0])
1.536 + polygon([
1.537 + [0, 0],
1.538 + [inner_back_slope_max_offset, 0],
1.539 + [inner_back_slope_min_offset,
1.540 + inner_back_slope_depth],
1.541 + [0, inner_back_slope_depth]
1.542 + ]);
1.543
1.544 - /* PCB supports. */
1.545 + translate([0, int_connector_back_depth, lower_extent])
1.546 + linear_extrude(height = int_connector_height)
1.547 + translate([int_connector_width / 2, 0, 0])
1.548 + polygon([
1.549 + [0, 0],
1.550 + [-inner_back_slope_max_offset, 0],
1.551 + [-inner_back_slope_min_offset,
1.552 + inner_back_slope_depth],
1.553 + [0, inner_back_slope_depth]
1.554 + ]);
1.555 +
1.556 + /* Inner back edge cavity. */
1.557 +
1.558 + translate([inner_back_edge_width / 2,
1.559 + int_connector_back_depth + inner_back_edge_depth, lower_extent])
1.560 + rotate([0, -90, 0])
1.561 + linear_extrude(height = inner_back_edge_width)
1.562 + polygon([
1.563 + [-extra, -inner_back_edge_depth],
1.564 + [inner_back_edge_height, -inner_back_edge_depth],
1.565 + [0, 0],
1.566 + [-extra, 0]
1.567 + ]);
1.568 +
1.569 + /* Fillets to round off the edges. */
1.570 +
1.571 + union() {
1.572
1.573 - if (ROM_CARTRIDGE) {
1.574 - pcb_support(-1, pcb_back_support_left_bump_height,
1.575 - pcb_back_support_left_bump_offset_from_bottom);
1.576 - pcb_support(1, pcb_back_support_right_bump_height,
1.577 - pcb_back_support_right_bump_offset_from_bottom);
1.578 + /* Top left and right rounding. */
1.579 +
1.580 + translate([payload_left_extent + ro, back_depth / 2, upper_extent - ro])
1.581 + rotate([0, 0, 180])
1.582 + rotate([90, 0, 0])
1.583 + fillet(rr, back_depth);
1.584 + translate([payload_right_extent - ro, back_depth / 2, upper_extent - ro])
1.585 + rotate([90, 0, 0])
1.586 + fillet(rr, back_depth);
1.587 +
1.588 + /* Top back rounding. */
1.589 +
1.590 + translate([payload_centre, back_depth - ro, upper_extent - ro])
1.591 + rotate([0, -90, 0])
1.592 + fillet(rr, payload_width);
1.593 +
1.594 + /* Outer edge rounding. */
1.595 +
1.596 + translate([payload_right_extent - ro, back_depth - ro, int_payload_lower_extent - bottom - extra])
1.597 + fillet_justified(rr, payload_height + bottom + extra);
1.598 +
1.599 + translate([payload_left_extent + ro, back_depth - ro, int_payload_lower_extent - bottom - extra])
1.600 + rotate([0, 0, 90])
1.601 + fillet_justified(rr, payload_height + bottom + extra);
1.602 +
1.603 + translate([connector_width / 2 - ro, back_depth - ro, lower_extent])
1.604 + fillet_partitioned(rr, connector_height - bottom);
1.605 +
1.606 + translate([-connector_width / 2 + ro, back_depth - ro, lower_extent])
1.607 + rotate([0, 0, 90])
1.608 + fillet_partitioned(rr, connector_height - bottom);
1.609
1.610 - /* Circular "lugs" to hold PCBs in place. */
1.611 + /*
1.612 + Outer edge rounding of the back extension. This is done as a
1.613 + separate removal operation rather than occurring when creating the
1.614 + extension in order to ensure that the edges are actually rounded.
1.615 +
1.616 + An extra overlapping measure is employed so that the filleting is
1.617 + continuous between the payload and connector portions. On the outside
1.618 + edges, the payload filleting is extended downwards.
1.619 + */
1.620 +
1.621 + translate([payload_left_extent + groove_depth + groove_ro, -groove_width_extra + groove_ro,
1.622 + int_payload_lower_extent - extra])
1.623 + rotate([0, 0, 180])
1.624 + fillet_justified(groove_rr, inner_payload_front_cutout_height + extra);
1.625 +
1.626 + translate([payload_right_extent - groove_depth - groove_ro, -groove_width_extra + groove_ro,
1.627 + int_payload_lower_extent - extra])
1.628 + rotate([0, 0, -90])
1.629 + fillet_justified(groove_rr, inner_payload_front_cutout_height + extra);
1.630
1.631 - pcb_lug(-1);
1.632 - pcb_lug(1);
1.633 + /* Sides of connector. */
1.634 +
1.635 + translate([-connector_width / 2 + groove_depth + groove_ro, -groove_width_extra + groove_ro,
1.636 + lower_extent])
1.637 + rotate([0, 0, 180])
1.638 + fillet_partitioned(groove_rr, inner_connector_front_cutout_height);
1.639 +
1.640 + translate([connector_width / 2 - groove_depth - groove_ro, -groove_width_extra + groove_ro,
1.641 + lower_extent])
1.642 + rotate([0, 0, -90])
1.643 + fillet_partitioned(groove_rr, inner_connector_front_cutout_height);
1.644 +
1.645 + /* Top of payload. */
1.646 +
1.647 + translate([payload_centre, -groove_width_extra + groove_ro,
1.648 + int_payload_upper_extent + inner_top_front_cutout_height - groove_ro])
1.649 + rotate([0, 0, 180])
1.650 + rotate([0, -90, 0])
1.651 + fillet(groove_rr, payload_width - groove_depth * 2);
1.652 }
1.653 }
1.654
1.655 - /* Label insets. */
1.656 + /* PCBs for checking. */
1.657 +
1.658 + if (PCB) if (MODEL == ROM_CARTRIDGE) {
1.659 + translate([0, 0, int_payload_lower_extent])
1.660 + difference() {
1.661
1.662 - union() {
1.663 -
1.664 - /* Top label. See also the front piece. */
1.665 + /* Mock PCB. */
1.666
1.667 - if (TOP_LABEL_INSET)
1.668 - translate([top_label_left_extent,
1.669 - -front_depth + top_label_offset_from_front,
1.670 - upper_extent - top_label_depth])
1.671 - cube([top_label_width, top_label_height,
1.672 - top_label_depth]);
1.673 - }
1.674 + union() {
1.675 + cube_at(pcb_width, pcb_depth,
1.676 + pcb_height - edge_connector_height,
1.677 + 0, 1, 1,
1.678 + 0, 0, 0);
1.679 + cube_at(edge_connector_width, pcb_depth,
1.680 + edge_connector_height,
1.681 + 0, 1, -1,
1.682 + 0, 0, 0);
1.683 + }
1.684
1.685 - /* Top and side grooves, positioned in the back portion. */
1.686 -
1.687 - union() {
1.688 -
1.689 - /* Left groove. */
1.690 + /* Holes for mounting. */
1.691
1.692 - cube_at(groove_depth, groove_width_normal, height,
1.693 - 1, 1, 0,
1.694 - payload_left_extent, 0, 0);
1.695 -
1.696 - /* Right groove. */
1.697 -
1.698 - cube_at(groove_depth, groove_width_normal, height,
1.699 - -1, 1, 0,
1.700 - payload_right_extent, 0, 0);
1.701 + union() {
1.702 + cube_at(pcb_hole_width, 1, pcb_left_hole_height,
1.703 + 1, 1, 1,
1.704 + pcb_left_hole_offset_from_centre, 0, pcb_left_hole_offset);
1.705 + translate([pcb_left_hole_offset_from_centre +
1.706 + pcb_hole_width / 2, pcb_hole_start_depth, pcb_left_hole_offset])
1.707 + rotate([-90, 0, 0])
1.708 + cylinder(h=pcb_hole_depth, r=pcb_hole_width / 2);
1.709 + translate([pcb_left_hole_offset_from_centre +
1.710 + pcb_hole_width / 2, pcb_hole_start_depth,
1.711 + pcb_left_hole_offset + pcb_left_hole_height])
1.712 + rotate([-90, 0, 0])
1.713 + cylinder(h=pcb_hole_depth, r=pcb_hole_width / 2);
1.714 + }
1.715
1.716 - /* Top grooves. */
1.717 + union() {
1.718 + cube_at(pcb_hole_width, 1, pcb_right_hole_height,
1.719 + -1, 1, 1,
1.720 + pcb_right_hole_offset_from_centre, 0, pcb_right_hole_offset);
1.721 + translate([pcb_right_hole_offset_from_centre -
1.722 + pcb_hole_width / 2, pcb_hole_start_depth, pcb_right_hole_offset])
1.723 + rotate([-90, 0, 0])
1.724 + cylinder(h=pcb_hole_depth, r=pcb_hole_width / 2);
1.725 + translate([pcb_right_hole_offset_from_centre -
1.726 + pcb_hole_width / 2, pcb_hole_start_depth,
1.727 + pcb_right_hole_offset + pcb_right_hole_height])
1.728 + rotate([-90, 0, 0])
1.729 + cylinder(h=pcb_hole_depth, r=pcb_hole_width / 2);
1.730 + }
1.731
1.732 - cube_at(payload_width, groove_width_normal, groove_depth,
1.733 - 0, 1, -1,
1.734 - payload_centre, 0, upper_extent);
1.735 + /* Holes for lugs. */
1.736
1.737 - cube_at(payload_width, top_groove_width, top_groove_depth,
1.738 - 0, 1, -1,
1.739 - payload_centre, -groove_width_extra, upper_extent);
1.740 + translate([
1.741 + -int_connector_width / 2 + pcb_lug_offset_from_inside,
1.742 + pcb_hole_start_depth, pcb_lug_offset_from_bottom])
1.743 + rotate([-90, 0, 0])
1.744 + cylinder(h=pcb_hole_depth, r=pcb_lug_hole_radius);
1.745 +
1.746 + translate([
1.747 + int_connector_width / 2 - pcb_lug_offset_from_inside,
1.748 + pcb_hole_start_depth, pcb_lug_offset_from_bottom])
1.749 + rotate([-90, 0, 0])
1.750 + cylinder(h=pcb_hole_depth, r=pcb_lug_hole_radius);
1.751 + }
1.752 }
1.753
1.754 - /* Back cavity. */
1.755 -
1.756 - if (BACK_CAVITY)
1.757 - intersection() {
1.758 -
1.759 - /* From the bottom upwards. */
1.760 + if (PCB) if (MODEL == WIDE_CARTRIDGE) {
1.761 + translate([0, 0, int_payload_lower_extent])
1.762 + difference() {
1.763
1.764 - translate([0, back_depth, lower_extent])
1.765 - linear_extrude(height = back_cavity_height)
1.766 - translate([-int_connector_width / 2, 0, 0])
1.767 - polygon([
1.768 - [back_cavity_offset_from_inner_left, 0],
1.769 - [back_cavity_inner_offset_from_inner_left,
1.770 - -back_cavity_depth],
1.771 - [back_cavity_inner_offset_from_inner_left +
1.772 - back_cavity_inner_width,
1.773 - -back_cavity_depth],
1.774 - [back_cavity_offset_from_inner_left +
1.775 - back_cavity_width, 0]
1.776 - ]);
1.777 -
1.778 - /* From left to right. */
1.779 -
1.780 - translate([back_cavity_width / 2, back_depth, lower_extent])
1.781 - rotate([0, -90, 0])
1.782 - linear_extrude(height = back_cavity_width)
1.783 - polygon([
1.784 - [-extra, -back_cavity_depth],
1.785 - [back_cavity_inner_height,
1.786 - -back_cavity_depth],
1.787 - [back_cavity_height, 0],
1.788 - [-extra, 0]
1.789 - ]);
1.790 - }
1.791 -
1.792 - /* Inner back cavities. */
1.793 + /* Mock PCB. */
1.794
1.795 - translate([0, int_connector_back_depth, lower_extent])
1.796 - linear_extrude(height = int_connector_height)
1.797 - translate([-int_connector_width / 2, 0, 0])
1.798 - polygon([
1.799 - [0, 0],
1.800 - [inner_back_slope_max_offset, 0],
1.801 - [inner_back_slope_min_offset,
1.802 - inner_back_slope_depth],
1.803 - [0, inner_back_slope_depth]
1.804 - ]);
1.805 + union() {
1.806 + cube_at(wide_pcb_width, wide_pcb_depth,
1.807 + wide_pcb_height - edge_connector_height,
1.808 + 0, 1, 1,
1.809 + payload_centre, 0, 0);
1.810 + cube_at(edge_connector_width, wide_pcb_depth,
1.811 + edge_connector_height,
1.812 + 0, 1, -1,
1.813 + 0, 0, 0);
1.814 + }
1.815
1.816 - translate([0, int_connector_back_depth, lower_extent])
1.817 - linear_extrude(height = int_connector_height)
1.818 - translate([int_connector_width / 2, 0, 0])
1.819 - polygon([
1.820 - [0, 0],
1.821 - [-inner_back_slope_max_offset, 0],
1.822 - [-inner_back_slope_min_offset,
1.823 - inner_back_slope_depth],
1.824 - [0, inner_back_slope_depth]
1.825 - ]);
1.826 -
1.827 - /* Inner back edge cavity. */
1.828 -
1.829 - translate([inner_back_edge_width / 2,
1.830 - int_connector_back_depth + inner_back_edge_depth, lower_extent])
1.831 - rotate([0, -90, 0])
1.832 - linear_extrude(height = inner_back_edge_width)
1.833 - polygon([
1.834 - [-extra, -inner_back_edge_depth],
1.835 - [inner_back_edge_height, -inner_back_edge_depth],
1.836 - [0, 0],
1.837 - [-extra, 0]
1.838 - ]);
1.839 -
1.840 - /* Fillets to round off the edges. */
1.841 + /* Holes for lugs. */
1.842
1.843 - union() {
1.844 + translate([
1.845 + payload_centre + int_payload_width / 2 - wide_pcb_lug_offset_from_inside ,
1.846 + wide_pcb_hole_start_depth,
1.847 + wide_pcb_height - edge_connector_height - wide_pcb_lug_offset_from_bottom])
1.848 + rotate([-90, 0, 0])
1.849 + cylinder(h=wide_pcb_hole_depth, r=wide_pcb_lug_hole_radius);
1.850
1.851 - /* Top left and right rounding. */
1.852 -
1.853 - translate([payload_left_extent + ro, back_depth / 2, upper_extent - ro])
1.854 - rotate([0, 0, 180])
1.855 - rotate([90, 0, 0])
1.856 - fillet(rr, back_depth);
1.857 - translate([payload_right_extent - ro, back_depth / 2, upper_extent - ro])
1.858 - rotate([90, 0, 0])
1.859 - fillet(rr, back_depth);
1.860 -
1.861 - /* Top back rounding. */
1.862 -
1.863 - translate([payload_centre, back_depth - ro, upper_extent - ro])
1.864 - rotate([0, -90, 0])
1.865 - fillet(rr, payload_width);
1.866 -
1.867 - /* Outer edge rounding. */
1.868 -
1.869 - translate([payload_right_extent - ro, back_depth - ro, int_payload_lower_extent - bottom - extra])
1.870 - fillet_justified(rr, payload_height + bottom + extra);
1.871 -
1.872 - translate([payload_left_extent + ro, back_depth - ro, int_payload_lower_extent - bottom - extra])
1.873 - rotate([0, 0, 90])
1.874 - fillet_justified(rr, payload_height + bottom + extra);
1.875 -
1.876 - translate([connector_width / 2 - ro, back_depth - ro, lower_extent])
1.877 - fillet_partitioned(rr, connector_height - bottom);
1.878 -
1.879 - translate([-connector_width / 2 + ro, back_depth - ro, lower_extent])
1.880 - rotate([0, 0, 90])
1.881 - fillet_partitioned(rr, connector_height - bottom);
1.882 + translate([
1.883 + payload_centre - int_payload_width / 2 + wide_pcb_lug_offset_from_inside ,
1.884 + wide_pcb_hole_start_depth,
1.885 + wide_pcb_height - edge_connector_height - wide_pcb_lug_offset_from_bottom])
1.886 + rotate([-90, 0, 0])
1.887 + cylinder(h=wide_pcb_hole_depth, r=wide_pcb_lug_hole_radius);
1.888
1.889 - /*
1.890 - Outer edge rounding of the back extension. This is done as a
1.891 - separate removal operation rather than occurring when creating the
1.892 - extension in order to ensure that the edges are actually rounded.
1.893 -
1.894 - An extra overlapping measure is employed so that the filleting is
1.895 - continuous between the payload and connector portions. On the outside
1.896 - edges, the payload filleting is extended downwards.
1.897 - */
1.898 -
1.899 - translate([payload_left_extent + groove_depth + groove_ro, -groove_width_extra + groove_ro,
1.900 - int_payload_lower_extent - extra])
1.901 - rotate([0, 0, 180])
1.902 - fillet_justified(groove_rr, inner_payload_front_cutout_height + extra);
1.903 -
1.904 - translate([payload_right_extent - groove_depth - groove_ro, -groove_width_extra + groove_ro,
1.905 - int_payload_lower_extent - extra])
1.906 - rotate([0, 0, -90])
1.907 - fillet_justified(groove_rr, inner_payload_front_cutout_height + extra);
1.908 + translate([
1.909 + payload_centre + int_payload_width / 2 - wide_pcb_lug_offset_from_inside ,
1.910 + wide_pcb_hole_start_depth,
1.911 + wide_pcb_lug_offset_from_bottom])
1.912 + rotate([-90, 0, 0])
1.913 + cylinder(h=wide_pcb_hole_depth, r=wide_pcb_lug_hole_radius);
1.914
1.915 - /* Sides of connector. */
1.916 -
1.917 - translate([-connector_width / 2 + groove_depth + groove_ro, -groove_width_extra + groove_ro,
1.918 - lower_extent])
1.919 - rotate([0, 0, 180])
1.920 - fillet_partitioned(groove_rr, inner_connector_front_cutout_height);
1.921 -
1.922 - translate([connector_width / 2 - groove_depth - groove_ro, -groove_width_extra + groove_ro,
1.923 - lower_extent])
1.924 - rotate([0, 0, -90])
1.925 - fillet_partitioned(groove_rr, inner_connector_front_cutout_height);
1.926 -
1.927 - /* Top of payload. */
1.928 -
1.929 - translate([payload_centre, -groove_width_extra + groove_ro,
1.930 - int_payload_upper_extent + inner_top_front_cutout_height - groove_ro])
1.931 - rotate([0, 0, 180])
1.932 - rotate([0, -90, 0])
1.933 - fillet(groove_rr, payload_width - groove_depth * 2);
1.934 + translate([
1.935 + payload_centre - int_payload_width / 2 + wide_pcb_lug_offset_from_inside ,
1.936 + wide_pcb_hole_start_depth,
1.937 + wide_pcb_lug_offset_from_bottom])
1.938 + rotate([-90, 0, 0])
1.939 + cylinder(h=wide_pcb_hole_depth, r=wide_pcb_lug_hole_radius);
1.940 + }
1.941 }
1.942 }
1.943 -
1.944 - /* PCB for checking. */
1.945 -
1.946 - pcb_width = 84.85; pcb_height = 62.5; pcb_depth = 1;
1.947 - edge_connector_width = 56.5; edge_connector_height = 11.85;
1.948 - pcb_position_y = int_payload_lower_extent;
1.949 -
1.950 - /*
1.951 - The rectangular part of the narrow left and right holes is smaller
1.952 - than the "bump" in the case, but the circular parts make the overall
1.953 - hole larger than the "bump". An extra depth is used for holes to avoid
1.954 - surface definition problems.
1.955 - */
1.956 -
1.957 - pcb_hole_margin = 0.55;
1.958 - pcb_hole_width = 2.2;
1.959 - pcb_hole_extra_depth = 0.1;
1.960 - pcb_lug_hole_radius = 3.75;
1.961 -
1.962 - pcb_left_hole_offset = pcb_back_support_left_bump_offset_from_bottom + pcb_hole_margin;
1.963 - pcb_left_hole_height = pcb_back_support_left_bump_height - pcb_hole_margin * 2;
1.964 - pcb_left_hole_offset_from_centre = pcb_support_offset_from_centre +
1.965 - pcb_back_support_width / 2 - pcb_hole_width / 2;
1.966 -
1.967 - pcb_right_hole_offset = pcb_back_support_right_bump_offset_from_bottom + pcb_hole_margin;
1.968 - pcb_right_hole_height = pcb_back_support_right_bump_height - pcb_hole_margin * 2;
1.969 - pcb_right_hole_offset_from_centre = -pcb_left_hole_offset_from_centre;
1.970 -
1.971 - pcb_hole_depth = pcb_depth + 2 * pcb_hole_extra_depth;
1.972 - pcb_hole_start_depth = -pcb_hole_extra_depth;
1.973 -
1.974 - if (PCB) if (ROM_CARTRIDGE) {
1.975 - translate([back_displacement, 0, 0])
1.976 - translate([0, 0, pcb_position_y])
1.977 - difference() {
1.978 -
1.979 - /* Mock PCB. */
1.980 -
1.981 - union() {
1.982 - cube_at(pcb_width, pcb_depth,
1.983 - pcb_height - edge_connector_height,
1.984 - 0, 1, 1,
1.985 - 0, 0, 0);
1.986 - cube_at(edge_connector_width, pcb_depth,
1.987 - edge_connector_height,
1.988 - 0, 1, -1,
1.989 - 0, 0, 0);
1.990 - }
1.991 -
1.992 - /* Holes for mounting. */
1.993 -
1.994 - union() {
1.995 - cube_at(pcb_hole_width, 1, pcb_left_hole_height,
1.996 - 1, 1, 1,
1.997 - pcb_left_hole_offset_from_centre, 0, pcb_left_hole_offset);
1.998 - translate([pcb_left_hole_offset_from_centre +
1.999 - pcb_hole_width / 2, pcb_hole_start_depth, pcb_left_hole_offset])
1.1000 - rotate([-90, 0, 0])
1.1001 - cylinder(h=pcb_hole_depth, r=pcb_hole_width / 2);
1.1002 - translate([pcb_left_hole_offset_from_centre +
1.1003 - pcb_hole_width / 2, pcb_hole_start_depth,
1.1004 - pcb_left_hole_offset + pcb_left_hole_height])
1.1005 - rotate([-90, 0, 0])
1.1006 - cylinder(h=pcb_hole_depth, r=pcb_hole_width / 2);
1.1007 - }
1.1008 -
1.1009 - union() {
1.1010 - cube_at(pcb_hole_width, 1, pcb_right_hole_height,
1.1011 - -1, 1, 1,
1.1012 - pcb_right_hole_offset_from_centre, 0, pcb_right_hole_offset);
1.1013 - translate([pcb_right_hole_offset_from_centre -
1.1014 - pcb_hole_width / 2, pcb_hole_start_depth, pcb_right_hole_offset])
1.1015 - rotate([-90, 0, 0])
1.1016 - cylinder(h=pcb_hole_depth, r=pcb_hole_width / 2);
1.1017 - translate([pcb_right_hole_offset_from_centre -
1.1018 - pcb_hole_width / 2, pcb_hole_start_depth,
1.1019 - pcb_right_hole_offset + pcb_right_hole_height])
1.1020 - rotate([-90, 0, 0])
1.1021 - cylinder(h=pcb_hole_depth, r=pcb_hole_width / 2);
1.1022 - }
1.1023 -
1.1024 - /* Holes for lugs. */
1.1025 -
1.1026 - translate([
1.1027 - -int_connector_width / 2 + pcb_lug_offset_from_inside,
1.1028 - pcb_hole_start_depth, pcb_lug_offset_from_bottom])
1.1029 - rotate([-90, 0, 0])
1.1030 - cylinder(h=pcb_hole_depth, r=pcb_lug_hole_radius);
1.1031 -
1.1032 - translate([
1.1033 - int_connector_width / 2 - pcb_lug_offset_from_inside,
1.1034 - pcb_hole_start_depth, pcb_lug_offset_from_bottom])
1.1035 - rotate([-90, 0, 0])
1.1036 - cylinder(h=pcb_hole_depth, r=pcb_lug_hole_radius);
1.1037 - }
1.1038 - }
1.1039 }
1.1040
1.1041 cartridge();