My self-made 3D-printable designs, mainly in OpenSCAD
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.

opi-pc-plus.scad 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. opi_width = 56;
  2. opi_length = 85.5;
  3. opi_holes = 2.8;
  4. opi_hole_dist = 3.0;
  5. opi_pcb_height = 1.6;
  6. opi_power_width = 8.2;
  7. opi_power_height = 6.2;
  8. opi_power_depth = 12.7;
  9. opi_power_off_x = 7.5;
  10. opi_power_off_y = -2.0;
  11. opi_hdmi_width = 15.2;
  12. opi_hdmi_height = 5.7;
  13. opi_hdmi_depth = 11.6;
  14. opi_hdmi_off_x = opi_power_off_x + opi_power_width + 14.5;
  15. opi_hdmi_off_y = opi_power_off_y;
  16. opi_audio_diameter = 5.1;
  17. opi_audio_depth = 13.0;
  18. opi_audio_off_x = opi_hdmi_off_x + opi_hdmi_width + 17.5;
  19. opi_audio_off_y = opi_hdmi_off_y;
  20. opi_sd_width = 14.8;
  21. opi_sd_height = 2.0;
  22. opi_sd_depth = 14.8;
  23. opi_sd_off_y = 16.5;
  24. opi_reset_diameter = 4.0;
  25. opi_reset_depth = 5.0;
  26. opi_reset_off_y = 8.5;
  27. opi_reset_off_x = -0.8;
  28. opi_reset_off_z = 1.1;
  29. opi_cam_width = 16.5;
  30. opi_cam_depth = 5.0;
  31. opi_cam_height = 2.0;
  32. opi_cam_off_y = 15.5;
  33. opi_cam_off_x = 1.0;
  34. opi_micro_usb_width = 7.9;
  35. opi_micro_usb_height = 2.9;
  36. opi_micro_usb_depth = 5.8;
  37. opi_micro_usb_off_y = opi_cam_off_y + opi_cam_width + 3.5;
  38. opi_micro_usb_off_x = -0.8;
  39. opi_ir_width = 6.0;
  40. opi_ir_height = 8.3;
  41. opi_ir_depth = 5.5;
  42. opi_ir_off_x = 16.5;
  43. opi_ir_off_y = -0.9;
  44. opi_single_usb_width = 5.8;
  45. opi_single_usb_height = 13.2;
  46. opi_single_usb_depth = 19.7;
  47. opi_single_usb_off_y = 6.8;
  48. opi_single_usb_off_x = -4.3;
  49. opi_lan_width = 16.1;
  50. opi_lan_depth = 21.7;
  51. opi_lan_height = 13.4;
  52. opi_lan_off_y = opi_single_usb_off_y + opi_single_usb_width + 3.0;
  53. opi_lan_off_x = -4.2;
  54. opi_dual_usb_width = 13.2;
  55. opi_dual_usb_depth = 17.5;
  56. opi_dual_usb_height = 15.0;
  57. opi_dual_usb_off_y = opi_lan_off_y + opi_lan_width + 4.3;
  58. opi_dual_usb_off_x = -4.1;
  59. standoff_height = 3.0;
  60. standoff_diameter = 5.0;
  61. standoff_hole = 2.5;
  62. outer_wall_size = 2.0;
  63. bottom_top_size = 2.0;
  64. total_height = (2 * bottom_top_size) + standoff_height + opi_pcb_height + opi_dual_usb_height;
  65. wall_height = total_height - (2 * bottom_top_size);
  66. top_standoff_height = wall_height - standoff_height - opi_pcb_height;
  67. top_standoff_hole = 3.0;
  68. sma_diameter = 5.9;
  69. sma_off_x = 15.0;
  70. sma_off_y = 15.0;
  71. cable_cut_width = 51.0;
  72. cable_cut_depth = 5.4;
  73. cable_cut_off_x = 8.8;
  74. cable_cut_off_y = 1.2;
  75. text_depth = 0.25;
  76. text1_font = "Liberation Sans";
  77. text1_size = 7;
  78. text1 = "OrangePi PC Plus";
  79. text1_off_x = 6;
  80. text1_off_y = 20;
  81. text2_font = "Liberation Sans";
  82. text2_size = 5.5;
  83. text2 = "by xythobuz.de";
  84. text2_off_x = 27;
  85. text2_off_y = 40.5;
  86. corner_helper_size = 20;
  87. corner_helper_height = 0.2;
  88. $fn = 20;
  89. module orangepi_pc_plus() {
  90. difference() {
  91. // pcb
  92. cube([opi_length, opi_width, opi_pcb_height]);
  93. // mounting holes
  94. for (i = [0 : 1]) {
  95. for (j = [0 : 1]) {
  96. translate([i * opi_length, j * opi_width, -1])
  97. translate([-((i * 2) - 1) * opi_hole_dist, 0, 0])
  98. translate([0, -((j * 2) - 1) * opi_hole_dist, 0])
  99. cylinder(d = opi_holes, h = opi_pcb_height + 2);
  100. }
  101. }
  102. }
  103. // power connector
  104. translate([opi_power_off_x, opi_power_off_y, opi_pcb_height])
  105. cube([opi_power_width, opi_power_depth, opi_power_height]);
  106. // hdmi connector
  107. translate([opi_hdmi_off_x, opi_hdmi_off_y, opi_pcb_height])
  108. cube([opi_hdmi_width, opi_hdmi_depth, opi_hdmi_height]);
  109. // audio connector
  110. translate([opi_audio_off_x + (opi_audio_diameter / 2), opi_audio_off_y + opi_audio_depth, opi_pcb_height + (opi_audio_diameter / 2)])
  111. rotate([90, 0, 0])
  112. cylinder(d = opi_audio_diameter, h = opi_audio_depth);
  113. // micro sd card slot
  114. translate([0, opi_sd_off_y, -opi_sd_height])
  115. cube([opi_sd_depth, opi_sd_width, opi_sd_height]);
  116. // reset button
  117. translate([opi_reset_off_x, opi_reset_off_y + (opi_reset_diameter / 2), opi_pcb_height + (opi_reset_diameter / 2) + opi_reset_off_z])
  118. rotate([0, 90, 0])
  119. cylinder(d = opi_reset_diameter, h = opi_reset_depth);
  120. // camera connector
  121. translate([opi_cam_off_x, opi_cam_off_y, opi_pcb_height])
  122. cube([opi_cam_depth, opi_cam_width, opi_cam_height]);
  123. // micro usb connector
  124. translate([opi_micro_usb_off_x, opi_micro_usb_off_y, opi_pcb_height])
  125. cube([opi_micro_usb_depth, opi_micro_usb_width, opi_micro_usb_height]);
  126. // ir receiver
  127. translate([opi_length - opi_ir_off_x - opi_ir_width, opi_width - opi_ir_off_y - opi_ir_depth, opi_pcb_height])
  128. cube([opi_ir_width, opi_ir_depth, opi_ir_height]);
  129. // single usb port
  130. translate([opi_length - opi_single_usb_off_x - opi_single_usb_depth, opi_width - opi_single_usb_off_y - opi_single_usb_width, opi_pcb_height])
  131. cube([opi_single_usb_depth, opi_single_usb_width, opi_single_usb_height]);
  132. // ethernet port
  133. translate([opi_length - opi_lan_off_x - opi_lan_depth, opi_width - opi_lan_off_y - opi_lan_width, opi_pcb_height])
  134. cube([opi_lan_depth, opi_lan_width, opi_lan_height]);
  135. // dual usb ports
  136. translate([opi_length - opi_dual_usb_off_x - opi_dual_usb_depth, opi_width - opi_dual_usb_off_y - opi_dual_usb_width, opi_pcb_height])
  137. cube([opi_dual_usb_depth, opi_dual_usb_width, opi_dual_usb_height]);
  138. }
  139. module case_bottom() {
  140. // bottom plate
  141. cube([opi_length + (2 * outer_wall_size), opi_width + (2 * outer_wall_size), bottom_top_size]);
  142. // print helper corner disks
  143. for (i = [0 : 1]) {
  144. for (j = [0 : 1]) {
  145. translate([i * (opi_length + (2 * outer_wall_size)), j * (opi_width + (2 * outer_wall_size)), 0])
  146. cylinder(d = corner_helper_size, h = corner_helper_height);
  147. }
  148. }
  149. // standoffs
  150. translate([outer_wall_size, outer_wall_size, 0])
  151. for (i = [0 : 1]) {
  152. for (j = [0 : 1]) {
  153. translate([i * opi_length, j * opi_width, bottom_top_size])
  154. translate([-((i * 2) - 1) * opi_hole_dist, 0, 0])
  155. translate([0, -((j * 2) - 1) * opi_hole_dist, 0])
  156. difference() {
  157. cylinder(d = standoff_diameter, h = standoff_height);
  158. cylinder(d = standoff_hole, h = standoff_height + 1);
  159. }
  160. }
  161. }
  162. // left (micro sd) wall
  163. translate([0, 0, bottom_top_size])
  164. difference() {
  165. cube([outer_wall_size, opi_width + (2 * outer_wall_size), standoff_height + opi_pcb_height]);
  166. // sd card cutout
  167. translate([-1, outer_wall_size + opi_sd_off_y, standoff_height - opi_sd_height])
  168. cube([outer_wall_size + 2, opi_sd_width, opi_sd_height + standoff_height]);
  169. }
  170. // front wall
  171. translate([outer_wall_size, 0, bottom_top_size])
  172. cube([opi_length, outer_wall_size, standoff_height + opi_pcb_height]);
  173. // back wall
  174. translate([outer_wall_size, opi_width + outer_wall_size, bottom_top_size])
  175. cube([opi_length, outer_wall_size, standoff_height + opi_pcb_height]);
  176. // right wall
  177. translate([outer_wall_size + opi_length, 0, bottom_top_size])
  178. cube([outer_wall_size, opi_width + (2 * outer_wall_size), standoff_height + opi_pcb_height]);
  179. }
  180. module case_top() {
  181. difference() {
  182. // top plate
  183. cube([opi_length + (2 * outer_wall_size), opi_width + (2 * outer_wall_size), bottom_top_size]);
  184. // sma connector
  185. translate([outer_wall_size + sma_off_x, outer_wall_size + opi_width - sma_off_y, -1])
  186. cylinder(d = sma_diameter, h = bottom_top_size + 2);
  187. // holes in top plate
  188. translate([outer_wall_size, outer_wall_size, 0])
  189. for (i = [0 : 1]) {
  190. for (j = [0 : 1]) {
  191. translate([i * opi_length, j * opi_width, -1])
  192. translate([-((i * 2) - 1) * opi_hole_dist, 0, 0])
  193. translate([0, -((j * 2) - 1) * opi_hole_dist, 0])
  194. cylinder(d = top_standoff_hole, h = bottom_top_size + 2);
  195. }
  196. }
  197. // cable cutout
  198. translate([outer_wall_size + cable_cut_off_x, outer_wall_size + opi_width - cable_cut_off_y - cable_cut_depth, -1])
  199. cube([cable_cut_width, cable_cut_depth, bottom_top_size + 2]);
  200. // text in top plate
  201. translate([text1_off_x, text1_off_y, bottom_top_size - text_depth])
  202. linear_extrude(height = text_depth + 0.1) {
  203. text(text1, font = text1_font, size = text1_size);
  204. }
  205. translate([text2_off_x, text2_off_y, bottom_top_size - text_depth])
  206. linear_extrude(height = text_depth + 0.1) {
  207. text(text2, font = text2_font, size = text2_size);
  208. }
  209. }
  210. // print helper corner disks
  211. for (i = [0 : 1]) {
  212. for (j = [0 : 1]) {
  213. translate([i * (opi_length + (2 * outer_wall_size)), j * (opi_width + (2 * outer_wall_size)), bottom_top_size - corner_helper_height])
  214. cylinder(d = corner_helper_size, h = corner_helper_height);
  215. }
  216. }
  217. // standoffs
  218. translate([outer_wall_size, outer_wall_size, 0])
  219. for (i = [0 : 1]) {
  220. for (j = [0 : 1]) {
  221. translate([i * opi_length, j * opi_width, -top_standoff_height])
  222. translate([-((i * 2) - 1) * opi_hole_dist, 0, 0])
  223. translate([0, -((j * 2) - 1) * opi_hole_dist, 0])
  224. difference() {
  225. cylinder(d = standoff_diameter, h = top_standoff_height);
  226. translate([0, 0, -1])
  227. cylinder(d = top_standoff_hole, h = top_standoff_height + 2);
  228. }
  229. }
  230. }
  231. // front wall
  232. translate([outer_wall_size, 0, -top_standoff_height])
  233. difference() {
  234. cube([opi_length, outer_wall_size, top_standoff_height]);
  235. // power connector
  236. translate([opi_power_off_x, -1, -1])
  237. cube([opi_power_width, outer_wall_size + 2, opi_power_height + 1]);
  238. // hdmi connector
  239. translate([opi_hdmi_off_x, -1, -1])
  240. cube([opi_hdmi_width, outer_wall_size + 2, opi_hdmi_height + 1]);
  241. // audio connector
  242. translate([opi_audio_off_x, -1, -1])
  243. cube([opi_audio_diameter, outer_wall_size + 2, opi_audio_diameter + 1]);
  244. }
  245. // back wall
  246. translate([outer_wall_size, opi_width + outer_wall_size, -top_standoff_height])
  247. difference() {
  248. cube([opi_length, outer_wall_size, top_standoff_height]);
  249. translate([opi_length - opi_ir_off_x - opi_ir_width, -1, -1])
  250. cube([opi_ir_width, outer_wall_size + 2, opi_ir_height + 1]);
  251. }
  252. // left wall
  253. translate([0, 0, -top_standoff_height])
  254. difference() {
  255. cube([outer_wall_size, opi_width + (2 * outer_wall_size), top_standoff_height]);
  256. // reset button
  257. translate([-1, outer_wall_size + opi_reset_off_y, -1])
  258. cube([outer_wall_size + 2, opi_reset_diameter, opi_reset_diameter + opi_reset_off_z + 1]);
  259. // camera connector
  260. translate([-1, outer_wall_size + opi_cam_off_y, -1])
  261. cube([outer_wall_size + 2, opi_cam_width, opi_cam_height + 1]);
  262. // micro usb connector
  263. translate([-1, outer_wall_size + opi_micro_usb_off_y, -1])
  264. cube([outer_wall_size + 2, opi_micro_usb_width, opi_micro_usb_height + 1]);
  265. }
  266. // right wall
  267. translate([outer_wall_size + opi_length, 0, -top_standoff_height])
  268. difference() {
  269. cube([outer_wall_size, opi_width + (2 * outer_wall_size), top_standoff_height]);
  270. // single usb port
  271. translate([-1, outer_wall_size + opi_width - opi_single_usb_off_y - opi_single_usb_width, -1])
  272. cube([outer_wall_size + 2, opi_single_usb_width, opi_single_usb_height + 1]);
  273. // ethernet port
  274. translate([-1, outer_wall_size + opi_width - opi_lan_off_y - opi_lan_width, -1])
  275. cube([outer_wall_size + 2, opi_lan_width, opi_lan_height + 1]);
  276. // dual usb ports
  277. translate([-1, outer_wall_size + opi_width - opi_dual_usb_off_y - opi_dual_usb_width, -1])
  278. cube([outer_wall_size + 2, opi_dual_usb_width, opi_dual_usb_height + 1]);
  279. }
  280. }
  281. module case_whole() {
  282. case_bottom();
  283. translate([0, 0, total_height - bottom_top_size])
  284. case_top();
  285. }
  286. // ---------------------
  287. // For looking at it in the OpenSCAD editor:
  288. /*
  289. case_whole();
  290. // place orangepi inside case, for visualization
  291. %translate([outer_wall_size, outer_wall_size, bottom_top_size + standoff_height])
  292. orangepi_pc_plus();
  293. */
  294. // ---------------------
  295. // For printing:
  296. /*
  297. case_bottom();
  298. */
  299. translate([0, 2 * (opi_width + (2 * outer_wall_size)) + 25, bottom_top_size])
  300. rotate([180, 0, 0])
  301. case_top();
  302. // ---------------------