No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

table.scad 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. /*
  2. * Resources used:
  3. * https://www.thingiverse.com/thing:16627
  4. * https://www.chiefdelphi.com/t/timing-pulley-design-tutorial/383204
  5. *
  6. * Hardware required:
  7. * https://www.banggood.com/15pcs-Transparent-Pulley-Wheel-with-625zz-Double-Bearing-for-V-slot-3D-Printer-p-1575067.html?cur_warehouse=CN&rmmds=search
  8. * 2x NEMA17 stepper
  9. * 2040 extrusions, lengths see console output
  10. * 2020 extrusions, lengths see console output
  11. * GT2 belt, lengths see console output
  12. */
  13. include <config.scad>;
  14. use <gt2_pulley.scad>;
  15. use <common.scad>;
  16. $fn = 42;
  17. /***********************************
  18. ********** Printed Parts **********
  19. ***********************************/
  20. module belt_pulley(tc, dia, for_motor = 1) {
  21. difference() {
  22. union() {
  23. cylinder(d = dia + belt_pulley_rim * 2, h = (belt_pulley_width - belt_pulley_tooth_width) / 2);
  24. translate([0, 0, (belt_pulley_width - belt_pulley_tooth_width) / 2])
  25. gt2_2mm_pulley(tc, belt_pulley_tooth_width);
  26. cylinder(d = dia, h = (belt_pulley_width - belt_pulley_tooth_width) / 2);
  27. translate([0, 0, (belt_pulley_width - belt_pulley_tooth_width) / 2 + belt_pulley_tooth_width])
  28. cylinder(d = dia + belt_pulley_rim * 2, h = (belt_pulley_width - belt_pulley_tooth_width) / 2);
  29. }
  30. if (for_motor) {
  31. // motor shaft hole
  32. translate([0, 0, -1])
  33. cylinder(d = belt_pulley_axis_hole, h = belt_pulley_width + 2);
  34. } else {
  35. // bearing hole
  36. translate([0, 0, -1])
  37. cylinder(d = bearing_outer, h = belt_pulley_width + 2);
  38. }
  39. // grub screw
  40. for (i = [0, 90])
  41. translate([0, 0, belt_pulley_width / 2])
  42. rotate([90, 0, i])
  43. cylinder(d = belt_pulley_fix_dia, h = dia / 2 + 1);
  44. }
  45. }
  46. module belt_tensioner_diff() {
  47. translate([-50, -belt_tensioner_diff_len, -belt_tensioner_diff_height / 2])
  48. cube([100, belt_tensioner_diff_len, belt_tensioner_diff_height]);
  49. translate([-belt_tensioner_diff_width / 2, -belt_tensioner_diff_len, -50])
  50. cube([belt_tensioner_diff_width, belt_tensioner_diff_len, 100]);
  51. }
  52. module belt_tensioner_mount_rail(height) {
  53. echo("belt tensioner", "t-nut", str(height * 2, "x"), str(motor_mount_hole_size_nominal, "mm"));
  54. difference() {
  55. if (height == 1) {
  56. for (i = [ 10, -10 - belt_tensioner_wall ])
  57. translate([i, 0, 0])
  58. cube([belt_tensioner_wall, belt_tensioner_mount_depth, 20 + belt_tensioner_wall]);
  59. } else {
  60. for (i = [ 10, -10 - belt_tensioner_wall ])
  61. translate([i, 0, -20])
  62. cube([belt_tensioner_wall, belt_tensioner_mount_depth, 40 + belt_tensioner_wall]);
  63. }
  64. for (i = [ 10, -10 ])
  65. translate([-10 - belt_tensioner_wall - 1, belt_tensioner_mount_depth / 2, i])
  66. rotate([0, 90, 0])
  67. cylinder(d = motor_mount_hole_size, h = 20 + 2 * belt_tensioner_wall + 2);
  68. }
  69. }
  70. module belt_tensioner_mount(height) {
  71. echo("belt tensioner", "screw", "1x", str("M", belt_tensioner_screw), str(">", belt_tensioner_diff_len + belt_tensioner_wall + 5 - real_belt_pulley_dia, "mm"));
  72. echo("belt tensioner", "nut", "1x", str("M", belt_tensioner_screw));
  73. belt_tensioner_mount_rail(height);
  74. difference() {
  75. hull() {
  76. if (height == 1) {
  77. for (i = [ 10, -10 - belt_tensioner_wall ])
  78. translate([i, 0, 0])
  79. cube([belt_tensioner_wall, 1, 20 + belt_tensioner_wall]);
  80. } else {
  81. for (i = [ 10, -10 - belt_tensioner_wall ])
  82. translate([i, 0, -20])
  83. cube([belt_tensioner_wall, 1, 40 + belt_tensioner_wall]);
  84. }
  85. translate([-10, -belt_tensioner_diff_len - belt_tensioner_wall - 5, 25 - 21])
  86. cube([20, belt_tensioner_wall, 20 + 1]);
  87. }
  88. translate([-10 - belt_tensioner_wall - 1, 0, -22])
  89. cube([20 + 2 * belt_tensioner_wall + 2, 50, 50]);
  90. translate([-10, 0, -22])
  91. cube([20, 50, 50]);
  92. translate([0, 0, 10 + belt_pulley_off])
  93. belt_tensioner_diff();
  94. translate([0, -belt_tensioner_diff_len - belt_tensioner_wall - 5 + 30 - 1, real_belt_pulley_dia / 2 + 0.175])
  95. rotate([90, 0, 0])
  96. cylinder(d = belt_tensioner_screw_hole, h = 30);
  97. }
  98. }
  99. module belt_tensioner_moving() {
  100. %color("red")
  101. translate([-belt_pulley_width / 2, 0, 0])
  102. rotate([0, 90, 0])
  103. rotate([0, 0, -acos(anim_pos_x * -2 + 1)])
  104. belt_pulley(teethcount, real_belt_pulley_dia, 0);
  105. color("cyan")
  106. difference() {
  107. for (i = [-1, 1])
  108. scale([i, 1, 1])
  109. translate([belt_pulley_width / 2 + belt_tensioner_moving_gap, belt_tensioner_moving_overlap - belt_tensioner_moving_len, -belt_tensioner_moving_height / 2])
  110. cube([belt_tensioner_wall, belt_tensioner_moving_len, belt_tensioner_moving_height]);
  111. translate([-belt_pulley_width / 2 - belt_tensioner_wall - belt_tensioner_moving_gap - 1, 0, 0])
  112. rotate([0, 90, 0])
  113. cylinder(d = axis_hole_diameter, h = belt_pulley_width + 2 * (belt_tensioner_wall + belt_tensioner_moving_gap) + 2);
  114. }
  115. color("cyan")
  116. translate([-belt_pulley_width / 2 - belt_tensioner_moving_gap, -belt_tensioner_moving_len + belt_tensioner_moving_overlap, -belt_tensioner_moving_height / 2])
  117. difference() {
  118. cube([belt_pulley_width + 2 * belt_tensioner_moving_gap, belt_tensioner_wall, belt_tensioner_moving_height]);
  119. translate([belt_pulley_width / 2 + belt_tensioner_moving_gap, belt_tensioner_wall + 1, belt_tensioner_moving_height / 2])
  120. rotate([90, 0, 0])
  121. cylinder(d = belt_tensioner_screw_hole, h = belt_tensioner_wall + 2);
  122. }
  123. }
  124. module belt_tensioner(height, length = 100, visual = 1) {
  125. if (visual)
  126. %translate([-10, 0, 0])
  127. if (length > 0) {
  128. if (height == 1) {
  129. rail_2020_y(length, "only for visualization");
  130. } else {
  131. rail_2040_y(length, "only for visualization");
  132. }
  133. }
  134. translate([0, -belt_tensioner_travel * $t, 0])
  135. translate([0, -real_belt_pulley_dia / 2, 10 + belt_pulley_off])
  136. belt_tensioner_moving();
  137. color("orange")
  138. belt_tensioner_mount(height);
  139. %color("yellow")
  140. translate([-belt_width / 2, -real_belt_pulley_dia / 2, 10 + real_belt_pulley_dia / 2 + belt_pulley_off - belt_thickness / 2])
  141. cube([belt_width, length + real_belt_pulley_dia / 2 + nema17_size / 2, belt_thickness]);
  142. %color("yellow")
  143. translate([-belt_width / 2, -real_belt_pulley_dia / 2, 10 - real_belt_pulley_dia / 2 - belt_thickness / 2 + belt_pulley_off])
  144. cube([belt_width, length + real_belt_pulley_dia / 2 + nema17_size / 2, belt_thickness]);
  145. }
  146. module motor_mount(height) {
  147. echo("motor mount", "t-nut", str(height * 2, "x"), str(motor_mount_hole_size_nominal, "mm"));
  148. echo("motor mount", "screw", "4x", str("M", nema17_hole_size), str(motor_mount_height + 2, "-", motor_mount_height + 4, "mm"));
  149. %color("yellow")
  150. translate([-nema17_len, 0, nema17_size - belt_pulley_off])
  151. rotate([0, 90, 0])
  152. nema17(nema17_len);
  153. %color("red")
  154. translate([motor_mount_height - belt_pulley_width / 2 + 10, nema17_size / 2, nema17_size / 2 - belt_pulley_off])
  155. rotate([0, 90, 0])
  156. rotate([0, 0, -acos(anim_pos_x * -2 + 1)])
  157. belt_pulley(teethcount, real_belt_pulley_dia, 1);
  158. color("cyan")
  159. difference() {
  160. hull() {
  161. translate([0, 0, -belt_pulley_off])
  162. cube([motor_mount_height, nema17_size, nema17_size]);
  163. translate([0, nema17_size, (nema17_size - 20) / 2])
  164. cube([motor_mount_height, motor_mount_length, height * 20]);
  165. }
  166. translate([0, 0, -belt_pulley_off])
  167. translate([-nema17_len, 0, nema17_size])
  168. rotate([0, 90, 0]) {
  169. nema17_holes_face(nema17_len, motor_mount_height + 5, nema17_hole_size + screw_gap);
  170. translate([nema17_size / 2, nema17_size / 2, nema17_len - 1])
  171. cylinder(d = nema17_center_size + 2, h = motor_mount_height + 2);
  172. }
  173. for (i = [0, motor_mount_hole_off])
  174. for (j = [0, 20 * (height - 1)])
  175. translate([0, i, j])
  176. translate([-1, nema17_size - motor_mount_hole_off / 2 + motor_mount_length / 2, nema17_size / 2])
  177. rotate([0, 90, 0]) {
  178. cylinder(d = motor_mount_hole_size, h = motor_mount_height + 2);
  179. }
  180. }
  181. }
  182. /***********************************
  183. ************** Plate **************
  184. ***********************************/
  185. module plate_holes(h) {
  186. for (i = [-1, 1])
  187. for (j = [-1, 1])
  188. translate([i * plate_mount_screws_distance_x / 2, j * plate_mount_screws_distance_y / 2, -1])
  189. cylinder(d = plate_mount_screw_hole, h = h + 2);
  190. }
  191. module plate() {
  192. echo("alu plate", "bed", plate_x, plate_y, "holes", plate_mount_screws_distance_x, plate_mount_screws_distance_y);
  193. difference() {
  194. cube([plate_x, plate_y, plate_z]);
  195. translate([plate_x / 2, plate_y / 2, 0])
  196. plate_holes(plate_z);
  197. }
  198. }
  199. /************************************
  200. ************** Y-Axis **************
  201. ************************************/
  202. module belt_mount(h) {
  203. difference() {
  204. hull() {
  205. translate([-belt_mount_width / 2, -belt_mount_depth / 2, 0])
  206. cube([belt_mount_width, belt_mount_depth, h]);
  207. translate([-belt_mount_full_width / 2, belt_mount_depth / 2, 0])
  208. cube([belt_mount_full_width, 1, h]);
  209. }
  210. translate([-belt_slot_width / 2, -belt_slot_depth / 2, -1])
  211. cube([belt_slot_width, belt_slot_depth, h + 2]);
  212. translate([-belt_mount_full_width / 2, -belt_mount_depth / 2 - 0.1, h / 2])
  213. rotate([-90, 0, 0])
  214. prism(belt_mount_full_width, h / 2 + 0.1, belt_mount_depth + 0.1);
  215. }
  216. }
  217. module y_carriage_post() {
  218. rotate([0, 0, 90])
  219. difference() {
  220. cylinder(d = y_carriage_post_dia, h = y_carriage_post_len, $fn = 6);
  221. translate([0, 0, -1])
  222. cylinder(d = y_carriage_post_screw_hole, h = (y_carriage_post_len - y_carriage_post_center) / 2 + 1);
  223. translate([y_carriage_post_hole_off, 0, (y_carriage_post_len + y_carriage_post_center) / 2])
  224. cylinder(d = y_carriage_post_screw_hole, h = (y_carriage_post_len - y_carriage_post_center) / 2 + 1);
  225. }
  226. }
  227. module y_carriage_posts() {
  228. for (i = [-1, 1])
  229. for (j = [-1, 1])
  230. translate([i * y_carriage_wheel_x_dist / 2, j * y_carriage_wheel_y_dist / 2, 0]) {
  231. color("blue")
  232. y_carriage_post();
  233. %color("yellow")
  234. translate([0, y_carriage_post_hole_off, y_carriage_pulley_off])
  235. rail_wheel();
  236. }
  237. }
  238. // also used as base for x-carriage
  239. // axis = 0 --> all holes, usable for both
  240. // axis = 1 --> holes for x-carriage
  241. // axis = 2 --> holes for y-carriage
  242. module y_carriage(axis = 0) {
  243. if (axis == 1) {
  244. echo("t-nut", "x-carriage", "2");
  245. }
  246. color("green")
  247. difference() {
  248. cube([y_carriage_x, y_carriage_y, y_carriage_h]);
  249. translate([y_carriage_x / 2, y_carriage_y / 2, 0])
  250. plate_holes(y_carriage_h);
  251. // holes to mount y-axis to x-carriage
  252. if ((axis == 0) || (axis == 1)) {
  253. translate([(y_carriage_x - plate_mount_screws_distance_x) / 2, 0, 0])
  254. for (i = [0, 1])
  255. translate([i * plate_mount_screws_distance_x, y_carriage_y / 2, -1])
  256. cylinder(d = y_carriage_post_screw_hole, h = y_carriage_h + 2);
  257. for (i = [x_carriage_holder_l - x_carriage_holder_hole_off, y_carriage_y - x_carriage_holder_l + x_carriage_holder_hole_off])
  258. translate([y_carriage_x / 2, i, -1])
  259. cylinder(d = y_carriage_post_screw_hole, h = y_carriage_h + 2);
  260. }
  261. translate([y_carriage_x / 2, y_carriage_y / 2, 0])
  262. for (i = [-1, 1])
  263. for (j = [-1, 1])
  264. translate([i * y_carriage_wheel_x_dist / 2, j * y_carriage_wheel_y_dist / 2, -1]) {
  265. cylinder(d = y_carriage_post_screw_hole, h = y_carriage_h + 2);
  266. }
  267. }
  268. %translate([y_carriage_x / 2, y_carriage_y / 2, y_carriage_h])
  269. y_carriage_posts();
  270. color("green")
  271. translate([y_carriage_x / 2, -belt_mount_depth / 2, 0])
  272. belt_mount(y_carriage_h);
  273. color("green")
  274. translate([y_carriage_x / 2, y_carriage_y + belt_mount_depth / 2, 0])
  275. scale([1, -1, 1])
  276. belt_mount(y_carriage_h);
  277. }
  278. module y_axis() {
  279. translate([y_carriage_x / 2, y_axis_animation_position, 20 + y_carriage_h + y_carriage_rail_dist])
  280. rotate([0, 180, 0])
  281. y_carriage(2);
  282. color("grey")
  283. translate([-10, 0, 0])
  284. rail_2040_y(y_axis_rail_len, "y-axis");
  285. translate([- motor_mount_height - 10, y_axis_rail_len + nema17_size, nema17_size / 2 + 10])
  286. rotate([180, 0, 0])
  287. motor_mount(2);
  288. belt_tensioner(2, y_axis_rail_len, 0);
  289. }
  290. /************************************
  291. ************** X-Axis **************
  292. ************************************/
  293. module x_carriage_holder() {
  294. echo("t-nut", "x-carriage-holder", "2");
  295. difference() {
  296. union() {
  297. cube([x_carriage_holder_l, x_carriage_holder_w, x_carriage_holder_h]);
  298. cube([x_carriage_holder_h, x_carriage_holder_w, 20]);
  299. }
  300. translate([0, (x_carriage_holder_w - x_carriage_holder_rail_hole_dist) / 2, 0])
  301. for (i = [0, x_carriage_holder_rail_hole_dist])
  302. translate([-1, i, 10])
  303. rotate([0, 90, 0])
  304. cylinder(d = y_carriage_post_screw_hole, h = x_carriage_holder_h + 2);
  305. translate([-(y_carriage_y - plate_mount_screws_distance_y) / 2, y_carriage_x / 2, 0])
  306. rotate([0, 0, 90])
  307. plate_holes(x_carriage_holder_h);
  308. translate([x_carriage_holder_hole_off, x_carriage_holder_w / 2, -1])
  309. cylinder(d = y_carriage_post_screw_hole, h = x_carriage_holder_h + 2);
  310. }
  311. }
  312. module x_carriage() {
  313. translate([0, -y_carriage_x / 2, y_carriage_h + y_carriage_rail_dist + 20])
  314. rotate([0, 180, -90])
  315. y_carriage(1);
  316. color("purple")
  317. for (i = [-1, 1])
  318. translate([y_carriage_y / 2, 0, 0])
  319. scale([i, 1, 1])
  320. translate([y_carriage_y / 2 - x_carriage_holder_l, 0, 0])
  321. translate([0, -x_carriage_holder_w / 2, 20 + y_carriage_h + y_carriage_rail_dist])
  322. x_carriage_holder();
  323. }
  324. module x_axis() {
  325. translate([x_axis_animation_position + 10, 0, 0])
  326. x_carriage();
  327. color("grey")
  328. translate([0, -10, 0])
  329. rail_2040_x(x_axis_rail_len, "x-axis");
  330. translate([x_axis_rail_len + nema17_size, motor_mount_height + 10, nema17_size / 2 + 10])
  331. rotate([0, 180, 90])
  332. motor_mount(2);
  333. rotate([0, 0, -90])
  334. belt_tensioner(2, x_axis_rail_len, 0);
  335. }
  336. /************************************
  337. ************* Assembly *************
  338. ************************************/
  339. module assembly_y_axis_plate() {
  340. translate([0, -y_carriage_y / 2 - y_axis_animation_position, 0])
  341. y_axis();
  342. %translate([-plate_x / 2, -plate_y / 2, 20 + y_carriage_h + y_carriage_rail_dist])
  343. plate();
  344. }
  345. module assembly_x_axis() {
  346. x_axis();
  347. translate([x_axis_animation_position + y_carriage_y / 2, -y_axis_rail_len / 2, 20 + y_carriage_h + y_carriage_rail_dist])
  348. translate([10, y_axis_animation_position + y_carriage_y / 2, 20])
  349. assembly_y_axis_plate();
  350. }
  351. module assembly() {
  352. translate([-x_axis_rail_len / 2, 0, 20]) {
  353. assembly_x_axis();
  354. color("grey")
  355. for (i = [1, -1])
  356. scale([1, i, 1])
  357. translate([left_support_off, -left_support_len - 10, -20])
  358. rail_2020_y(left_support_len, "left support");
  359. color("grey")
  360. for (i = [1, -1])
  361. scale([1, i, 1])
  362. translate([x_axis_rail_len - 20 - right_support_off, -right_support_len - 10, -20])
  363. rail_2020_y(right_support_len, "right support");
  364. }
  365. }
  366. module xy_table() {
  367. translate([-point_that_reaches_everywhere_x, -point_that_reaches_everywhere_y, -40 + -40 + (y_carriage_rail_dist + y_carriage_h) * -2 + -plate_z])
  368. assembly();
  369. }
  370. /***********************************
  371. ************ Rendering ************
  372. ***********************************/
  373. //dispenser();
  374. //rail_2020_x(100);
  375. //rail_wheel();
  376. //motor_mount(1);
  377. //motor_mount(2);
  378. //belt_pulley(teethcount, real_belt_pulley_dia, 1);
  379. //belt_tensioner_mount(2);
  380. //belt_tensioner_moving();
  381. //belt_tensioner(1);
  382. //belt_tensioner(2);
  383. //belt_pulley(teethcount, real_belt_pulley_dia, 0);
  384. //y_carriage_post();
  385. //x_carriage_holder();
  386. //y_carriage(0);
  387. //y_carriage(1);
  388. //y_carriage(2);
  389. x_carriage();
  390. //y_axis();
  391. //x_axis();
  392. //assembly();
  393. //xy_table();