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 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  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.8;
  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. cutout_gap = 0.2;
  89. $fn = 20;
  90. module orangepi_pc_plus() {
  91. difference() {
  92. // pcb
  93. cube([opi_length, opi_width, opi_pcb_height]);
  94. // mounting holes
  95. for (i = [0 : 1]) {
  96. for (j = [0 : 1]) {
  97. translate([i * opi_length, j * opi_width, -1])
  98. translate([-((i * 2) - 1) * opi_hole_dist, 0, 0])
  99. translate([0, -((j * 2) - 1) * opi_hole_dist, 0])
  100. cylinder(d = opi_holes, h = opi_pcb_height + 2);
  101. }
  102. }
  103. }
  104. // power connector
  105. translate([opi_power_off_x, opi_power_off_y, opi_pcb_height])
  106. cube([opi_power_width, opi_power_depth, opi_power_height]);
  107. // hdmi connector
  108. translate([opi_hdmi_off_x, opi_hdmi_off_y, opi_pcb_height])
  109. cube([opi_hdmi_width, opi_hdmi_depth, opi_hdmi_height]);
  110. // audio connector
  111. translate([opi_audio_off_x + (opi_audio_diameter / 2), opi_audio_off_y + opi_audio_depth, opi_pcb_height + (opi_audio_diameter / 2)])
  112. rotate([90, 0, 0])
  113. cylinder(d = opi_audio_diameter, h = opi_audio_depth);
  114. // micro sd card slot
  115. translate([0, opi_sd_off_y, -opi_sd_height])
  116. cube([opi_sd_depth, opi_sd_width, opi_sd_height]);
  117. // reset button
  118. translate([opi_reset_off_x, opi_reset_off_y + (opi_reset_diameter / 2), opi_pcb_height + (opi_reset_diameter / 2) + opi_reset_off_z])
  119. rotate([0, 90, 0])
  120. cylinder(d = opi_reset_diameter, h = opi_reset_depth);
  121. // camera connector
  122. translate([opi_cam_off_x, opi_cam_off_y, opi_pcb_height])
  123. cube([opi_cam_depth, opi_cam_width, opi_cam_height]);
  124. // micro usb connector
  125. translate([opi_micro_usb_off_x, opi_micro_usb_off_y, opi_pcb_height])
  126. cube([opi_micro_usb_depth, opi_micro_usb_width, opi_micro_usb_height]);
  127. // ir receiver
  128. translate([opi_length - opi_ir_off_x - opi_ir_width, opi_width - opi_ir_off_y - opi_ir_depth, opi_pcb_height])
  129. cube([opi_ir_width, opi_ir_depth, opi_ir_height]);
  130. // single usb port
  131. 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])
  132. cube([opi_single_usb_depth, opi_single_usb_width, opi_single_usb_height]);
  133. // ethernet port
  134. translate([opi_length - opi_lan_off_x - opi_lan_depth, opi_width - opi_lan_off_y - opi_lan_width, opi_pcb_height])
  135. cube([opi_lan_depth, opi_lan_width, opi_lan_height]);
  136. // dual usb ports
  137. 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])
  138. cube([opi_dual_usb_depth, opi_dual_usb_width, opi_dual_usb_height]);
  139. }
  140. module case_bottom() {
  141. // bottom plate
  142. cube([opi_length + (2 * outer_wall_size), opi_width + (2 * outer_wall_size), bottom_top_size]);
  143. // print helper corner disks
  144. for (i = [0 : 1]) {
  145. for (j = [0 : 1]) {
  146. translate([i * (opi_length + (2 * outer_wall_size)), j * (opi_width + (2 * outer_wall_size)), 0])
  147. cylinder(d = corner_helper_size, h = corner_helper_height);
  148. }
  149. }
  150. // standoffs
  151. translate([outer_wall_size, outer_wall_size, 0])
  152. for (i = [0 : 1]) {
  153. for (j = [0 : 1]) {
  154. translate([i * opi_length, j * opi_width, bottom_top_size])
  155. translate([-((i * 2) - 1) * opi_hole_dist, 0, 0])
  156. translate([0, -((j * 2) - 1) * opi_hole_dist, 0])
  157. difference() {
  158. cylinder(d = standoff_diameter, h = standoff_height);
  159. cylinder(d = standoff_hole, h = standoff_height + 1);
  160. }
  161. }
  162. }
  163. // left (micro sd) wall
  164. translate([0, 0, bottom_top_size])
  165. difference() {
  166. cube([outer_wall_size, opi_width + (2 * outer_wall_size), standoff_height + opi_pcb_height]);
  167. // sd card cutout
  168. translate([-1, outer_wall_size + opi_sd_off_y - cutout_gap, standoff_height - opi_sd_height])
  169. cube([outer_wall_size + 2, opi_sd_width + (2 * cutout_gap), opi_sd_height + standoff_height]);
  170. }
  171. // front wall
  172. translate([outer_wall_size, 0, bottom_top_size])
  173. cube([opi_length, outer_wall_size, standoff_height + opi_pcb_height]);
  174. // back wall
  175. translate([outer_wall_size, opi_width + outer_wall_size, bottom_top_size])
  176. cube([opi_length, outer_wall_size, standoff_height + opi_pcb_height]);
  177. // right wall
  178. translate([outer_wall_size + opi_length, 0, bottom_top_size])
  179. cube([outer_wall_size, opi_width + (2 * outer_wall_size), standoff_height + opi_pcb_height]);
  180. }
  181. module case_top() {
  182. difference() {
  183. // top plate
  184. cube([opi_length + (2 * outer_wall_size), opi_width + (2 * outer_wall_size), bottom_top_size]);
  185. // sma connector
  186. translate([outer_wall_size + sma_off_x, outer_wall_size + opi_width - sma_off_y, -1])
  187. cylinder(d = sma_diameter, h = bottom_top_size + 2);
  188. // holes in top plate
  189. translate([outer_wall_size, outer_wall_size, 0])
  190. for (i = [0 : 1]) {
  191. for (j = [0 : 1]) {
  192. translate([i * opi_length, j * opi_width, -1])
  193. translate([-((i * 2) - 1) * opi_hole_dist, 0, 0])
  194. translate([0, -((j * 2) - 1) * opi_hole_dist, 0])
  195. cylinder(d = top_standoff_hole, h = bottom_top_size + 2);
  196. }
  197. }
  198. // cable cutout
  199. translate([outer_wall_size + cable_cut_off_x, outer_wall_size + opi_width - cable_cut_off_y - cable_cut_depth, -1])
  200. cube([cable_cut_width, cable_cut_depth, bottom_top_size + 2]);
  201. // text in top plate
  202. translate([text1_off_x, text1_off_y, bottom_top_size - text_depth])
  203. linear_extrude(height = text_depth + 0.1) {
  204. text(text1, font = text1_font, size = text1_size);
  205. }
  206. translate([text2_off_x, text2_off_y, bottom_top_size - text_depth])
  207. linear_extrude(height = text_depth + 0.1) {
  208. text(text2, font = text2_font, size = text2_size);
  209. }
  210. }
  211. // print helper corner disks
  212. for (i = [0 : 1]) {
  213. for (j = [0 : 1]) {
  214. translate([i * (opi_length + (2 * outer_wall_size)), j * (opi_width + (2 * outer_wall_size)), bottom_top_size - corner_helper_height])
  215. cylinder(d = corner_helper_size, h = corner_helper_height);
  216. }
  217. }
  218. // standoffs
  219. translate([outer_wall_size, outer_wall_size, 0])
  220. for (i = [0 : 1]) {
  221. for (j = [0 : 1]) {
  222. translate([i * opi_length, j * opi_width, -top_standoff_height])
  223. translate([-((i * 2) - 1) * opi_hole_dist, 0, 0])
  224. translate([0, -((j * 2) - 1) * opi_hole_dist, 0])
  225. difference() {
  226. cylinder(d = standoff_diameter, h = top_standoff_height);
  227. translate([0, 0, -1])
  228. cylinder(d = top_standoff_hole, h = top_standoff_height + 2);
  229. }
  230. }
  231. }
  232. // front wall
  233. translate([outer_wall_size, 0, -top_standoff_height])
  234. difference() {
  235. cube([opi_length, outer_wall_size, top_standoff_height]);
  236. // power connector
  237. translate([opi_power_off_x - cutout_gap, -1, -1])
  238. cube([opi_power_width + (2 * cutout_gap), outer_wall_size + 2, opi_power_height + 1]);
  239. // hdmi connector
  240. translate([opi_hdmi_off_x - cutout_gap, -1, -1])
  241. cube([opi_hdmi_width + (2 * cutout_gap), outer_wall_size + 2, opi_hdmi_height + 1]);
  242. // audio connector
  243. translate([opi_audio_off_x - cutout_gap, -1, -1])
  244. cube([opi_audio_diameter + (2 * cutout_gap), outer_wall_size + 2, opi_audio_diameter + 1]);
  245. }
  246. // back wall
  247. translate([outer_wall_size, opi_width + outer_wall_size, -top_standoff_height])
  248. difference() {
  249. cube([opi_length, outer_wall_size, top_standoff_height]);
  250. translate([opi_length - opi_ir_off_x - opi_ir_width - cutout_gap, -1, -1])
  251. cube([opi_ir_width + (2 * cutout_gap), outer_wall_size + 2, opi_ir_height + 1]);
  252. }
  253. // left wall
  254. translate([0, 0, -top_standoff_height])
  255. difference() {
  256. cube([outer_wall_size, opi_width + (2 * outer_wall_size), top_standoff_height]);
  257. // reset button
  258. translate([-1, outer_wall_size + opi_reset_off_y - cutout_gap, -1])
  259. cube([outer_wall_size + 2, opi_reset_diameter + (2 * cutout_gap), opi_reset_diameter + opi_reset_off_z + 1]);
  260. // camera connector
  261. translate([-1, outer_wall_size + opi_cam_off_y - cutout_gap, -1])
  262. cube([outer_wall_size + 2, opi_cam_width + (2 * cutout_gap), opi_cam_height + 1]);
  263. // micro usb connector
  264. translate([-1, outer_wall_size + opi_micro_usb_off_y - cutout_gap, -1])
  265. cube([outer_wall_size + 2, opi_micro_usb_width + (2 * cutout_gap), opi_micro_usb_height + 1]);
  266. }
  267. // right wall
  268. translate([outer_wall_size + opi_length, 0, -top_standoff_height])
  269. difference() {
  270. cube([outer_wall_size, opi_width + (2 * outer_wall_size), top_standoff_height]);
  271. // single usb port
  272. translate([-1, outer_wall_size + opi_width - opi_single_usb_off_y - opi_single_usb_width - cutout_gap, -1])
  273. cube([outer_wall_size + 2, opi_single_usb_width + (2 * cutout_gap), opi_single_usb_height + 1]);
  274. // ethernet port
  275. translate([-1, outer_wall_size + opi_width - opi_lan_off_y - opi_lan_width - cutout_gap, -1])
  276. cube([outer_wall_size + 2, opi_lan_width + (2 * cutout_gap), opi_lan_height + 1]);
  277. // dual usb ports
  278. translate([-1, outer_wall_size + opi_width - opi_dual_usb_off_y - opi_dual_usb_width - cutout_gap, -1])
  279. cube([outer_wall_size + 2, opi_dual_usb_width + (2 * cutout_gap), opi_dual_usb_height + 1]);
  280. }
  281. }
  282. module case_whole() {
  283. case_bottom();
  284. translate([0, 0, total_height - bottom_top_size])
  285. case_top();
  286. }
  287. // ---------------------
  288. // For looking at it in the OpenSCAD editor:
  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. // For printing:
  295. /*
  296. case_bottom();
  297. *//*
  298. translate([0, 2 * (opi_width + (2 * outer_wall_size)) + 25, bottom_top_size])
  299. rotate([180, 0, 0])
  300. case_top();
  301. */
  302. // ---------------------