Files
temperature/cad/cyd_climate_case.scad
DESKTOP-PUHFO60\dsx2016 c35ed7a7a9 Add parametric CYD desk-stand case with DHT11 vent bay.
Provide OpenSCAD source, watertight front/back STLs, and print/assembly docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-17 14:58:34 +08:00

301 lines
8.5 KiB
OpenSCAD
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* CYD ESP32-2432S028R + DHT11 桌面斜立外壳
* Climate Dashboard Case — parametric OpenSCAD
*
* 零件:
* part = "front" 前框(屏窗)
* part = "back" 后盖 + 斜立支架 + DHT 通风仓
* part = "assembly" 装配预览(半透明板子)
*
* 导出 STL(本机安装 OpenSCAD 后):
* openscad -o export/front.stl -D part=\"front\" cyd_climate_case.scad
* openscad -o export/back.stl -D part=\"back\" cyd_climate_case.scad
*/
/* [Which part] */
part = "assembly"; // ["front", "back", "assembly"]
/* [PCB / CYD] */
pcb_l = 86.0;
pcb_w = 50.0;
pcb_t = 1.6;
pcb_corner_r = 4.0;
mh_inset = 4.0; // 安装孔距角边中心
mh_dia = 3.2; // PCB 孔
/* [Display] */
disp_l = 69.0;
disp_w = 50.0;
disp_h = 4.0;
disp_x = 8.0; // 屏相对 PCB 左边偏移
view_l = 59.5;
view_w = 45.0;
view_inset_x = 7.0; // 相对屏模组
view_inset_y = 2.5;
/* [Case shell] */
wall = 2.4;
gap = 0.4; // 板与壳间隙
front_lip = 1.2; // 屏边压边宽度
bezel_front_t = 2.0; // 前框面板厚度
cavity_back = 7.0; // 背面元件净空
stand_angle = 60; // 桌面倾角(度,相对水平)
stand_foot = 18; // 支脚接触深度
/* [USB dual cutout] */
usb_dual = true;
usb_w = 14.0; // 双口合并开孔宽
usb_h = 8.5;
usb_y = 30.5; // 相对 PCB 原点(短边为 X=0 侧)
/* [Buttons] */
btn_enable = true;
btn_dia = 4.5;
/* [DHT11 bay] */
dht_enable = true;
dht_bay_l = 22;
dht_bay_w = 18;
dht_bay_h = 14;
dht_vent_slot = 1.6;
dht_vent_gap = 2.8;
/* [Screws] */
screw_m3 = 3.2;
boss_od = 7.2;
boss_id = 2.6; // 自攻进塑料
$fn = 48;
// ---- derived ----
inner_l = pcb_l + 2 * gap;
inner_w = pcb_w + 2 * gap;
outer_l = inner_l + 2 * wall;
outer_w = inner_w + 2 * wall;
case_h = bezel_front_t + disp_h + pcb_t + cavity_back + wall;
mh_pts = [
[mh_inset, mh_inset],
[pcb_l - mh_inset, mh_inset],
[pcb_l - mh_inset, pcb_w - mh_inset],
[mh_inset, pcb_w - mh_inset]
];
module rounded_rect(l, w, h, r) {
hull() {
for (x = [r, l - r], y = [r, w - r])
translate([x, y, 0]) cylinder(h = h, r = r);
}
}
module cyd_mock() {
color("gold")
difference() {
rounded_rect(pcb_l, pcb_w, pcb_t, pcb_corner_r);
for (p = mh_pts)
translate([p[0], p[1], -0.1])
cylinder(d = mh_dia, h = pcb_t + 0.2);
}
color("black")
translate([disp_x, 0, pcb_t])
cube([disp_l, disp_w, disp_h]);
color("navy")
translate([disp_x + view_inset_x, view_inset_y, pcb_t + disp_h])
cube([view_l, view_w, 0.2]);
}
// 前框:从屏面方向看,Z=0 为最前表面
module front_bezel() {
view_x = wall + gap + disp_x + view_inset_x;
view_y = wall + gap + view_inset_y;
difference() {
union() {
// 前表面
rounded_rect(outer_l, outer_w, bezel_front_t, 3);
// 侧壁向下包住屏+PCB 前半
translate([0, 0, bezel_front_t])
difference() {
rounded_rect(outer_l, outer_w, disp_h + pcb_t * 0.5, 3);
translate([wall, wall, -0.1])
rounded_rect(inner_l, inner_w, disp_h + pcb_t + 1, 2);
}
// 止口(与后盖搭接)
translate([wall * 0.45, wall * 0.45, bezel_front_t + disp_h + pcb_t * 0.5 - 0.01])
difference() {
rounded_rect(outer_l - wall * 0.9, outer_w - wall * 0.9, 2.2, 2.4);
translate([wall * 0.55, wall * 0.55, -0.1])
rounded_rect(outer_l - wall * 2.0, outer_w - wall * 2.0, 3, 1.6);
}
}
// 可视窗
translate([view_x - 0.3, view_y - 0.3, -0.1])
cube([view_l + 0.6, view_w + 0.6, bezel_front_t + 1]);
// 屏模组沉台(背面)
translate([wall + gap + disp_x - 0.3, wall + gap - 0.2, bezel_front_t - 0.05])
cube([disp_l + 0.6, disp_w + 0.4, disp_h + 0.5]);
// 螺丝通孔
for (p = mh_pts)
translate([wall + gap + p[0], wall + gap + p[1], -0.1])
cylinder(d = screw_m3 + 0.2, h = case_h);
}
// 压屏边框内侧(窄边)
difference() {
translate([wall + gap + disp_x, wall + gap, bezel_front_t])
cube([disp_l, disp_w, 0.8]);
translate([view_x - 0.2, view_y - 0.2, bezel_front_t - 0.1])
cube([view_l + 0.4, view_w + 0.4, 2]);
}
}
// 后盖主体(不含支架倾转);本地坐标:PCB 底面朝上放置时的壳
module back_shell_body() {
shell_h = cavity_back + wall;
pcb_z = wall + cavity_back; // PCB 底面高度(元件朝下进腔)
difference() {
union() {
rounded_rect(outer_l, outer_w, shell_h, 3);
// 止口凹槽配合前框(外壳顶部一圈台阶)
translate([0, 0, shell_h - 0.01])
difference() {
rounded_rect(outer_l, outer_w, 2.0, 3);
translate([wall * 0.5, wall * 0.5, -0.05])
rounded_rect(outer_l - wall, outer_w - wall, 2.5, 2.4);
}
// 螺丝柱
for (p = mh_pts) {
translate([wall + gap + p[0], wall + gap + p[1], wall])
difference() {
cylinder(d = boss_od, h = cavity_back - 0.2);
translate([0, 0, 1])
cylinder(d = boss_id, h = cavity_back);
}
}
// DHT 通风仓(PCB 长边外侧,靠近 CN1:x≈51)
if (dht_enable) {
dht_x = wall + gap + 48;
dht_y = outer_w - wall * 0.2;
translate([dht_x, dht_y, wall])
dht_bay();
}
}
// 内腔
translate([wall, wall, wall])
rounded_rect(inner_l, inner_w, shell_h, 1.8);
// USB 开孔(短边 x=0 侧)
usb_cut_y = wall + gap + usb_y - usb_w / 2;
translate([-0.1, usb_cut_y, wall + 1.5])
cube([wall + 1.2, usb_w, usb_h]);
// SD 卡槽(可选宽缝)
translate([wall + gap + 28, outer_w - wall - 0.1, wall + 2])
cube([16, wall + 1, 3.2]);
// BOOT / RST 软按开孔(背面)
if (btn_enable) {
translate([wall + gap + 10, wall + gap + 12, -0.1])
cylinder(d = btn_dia, h = wall + 0.3);
translate([wall + gap + 10, wall + gap + 22, -0.1])
cylinder(d = btn_dia, h = wall + 0.3);
}
// 散热缝
for (i = [0:4])
translate([wall + 12 + i * 12, wall + 8, -0.1])
hull() {
cylinder(d = 2.2, h = wall + 0.3);
translate([0, 10, 0]) cylinder(d = 2.2, h = wall + 0.3);
}
// DHT 线槽通向 CN1
if (dht_enable) {
translate([wall + gap + 48, outer_w - wall - 2, wall + 2])
cube([8, wall + 4, 4]);
}
}
}
module dht_bay() {
// 局部:仓体贴在 outer 长边外侧
difference() {
translate([0, 0, 0])
rounded_rect(dht_bay_l, dht_bay_w + wall, dht_bay_h, 2);
translate([wall * 0.6, wall * 0.6, wall * 0.6])
cube([dht_bay_l - wall * 1.2, dht_bay_w, dht_bay_h]);
// 顶面百叶通风
for (i = [0:4])
translate([3 + i * dht_vent_gap, dht_bay_w * 0.3, dht_bay_h - wall - 0.1])
cube([dht_vent_slot, dht_bay_w * 0.55, wall + 0.3]);
// 侧面通风
for (i = [0:2])
translate([4 + i * 5.5, dht_bay_w + wall - 0.2, 3 + i * 0.2])
cube([dht_vent_slot, wall + 0.4, 6]);
}
}
// 带斜立支架的后盖(打印时支脚朝下)
module back_with_stand() {
shell_h = cavity_back + wall;
// 后盖:PCB 元件朝下;支架使屏幕斜立
// 组装时:屏幕朝向 -Z 转 stand_angle
union() {
back_shell_body();
// 三角形支脚(沿 PCB 长边下方)
stand_len = outer_l * 0.72;
stand_x = (outer_l - stand_len) / 2;
// 支脚从后盖底面向后延伸
translate([stand_x, -stand_foot + 0.5, 0])
difference() {
cube([stand_len, stand_foot, shell_h]);
// 挖空减料
translate([2, 2, wall])
cube([stand_len - 4, stand_foot - 2, shell_h]);
// 斜切贴合桌面视觉(打印可平放)
translate([-0.1, 0, shell_h])
rotate([-stand_angle + 90, 0, 0])
cube([stand_len + 0.2, 40, 40]);
}
// 后支撑肋
translate([outer_l * 0.5 - 1.2, -stand_foot + 1, wall])
cube([2.4, stand_foot - 1, shell_h - wall - 1]);
}
}
module assembly() {
// 后盖在下
color("SteelBlue", 0.85) back_with_stand();
// PCB:元件朝下坐在腔顶
translate([wall + gap, wall + gap, wall + cavity_back])
rotate([180, 0, 0])
translate([0, -pcb_w, -pcb_t])
%cyd_mock();
// 前框盖上
translate([0, 0, wall + cavity_back + pcb_t + disp_h + bezel_front_t])
rotate([180, 0, 0])
translate([0, -outer_w, 0])
color("SlateGray", 0.7) front_bezel();
}
if (part == "front")
front_bezel();
else if (part == "back")
back_with_stand();
else
assembly();