X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=fairphone4-case.scad;h=0a4b63d6efee47c6ca669319ba61c10e8d96a7dc;hb=refs%2Fheads%2Fmaster;hp=d4fbd3a7545d248a268157fce83047a547e48393;hpb=fdb4d144e8bde08f65348354cb7856a986318e4a;p=reprap-play.git diff --git a/fairphone4-case.scad b/fairphone4-case.scad index d4fbd3a..0a4b63d 100644 --- a/fairphone4-case.scad +++ b/fairphone4-case.scad @@ -9,17 +9,12 @@ // // 1. You will want to git clone this repository. // -// 2. Decide about the notification LED aperture. See the variable -// led_window_style, below. The default here is "ad-hoc -// multi-colour", which can produces a translucent (clear-ish) -// window set into the lid, even on a single-nozzle printer. -// See "Ad-hoc multi-colour", below. +// 2. // // 3. use "make" to generate the necessary files: // // make -j8 fairphone-case.auto.scads `for f in \ -// HingePrint \ -// LidWindowPrint \ +// HingeLeverPrint \ // LidPrint \ // OneKeeperPrint \ // Case \ @@ -28,34 +23,25 @@ // 4. Print them. Case and OneKeeperPrint should probably be // the same colour. // -// For Lid and LidWindowPrint, if you are doing ad-hoc -// multi-colour: -// i. Set up for clear filament -// ii. Print LidWindowPrint. Wait for it to finish. -// It won't take long. As soon as it finishes, tell -// your printer to warm up (so that in fact it does -// not cool down). -// iii. Leaving the output so far on the printbed, reload -// your printer with the main lid colour. -// iv. Print LidPrint. You can let this go unattended. +// 5. Assemble the hinge. After placing the parts in the appropirate +// relative placement: // -// 5. Assemble the hinge. You will need 4x M2 12mm machine screws -// and 8x M2 full nuts. +// Use long bit of wire to ensure holes are lined up and proper +// Cut four short bits of wire, using above as a guage // -// Make sure you get the hinge the right way round. If you're not -// sure, run -// openscad fairphone-case,DemoHinge.auto.scad -// to see an assembly diagram. +// Push two short bits into two holes on same side +// Use long bit of wire to ensure properly in holes +// Keep that side up so they don't fall out! // -// The nuts recess into the hinge. You will want very fine -// pliers. As you screw each screw in, add the second nut when -// the screw thread emerges from the first - this will be a -// locknut. Screw each screw to an appropriate tightness for the -// hinge stiffness. You want the lid-side hinge to be stiffer as -// that makes closing the case work better. +// For each of the two holes +// Use 20-30cm hunk of 2.85mm PLA +// Use gas flame to melt end until it catches fire (!) +// Remove from flame, wave to extinguish, and quickly: +// Dab end onto where hole is +// As it congeals, use sidecutters to cut off by hole // -// When you have the stiffness right, tighten the locknuts onto -// each first nut. +// Repeat for two holes on other side +// When cool, file down rough edges // // 6. In use: // @@ -67,27 +53,6 @@ // portrait orientation only right now). See // openscad fairphone-case,DemoPropAngles.auto.scad // -// Ad-hoc multi-colour -// -// This file is set up to let you make a translucent window using a -// single-extruder printer, using a "two print run" technique. This -// works well with our Lulzbot TAZ 5 and Aleph Objects' version of -// Cura. If you are using a different printer, you may need to -// adjust the parameters or try a different technique. In particular, -// initial_layer_thick -// set so that the window is one layer thick -// initial_layer_width -// set so that the slicer draws a rectangle around the whole -// object, rather than putting a "skirt" or anything inside -// -// If you have a dual-extruder printer, you can set led_window_style -// to 2 and do a single print of LidPrint and LidWindowPrint. -// -// Alternatively you can set it to 1 (just a hole) or 0 (no hole). -// -// Thanks to Clare Boothby for the ad-hoc multi-colour technique (and -// the parameters for our Lulzbot TAZ 5 and Aleph Objects's Cura). -// // Other phones // // It might well be possible to adapt this file for other phones. @@ -96,7 +61,7 @@ // // AUTHORSHIP, COPYRIGHT, LICENCE, AND LACK OF WARRANTY // -// Copyright (C)2018 Ian Jackson. +// Copyright (C) 2018-2022 Ian Jackson. // // This program for generating a 3D model is free software: you can // redistribute it and/or modify it under the terms of the GNU @@ -149,35 +114,38 @@ button_cutout_depth = 9; phone_edge_thick = 11.25; -// xxx this is all wrong -camera_pos_tl = [ 6.450, 12.750 ]; // measured from tl corner -camera_pos_br = [ 22.300, 37.600 ]; // tl/br as seen from back +camera_pos_tl = [ 5.600, 5.750 ]; // from tl corner (as seen from back) +camera_edge_rad = 9.750 + 0.700; +camera_sz = 32.920 + .750 + 1.000; // this is disabled, FP4 doesn't have one jack_pos = [ 13.83, 8.485 ]; jack_dia = 10.64 + .5; // some jack I had lying around // this led stuff, is irrelevant, we have disabled it as it doesn't have one -led_pos = [ 13.98, 10.00 ]; +led_pos = []; // [ 13.98, 10.00 ]; led_aperture = 9; led_window_ledge = 0.75; // each side -noisecancelmic_pos = [ 15.08, 4.35 ]; // from rhs, from top edge +noisecancelmic_pos = [ 15.08 + .720, 4.35 ]; // from rhs, from top edge noisecancelmic_dia = 4.00; -lhshole_pos = [ phone[1]/2, 4.35 ]; +mainmic_pos = [ 21.0, 4.65 ]; // from lhs, from top edge +mainmic_dia = 4.00; -// fingerpushhole_dias = []; xxx what was this -fingerpushhole_dias = [ 15, 18 ]; +lhshole_pos = [ phone[1]/2 + 0.40, 4.35 ]; + +fingerpushhole_dias = []; +//fingerpushhole_dias = [ 15, 18 ]; // this is for testing lanyard_half_dia = 1.15; lanyard_entry_rel_breadth = 2; lanyard_channel_len = 8; -rearspeaker_pos_bl = [ 12.64, 18.72 ]; -rearspeaker_size = [ 3.76, 7.36 ]; +//rearspeaker_pos_bl = [ 12.64, 18.72 ]; +//rearspeaker_size = [ 3.76, 7.36 ]; -bottomspeaker_size = [ 11.35, 1.40 ] + [1,1] * 1.0; -bottomspeaker_pos = [ 19.45, 4.82 ]; +bottomspeaker_size = [ 11.35, 1.90 ] + [1,1] * 0.5; +bottomspeaker_pos = [ 17.55, 5.17 ]; // from rhs, from top microusb_above = 1.64 - 0.25; microusb_below = 2.42; @@ -185,7 +153,7 @@ microusb_width = 12.16 + 2.0 + 1.25; case_th_bottom = 2.5; case_th_lid = 3.0; -case_th_side = 2.3; +case_th_side = 2.6; case_th_lip = 1.2; lid_screen_gap_extra = .66; @@ -205,6 +173,9 @@ keeper_gap_z_top = 0.25; keeper_gap_z_bot = 0.75; keeper_gap_x = 0.25; keeper_gap_x_holes = 0.75; +keeper_fatter = 0.45; +keeper_fatter_hole = 1.20; +keeper_stubbier = 0.0; keeper_side = 0; // 0 = lhs; 1 = rhs @@ -215,16 +186,14 @@ lid_gap_z = 0.25; lid_lip = 1.75; lid_edgepart_width = 5.0; lid_buttoncover_thick = 1.3; -lid_buttoncover_reinf = 0.65; +lid_buttoncover_reinf = 0.95; foldover_gap = 0.50; foldover_lever_gap = 0.50; -// xxx replace hinge screw with nail plan - // properties of the hinge fasteners -hingescrew_shaft_dia = 2.0 + 0.25; // M2 x 12mm machine screw -hingescrew_shaft_len = 12; +hingescrew_shaft_dia = 1.600 + 0.45; // beading wire +hingescrew_shaft_len = 10; hingescrew_fasteners_extra_thick = 0.40; // ^ amount of thread protruding if everything was completely nominal // and we are using two nuts @@ -256,9 +225,10 @@ hinge_x_gap = 0.125; hinge_x_postscrew_gap = 0.75; hinge_x_arms_gap = 0.35; hinge_r_arms_gap = 0.55; +hinge_over_nut_plate = -0.50; // bodge apropos slope -// xxx there isn't one of these, speaker is by hinge -rearspeaker_gap = [ 2.0, 2.0 ]; // each side +// there isn't one of these, speaker is by hinge +// rearspeaker_gap = [ 2.0, 2.0 ]; // each side thumbrecess_depth = 1.3; thumbrecess_width = 16.5; @@ -281,6 +251,7 @@ lid_fold_clearance_antislop = 0.5; $button_leg_only = false; $suppress_forward_holes = false; +$suppress_hinge = false; // ---------- calculated ---------- @@ -307,9 +278,6 @@ lid_buttoncover_overlap = case_th_lip + keeper_gap_z_top; //prop_recess_width = prop_main_th / cos(prop_max_angle) + prop_backfwd_gap; -//lid_lip_overlap_width xxx bad name = ; -//lid_lip_inner_slope = [ 5, 5 ]; // xxx - epp0 = [0,0]; epp1 = [0, -phone_edge_thick]; epp2i = epp1; // conflated for FP4 @@ -410,17 +378,17 @@ hex23 = hex27 - (hingescrew_nut_thick*2 + hingescrew_fasteners_extra_thick); hex26 = hex23 + hingescrew_nut_thick * 2/3; -echo(hex20, hex21, hex22, hex23, hex24); -// 6, 10.8725, 10.9975, 13.74, 18.75 -module chk(act,exp) { - if (abs(act-exp) > 1e-9) echo("WRONG", act, exp); - else echo("ok", act); -} -chk(hex20, 6); -chk(hex21, 10.8725); -chk(hex22, 10.9975); -chk(hex23, 13.74); -chk(hex24, 18.75); +//echo(hex20, hex21, hex22, hex23, hex24); +//// 6, 10.8725, 10.9975, 13.74, 18.75 +//module chk(act,exp) { +// if (abs(act-exp) > 1e-9) echo("WRONG", act, exp); +// else echo("ok", act); +//} +//chk(hex20, 6); +//chk(hex21, 10.8725); +//chk(hex22, 10.9975); +//chk(hex23, 13.74); +//chk(hex24, 18.75); lid_fold_clearance_skew = (lpp10[1] - hppB[1]) / @@ -504,9 +472,15 @@ module AdhocMultiprintFrame(phase, z0, zs) { } } -module KeeperProfile(slant=0){ +module KeeperProfile(fatter=0, slant=0, stubbier=0){ use_e = kppe + [0,-1] * slant * keeper_inner_width / keeper_slant_slope; - polygon([use_e, kppd, kppc, kppb, kppa, kppf]); + polygon([use_e + [+1,-1] * fatter, + kppd + [ 0,-1] * fatter - stubbier * [1,0], + kppc - stubbier * [1,0], + kppb, + kppa + stubbier * [0,1], + kppf + [+1, 0] * fatter + stubbier * [0,1] + ]); } module EdgeProfile(){ @@ -830,8 +804,8 @@ module Buttons(){ Flip_rhs(1) SideButton(64.220, +1, 14.500 ) children(); // power Flip_rhs(1) LidButtonishLeg(14, -1) children(); Flip_rhs(0) LidButtonishLeg(21, -1) children(); + Flip_rhs(0) LidButtonishLeg(38, +1) children(); Flip_rhs(0) LidButtonishLeg(14, +1) children(); - // xxx need hole for whatever that hole is on lhs } module Struts(x_start, z_min, th){ @@ -869,6 +843,12 @@ module MicroUSBEtc(){ rectfromto([-microusb_width/2, epp2i[1] + microusb_below], [+microusb_width/2, epp0[1] + -microusb_above]); } +} + +module OrdinaryBottomEdgeApertures(){ + Flip_bot(1) + CaseAperture(mainmic_pos, mainmic_dia, 8); + Flip_bot(1) Flip_rhs(1) { linextr_y_xz(-epp2i[0], 60) hull() @@ -884,13 +864,15 @@ module MicroUSBEtc(){ module OrdinaryRearApertures(){ // rear speaker - OrdinaryRearAperture(1,1, rearspeaker_pos_bl) - rectfromto(-rearspeaker_gap, - rearspeaker_size + rearspeaker_gap); + // OrdinaryRearAperture(1,1, rearspeaker_pos_bl) + // rectfromto(-rearspeaker_gap, + // rearspeaker_size + rearspeaker_gap); +} +module NotInTestFrameRearApertures(){ // finger hole to remove phone if (len(fingerpushhole_dias)) - OrdinaryRearAperture(1,0, [ fingerpushhole_dias[0]/2 + epp2i[0], + OrdinaryRearAperture(0,0, [ fingerpushhole_dias[0] + epp2i[0], phone[1]/2 ]) scale(fingerpushhole_dias) circle(r= 0.5 ); @@ -899,10 +881,19 @@ module OrdinaryRearApertures(){ module RearCameraAperture(){ Flip_rhs(1) mirror([0, 0, 1]) + translate([0,0,0]) + hull() // there is some kind of bug if hull() is done in 2D here! linear_extrude(height = 20) mirror([0, 1, 0]) translate(bumper) - rectfromto(camera_pos_tl, camera_pos_br); + translate(camera_pos_tl) + for (xy = [ [0,0], [0,1], [1,0] ]) { + translate( + camera_edge_rad * [1,1] + + xy * (camera_sz - camera_edge_rad * 2) + ) + circle(r = camera_edge_rad); + } } module HingeLidProfile(){ @@ -1107,7 +1098,7 @@ module Case(){ ////toplevel Flip_rhs(1-keeper_side) intersection(){ rotate([90, 0, 0]) linear_extrude(height = phone_height + phone_cnr_rad * 2) - KeeperProfile(1); + KeeperProfile(fatter=0, slant=1); // outline of the whole case, to stop it protruding translate([0,0, -25]) @@ -1118,7 +1109,8 @@ module Case(){ ////toplevel } // hinge - HingePortion(hex20, hex21) HingeBaseProfile(); + if (!$suppress_hinge) + HingePortion(hex20, hex21) HingeBaseProfile(); // buildout for prop recess if (prop_caserecess_buildout_r > 0) Flip_rhs(1) @@ -1137,7 +1129,7 @@ module Case(){ ////toplevel rotate([90, 0, 0]) linear_extrude(height = phone_height + phone_cnr_rad * 2) minkowski(){ - KeeperProfile(); + KeeperProfile(fatter=keeper_fatter_hole); rectfromto([ -keeper_gap_x, -keeper_gap_z_bot ], [ keeper_gap_x_holes, +keeper_gap_z_top ]); } @@ -1179,23 +1171,28 @@ module Case(){ ////toplevel // CaseAperture(jack_pos, jack_dia, 8); Flip_rhs(1) CaseAperture(noisecancelmic_pos, noisecancelmic_dia, 8); - CaseAperture(lhshole_pos, noisecancelmic_dia, 8, 1); } + CaseAperture(lhshole_pos, noisecancelmic_dia, 8, 1); + + OrdinaryBottomEdgeApertures(); OrdinaryRearApertures(); + NotInTestFrameRearApertures(); MicroUSBEtc(); // gaps for the lid's hinge arms - HingePortion(hex20 - hinge_x_arms_gap, - hex21 + hinge_x_arms_gap) - minkowski(){ + if (!$suppress_hinge) { + HingePortion(hex20 - hinge_x_arms_gap, + hex21 + hinge_x_arms_gap) + minkowski(){ HingeLidProfile(); circle(r= hinge_r_arms_gap, $fn= 8); } - // screw holes in the hinge arms - HingeScrews(); + // screw holes in the hinge arms + HingeScrews(); + } // thumb recess ThumbRecessApply(epp4[1]) @@ -1314,19 +1311,41 @@ module HingeLever(){ ////toplevel HingeLeverOuterProfile(); // space for the screws - HingePortion(hex26, hex24) - HingeLeverInnerProfile(); +// HingePortion(hex26, hex24) +// HingeLeverInnerProfile(); // recesses for the nuts - HingePortion(hex23, hex26+1) - HingeLeverNutProfile(); +// HingePortion(hex23, hex26+1) +// HingeLeverNutProfile(); // bores for the screws HingeScrews(); - // space for the charging cable - MicroUSBEtc(); - Flip_hinge() MicroUSBEtc(); + // space for the charging cable and speaker and micc apertures + hull() { + for (x = [-1,+1]) { + multmatrix([[ 1,0, + + x + * ( (hex24 + hinge_over_nut_plate) - + (phone_width/2 - microusb_width/2) + ) + / ( (epp0[1] - microusb_above) + - + (hppB[1] - hp_r2) ), + + x * (epp0[1] - microusb_above) + + ], + [ 0,1,0, 0 ], + [ 0,0,1, 0 ]]) { + union(){ + MicroUSBEtc(); + Flip_hinge() MicroUSBEtc(); + } + } + } + } } } @@ -1451,7 +1470,7 @@ module OneKeeper(){ ////toplevel translate([0, -phone_cnr_rad, 0]) rotate([90, 0, 0]) linear_extrude(height = phone_height - phone_cnr_rad * 2) - KeeperProfile(); + KeeperProfile(fatter=keeper_fatter, stubbier=keeper_stubbier); } module OneKeeperPrint(){ ////toplevel @@ -1473,11 +1492,17 @@ module TestSelectFrame(){ linear_extrude(height=200) rectfromto(include, inside_br - include); } + + for (i= [1,2]) { + translate([ 0, -phone[1] * i/3, 0 ]) + cube(center=true, [1000, 4, 100]); + } } module TestSelectLidFrame(){ TestSelectFrame(); - translate([led_pos[0], -led_pos[1], -50]) + if (len(led_pos)) + translate([led_pos[0], -led_pos[1], -50]) cylinder(r= nla_r2+3, h=100); }