123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- /*
- * Trackball
- *
- * Copyright (c) 2022 - 2023 Thomas Buck (thomas@xythobuz.de)
- * Philipp Schönberger (mail@phschoen.de)
- *
- * Required parts:
- * - 1x Raspberry Pi Pico
- * - 4x Cherry MX compatible switches and keycaps
- * - 1x Billard ball, diameter 38mm
- * - 3x Si3N4 static bearing balls, diameter 3mm
- * - 1x PMW3360 sensor with breakout board
- * - 8x M2 screw, length 5mm
- * - 8x M2 heat melt insert, length 4mm
- *
- * For the PMW3360 breakout board get this:
- * https://github.com/jfedor2/pmw3360-breakout
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * See <http://www.gnu.org/licenses/>.
- */
-
- include<mx_switch.scad>; // need include since the parameters are in there
- include <pico.scad>; // need include since the parameters are in there
-
- use<usbc.scad>;
- use<sensor_pmw3360.scad>;
- use<pico.scad>;
- use<bearing.scad>;
- use<ball_and_bearing.scad>;
- use<util.scad>;
- use<external/led_ring.scad>;
-
- include<config.scad>;
-
- translate([$t*assembly_dist,$t*-assembly_dist,0])
- top_hand_wrest();
-
- trackball_top();
-
- translate([0,0,-$t*assembly_dist])
- trackball_bot();
-
- // %translate([-13,38,5-trackball_dia/2])
- // scale(150)
- // rotate([0,0,-133])
- // import("external/mouse_scan_v1.stl");
-
- module trackball_bot()
- {
- difference() {
- color("green")
- trans_bot_of_top_part()
- translate([0,0,-wall])
- linear_extrude(wall)
- {
- hull()
- projection() {
- trackball_top();
- }
- projection() {
- top_hand_wrest();
- }
- }
-
- trackball_bot_screw_cuts();
- }
- }
-
- module trackball_bot_screw_cuts(e=2)
- {
- pos= [
- // offset angle
- [ trackball_dia/2 + 15, 52 + 15 ],
- [ trackball_dia/2 + 15, 52 - 40 ],
- [ trackball_dia/2 + 15, 52 - 15 + 180 ],
- [ trackball_dia/2 + 15, 52 + 40 + 180 ],
- [ trackball_dia/2 + 75, 52 - 90 -10],
- [ trackball_dia/2 + 75, 52 - 90 +10],
- ];
-
- for(p = pos)
- rotate([0,0,p[1]])
- translate([p[0],0,0])
- translate([0,0,7-$e*2])
- trans_bot_of_top_part()
- rotate([0,180,0])
- {
- m3_screw_insert_cut(8);
- }
- }
-
- module trackball_top()
- {
- if (draw_ball_bearing_holder)
- %ball_and_bearing_holder();
-
- difference()
- {
- hull()
- {
- intersection_top_part(is_wristrest = false)
- trackball_top_hull(with_bot_cuts=true);
-
- trans_bot_of_top_part()
- linear_extrude($e)
- projection() {
- intersection_top_part(is_wristrest = false)
- trackball_top_hull(with_bot_cuts=true);
- }
- }
-
- top_body_cutouts();
- }
- }
-
- module intersection_top_part(is_wristrest = false)
- {
- intersection()
- {
- rotate([0,0,-38])
- translate([37.1,-50,-50])
- trans_bot_of_top_part()
- if(is_wristrest == true)
- cube([100,200,200]);
- else
- translate([-100,0,0])
- cube([100,200,200]);
-
- children();
- }
- }
-
- module m3_screw_insert_cut(l=20)
- {
- // screw thread cutout
- color("silver")
- cylinder(d=3,h=50);
-
- // insert cutout itself
- color("gold")
- cylinder(d=4.6+$c*2,h=7);
-
- // screw head cutout for sliding in
- translate([0,0,l])
- color("silver")
- cylinder(d=6+$c*2,h=50);
-
- // insert iself
- // % color("gold")
- // cylinder(d=4.6,h=5.7);
- }
-
- module wrest_screw_cutout()
- {
- for(i=[1,-1])
- rotate([0,0,-38])
- translate([31,i*15,14])
- trans_bot_of_top_part()
- rotate([0,20,0])
- rotate([0,90,0])
- {
- m3_screw_insert_cut(20);
- }
- }
-
- module top_hand_wrestv1()
- {
- difference()
- {
- intersection_top_part(is_wristrest = true)
- rotate([0,0,-38])
- translate([60,0,0])
- trans_bot_of_top_part()
- intersection()
- {
-
- scale([3.5,1.5,1])
- cylinder(r = 20, h = trackball_dia+17);
-
- translate([15,0,20-trackball_dia/2])
- rotate([0,30,0])
- scale([1.3,1.4,1])
- sphere(d=70);
- }
-
- // screw cutout for attaching the wrist rest to the top part
- wrest_screw_cutout();
-
-
- // screw cutouts for the bottom plate
- translate([0,0,-$e])
- trackball_bot_screw_cuts(e=0);
-
- // pi pico cutout
- rotate([0,0,50])
- trans_bot_of_top_part()
- translate([3,-80,3])
- {
- %if(draw_pico) pico_wrap();
- pico_cutout(20);
- }
- }
- }
- module top_hand_wrest()
- {
- difference()
- {
-
- intersection_top_part(is_wristrest = true)
- rotate([0,0,-38])
- translate([60,0,0])
- trans_bot_of_top_part()
- intersection() {
- translate([-200,-200,0])
- cube([400,400,100]);
-
- minkowski() {
- intersection()
- {
-
- scale([3.5,1.5,1])
- cylinder(r = 20, h = trackball_dia+17);
-
- translate([15,0,20-trackball_dia/2])
- rotate([0,30,0])
- scale([1.3,1.4,1])
- sphere(d=70);
- }
-
- sphere(r = 3);
-
- }
- }
-
- // screw cutout for attaching the wrist rest to the top part
- wrest_screw_cutout();
-
- // screw cutouts for the bottom plate
- translate([0,0,-$e])
- trackball_bot_screw_cuts(e=0);
-
- // pi pico cutout
- rotate([0,0,50])
- trans_bot_of_top_part()
- translate([3,-80,3])
- {
- %if(draw_pico) pico_wrap();
- pico_cutout(20);
- }
- }
- }
-
- module pico_cutout(extra)
- {
- translate([-pico_w / 2, -pico_l / 2, -extra]) {
-
- // pcb cutout
- cube([pico_w, pico_l, 4 + extra]);
-
- // screw cutouts
- for (x = [0, pico_hole_d_x])
- for (y = [0, pico_hole_d_y])
- translate([pico_hole_x + x, pico_hole_y + y, extra])
- cylinder(d = pico_hole_d, h = pico_d + 2+5);
-
- // cable channels
- translate([pico_w/2-9/2,pico_l-10,0])
- cube([9, trackball_dia+10, 4 + extra+2]);
- }
- }
-
- module top_body_cutouts()
- {
- // space for roller holder
- bearing_rot_trans()
- translate([0,0,-bearing_h])
- cylinder(d = bearing_mount_dia + 1, h = trackball_dia / 2 + bearing_h);
-
- // room for ball itself
- sphere($fn = $fn * 2, d = trackball_dia + $c * 2 + 4);
-
- // grub screws for the bearing holder
- bearing_rot_trans()
- rotate([0,-90,90])
- translate([-bearing_h+4, 0, 0])
- {
- cylinder(d = grub_screw_dia, h = trackball_dia);
-
- translate([0, 0, bearing_mount_grub_screw_l]) // outside of wall
-
- translate([0, 0, bearing_mount_dia/2 +wall/2]) // outside of wall
- cylinder(d = grub_channel_dia, h = trackball_dia);
- }
-
- // sensor lens
- sensor_cutout();
- %if(draw_sensor) sensor_pos();
-
- // switch cutouts
- //translate([0, 0, trackball_dia / 2 + ball_h])
- switch_rot_trans(0)
- translate([10,10,0])
- {
- // switch cutout itself
- mx_switch_cutout(mx_co_depth);
-
- %if(draw_switches)
- translate([0,0,10])
- mx_switch();
- }
-
- switch_rot_trans(0,false)
- translate([10,10,0])
- {
- // cable channel
- rotate([-40,0,0])
- rotate([0,180,0])
- cylinder(d=3,h=trackball_dia);
- }
-
- // led ring
- translate([0,0,-trackball_dia/2])
- {
- led_ring(cutout=true, extra = trackball_dia/2);
- %if(draw_led) led_ring();
- }
-
- // screw cutouts for the wrist rest
- wrest_screw_cutout();
-
- // screw cutouts for the bottom plate
- translate([0,0,-$e])
- trackball_bot_screw_cuts(e=0);
-
- // pico cutout
- rotate([0,0,50])
- trans_bot_of_top_part()
- translate([3,-80,3])
- {
- pico_cutout(20);
- pico_cutout(20);
- }
-
- // usb cutout
- rotate([0,0,180+50])
- trans_bot_of_top_part()
- translate([0,-trackball_dia/2-8,2])
- {
- %if(draw_usb_c)usb_c();
- usb_c_cutout();
- }
- }
-
- module switch_rot_trans(r,x_rot=true)
- {
- for ( i = [0:len(sw)-1] )
- {
- rotate([0,0,sw[i][0][2]])
- translate(sw[i][1])
- rotate([90+(x_rot ? sw[i][0][0] : 0),0,sw[i][0][1]])
- translate([-sw_mount_w/2 - r, -sw_mount_w/2 - r, -r - r/2])
- children();
- }
- }
-
- module trans_bot_of_top_part()
- {
- translate([0, 0, -trackball_dia / 2 -11])
- children();
- }
-
- module trackball_top_hull(with_bot_cuts=true)
- {
- difference() {
- color("orange")
- union(){
- hull() {
- // bearing holder cylinders
- bearing_rot_trans()
- bearing_holder_mount();
-
- // base circle
- trans_bot_of_top_part()
- cylinder(d = base_dia, h = $e);
-
- // switch
- switch_rot_trans(sw_mount_r)
- translate([0,0,sw_mount_r*2])
- fully_rounded_cube([sw_mount_w + sw_mount_r*2,
- sw_mount_w + sw_mount_r*2,
- mx_co_depth], sw_mount_r);
- }
- }
- }
- }
|