Information and documentation on building an embedded board test lab.
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.
 
 
 
 

256 lines
8.9 KiB

  1. /* [Bolt holes in the corners] */
  2. // Pick the size of the long threaded rods that run through
  3. // the corners and hold everything together.
  4. //
  5. // These are the sizes that are commonly available at
  6. // Home Depot or Lowes:
  7. //
  8. // 1/4 inch: 3.175
  9. // #12 : 2.778125
  10. // #10 : 2.38125 (default and recommended)
  11. //
  12. // Note: you should pick the same size and fudge factor
  13. // for the ear parts.
  14. bolt_size = 2.38125;
  15. // Make the bolt holes this much bigger than the size of the bolt
  16. // to give a more comfortable fit
  17. bolt_hole_fudge = 0.2; // [0:0.25:1]
  18. /* [Notches and tabs for stacking] */
  19. // You can optionally omit the notches for the frame on the end
  20. // that joins with an ear with no tabs. For all of the others
  21. // you should leave this at its default of true.
  22. notches_enabled = true;
  23. // Make the slot this much taller than the tabs
  24. // to give a more comfortable fit.
  25. notch_fudge = 0.3; // [0:0.25:1]
  26. /* [Size] */
  27. // The default is to fit 12 units with PoE hats in a standard rack.
  28. // 12 is a good fit, and it works nicely with many PoE switches, which
  29. // often come with 12 or 24 ports. You can bump it up to 13 units and
  30. // they will still fit nicely with PoE hats, or you can go up to 14
  31. // of you are not using the hats.
  32. number_to_fit = 12; // [12:Relaxed fit, 13:Using PoE, 14:Without PoE hats]
  33. /* [Hidden] */
  34. // make the screw holes this much bigger than the
  35. // actual screw for a more comfortable fit
  36. // (a bigger number here will make the screws fit looser)
  37. screw_hole_fudge = 0.15;
  38. height = (450.85 - 20) / number_to_fit;
  39. width = 82;
  40. length = 90;
  41. // The height of the notches and tabs
  42. notch_height = 2;
  43. // epsilon is used to slightly overlap pieces to help the previewer
  44. epsilon = 0.001;
  45. bolt_radius = bolt_size + bolt_hole_fudge;
  46. outer_wall_thickness = 12;
  47. inner_wall_thickness = 7;
  48. back_wall_thickness = 5;
  49. wall_diff = outer_wall_thickness - inner_wall_thickness;
  50. floor_depth = 3;
  51. tray_depth = 5;
  52. tray_slot_depth = 2.5;
  53. spacer_depth = 3;
  54. sd_window_width = 40;
  55. sd_window_height = height - (tray_depth + floor_depth)*2;
  56. near_pillar_width = 15;
  57. far_pillar_width = 10;
  58. floor_window_width = sd_window_width;
  59. floor_window_border = (width - floor_window_width - outer_wall_thickness*2) / 2;
  60. floor_window_length = length - back_wall_thickness - floor_window_border*2;
  61. port_window_width = length - near_pillar_width - far_pillar_width;
  62. port_window_frame_height = floor_depth + tray_depth + spacer_depth - notch_height;
  63. difference() {
  64. union() {
  65. // the main block
  66. cube([width, length, height]);
  67. // the tabs
  68. translate([ wall_diff,
  69. near_pillar_width + wall_diff,
  70. height - epsilon]) {
  71. cube([ inner_wall_thickness - 2,
  72. length - near_pillar_width - far_pillar_width - wall_diff*2,
  73. notch_height + epsilon]);
  74. }
  75. translate([ width - outer_wall_thickness + 2,
  76. near_pillar_width + wall_diff,
  77. height - epsilon]) {
  78. cube([ inner_wall_thickness - 2,
  79. length - near_pillar_width - far_pillar_width - wall_diff*2,
  80. notch_height + epsilon]);
  81. }
  82. }
  83. // carve out the interior
  84. translate([outer_wall_thickness, -epsilon, floor_depth]) {
  85. cube( [width - outer_wall_thickness*2,
  86. length - back_wall_thickness + epsilon,
  87. height + notch_height - floor_depth + epsilon]);
  88. }
  89. // punch a hole for the sd card
  90. translate([ (width - sd_window_width) / 2,
  91. length - back_wall_thickness - epsilon,
  92. tray_depth + floor_depth]) {
  93. cube([ sd_window_width,
  94. back_wall_thickness + 2*epsilon,
  95. height - port_window_frame_height - tray_depth - floor_depth + notch_height]);
  96. }
  97. // punch a hole for side port access
  98. translate([ -epsilon,
  99. near_pillar_width,
  100. port_window_frame_height + notch_height]) {
  101. cube([ width + 2*epsilon,
  102. port_window_width,
  103. height - port_window_frame_height*2]);
  104. }
  105. // punch a hole in the bottom
  106. translate([ outer_wall_thickness + floor_window_border,
  107. floor_window_border,
  108. -epsilon]) {
  109. cube([ floor_window_width,
  110. floor_window_length,
  111. floor_depth + 2*epsilon]);
  112. }
  113. // open a groove that the speaker jack can slide through
  114. translate([ outer_wall_thickness - 2,
  115. -epsilon,
  116. port_window_frame_height + notch_height]) {
  117. cube([ 2 + epsilon,
  118. near_pillar_width + 2*epsilon,
  119. 8]);
  120. }
  121. // soften the leading edge a bit
  122. translate([ outer_wall_thickness,
  123. 0,
  124. floor_depth-0.5]) {
  125. rotate([25,0,0]) {
  126. cube([ width - outer_wall_thickness*2,
  127. 2,
  128. 2]);
  129. }
  130. }
  131. if (notches_enabled) {
  132. // cut the notches in the bottom
  133. translate([ -epsilon,
  134. near_pillar_width + wall_diff,
  135. -epsilon]) {
  136. cube([ outer_wall_thickness - 2 + epsilon,
  137. length - near_pillar_width - far_pillar_width - wall_diff*2,
  138. notch_height + notch_fudge + epsilon]);
  139. }
  140. translate([ width - outer_wall_thickness + 2,
  141. near_pillar_width + wall_diff,
  142. -epsilon]) {
  143. cube([ outer_wall_thickness - 2 + epsilon,
  144. length - near_pillar_width - far_pillar_width - wall_diff*2,
  145. notch_height + notch_fudge + epsilon]);
  146. }
  147. }
  148. // cut out the sides to make them thinner
  149. polyhedron(
  150. points = [
  151. [ wall_diff, length-far_pillar_width-wall_diff, height+notch_height+epsilon],
  152. [ wall_diff, near_pillar_width+wall_diff, height+notch_height+epsilon],
  153. [ wall_diff, length-far_pillar_width-wall_diff, -epsilon],
  154. [ wall_diff, near_pillar_width+wall_diff, -epsilon],
  155. [-wall_diff, length-far_pillar_width+wall_diff, height+notch_height+epsilon],
  156. [-wall_diff, near_pillar_width-wall_diff, height+notch_height+epsilon],
  157. [-wall_diff, length-far_pillar_width+wall_diff, -epsilon],
  158. [-wall_diff, near_pillar_width-wall_diff, -epsilon]
  159. ],
  160. faces = [
  161. [1,0,2,3],
  162. [4,5,7,6],
  163. [0,4,6,2],
  164. [6,7,3,2],
  165. [7,5,1,3],
  166. [5,4,0,1]
  167. ],
  168. convexity = 10);
  169. polyhedron(
  170. points = [
  171. [width-wall_diff, near_pillar_width+wall_diff, height+notch_height+epsilon],
  172. [width-wall_diff, length-far_pillar_width-wall_diff, height+notch_height+epsilon],
  173. [width-wall_diff, near_pillar_width+wall_diff, -epsilon],
  174. [width-wall_diff, length-far_pillar_width-wall_diff, -epsilon],
  175. [width+wall_diff, near_pillar_width-wall_diff, height+notch_height+epsilon],
  176. [width+wall_diff, length-far_pillar_width+wall_diff, height+notch_height+epsilon],
  177. [width+wall_diff, near_pillar_width-wall_diff, -epsilon],
  178. [width+wall_diff, length-far_pillar_width+wall_diff, -epsilon]
  179. ],
  180. faces = [
  181. [1,0,2,3],
  182. [4,5,7,6],
  183. [0,4,6,2],
  184. [6,7,3,2],
  185. [7,5,1,3],
  186. [5,4,0,1]
  187. ],
  188. convexity = 10);
  189. // drill the bolt holes
  190. for (a=[[outer_wall_thickness/2, near_pillar_width/2],
  191. [outer_wall_thickness/2, length - far_pillar_width/2],
  192. [width - outer_wall_thickness/2, near_pillar_width/2],
  193. [width - outer_wall_thickness/2, length - far_pillar_width/2]]) {
  194. translate([a[0], a[1], -epsilon]) {
  195. cylinder( h=height + notch_height + 2*epsilon,
  196. r=bolt_radius,
  197. center=false,
  198. $fn=360);
  199. }
  200. }
  201. // cut the tray insert slots
  202. // note: the tray will be slightly narrower to
  203. // give a more comfortable fit. If it is too loose or too tight,
  204. // adjust the tray.
  205. for (a=[ outer_wall_thickness,
  206. width - outer_wall_thickness]) {
  207. translate([ a,
  208. -epsilon,
  209. floor_depth + tray_depth/2]) {
  210. intersection() {
  211. rotate([0, 45, 0]) {
  212. translate([-tray_depth/sqrt(2)/2, 0, -tray_depth/sqrt(2)/2]) {
  213. cube([ tray_depth/sqrt(2),
  214. length - back_wall_thickness + epsilon,
  215. tray_depth/sqrt(2)]);
  216. }
  217. }
  218. translate([-tray_depth/2+0.5, 0, -tray_depth/2]) {
  219. cube([ tray_depth-1,
  220. length - back_wall_thickness + epsilon,
  221. tray_depth]);
  222. }
  223. }
  224. }
  225. }
  226. }