concertina

Elecronic concertina
git clone https://git.woozle.org/neale/concertina.git

concertina / 3d
Neale Pickett  ·  2026-02-06

proto1.scad

  1include <BOSL2/std.scad>
  2include <BOSL2/constants.scad>
  3include <cherryvoid.scad>
  4include <board.scad>
  5include <cherry_mx.scad>
  6
  7inch = 25.4;
  8HandRestHeight = 38;
  9ThumbRestHeight = 16;
 10
 11// The size of your strap hole (width * height).
 12// Make it a little larger than your strap, so it can move freely.
 13StrapHole = [14, 4];
 14
 15thumbLength = 117 - 84 - StrapHole[1];
 16
 17// Make circles circular in final renders.
 18$fn = $preview ? 0 : 180;
 19
 20module row() {
 21  for (x = [0:14:28]) {
 22    translate([x, 0, 0]) cherry_switch_void();
 23  }
 24}
 25
 26ORIGIN = BOTTOM+FRONT+LEFT;
 27
 28difference () {
 29  union() {
 30    // Main plate
 31    cuboid([126, 103, 10], rounding=2, except=BOTTOM, anchor=ORIGIN);
 32
 33    // Wrist rest
 34    translate([thumbLength + StrapHole[1], 0, 0]) cuboid([93, StrapHole[0]+4, HandRestHeight], , rounding=2, anchor=ORIGIN);
 35
 36    // Thumb rest
 37    translate([0, 0, 0]) cuboid([100, StrapHole[0]+4, ThumbRestHeight], rounding=2, anchor=ORIGIN);
 38  }
 39
 40  // Keypads
 41  // 40mm from edge of wrist rest to center of index finger button
 42  translate([thumbLength+17,StrapHole[1]+54, 5]) rotate(20) {
 43    rows = [0, -3, -7, -14, -22];
 44    spacing = 15.5;
 45    for (i = [0 : len(rows)-1]) {
 46      y = rows[i];
 47      x = i * spacing;
 48      translate([x, y]) rotate(90) row();
 49    }
 50  }
 51  // 18mm from edge of wrist rest to center of thumb button
 52  translate([10, 37, 5]) {
 53    translate([0, 0, 0]) cherry_switch_void();
 54    translate([14, 0, 0]) cherry_switch_void();
 55  }
 56
 57  // Window for display
 58  translate([6, 82, -1]) rotate(0) cube([16.6, 14.85, 100]); // 64×32 (footprint)
 59  //translate([12, 50, -1]) rotate(20) cube([23.6, 18.5, 100]); // 64×48 (footprint)
 60  //translate([-1, 47, -1]) rotate(0) cube([38, 12, 100]); // 128×32 (footprint)
 61  //translate([5, 50, -1]) rotate(0) cube([30, 11.5, 100]);
 62  //translate([3, 47, -1]) cube([27.8, 27.3, 100]); // 128×64 (footprint)
 63  //translate([3, 47+8.3/2, -1]) cube([27.3, 19.0, 100]); // 128×64 (footprint)
 64
 65  translate([0, 60, -0.01]) {
 66    translate([0.05, 0, 0]*INCH) cuboid([1, 3/8, 3/8]*INCH, rounding=0.5, anchor=ORIGIN);
 67    translate([-0.01, 3/16, 3/16]*INCH) rotate([0, 90, 0]) cylinder(h=8, d=1/4*INCH);
 68}
 69
 70  // Strap holes
 71  translate([thumbLength, 2, -0.01]) {
 72    cuboid([StrapHole[1], StrapHole[0], 50], rounding=0.5, anchor=ORIGIN);
 73  }
 74  translate([119.3, 2, -5]) {
 75    rotate([0, 10, 0]) cuboid([StrapHole[1], StrapHole[0], 50], rounding=0.5, anchor=ORIGIN);
 76  }
 77
 78  // Microswitch
 79  if (false) {
 80    translate([60, 2+StrapHole[0]/2, 0]) {
 81      cuboid([20.2, 6.5, 20], anchor=LEFT);
 82    }
 83  }
 84
 85  // Fucking Magnets: 2×5×20mm
 86  for (x = [10, 60, 110]) {
 87    translate([x, -0.01, 1]) cube([5*1.05, 24, 2*1.08]);
 88  }
 89
 90  // Ruby
 91  translate([121, 86, 10-2]) {
 92    rotate([0, 0, 90]) {
 93      linear_extrude(height=10, convexity=6) {
 94        import("ruby.svg");
 95      }
 96    }
 97  }
 98
 99  //#translate([2, 25, 0]) pcb();
100}
101
102translate([10, 37, 20]) switch();
103translate([24, 37, 20]) switch();