pre-bemis
This commit is contained in:
338
rpi-case/rpi5_industrial_case_004.scad
Normal file
338
rpi-case/rpi5_industrial_case_004.scad
Normal file
@@ -0,0 +1,338 @@
|
||||
// ============================================================
|
||||
// RPi5 Industrial Enclosure — Luckfox DHX-10.1" Touchscreen
|
||||
// Version: 004
|
||||
// Changes vs 003:
|
||||
// 1. KICKSTAND is now a separate, removable piece (own module + color)
|
||||
// - Full enc_w width (no shorter ks_width param)
|
||||
// - 3 prongs on rear edge that slide into slots in case bottom wall
|
||||
// - Tapered prong tips for easy insertion
|
||||
// 2. Prong slots added to rear cover bottom wall
|
||||
// 3. USB-C touch cutout on left wall REMOVED (per user request)
|
||||
// 4. Wall thickness increased 2.5 → 4 mm for rigidity
|
||||
// 5. Bezel screw holes now countersunk + clearly sized
|
||||
// 6. Insert bosses on rear cover made taller and more prominent
|
||||
// so the two-piece (bezel + rear cover) joint is obvious in renders
|
||||
// 7. Render shows THREE separate bodies: bezel / rear cover / kickstand
|
||||
// ============================================================
|
||||
|
||||
// ── SCREEN PARAMETERS ───────────────────────────────────────
|
||||
scr_w = 236; // screen outer width (mm)
|
||||
scr_h = 144; // screen outer height (mm)
|
||||
scr_d = 19; // screen outer depth (mm)
|
||||
scr_active_w = 222; // active display area width (mm) ← confirm
|
||||
scr_active_h = 130; // active display area height (mm) ← confirm
|
||||
scr_mount_x = 75; // screen rear M2.5 hole pattern X (mm) ← verify
|
||||
scr_mount_y = 75; // screen rear M2.5 hole pattern Y (mm) ← verify
|
||||
|
||||
// ── RASPBERRY PI 5 PARAMETERS ────────────────────────────────
|
||||
pi_w = 85; // Pi board width (mm)
|
||||
pi_h = 56; // Pi board height (mm)
|
||||
pi_d = 17; // Pi board + tallest component (mm)
|
||||
pi_mnt_x = 58; // Pi mount hole pattern X (mm)
|
||||
pi_mnt_y = 49; // Pi mount hole pattern Y (mm)
|
||||
pi_standoff = 5; // standoff height screen-rear → Pi PCB (mm)
|
||||
pi_offset_x = 0; // Pi centre X offset from screen centre (mm)
|
||||
pi_offset_y = 5; // Pi centre Y offset upward from screen centre (mm)
|
||||
|
||||
// ── ENCLOSURE PARAMETERS ─────────────────────────────────────
|
||||
wall = 4.0; // wall thickness — increased for rigidity (mm)
|
||||
chamfer = 1.5; // external edge chamfer (mm)
|
||||
recess = 1.0; // screen recess in front bezel (mm)
|
||||
gap = 0.3; // bezel ↔ rear cover fit clearance (mm)
|
||||
|
||||
// ── VENT PARAMETERS ──────────────────────────────────────────
|
||||
vent_w = 3; // vent slot width (mm)
|
||||
vent_l = 20; // vent slot length (mm)
|
||||
vent_sp = 4; // slot gap edge-to-edge (mm)
|
||||
soc_vent_sz = 30; // SoC direct-vent area size (mm)
|
||||
|
||||
// ── CABLE GLAND PARAMETERS ───────────────────────────────────
|
||||
gland_count = 2; // number of M16 cable glands
|
||||
gland_dia = 16.5; // M16 clearance hole diameter (mm)
|
||||
gland_spacing= 40; // gland centre-to-centre (mm)
|
||||
|
||||
// ── KICKSTAND PARAMETERS ─────────────────────────────────────
|
||||
// Separate removable piece — slides onto case bottom via 3 prongs.
|
||||
// Wedge shape: thin at rear (prong end), thick at front desk-contact end.
|
||||
// When flat on desk the screen sits at ks_tilt degrees from horizontal.
|
||||
ks_tilt = 75; // screen angle from horizontal when standing (deg)
|
||||
// 75° from horiz ≈ 15° lean-back from vertical
|
||||
ks_depth = 60; // plate reach in -Z from case rear face (mm)
|
||||
ks_thick = 5; // plate thickness at thin (rear) end (mm)
|
||||
|
||||
// Prong dimensions — 3 prongs slide into 3 slots in case bottom wall
|
||||
ks_prong_n = 3; // number of prongs
|
||||
ks_prong_w = 12; // prong width (X, mm)
|
||||
ks_prong_h = 14; // prong insertion height into cavity (mm)
|
||||
ks_prong_t = 5; // prong depth (Z, mm) — same as slot depth
|
||||
ks_prong_clr = 0.25; // diametral clearance for fit (mm)
|
||||
|
||||
// ── ASSEMBLY PARAMETERS ──────────────────────────────────────
|
||||
m3_dia = 3.4; // M3 clearance hole (mm)
|
||||
m3_cs_dia = 6.5; // M3 countersink diameter (mm)
|
||||
m3_cs_depth = 3.0; // countersink depth (mm)
|
||||
insert_dia = 4.2; // M3 heat-set insert OD (mm)
|
||||
insert_h = 6; // heat-set insert depth (mm)
|
||||
boss_od = 10; // insert boss outer diameter — prominent (mm)
|
||||
boss_h = insert_h + 5; // boss total height from inner face (mm)
|
||||
|
||||
// ── DERIVED DIMENSIONS ───────────────────────────────────────
|
||||
rear_d = pi_standoff + pi_d + 10; // cavity depth = 32 mm
|
||||
enc_w = scr_w + 2*wall; // outer width = 244 mm
|
||||
enc_h = scr_h + 2*wall; // outer height = 152 mm
|
||||
enc_d = rear_d + wall; // rear cover depth = 36 mm
|
||||
|
||||
// Corner inset for boss/screw centres (keeps them inside the wall)
|
||||
corner_inset = wall + boss_od/2 + 0.5; // ≈ 9.5 mm
|
||||
|
||||
// Pi centre in enclosure coordinates
|
||||
pi_enc_cx = wall + scr_w/2 + pi_offset_x; // 122 mm
|
||||
pi_enc_cy = wall + scr_h/2 + pi_offset_y; // 81 mm
|
||||
pi_z = wall + pi_standoff; // 9 mm (Pi PCB Z from rear face)
|
||||
|
||||
// Kickstand geometry
|
||||
ks_drop = ks_depth * tan(90 - ks_tilt); // ≈ 16 mm tip drop
|
||||
|
||||
// Prong slot Z position — prongs sit right at the case rear face
|
||||
ks_prong_z = 0; // prong rear face flush with case Z=0
|
||||
|
||||
$fn = 48;
|
||||
|
||||
// ============================================================
|
||||
// PRIMITIVES
|
||||
// ============================================================
|
||||
|
||||
module cbox(w, h, d, c=chamfer) {
|
||||
hull() {
|
||||
translate([c, c, 0]) cube([w-2*c, h-2*c, d ]);
|
||||
translate([0, c, c]) cube([w, h-2*c, d-2*c]);
|
||||
translate([c, 0, c]) cube([w-2*c, h, d-2*c]);
|
||||
}
|
||||
}
|
||||
|
||||
module slot(len, w, d) {
|
||||
r = w/2;
|
||||
hull() {
|
||||
translate([0, -len/2+r, 0]) cylinder(r=r, h=d);
|
||||
translate([0, len/2-r, 0]) cylinder(r=r, h=d);
|
||||
}
|
||||
}
|
||||
|
||||
module vent_row(n, len, w, spacing, depth) {
|
||||
for(i = [0:n-1])
|
||||
translate([i*(w+spacing), 0, 0])
|
||||
slot(len, w, depth);
|
||||
}
|
||||
|
||||
// Heat-set insert boss
|
||||
module insert_boss() {
|
||||
difference() {
|
||||
cylinder(d=boss_od, h=boss_h);
|
||||
cylinder(d=insert_dia, h=insert_h);
|
||||
translate([0,0,insert_h]) cylinder(d=m3_dia, h=boss_h);
|
||||
}
|
||||
}
|
||||
|
||||
// Countersunk M3 hole (for bezel face)
|
||||
module m3_countersunk(depth) {
|
||||
cylinder(d=m3_dia, h=depth+0.1);
|
||||
translate([0, 0, depth - m3_cs_depth])
|
||||
cylinder(d1=m3_dia, d2=m3_cs_dia, h=m3_cs_depth+0.1);
|
||||
}
|
||||
|
||||
// Prong slot — cut from bottom wall, prong inserts up into cavity
|
||||
module prong_slot() {
|
||||
translate([-ks_prong_w/2 - ks_prong_clr,
|
||||
-0.1,
|
||||
ks_prong_z - ks_prong_clr])
|
||||
cube([ks_prong_w + 2*ks_prong_clr,
|
||||
ks_prong_h + wall + 0.2,
|
||||
ks_prong_t + 2*ks_prong_clr]);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// KICKSTAND (separate removable piece)
|
||||
// ============================================================
|
||||
//
|
||||
// Side view (Y-Z plane, unit standing on kickstand):
|
||||
//
|
||||
// Y=0 (case bottom) ─────────────────────────────
|
||||
// │↑↑↑ prongs (insert into case)
|
||||
// Y=-ks_thick ─────┼─────────────────────────────────┐
|
||||
// \ wedge plate (bottom surface │
|
||||
// \ angled so it lies flat when │
|
||||
// Y=-(ks_thick+ks_drop)\ screen tilts to ks_tilt) │
|
||||
// └──────────────────────────────┘
|
||||
// Z=0 Z=-ks_depth
|
||||
//
|
||||
module kickstand() {
|
||||
ks_front_h = ks_thick + ks_drop; // total height at the front (desk-contact) edge
|
||||
|
||||
// Main wedge plate
|
||||
hull() {
|
||||
// Rear (thin) edge, at Z=0 — where prongs attach
|
||||
translate([0, -ks_thick, 0])
|
||||
cube([enc_w, ks_thick, wall]);
|
||||
// Front (thick) edge, at Z=-ks_depth — rests on desk
|
||||
translate([0, -ks_front_h, -ks_depth])
|
||||
cube([enc_w, ks_front_h, wall]);
|
||||
}
|
||||
|
||||
// Three prongs — evenly spaced, rise from Y=0 into case cavity
|
||||
for(i = [0:ks_prong_n-1]) {
|
||||
px = enc_w * (i+1) / (ks_prong_n+1);
|
||||
translate([px - ks_prong_w/2, 0, ks_prong_z]) {
|
||||
// Tapered tip so prong slides in easily
|
||||
hull() {
|
||||
// Base: full-width prong up to the tapered section
|
||||
cube([ks_prong_w,
|
||||
ks_prong_h - 2,
|
||||
ks_prong_t]);
|
||||
// Tip: narrowed 1 mm per side for 45° insertion chamfer
|
||||
translate([1, ks_prong_h - 2, 0])
|
||||
cube([ks_prong_w - 2, 2, ks_prong_t]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// FRONT BEZEL
|
||||
// ============================================================
|
||||
// Removable front frame — held to rear cover by 4× M3 screws
|
||||
// through countersunk holes at each corner, threading into
|
||||
// heat-set inserts pressed into the rear cover's corner bosses.
|
||||
module front_bezel() {
|
||||
difference() {
|
||||
cbox(enc_w, enc_h, wall + recess);
|
||||
|
||||
// Active display window
|
||||
translate([(enc_w - scr_active_w)/2,
|
||||
(enc_h - scr_active_h)/2,
|
||||
-0.1])
|
||||
cube([scr_active_w, scr_active_h, wall+recess+0.2]);
|
||||
|
||||
// 1 mm recess pocket — bezel lip grips screen edge
|
||||
translate([(enc_w - scr_w)/2,
|
||||
(enc_h - scr_h)/2,
|
||||
wall])
|
||||
cube([scr_w, scr_h, recess+0.1]);
|
||||
|
||||
// 4× M3 countersunk screw holes at corners
|
||||
for(x = [corner_inset, enc_w - corner_inset])
|
||||
for(y = [corner_inset, enc_h - corner_inset])
|
||||
translate([x, y, 0])
|
||||
m3_countersunk(wall + recess);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// REAR COVER
|
||||
// ============================================================
|
||||
module rear_cover() {
|
||||
n_vent = 6;
|
||||
vent_block_w = n_vent*(vent_w+vent_sp) - vent_sp;
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
cbox(enc_w, enc_h, enc_d);
|
||||
|
||||
// ── Insert bosses: 4 corners, proud on inner rear face ──
|
||||
// These are clearly visible tall cylinders that receive the
|
||||
// heat-set inserts; M3 screws from the bezel thread into them.
|
||||
for(x = [corner_inset, enc_w - corner_inset])
|
||||
for(y = [corner_inset, enc_h - corner_inset])
|
||||
translate([x, y, enc_d])
|
||||
rotate([180, 0, 0])
|
||||
insert_boss();
|
||||
}
|
||||
|
||||
// ── HOLLOW INTERIOR ───────────────────────────────────
|
||||
translate([wall, wall, wall])
|
||||
cube([scr_w, scr_h, enc_d]);
|
||||
|
||||
// ── PORT CUTOUTS ──────────────────────────────────────
|
||||
|
||||
// LEFT WALL — USB-C power + HDMI ×2 (Pi left short-edge ports)
|
||||
pi_bot = pi_enc_cy - pi_h/2;
|
||||
// USB-C power
|
||||
translate([-0.1, pi_bot + 3, pi_z + 2]) cube([wall+0.2, 11, 11]);
|
||||
// HDMI 0
|
||||
translate([-0.1, pi_bot + 16, pi_z + 2]) cube([wall+0.2, 17, 9]);
|
||||
// HDMI 1
|
||||
translate([-0.1, pi_bot + 35, pi_z + 2]) cube([wall+0.2, 17, 9]);
|
||||
|
||||
// RIGHT WALL — RJ45 + USB-A ×4 (Pi right short-edge ports)
|
||||
pi_top = pi_enc_cy + pi_h/2;
|
||||
// RJ45
|
||||
translate([enc_w-wall-0.1, pi_top - 24, pi_z + 1])
|
||||
cube([wall+0.2, 22, 16]);
|
||||
// USB-A ×4
|
||||
translate([enc_w-wall-0.1, pi_bot + 2, pi_z + 1])
|
||||
cube([wall+0.2, 50, 15]);
|
||||
|
||||
// NOTE: USB-C touch cutout (screen side) REMOVED per v004 request.
|
||||
// GPIO header is internal — access by removing bezel + rear cover.
|
||||
|
||||
// ── COOLING VENTS ─────────────────────────────────────
|
||||
|
||||
// Bottom intake slots (through bottom wall)
|
||||
translate([enc_w/2 - vent_block_w/2, -0.1, wall + 8])
|
||||
rotate([-90, 0, 0])
|
||||
vent_row(n_vent, vent_l, vent_w, vent_sp, wall+0.2);
|
||||
|
||||
// Top exhaust slots (through top wall)
|
||||
translate([enc_w/2 - vent_block_w/2,
|
||||
enc_h - wall + 0.1,
|
||||
wall + 8])
|
||||
rotate([90, 0, 0])
|
||||
vent_row(n_vent, vent_l, vent_w, vent_sp, wall+0.2);
|
||||
|
||||
// SoC direct-vent on rear panel
|
||||
translate([pi_enc_cx - soc_vent_sz/2,
|
||||
pi_enc_cy - soc_vent_sz/2,
|
||||
enc_d - wall - 0.1]) {
|
||||
n_soc = floor(soc_vent_sz / (vent_w + vent_sp));
|
||||
for(i = [0:n_soc-1])
|
||||
translate([i*(vent_w+vent_sp),
|
||||
soc_vent_sz/2 - vent_l/2,
|
||||
0])
|
||||
slot(vent_l, vent_w, wall+0.2);
|
||||
}
|
||||
|
||||
// ── CABLE GLANDS — rear panel, bottom area ────────────
|
||||
for(i = [0:gland_count-1]) {
|
||||
cx = enc_w/2 + (i - (gland_count-1)/2) * gland_spacing;
|
||||
translate([cx, wall + gland_dia/2 + 4, -0.1])
|
||||
cylinder(d=gland_dia, h=wall+0.2);
|
||||
}
|
||||
|
||||
// ── KICKSTAND PRONG SLOTS — bottom wall ───────────────
|
||||
// 3 slots matching kickstand prong positions and sizes.
|
||||
// Slots pass through the bottom wall into the cavity so prongs
|
||||
// engage wall + (ks_prong_h - wall) mm inside the cavity.
|
||||
for(i = [0:ks_prong_n-1]) {
|
||||
px = enc_w * (i+1) / (ks_prong_n+1);
|
||||
translate([px, 0, ks_prong_z])
|
||||
prong_slot();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// SCENE — three separate bodies, exploded for clarity
|
||||
// ============================================================
|
||||
|
||||
// Front bezel — exploded up, face toward viewer
|
||||
color("DarkSlateGray", 0.92)
|
||||
translate([0, 0, enc_d + 14])
|
||||
front_bezel();
|
||||
|
||||
// Rear cover — at origin
|
||||
color("SlateGray", 0.88)
|
||||
rear_cover();
|
||||
|
||||
// Kickstand — exploded below, separate piece
|
||||
color("DimGray", 0.85)
|
||||
translate([0, -(ks_thick + ks_drop + 20), 0])
|
||||
kickstand();
|
||||
Reference in New Issue
Block a user