arcade-panel: start on hinge, better panel layout
authorClinton Ebadi <clinton@unknownlamer.org>
Mon, 13 Mar 2017 06:02:30 +0000 (02:02 -0400)
committerClinton Ebadi <clinton@unknownlamer.org>
Mon, 13 Mar 2017 06:02:30 +0000 (02:02 -0400)
Half of one half of the hinge, and an attempt to make better use of
the attach() module.

Move closer to a workable panel layout: fix button hole sizes, lower
buttons vs joystick (seems to be a common design decision for compact
control panels), and switch the 1P start / coin buttons to 16mm round
switches to save space.

Hinge uses OpenSCAD Joint Connectors v1.0 by MakerBlock
<www.thingiverse.com/thing:33426> CC BY, source included for
convenience / possible local changes.

ble arcade controller/arcade-box.scad
ble arcade controller/joints.scad [new file with mode: 0644]

index 21c55be..fe32dff 100644 (file)
@@ -5,9 +5,13 @@
 
 use <obiscad/bcube.scad>
 use <obiscad/attach.scad>
 
 use <obiscad/bcube.scad>
 use <obiscad/attach.scad>
+use <joints.scad>
+
+
 
 // PREVIEW
 
 // PREVIEW
-union () {
+preview();
+module preview () {
      rotate ([-10, 0, 0]) translate ([0, 0, box_h+20]) panel ();
      case ();
 }
      rotate ([-10, 0, 0]) translate ([0, 0, box_h+20]) panel ();
      case ();
 }
@@ -26,10 +30,14 @@ base_h = 5; //fixme: thickness?
 cr = box_wall*2;
 cres = 0;
 
 cr = box_wall*2;
 cres = 0;
 
-$button_d = 28;
+$button_d = 30;
 js_width = 85;
 js_height = 40;
 
 js_width = 85;
 js_height = 40;
 
+hinge_joint_width = 4;
+hinge_joint_thickness = 5;
+hinge_base_height = 10;
+
 // PANEL COMPONENTS
 
 module button (bezel = $button_d+4) {
 // PANEL COMPONENTS
 
 module button (bezel = $button_d+4) {
@@ -60,13 +68,41 @@ module case_base (h=base_h) {
 module case_walls () {
      difference() {
          bcube([panel_w, panel_h, box_h-base_h], cr, cres);
 module case_walls () {
      difference() {
          bcube([panel_w, panel_h, box_h-base_h], cr, cres);
-         bcube([panel_w-box_wall, panel_h-box_wall, box_h], cr, cres);
+         bcube([panel_w-box_wall, panel_h-box_wall, box_h+1], cr, cres);
      }
      }
+     %connector (case_connector_wall (x=10));
+     attach (case_connector_wall (x=10), hinge_connector_back ()) hinge_female ();
 }
 
 module case () {
      case_base ();
 }
 
 module case () {
      case_base ();
-     translate ([0, 0, (box_h)/2]) case_walls ();
+     translate ([0, 0, box_h/2]) case_walls ();
+}
+
+
+// todo:
+//   specify which wall (rear, front, left, right).
+//   offset from center of wall, as vector
+//   optional: inside/outside
+function case_connector_wall (x=0, y=0, z=0) = [ [panel_w/2-x, panel_h/2-y, (box_h-base_h)/2-z], [0,-1, 0], 0 ];
+
+// HINGE
+
+function hinge_connector_back (th=hinge_joint_thickness*2, h=hinge_base_height) = [ [0, th/2, h/2], [0,1, 0], 0 ];
+
+module hinge_female () {
+     w  = hinge_joint_width * 2;
+     th = hinge_joint_thickness * 2;
+     jt = hinge_joint_thickness;
+     jw = hinge_joint_width;
+     h  = hinge_base_height;
+
+     %connector (hinge_connector_back ());
+
+     difference () {
+         cube ([w, th, h], center=true);
+         joint_male_negative(male_joint_width=jw, male_joint_thickness=jt, forward_rom=90, backward_rom=90, male_joint_height=10);
+     }
 }
 
 
 }
 
 
@@ -82,9 +118,9 @@ module panel () {
 module panel_attach (position, angle=0) {
      x = position[0];
      y = position[1];
 module panel_attach (position, angle=0) {
      x = position[0];
      y = position[1];
-     c1 =  [ [x, y, base_h/2], [0,0,1], angle ]; //[0, 0, h];
+     c1 =  [ [x, y, base_h/2], [0,0,1], angle ];
      a1 = [ [0,0, 0], [0,0,0], 0 ];
      a1 = [ [0,0, 0], [0,0,0], 0 ];
-//     connector (c1);
+//    %connector (c1); // fixme: don't use 2d for layout
      attach (c1, a1) children ();
 }
 
      attach (c1, a1) children ();
 }
 
@@ -94,20 +130,18 @@ module panel_layout () {
          panel_attach ([0, 0], 90) joystick ();
 
          // p1, coin (floating off in the distance...)
          panel_attach ([0, 0], 90) joystick ();
 
          // p1, coin (floating off in the distance...)
-         union () {
-              $button_d=18;
+         translate ([160, 0, 0]) {
+              $button_d=16;
               for (x = [0, $button_d+10]) {
               for (x = [0, $button_d+10]) {
-                   panel_attach ([x, 90]) button ();
-                   panel_attach ([x, 90]) button ();
+                   panel_attach ([x, 42]) button ();
               }
          }
 
          // a, b, c, d
               }
          }
 
          // a, b, c, d
-         union () {
-              buttons_offset = 60;
-              panel_attach ([buttons_offset, 0]) button ();
+         translate ([60, -20, 0]) {
+              panel_attach ([0, 0]) button ();
               for (i = [ 1 : 3 ]) {
               for (i = [ 1 : 3 ]) {
-                   panel_attach ([i*($button_d+10)+buttons_offset-5, 30]) button ();
+                   panel_attach ([i*($button_d+10)-10, $button_d]) button ();
               }
          }
      }
               }
          }
      }
diff --git a/ble arcade controller/joints.scad b/ble arcade controller/joints.scad
new file mode 100644 (file)
index 0000000..cabc309
--- /dev/null
@@ -0,0 +1,179 @@
+/* OpenSCAD Joint Connectors v1.0 by MakerBlock */
+/* Published on October 31, 2012 */
+/* www.thingiverse.com/thing:33426 */
+/* Creative Commons - Attribution */
+
+//     Settings
+       facets = 32;
+       tolerance = 0.3;
+       rotation_degrees = 20;
+
+joint_examples_with_descriptions_in_comments();
+
+module joint_examples_with_descriptions_in_comments()
+       {
+       //      Hypothetical build platform
+       %       cube([100,100,0.1], center=true);
+       //      A single end male connector, on its side
+       translate([0,0,0]) joint_male(male_joint_width=3, male_joint_thickness=3, male_joint_height=10, side=true);
+       //      A single end male connector, upright
+       translate([-8,0,0]) joint_male(male_joint_width=3, male_joint_thickness=3, male_joint_height=10, side=false);
+       //      A dual end male connector
+       translate([-16,0,0]) 
+               {
+               for (i=[0,1]) mirror([0,i,0]) 
+               translate([0,-10/2,0]) joint_male(male_joint_width=3, male_joint_thickness=3, male_joint_height=10, side=true);
+               }
+       //      A female connector, with 0 degrees range of movement
+       translate([8,0,10/2]) 
+               {
+               difference()
+                       {
+                       cube([6,6,10], center=true);
+                       translate([0,0,2]) joint_male_negative(male_joint_width=3, male_joint_thickness=3, male_joint_height=10);
+                       }
+               }
+       //      A female connector, with 180 degrees range of movement
+       translate([16,0,10/2]) 
+               {
+               difference()
+                       {
+                       cube([6,6,10], center=true); 
+                       translate([0,0,2]) 
+                               joint_male_negative(male_joint_width=3, male_joint_thickness=3, forward_rom=90, backward_rom=90, male_joint_height=10);
+                       }
+               }
+       //      A female connector, with a range of movement of 30 degrees forward and 90 degrees backward, and a clearance edge of 3mm
+       translate([24,0,10/2]) 
+               {
+               difference()
+                       {
+                       cube([6,6,10], center=true); 
+                       translate([0,0,2]) 
+                               joint_male_negative(male_joint_width=3, male_joint_thickness=3, forward_rom=30, 
+                                       backward_rom=90, clearance_edge=3, male_joint_height=10);
+                       }
+               }
+       }
+
+module joint_male(male_joint_width=4, male_joint_thickness=4, male_joint_height=8, fn=facets, side=false)
+       {
+       if (side==false)
+               { joint_male_vertical(male_joint_width, male_joint_thickness, male_joint_height, fn=facets); }
+       else if (side==true)
+               { joint_male_horizontal(male_joint_width, male_joint_thickness, male_joint_height, fn=facets); }
+       }
+
+module joint_female();
+       {
+       
+       }
+
+module joint_male_negative(male_joint_width=4, male_joint_thickness=5, male_joint_height=8, 
+       forward_rom=0, backward_rom=0, clearance_edge=0, fn=facets)
+       {
+       //      Spherical axis/hinge bit
+       for (i=[0,1]) mirror([i,0,0])
+               translate([(male_joint_width/2-male_joint_thickness/8+tolerance), 0, 0]) rotate([0,90,0])
+                       sphere(r=male_joint_thickness/4+tolerance, $fn=fn/2);
+       //      Rotated cutout
+       rotate([0,-90,0]) difference()
+               {
+               linear_extrude(height=male_joint_width+tolerance*2+clearance_edge*2, center=true) 
+                       {
+                       //      Forward rotation
+                       hull()
+                               {
+                               circle(r=male_joint_thickness/2+tolerance, $fn=fn);
+                               for(i=[0:-forward_rom/rotation_degrees]) rotate([0,0,i*rotation_degrees]) 
+                                       translate([male_joint_height+(male_joint_thickness/2+tolerance)*2,0,0]) 
+                                       { square((male_joint_thickness/2+tolerance)*2, center=true); }
+                               }
+                       //      Backward rotation
+                       mirror([0,1,0]) hull()
+                               {
+                               circle(r=male_joint_thickness/2+tolerance, $fn=fn);
+                               for(j=[0:-backward_rom/rotation_degrees]) rotate([0,0,j*rotation_degrees]) 
+                                       translate([male_joint_height+(male_joint_thickness/2+tolerance)*2,0,0]) 
+                                       { square((male_joint_thickness/2+tolerance)*2, center=true); }
+                               }
+                       }
+               for(i=[0,1]) mirror([0,0,i])
+               translate([0,0,male_joint_width/2+tolerance]) 
+                       cylinder(r=male_joint_thickness, h=male_joint_width+tolerance*2, $fn=fn, center=false);
+               }
+       }
+
+module joint_male_vertical(male_joint_width=4, male_joint_thickness=5, male_joint_height=8, fn=facets)
+       {
+       difference()
+               {
+               joint_male_solid(male_joint_width, male_joint_thickness, male_joint_height, fn);
+               joint_male_cutout(male_joint_width, male_joint_thickness, male_joint_height, fn);
+               }
+       }
+
+module joint_male_horizontal(male_joint_width=4, male_joint_thickness=5, male_joint_height=8, fn=facets)
+       {
+       translate([0,male_joint_height/2,male_joint_thickness/2]) rotate([90,0,0]) 
+               joint_male_vertical(male_joint_width, male_joint_thickness, male_joint_height, fn);
+       }
+
+module joint_male_solid(male_joint_width=4, male_joint_thickness=5, male_joint_height=8, fn=facets)
+       {
+       difference()
+               {
+               union()
+                       {
+                       //      Main joint
+                       translate([0,0,(male_joint_height-male_joint_thickness/2)/2]) 
+                               cube([male_joint_width, male_joint_thickness, male_joint_height-male_joint_thickness/2], center=true);
+                       //      Rounded edge of joint
+                       translate([0,0,male_joint_height-male_joint_thickness/2]) rotate([0,90,0])
+                               cylinder(r=male_joint_thickness/2, h=male_joint_width, center=true,$fn=fn);
+                       //      Sphere/buds, on either side
+                       for (i=[0,1])
+                               {
+                               mirror([i,0,0]) translate([(male_joint_width/2-male_joint_thickness/8+tolerance), 0, male_joint_height-male_joint_thickness/2]) 
+                                       sphere(r=male_joint_thickness/4, $fn=fn/2);
+                               }
+                       }
+               //      In some circumstances, the rounded edge can protrude below the build surface, this cuts that off
+               if (male_joint_thickness>male_joint_height)
+                       {
+                       translate([0,0,-male_joint_height*1.1/2]) 
+                               cube([male_joint_width+male_joint_thickness/2, male_joint_thickness+1, male_joint_height*1.1], center=true);
+                       }
+               }
+       }
+
+module joint_male_cutout(male_joint_width=4, male_joint_thickness=5, male_joint_height=8, fn=facets)
+       {
+       //      Middle cutout - this is important so that the part will flex as it is inserted.  We need to consider several uses
+
+       //      Thin, but wide male connector
+       if (male_joint_height > male_joint_width*1.5 && male_joint_width > male_joint_thickness*1.5)
+               { 
+               translate([0,0,male_joint_height*3/2-male_joint_width]) 
+                       cube([male_joint_width/3, male_joint_thickness+1, male_joint_height], center=true); 
+               }
+       //      Thick, but narrow male connector
+       else if (male_joint_height-male_joint_thickness > male_joint_width && male_joint_width < male_joint_thickness)
+               { 
+               translate([0,0,male_joint_height*3/2-male_joint_thickness]) 
+                       cube([male_joint_width/4, male_joint_thickness+1, male_joint_height], center=true); 
+               }
+       //      Square footprint male connector
+       else if (male_joint_height-male_joint_thickness > male_joint_width && male_joint_width == male_joint_thickness)
+               { 
+               translate([0,0,male_joint_height*3/2-male_joint_thickness*1.25]) 
+                       cube([male_joint_width/4, male_joint_thickness+1, male_joint_height], center=true); 
+               }
+       //      Cases where the connector is really short
+       else
+               {
+               translate([0,0,male_joint_height/2+male_joint_height*0.25]) 
+                       cube([male_joint_width/4, male_joint_thickness+1, male_joint_height], center=true); 
+               }
+
+       }