cable_cap.scad 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Waveshare 2.13" e-Paper HAT (B) — ESP32 Nametag Case
  2. // Display slides in from X+; FPC cable exits out the closed X- face through a hull slot
  3. // --- Display Dimensions (landscape: portrait rotated 90°) ---
  4. DISP_W = 59.20; // overall width (X) — portrait height
  5. DISP_D = 29.20; // overall depth (Y) — portrait width
  6. DISP_T = 1.0; // thickness (Z)
  7. // --- Active (Visible) Area ---
  8. ACT_W = 48.55; // active area width (X) — portrait AA height
  9. ACT_D = 23.71; // active area depth (Y) — portrait AA width
  10. // Border offsets from display edge to active area:
  11. // X-: portrait FPC border ≈ 8.70 mm (closed/backstop side — cable exits here)
  12. // X+: portrait top border ≈ 1.95 mm (open/entry side)
  13. // Y±: symmetric ≈ 2.75 mm each side
  14. ACT_X_OFFSET = 8.70;
  15. ACT_Y_OFFSET = 2.75;
  16. // --- FPC Cable (exits X- side) ---
  17. FPC_W = 12.5;
  18. FPC_T = 0.3;
  19. FPC_LEN = 20.0; // visualization length of hanging tail
  20. // --- FPC Return Pocket (cable wraps around behind screen) ---
  21. FPC_POCKET_DEPTH = 0.75; // how far below display cavity floor (z-)
  22. FPC_POCKET_LEN = 20.0; // how far in from X- face
  23. // --- Case Parameters ---
  24. WALL = 3.0; // must exceed MAG_LIP_H (2.0) to keep pocket floor
  25. LIP = 1.5; // front bezel lip thickness (Z)
  26. TOL = 0.3; // per-side display clearance
  27. CHAM = 1.0;
  28. CHAM_ANGLE = 60;
  29. CORNER_R = 2.5;
  30. CLIP_Z = 0; // preview: mm to remove from Z+ (0 = full model)
  31. CLIP_Y = 20; // preview: mm to remove from Y+ (0 = full model)
  32. SHOW_DISP = true;
  33. SCREEN_EXPLODE = 0; // mm to pull display toward X+ in preview
  34. // --- Magnetic Strip Locating Lip (rear face) ---
  35. MAG_L = 1.772 * 25.4; // strip length ≈ 45.01 mm
  36. MAG_W = 0.512 * 25.4; // strip width ≈ 13.00 mm
  37. MAG_LIP_H = 2.0; // lip height protruding from rear face
  38. MAG_LIP_WALL = 1.0; // lip wall thickness
  39. MAG_TOL = 0.2; // per-side clearance for strip fit
  40. // --- Derived Dimensions ---
  41. cav_w = DISP_W + TOL * 2;
  42. cav_d = DISP_D + TOL * 2;
  43. case_w = WALL + cav_w; // no X+ wall; open for display entry
  44. case_h = WALL + DISP_T + LIP;
  45. case_d = WALL * 2 + cav_d;
  46. _cham_xy = CHAM * tan(CHAM_ANGLE);
  47. win_x = WALL + TOL + ACT_X_OFFSET;
  48. win_y = WALL + TOL + ACT_Y_OFFSET;
  49. // Magnetic strip recess geometry (centered on back face)
  50. _lip_il = MAG_L + 2 * MAG_TOL;
  51. _lip_iw = MAG_W + 2 * MAG_TOL;
  52. _lip_x = case_w / 2 - _lip_il / 2;
  53. _lip_y = case_d / 2 - _lip_iw / 2;
  54. // -------------------------------------------------------------------
  55. // Display mockup — approximate geometry for preview only
  56. // -------------------------------------------------------------------
  57. module EPD213B() {
  58. color([0.82, 0.84, 0.80])
  59. cube([DISP_W, DISP_D, DISP_T]);
  60. color("white")
  61. translate([ACT_X_OFFSET, ACT_Y_OFFSET, DISP_T])
  62. cube([ACT_W, ACT_D, 0.02]);
  63. color([1.0, 0.85, 0.1])
  64. translate([-FPC_LEN, (DISP_D - FPC_W) / 2, (DISP_T - FPC_T) / 2])
  65. cube([FPC_LEN, FPC_W, FPC_T]);
  66. }
  67. // -------------------------------------------------------------------
  68. module rounded_box(l, w, h, r) {
  69. hull()
  70. for (dx = [r, l-r], dy = [r, w-r])
  71. translate([dx, dy, 0]) cylinder(r=r, h=h, $fn=32);
  72. }
  73. module epd_case() {
  74. difference() {
  75. rounded_box(case_w, case_d, case_h, CORNER_R);
  76. // Display cavity — extends 0.01 mm past X+ face to leave that side open
  77. translate([WALL, WALL, WALL])
  78. cube([cav_w + 0.01, cav_d, DISP_T + TOL]);
  79. // Active area window + chamfered top edges
  80. translate([win_x, win_y, WALL + DISP_T - 0.01])
  81. cube([ACT_W, ACT_D, LIP - CHAM + 0.02]);
  82. hull() {
  83. translate([win_x, win_y, case_h - CHAM])
  84. cube([ACT_W, ACT_D, 0.01]);
  85. translate([win_x - _cham_xy, win_y - _cham_xy, case_h])
  86. cube([ACT_W + 2*_cham_xy, ACT_D + 2*_cham_xy, 0.01]);
  87. }
  88. // FPC slot through X- wall — hulled path, 2 mm padding each side of cable
  89. hull() {
  90. translate([-0.01, WALL + TOL + (DISP_D - FPC_W) / 2 - 2, WALL - 0.01])
  91. cube([0.01, FPC_W + 4, DISP_T + TOL + 0.02]);
  92. translate([WALL, WALL + TOL + (DISP_D - FPC_W) / 2 - 2, WALL - 0.01])
  93. cube([0.01, FPC_W + 4, DISP_T + TOL + 0.02]);
  94. }
  95. // FPC return pocket — below display cavity floor, aligned with cable slot, from X- face inward
  96. translate([-0.01, WALL + TOL + (DISP_D - FPC_W) / 2 - 2, WALL - FPC_POCKET_DEPTH])
  97. cube([FPC_POCKET_LEN + 0.01, FPC_W + 4, FPC_POCKET_DEPTH + 0.02]);
  98. // Magnetic strip recess in back face
  99. translate([_lip_x, _lip_y, -0.01])
  100. cube([_lip_il, _lip_iw, MAG_LIP_H + 0.01]);
  101. }
  102. }
  103. color("#004B49")
  104. intersection() {
  105. epd_case();
  106. cube([case_w + 1,
  107. ($preview && CLIP_Y > 0) ? max(0.01, case_d - CLIP_Y) : case_d + 1,
  108. ($preview && CLIP_Z > 0) ? max(0.01, case_h - CLIP_Z) : case_h + 1]);
  109. }
  110. if ($preview && SHOW_DISP)
  111. translate([WALL + TOL + SCREEN_EXPLODE, WALL + TOL, WALL])
  112. EPD213B();