// Waveshare 2.13" e-Paper HAT (B) — ESP32 Nametag Case // Display slides in from X+; FPC cable exits freely out the open X+ side // --- Display Dimensions (landscape: portrait rotated 90°) --- DISP_W = 59.20; // overall width (X) — portrait height DISP_D = 29.20; // overall depth (Y) — portrait width DISP_T = 1.0; // thickness (Z) // --- Active (Visible) Area --- ACT_W = 48.55; // active area width (X) — portrait AA height ACT_D = 23.71; // active area depth (Y) — portrait AA width // Border offsets from display edge to active area: // X-: portrait top border ≈ 1.95 mm (closed/backstop side) // X+: portrait FPC border ≈ 8.70 mm (open/entry side) // Y±: symmetric ≈ 2.75 mm each side ACT_X_OFFSET = 1.95; ACT_Y_OFFSET = 2.75; // --- FPC Cable (exits X+ side) --- FPC_W = 12.5; FPC_T = 0.3; FPC_LEN = 20.0; // visualization length of hanging tail // --- Case Parameters --- WALL = 3.0; // must exceed MAG_LIP_H (2.0) to keep pocket floor LIP = 1.5; // front bezel lip thickness (Z) TOL = 0.3; // per-side display clearance CHAM = 1.0; CHAM_ANGLE = 60; CORNER_R = 2.5; CLIP_Z = 0; // preview: mm to remove from Z+ (0 = full model) SHOW_DISP = true; SCREEN_EXPLODE = 0; // mm to pull display toward X+ in preview // --- Magnetic Strip Locating Lip (rear face) --- MAG_L = 1.772 * 25.4; // strip length ≈ 45.01 mm MAG_W = 0.512 * 25.4; // strip width ≈ 13.00 mm MAG_LIP_H = 2.0; // lip height protruding from rear face MAG_LIP_WALL = 1.0; // lip wall thickness MAG_TOL = 0.2; // per-side clearance for strip fit // --- Derived Dimensions --- cav_w = DISP_W + TOL * 2; cav_d = DISP_D + TOL * 2; case_w = WALL + cav_w; // no X+ wall; open for display entry case_h = WALL + DISP_T + LIP; case_d = WALL * 2 + cav_d; _cham_xy = CHAM * tan(CHAM_ANGLE); win_x = WALL + TOL + ACT_X_OFFSET; win_y = WALL + TOL + ACT_Y_OFFSET; // Magnetic strip recess geometry (centered on back face) _lip_il = MAG_L + 2 * MAG_TOL; _lip_iw = MAG_W + 2 * MAG_TOL; _lip_x = case_w / 2 - _lip_il / 2; _lip_y = case_d / 2 - _lip_iw / 2; // ------------------------------------------------------------------- // Display mockup — approximate geometry for preview only // ------------------------------------------------------------------- module EPD213B() { color([0.82, 0.84, 0.80]) cube([DISP_W, DISP_D, DISP_T]); color("white") translate([ACT_X_OFFSET, ACT_Y_OFFSET, DISP_T]) cube([ACT_W, ACT_D, 0.02]); color([1.0, 0.85, 0.1]) translate([DISP_W, (DISP_D - FPC_W) / 2, (DISP_T - FPC_T) / 2]) cube([FPC_LEN, FPC_W, FPC_T]); } // ------------------------------------------------------------------- module rounded_box(l, w, h, r) { hull() for (dx = [r, l-r], dy = [r, w-r]) translate([dx, dy, 0]) cylinder(r=r, h=h, $fn=32); } module epd_case() { difference() { rounded_box(case_w, case_d, case_h, CORNER_R); // Display cavity — extends 0.01 mm past X+ face to leave that side open translate([WALL, WALL, WALL]) cube([cav_w + 0.01, cav_d, DISP_T + TOL]); // Active area window + chamfered top edges translate([win_x, win_y, WALL + DISP_T - 0.01]) cube([ACT_W, ACT_D, LIP - CHAM + 0.02]); hull() { translate([win_x, win_y, case_h - CHAM]) cube([ACT_W, ACT_D, 0.01]); translate([win_x - _cham_xy, win_y - _cham_xy, case_h]) cube([ACT_W + 2*_cham_xy, ACT_D + 2*_cham_xy, 0.01]); } // Magnetic strip recess in back face translate([_lip_x, _lip_y, -0.01]) cube([_lip_il, _lip_iw, MAG_LIP_H + 0.01]); } } color("#004B49") intersection() { epd_case(); cube([case_w + 1, case_d + 1, ($preview && CLIP_Z > 0) ? max(0.01, case_h - CLIP_Z) : case_h + 1]); } if ($preview && SHOW_DISP) translate([WALL + TOL + SCREEN_EXPLODE, WALL + TOL, WALL]) EPD213B();