fpc_adapter.scad 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Waveshare e-Paper FPC Adapter — parametric mockup
  2. //
  3. // Coordinate system:
  4. // Origin at PCB Z- face, lower-left corner (X=0, Y=0, Z=0).
  5. // X: board long axis (width)
  6. // Y: board short axis (height)
  7. // Z: 0 = bottom face (Z-); PCB_T = top face (Z+, component side)
  8. //
  9. // Two FPC connectors sit on the Z+ face:
  10. // Connector A (Y+): FPC exits in +Y direction
  11. // Connector B (Y-): FPC exits in -Y direction
  12. //
  13. // Mounting bosses hang from the Z- face (z=0, downward in -Z).
  14. // Stud pins extend upward from z=0 through the PCB locating holes.
  15. // When the board is flipped for ceiling-mount (rotate([0,180,0])):
  16. // bosses point toward the ceiling, stud tips snap down through the PCB.
  17. //
  18. // fpc_adapter() always produces boss geometry.
  19. // PCB / connector / FPC visuals are shown only in $preview.
  20. // ── PCB ────────────────────────────────────────────────────────────────
  21. PCB_W = 32.0;
  22. PCB_H = 18.0;
  23. PCB_T = 1.6; // standard; measured ~1.72
  24. PCB_R = 3.0; // corner radius
  25. // ── Mounting holes ─────────────────────────────────────────────────────
  26. HOLE_D = 3.0;
  27. HOLE_MX = 3.75; // hole center from nearest X edge (2.25 clearance + 1.5 radius)
  28. HOLE_MY = 3.75; // hole center from nearest Y edge
  29. // ── FPC connectors (simple box approximation) ──────────────────────────
  30. CON_W = 15.5; // connector width along X
  31. CON_D = 5.85; // connector depth along Y
  32. CON_H = 2.05; // connector height above Z+ face (total stack 3.65 − PCB_T)
  33. CON_CX = PCB_W / 2;
  34. CON_A_Y1 = PCB_H - CON_D; // Connector A inner face (Y+ side)
  35. CON_B_Y0 = 0; // Connector B outer face (Y- side)
  36. // ── FPC cable (simple flat box) ────────────────────────────────────────
  37. FPC_W = 12.5;
  38. FPC_T = 0.3;
  39. // Default stub lengths. 0 = no cable; >0 = stub that many mm.
  40. FPC_YP = 20;
  41. FPC_YN = 0;
  42. // ── Mounting bosses ────────────────────────────────────────────────────
  43. BOSS_D = 6.0; // boss outer diameter
  44. BOSS_H = 2.0; // boss standoff height (extends below Z- face)
  45. SCREW_D = 3.2; // retained for reference; drives nothing (see SCREW_PILOT_D)
  46. SCREW_PILOT_D = 1.7; // M2 self-tapper pilot, SLA resin
  47. STUD_R = 1.5; // locating stud radius
  48. STUD_H = PCB_T + 1.0; // stud height: pierces PCB with 1 mm snap-through
  49. // ═══════════════════════════════════════════════════════════════════════
  50. // Private helpers
  51. // ═══════════════════════════════════════════════════════════════════════
  52. module _pcb_shape(h) {
  53. r = PCB_R;
  54. linear_extrude(h)
  55. offset(r=r)
  56. translate([r, r])
  57. square([PCB_W - 2*r, PCB_H - 2*r]);
  58. }
  59. // Boss hangs from Z- face (z=0) downward; stud pin rises through PCB hole.
  60. // Stud diagonal: (X1,Y1)+(X2,Y2); screw diagonal: (X1,Y2)+(X2,Y1).
  61. module _adapt_boss(px, py, stud=false) {
  62. translate([px, py, 0]) {
  63. translate([0, 0, -BOSS_H])
  64. difference() {
  65. cylinder(d=BOSS_D, h=BOSS_H, $fn=24);
  66. if (!stud)
  67. translate([0, 0, -0.1])
  68. cylinder(d=SCREW_PILOT_D, h=BOSS_H + 0.2, $fn=18);
  69. }
  70. if (stud) {
  71. cylinder(r=STUD_R, h=STUD_H, $fn=24);
  72. translate([0, 0, STUD_H])
  73. sphere(r=STUD_R, $fn=24);
  74. }
  75. }
  76. }
  77. // ═══════════════════════════════════════════════════════════════════════
  78. // Public module
  79. // ═══════════════════════════════════════════════════════════════════════
  80. module fpc_adapter(fpc_yp=FPC_YP, fpc_yn=FPC_YN) {
  81. // ── Visual geometry (preview only) ──────────────────────────────────
  82. if ($preview) {
  83. color("darkgray", 0.85) {
  84. difference() {
  85. _pcb_shape(PCB_T);
  86. for (xi = [HOLE_MX, PCB_W - HOLE_MX])
  87. for (yi = [HOLE_MY, PCB_H - HOLE_MY])
  88. translate([xi, yi, -0.1])
  89. cylinder(d=HOLE_D, h=PCB_T + 0.2, $fn=24);
  90. }
  91. // Connector A (Y+ edge, FPC exits +Y)
  92. translate([CON_CX - CON_W/2, CON_A_Y1, PCB_T])
  93. cube([CON_W, CON_D, CON_H]);
  94. if (fpc_yp > 0)
  95. translate([CON_CX - FPC_W/2, PCB_H, PCB_T + (CON_H - FPC_T)/2])
  96. cube([FPC_W, fpc_yp, FPC_T]);
  97. // Connector B (Y- edge, FPC exits -Y)
  98. translate([CON_CX - CON_W/2, CON_B_Y0, PCB_T])
  99. cube([CON_W, CON_D, CON_H]);
  100. if (fpc_yn > 0)
  101. translate([CON_CX - FPC_W/2, -fpc_yn, PCB_T + (CON_H - FPC_T)/2])
  102. cube([FPC_W, fpc_yn, FPC_T]);
  103. }
  104. }
  105. // ── Mounting bosses (always — structural geometry for host part) ─────
  106. color("#004B49") {
  107. _adapt_boss(HOLE_MX, HOLE_MY, stud=true);
  108. _adapt_boss(PCB_W - HOLE_MX, PCB_H - HOLE_MY, stud=true);
  109. _adapt_boss(HOLE_MX, PCB_H - HOLE_MY, stud=false);
  110. _adapt_boss(PCB_W - HOLE_MX, HOLE_MY, stud=false);
  111. }
  112. }
  113. // Standalone render
  114. fpc_adapter(fpc_yp=FPC_YP, fpc_yn=FPC_YN);