| 1 | /* Arcade Button Bar Helper |
| 2 | * Copyright (C) 2017 Clinton Ebadi <clinton@unknownlamer.org> |
| 3 | * |
| 4 | * This program is free software: you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License as published by |
| 6 | * the Free Software Foundation, either version 3 of the License, or |
| 7 | * (at your option) any later version. |
| 8 | * |
| 9 | * This program is distributed in the hope that it will be useful, |
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | * GNU General Public License for more details. |
| 13 | * |
| 14 | * You should have received a copy of the GNU General Public License |
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 16 | */ |
| 17 | |
| 18 | |
| 19 | // todo |
| 20 | // - integrate good key cap library for example keys |
| 21 | |
| 22 | |
| 23 | $fs = 0.1; |
| 24 | |
| 25 | cols = 6; |
| 26 | rows = 1; |
| 27 | |
| 28 | bolt_depth = 12; |
| 29 | screw_d = 3.5; |
| 30 | |
| 31 | wall = 4; |
| 32 | bottom = 2; |
| 33 | border = 3; |
| 34 | |
| 35 | nutcatch_size = 6; |
| 36 | |
| 37 | |
| 38 | // switch depth + pin depth + clearance + room for mcu and wires |
| 39 | case_depth = 3.5 + 3.3 + 3.2 + 3; |
| 40 | |
| 41 | echo ("case_depth = ", case_depth); |
| 42 | |
| 43 | button_size = 20; |
| 44 | |
| 45 | // derived |
| 46 | box_size_x = cols*button_size+border*2; |
| 47 | box_size_y = rows*button_size+border*2; |
| 48 | |
| 49 | |
| 50 | module supports () { |
| 51 | for (x = [ 0, ceil (cols/2)*button_size+border*2 - nutcatch_size, box_size_x - nutcatch_size], y = [ 0, box_size_y - nutcatch_size]) { |
| 52 | translate ([x, y, 0]) { |
| 53 | children (); |
| 54 | } |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | module plate_hole () { |
| 59 | translate ([nutcatch_size/2, nutcatch_size/2, 0]) |
| 60 | circle (d = screw_d, $fs = 0.1); |
| 61 | } |
| 62 | |
| 63 | module nutcatch (screw_only=false) { |
| 64 | translate ([nutcatch_size/2, nutcatch_size/2, (case_depth+wall)/2]) { |
| 65 | difference () { |
| 66 | if (!screw_only) cube ([nutcatch_size, nutcatch_size, case_depth+wall], center=true); |
| 67 | |
| 68 | translate ([0, 0, (case_depth+wall-bolt_depth)/2+0.01]) cylinder (d = screw_d - 1, h = bolt_depth, center=true, $fs=0.1); |
| 69 | } |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | module cherrymx_slot () { |
| 74 | width = 14; |
| 75 | square (width, center=true); |
| 76 | // y=width-2 is supposed to be correct, but seemed better this way |
| 77 | square ([width+2, width-3], center=true); |
| 78 | } |
| 79 | |
| 80 | |
| 81 | module switch_plate_base (bevel=2, holes=true) { |
| 82 | difference () { |
| 83 | offset (r=bevel) offset (r=-bevel) square ([box_size_x, box_size_y]); |
| 84 | translate ([border, border, 0]) { |
| 85 | for (i = [ 0 : cols-1 ]) { |
| 86 | for (j = [ 0 : rows-1 ]) { |
| 87 | translate ([i*button_size + button_size/2, button_size/2 + j*button_size, 0]) |
| 88 | children (); |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | if (holes) { |
| 93 | supports () plate_hole (); |
| 94 | } |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | |
| 99 | |
| 100 | |
| 101 | module switch_plate (thickness=1.5, bevel=2) { |
| 102 | linear_extrude (height=thickness) { |
| 103 | switch_plate_base (cols=cols, rows=rows, button_size=button_size, bevel=bevel) |
| 104 | { |
| 105 | children (); |
| 106 | } |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | |
| 111 | |
| 112 | module case (depth=case_depth, wall=wall) { |
| 113 | module usb_port (w = 13, h = bottom + 6) { |
| 114 | translate ([wall, box_size_y/2-w/2, bottom]) rotate ([0, 0, 90]) cube ([w, wall+0.01, h]); |
| 115 | |
| 116 | } |
| 117 | |
| 118 | module mcu_holder () { |
| 119 | barrier_depth = 3; |
| 120 | barrier_x = 35.0 + nutcatch_size; |
| 121 | barrier_width = 2; |
| 122 | |
| 123 | translate ([barrier_x, 0, bottom]) cube ([barrier_width, box_size_y, barrier_depth]); |
| 124 | } |
| 125 | |
| 126 | difference () { |
| 127 | linear_extrude (height=depth+bottom) switch_plate_base (cols=cols, rows=rows, holes=false); |
| 128 | supports () nutcatch (screw_only=true); |
| 129 | |
| 130 | difference () { |
| 131 | translate ([wall/2, wall/2, bottom+0.01]) |
| 132 | linear_extrude (height=depth) resize ([box_size_x-wall, box_size_y-wall, 1]) switch_plate_base (cols=cols, rows=rows, holes=false); |
| 133 | supports () nutcatch (); |
| 134 | } |
| 135 | usb_port (); |
| 136 | } |
| 137 | mcu_holder (); |
| 138 | } |
| 139 | |
| 140 | module keys () { |
| 141 | $fs = 0.1; |
| 142 | $fa = 0.1; |
| 143 | keys = [ "", "", "", "" ,"",]; |
| 144 | |
| 145 | for (i = [ 0 : len (keys) ]) |
| 146 | translate ([i * button_size + border, border, 0]) |
| 147 | oneAlphanumericKey(keys[i], xOffset=-38.5, font="fontawesome"); |
| 148 | |
| 149 | translate ([(cols-1) * button_size + border, (rows-1) * button_size + border, 0]) oneAlphanumericKey ("⏎", xOffset=-38.5, font="DejaVu Sans"); |
| 150 | } |
| 151 | |
| 152 | module test_fit () { |
| 153 | color ("OliveDrab") switch_plate () { cherrymx_slot (); } |
| 154 | color (alpha=0.6) translate ([45, 10, 10]) keys (); |
| 155 | translate ([0, 0, -30]) case (); |
| 156 | |
| 157 | } |
| 158 | |
| 159 | module print () { |
| 160 | switch_plate () { cherrymx_slot (); } |
| 161 | translate ([0, box_size_y+5, 0]) case (); |
| 162 | } |
| 163 | |
| 164 | print (); |
| 165 | //test_fit (); |
| 166 | |
| 167 | /* module keys () { */ |
| 168 | /* $fs = 0.1; */ |
| 169 | /* $fa = 0.1; */ |
| 170 | /* keys = [ "", "", "", "", "" ]; */ |
| 171 | /* for (j = [ 0 : rows-1 ]) { */ |
| 172 | /* for (i = [ 0 : cols-1 ]) { */ |
| 173 | /* index = i*(cols-1)+j; */ |
| 174 | /* if (index < len(keys)) { */ |
| 175 | /* echo (i, j, i*j, index); */ |
| 176 | /* translate ([i * button_size + border, j * button_size + border, 0]) */ |
| 177 | /* oneAlphanumericKey(keys[index], xOffset=-38.5, font="fontawesome"); */ |
| 178 | /* } */ |
| 179 | /* } */ |
| 180 | /* } */ |
| 181 | |
| 182 | |
| 183 | /* translate ([(cols-1) * button_size + border, (rows-1) * button_size + border, 0]) oneAlphanumericKey ("⏎", xOffset=-38.5, font="DejaVu Sans"); */ |
| 184 | /* } */ |