会随昼夜变化的 3D 智能客厅:五路真实传感器驱动的数字孪生课堂

2026-11-072

前言:

首先向云天老师致敬!本项目思路受到社区文章《STEM 教育 · 行空板 K10:低成本搭建物联网智能家居演示》启发,但硬件平台、系统架构、阈值算法、显示与交互均为本项目重新设计与实现,具体差异见第一节。

简介

这是一套面向中小学课堂的物联网教学装置:一块行空板 M10 负责采集真实的温度、湿度、光线、声音与按键输入,电脑浏览器里那间可以转动视角的 3D 客厅负责表现。学生遮一下光、拍一下手、对着探头哈一口气,屏幕里的窗帘、窗户、空调就会跟着动。[会随昼夜变化的 3D 智能客厅_哔哩哔哩_bilibili](https://)

与原方案相比,本项目做了三点较大的改动:把「K10+ 电脑桥接服务」的三层结构压缩成 M10 单机两层;把写死的阈值换成开机 3 秒自适应标定,换一间教室不用改参数;把显示从三处扩到四处,并让统一的时钟参与画面,窗外天色会随时间从白天走到亮起星星与住户灯火的夜晚。全部依赖本地化,断网也能运行,工程源码随文附上。会随昼夜变化的 3D 智能客厅:五路真实传感器驱动的数字孪生课堂_image_1.webp

图 1 白天模式下的 3D 智能客厅总览:顶栏为日期时间与数据源,左侧为四路传感器读数,右侧为墙上电子屏的同步读数板,底部为五个虚拟设备按钮

一、为什么做这个项目

在乡村学校的信息科技课堂里讲「智能家居」,常遇到三个现实问题。

一是器材成本与准备时间。要把灯、电视、窗帘、空调、窗户五种设备都做成实物,需要继电器、灯具、电机、模型和大量接线,一节课的准备时间比讲课时间还长,还涉及用电安全。二是演示不稳定。真实窗帘会卡住,几十个学生轮流操作后设备容易出故障,出问题往往只能停课排查。三是概念太抽象。「感知、传输、判断、执行、反馈」这五个词写在黑板上,学生很难把它们和自己的动作对应起来。

社区里已有的 K10 方案给了一个很好的思路:把传感器留在真实世界,把执行器搬进浏览器。我手上没有 K10,只有一块行空板 M10,于是先做了一次完整的适配评估,再按乡村课堂的实际条件重新设计。这套系统与那篇文章的主要差异如下。

维度 K10 原方案 本项目 M10 方案
硬件平台 行空板 K10,MicroPython 行空板 M10,Debian 完整 Python 3.12
系统架构 K10 经 UDP 4210 发到电脑桥接服务,再由 HTTP 8000 供浏览器 M10 单进程完成采集、状态机、HTTP 与静态页面,电脑只当浏览器
声音输入 外接 DFR0034 模拟声音传感器 直接读板载麦克风 Audio().sound_level(),省掉一个外接模块
温湿度输入 板载 AHT20 M10 无板载温湿度,P21 外接 DHT11
阈值 固定数值(80/200 lx、70%RH 等) 开机 3 秒采基线中位数,按相对偏移自动标定
同源显示 板子屏幕、墙面电子屏、网页数据栏,共三处 增加右上角 1:1 同步读数板,共四处
时间 未涉及 服务端统一下发年月日、星期、时分秒与校时状态,窗外天色按小时连续变化
交互 拖动视角、点击 3D 物体 增加指针穿透、拖拽让位、大字模式、断线自检、双击文件中文提示
课堂组织 演示与分层任务 增加学生实验台、三种组织形态、40 分钟流程与可印发任务卡

需要说明的是,架构从三层变两层不是简单的删减。M10 跑的是完整 Debian,能直接承载 HTTP 服务与 Python 状态机,因此不必再写 UDP 桥接、不必配置 PC_IP、不受 Windows 防火墙影响,也不用额外准备 UDP 模拟器;课堂布置从「一块板 + 一台跑服务的电脑 + 一台展示电脑」变成「一块板 + 任意一台能开浏览器的电脑」。代价是 M10 没有视频输出口,3D 画面仍须由浏览器呈现。

二、项目效果

学生能亲手触发的五组联动如下。

学生动作 真实输入 判断规则 虚拟设备的反应
按板载 A 键,或按键盘 A,或点落地灯 按键边沿 翻转灯光,进入 20 秒手动优先 灯罩自发光、地面暖色光池渐亮
按板载 B 键,或按键盘 B,或点电视 按键边沿 翻转电视,进入 20 秒手动优先 电视播放动态画面,电视墙泛蓝光
用手遮住板子上方光线传感器 光照降到关帘线以下 关窗帘 两侧窗帘约 1.2 秒缓缓合拢
松开手 光照回到开帘线以上 开窗帘 窗帘收拢打开
拍手或大声说话 噪声超过关窗线 立即关窗,安静计时清零 两扇窗扇横向滑动关上
保持安静 噪声低于开窗线且持续满 8 秒 开窗户 窗扇重新打开
对着 P21 的 DHT11 哈气 湿度超过触发线 开空调 出风口叶片摆动、气流粒子出现
等环境恢复 温度与湿度双双回落到关闭线以下 关空调 空调停止

除联动外,还有三处适合在课堂上指出来的现象:四块屏上的数值与设备状态始终一致;落在两条阈值之间的死区时设备保持现状,不会来回抖动;手动操作后按钮出现 MANUAL 20s,倒计时结束自动规则才重新接管。会随昼夜变化的 3D 智能客厅:五路真实传感器驱动的数字孪生课堂_image_2.webp

图 2 同一间客厅在白天、黄昏、夜晚三个时段的效果对比:天空渐变、太阳位置、星月与远处住户窗灯随时间变化,室内环境光同步变暗

三、硬件与软件清单

硬件:

  • 行空板 M10 ×1(官方介绍与购买入口),用作主控、采集与 HTTP 服务器
  • DHT11 温湿度模块 ×1,数据脚接 P21,需 3V3、GND、DATA 三根线
  • USB-C 电源线与电源适配器 ×1,给 M10 独立供电
  • 电脑或教室大屏 ×1,只需一个支持 WebGL 的浏览器,与 M10 处于同一局域网
  • 同一局域网的 WiFi 环境 ×1;校园网若有网页认证或 AP 隔离,建议自备一个手机热点作为兜底
  • 可选:HDMI 线与转接头,用于把教师笔记本投到大屏

M10 板载已被用上的资源:A / B 按键、光线传感器、麦克风、240 × 320 触摸彩屏。整个项目不接继电器、不接 220 V 灯具、不接电机,课堂用电安全。

软件与依赖:

  • M10 端:Debian 系统自带 Python 3.12.7、pinpong 0.6.2、unihiker 库,systemd 用于开机自启
  • 电脑端:Chrome 或 Edge 等支持 WebGL 的浏览器;仅在不接硬件的演示模式与批量部署脚本中需要 Python 3.8 及以上和 paramiko
  • 前端:Three.js r160 与 OrbitControls,全部放在本地 vendor/ 目录,不使用任何 CDN、在线字体或外部脚本
  • 服务端:仅 Python 标准库 http.server.ThreadingHTTPServer,无数据库、无云平台、无消息队列
  • 随工程提供:m10/deploy.py(一键上传、支持多板批量)、m10/capture_screen.py(读取帧缓冲生成板载屏截图)、start-big-screen.bat(Windows 一键启动演示服务)

参考文档:

四、技术原理与系统架构

整套系统只有一份状态、一个决策者。

┌─────────────────────────────────────────────┐
│  行空板 M10(单进程 main.py)                  │
│  · 采集:light.read / button_a / button_b     │
│           Audio().sound_level / P21 DHT11     │
│  · 决策:复用 server/bridge.py 的 Home 状态机  │
│  · 服务:HTTP :8000  /api/state + 静态页面     │
└──────────────────────┬──────────────────────┘
                       │ HTTP / JSON(同源,无 UDP 中转)
       ┌───────────────┼───────────────┬────────────────┐
       ▼               ▼               ▼                ▼
  浏览器 3D 客厅   网页 HUD      3D 墙面电子屏      M10 板载小屏
  (虚拟执行器)   (四路读数)   (CanvasTexture)  (240×320 面板)
       │
       └── 右上角 1:1 同步读数板(复制墙面屏同一张离屏画布)

浏览器每 380 毫秒拉取一次 /api/state,只负责显示,不自行推演设备状态;点击设备或按下按键时向 /api/command 下发指令。状态机是唯一真相来源,因此不会出现「板子显示开、网页显示关」。

/api/state 的关键字段:source 区分真机与演示;sensors 含 temp、humi、lux、noise;devices 含 lamp、tv、curtain、ac、window 五个布尔值;threshold 与 threshold_default 分别是当前阈值与开机标定值;clock 含日期、星期、时分秒、UTC+0800 与 synced 校时标记;url 是板子算出的访问地址;has_dht 与 simulated 用来诚实标明哪些输入是真、哪些是模拟。

自动化规则有三条,都带死区:光照驱动窗帘、噪声驱动窗户、温湿度驱动空调。噪声规则额外要求持续安静 8 秒才开窗;任意手动操作会设置 20 秒优先期,期间自动规则不接管该设备。这三条不是为了让演示更花哨,而是控制论里「回差防抖」「确认时间」「手动覆盖自动」的最小可讲解实例。

时间也只从服务端下发一次。clock_snapshot() 生成快照,显示端按 ts 与本地计时按秒推算,避免电脑与板子的时区名称不一致;M10 没有硬件 RTC,未同步 NTP 时页面会显示「时间未校准」。3D 场景读的是同一份 clock,所以屏上是上午十点,窗外就不会满天星。会随昼夜变化的 3D 智能客厅:五路真实传感器驱动的数字孪生课堂_image_3.webp

图 3 真机夜间效果:窗外为深蓝夜空,可见月亮、星星与远处亮灯的住户;室内变暗但家具与墙面电子屏仍可辨认

五、制作过程与关键代码注释

下面按实际搭建顺序记录,每一步都有可以当场核对的验证动作。完整源码见文末附件。

第 1 步:先让网页在没有硬件时跑起来

在电脑上执行 python server/bridge.py --demo --port 8000,浏览器打开 http://127.0.0.1:8000。此时应看到完整 3D 客厅与自动波动的四组数值,可以点五个设备按钮、拖动视角、滚轮缩放。

验证:页面右下角数据源显示「电脑模拟演示」,simulated 非空。这一步的目的是把「网页能不能跑」和「硬件有没有接对」分开排查,避免两层问题搅在一起。

注意页面必须通过 HTTP 打开。ES module 与 importmap 在 file:// 下会被浏览器拦截,双击 index.html 会黑屏;本项目为此加了一屏中文提示,告诉现场的人该用哪个入口。

第 2 步:接上 M10 与 P21 的 DHT11

M10 在板载 Home 菜单或 nmcli 里连好 WiFi,然后把工程上传到 /root/3d-smart-home/。DHT11 按 VCC 接 3V3、GND 接 GND、DATA 接 P21 接线,运行 python3 main.py。

接线与调用的对应关系:

输入 调用 返回量纲 实测范围
光线 light.read() 0–4095 原始 ADC,不是勒克斯 室内约 1665–3922
A / B 按键 button_a.is_pressed() 布尔值 配合边沿检测,避免长按重复触发
声音 Audio().sound_level() 0–100 映射值,不是分贝 安静 0–20,教室底噪 20–35
温湿度 DHT11(Pin(Pin.P21)).temp_c() / humidity() 摄氏度、相对湿度 首次实测 25.4°C / 29%

验证:/api/state 返回 source = M10 真机、has_dht = true、simulated = [];板载小屏亮起并显示四路读数。

这里有两个必须实测才知道的坑。Board().begin() 大约需要 2.1 秒,开机立刻判定失败会误报;DHT11 单次读取约 2 秒,如果塞进 200 毫秒的采集循环,按键会被吞掉。因此把温湿度放进独立线程缓存,至少 1 秒读一次,主循环只读缓存。会随昼夜变化的 3D 智能客厅:五路真实传感器驱动的数字孪生课堂_image_4.webp

图 4 行空板 M10 板载 240×320 小屏主页:标题下方暖黄色一行显示学生应输入的访问地址,中部为四路读数与设备状态,底部为作者署名条

第 3 步:把写死的阈值换成开机自适应标定

这是本项目最关键的一处改动。原方案的 80/200 lx 阈值在 M10 上完全失效:light.read() 返回的是 0–4095 的原始 ADC,教室里正常光照就有三千多;北方教室冬天湿度常常只有 30% 左右,70% 的空调触发线哈气根本够不到。

解决办法是让板子在开机头 3 秒安静地采一组基线,取中位数 L0、N0、T0、H0,再按相对偏移算出八条阈值,写入 config.json:

# m10/main.py —— 启动 3 秒基线标定,阈值全部相对基线计算
L0 = statistics.median(luxs)      # 光照基线(0-4095 原始 ADC)
N0 = statistics.median(noises)    # 噪声基线(0-100 映射值)
T0 = statistics.median(temps)     # 温度基线(摄氏度)
H0 = statistics.median(humis)     # 湿度基线(%RH)

th = {
    "lux_close":   max(30, int(L0 * 0.45)),       # 遮光到不足一半 → 关帘
    "lux_open":    max(60, int(L0 * 0.80)),       # 恢复到八成 → 开帘
    "noise_close": max(30.0, round(N0 + 20, 1)),  # 拍手 → 立即关窗
    "noise_open":  max(8.0,  round(N0 + 8, 1)),   # 安静 8s → 开窗
    "ac_on_temp":  round(T0 + 3.0, 1),
    "ac_off_temp": round(T0 + 2.0, 1),
    "ac_on_humi":  round(H0 + 16, 1),             # 哈气主要抬湿度,以湿度为主力
    "ac_off_humi": round(H0 + 11, 1),             # 关闭余量必须大于 DHT11 精度
}

某次真实标定结果:lux_close = 1740、lux_open = 3094、noise_close ≈ 54.3、ac_on_humi ≈ 44.9。换教室、换季节、换传感器只需 python3 main.py --recalibrate;课堂上也可以直接在地址栏调 /api/threshold。

验证:遮光时先记下页面上的光照数字,再对照小屏阈值页,确认它确实越过了关帘线,而不是凭感觉猜。阈值页可由板载小屏上的小热区切换。

会随昼夜变化的 3D 智能客厅:五路真实传感器驱动的数字孪生课堂_image_5.webp
图 5 板载小屏阈值页:列出八条当前生效的触发线,便于学生在现场核对「为什么刚才动了」

第 4 步:让四块屏读同一份数据

网页 HUD 好办,直接读 /api/state。3D 墙面那块电子屏是一张 512 × 320 的离屏画布,用 CanvasTexture 贴到墙上,每次纹理重画后版本号加一;M10 板载小屏是一个独立进程,通过 HTTP 读同一份状态,用 tkinter 画成 240 × 320 全屏置顶面板。

难点在于「看不清」。最初把 OFF 状态画成暗灰,在教室投影上对比度只有 2.12:1,后排基本读不出。按 WCAG 对比度重新校准后统一提亮:OFF 用 #93a9b8,次级文字用 #9fc9de,分隔线用 #2e566b,单位小字同步提亮,OFF 状态提升到 7.68:1。

另一个难点是拖拽。早期 HUD 的四个撑满宽度的块都拦截指针,鼠标一落到传感器卡片上就转不动视角,卡片又正好压在墙面电子屏上。现在 HUD 整层默认 pointer-events: none,只有设备按钮与少量功能按钮恢复可点;按下并移动超过 5 像素才判定为拖拽,拖拽中 HUD 淡出到约 0.07 且全层禁指针,松手后保留约 1 秒无遮挡观察窗口,之后平滑恢复。同时新增右上角 1:1 同步读数板:它把墙面电子屏用的那张离屏画布原样画出来,正对、无透视、不随视角变化,本身从不拦截指针。

/* css/style.css —— HUD 默认穿透,只有真正可点的控件恢复指针事件 */
.hud, .hud * { pointer-events: none; }
.hud .dev, .hud .blow, .hud .mirror-close { pointer-events: auto; }

/* 拖拽中连设备按钮也临时禁指针,避免手势被按钮截断 */
html.dragging .hud { opacity: 0.07; }
html.dragging .hud * { pointer-events: none; }

验证:在任意一张传感器卡片上按住并拖动,视角应连续旋转不中断;松手后墙面电子屏与右上角读数板的数值完全一致;按 V 可收起或展开读数板,按 F 可切换大字模式。

会随昼夜变化的 3D 智能客厅:五路真实传感器驱动的数字孪生课堂_image_6.webp
图 6 交互修复后的界面:右侧同步读数板完整显示墙面电子屏内容,左侧 HUD 不再拦截拖拽,中央 3D 电子屏无遮挡

会随昼夜变化的 3D 智能客厅:五路真实传感器驱动的数字孪生课堂_image_7.webp
图 7 文字可读性校准前后对比:OFF 状态、单位小字与分隔线统一提亮,投影环境下后排可读

第 5 步:让时间参与画面

窗外原本只是一块永远淡蓝色的纯色平面。改成 512 × 512 的 CanvasTexture 天空后,按小时画渐变天色、6 点左升 18 点右落的太阳、弯月、确定性生成的星星(不会每帧闪)、白天薄云、远山剪影和三家住户;入夜后住户窗户亮起暖黄灯。8 个时间关键帧之间用 smoothstep 插值,黄昏是慢慢暗下去而不是整点切图。

两条边界很要紧。第一,时间仍只有一份:顶栏时段、墙面电子屏、窗外天色算的都是 clock.live,服务端一行没改。第二,昼夜只改 ambient / hemi / sun 的颜色与强度、玻璃色调与背景雾色,不碰灯光与电视的发光材质,也不改任何设备状态——天黑不会偷偷把灯打开,否则四块屏会当场打架。夜间保留最低照度,屋子明显变暗但家具和电子屏仍读得清。

还有一个只在真实浏览器里暴露的问题:最初用渲染帧的 dt 推进昼夜,在低帧率的教学一体机上只有 5–10 fps,切到「夜晚」等了近 5 秒画面还停在傍晚。改成按 performance.now() 的真实差值推进后,与帧率解耦。

// js/scene.js —— 按真实经过时间推进,掉帧时昼夜不会越走越慢
const nowMs = performance.now();
const realDt = Math.min(1.0, (nowMs - lastSkyTick) / 1000);
lastSkyTick = nowMs;
let dh = wantHour - displayHour;
while (dh > 12) dh -= 24;   // 23:59 → 00:00 走最短路径,不倒着绕一整圈
while (dh < -12) dh += 24;
displayHour = (displayHour + dh * (1 - Math.exp(-1.6 * realDt)) + 24) % 24;

课堂演示时按 N 可循环「自动、黎明、白天、黄昏、夜晚」,或给地址加 ?time=night,顶栏会明确标注「演示」二字,不会让人误以为板子时间错了。

第 6 步:开机自启、批量部署与现场适配

板子上配置两个 systemd 服务:smart-home.service 跑主程序,smart-home-screen.service 跑板载小屏,均设为 active + enabled,上课插电即用。屏服务需要设置 DISPLAY=:0 与 XAUTHORITY=/var/run/lightdm/root/:0。系统自带的 Home 菜单服务是 Restart=always,不去硬停它,而是用全屏置顶窗口盖住;停掉自建服务即可恢复菜单。

多块板子用 python m10/deploy.py --hosts 192.168.1.91,192.168.1.92,192.168.1.93 一次推完,单块失败不中断其余板子。上传清单不包含本地 config.json,每块板会按自己教室的光线重新标定。

现场还做了几项保护:大字模式把 HUD 放大约 1.6 倍并把 WebGL 像素比锁到 1,避免 4K 一体机在 200% 缩放下渲染到近 7680 × 4320 而卡顿;接口连续失败 3 次会弹出中文排查横幅,列出当前地址与三条可能原因;静态资源一律带 Cache-Control: no-store。

验证:拔电重启,不做任何操作,两分钟后从另一台电脑打开 http://板子IP:8000,页面与板载小屏都应正常;板载小屏标题下方那行暖黄色文字会直接给出该输的地址,学生不用老师逐台查 IP。

六、课堂怎么用

这套系统的定位是「学生自己动手」,不是教师单机演示。M10 是服务器,学生电脑只是一个浏览器,不用装 Python、不用装软件、不用接线,输自己那块板的地址就行。

三种组织形态按板子数量选:每组一块 M10 完全隔离,最理想;板子不够时学生电脑跑本地演示模式,用模拟数据完成「改触发线看规则」的进阶任务;只有一块板时全班共用,此时状态机只有一份,多人同时点按钮会互相覆盖,应改为轮流派代表操作,其余同学做「预测—观察—记录」。

网页里的「学生实验台」(按 L 打开)把三条触发线做成滑块,每组显示当前传感器读数与一句结果预测,让学生先猜、再改、再验证。调参加 persist=0,只影响本次运行、不写标定文件;「恢复初始」用服务端下发的开机标定值,学生刷新页面也不会把改后的值误当成初始值,下课点一下即可还原。

会随昼夜变化的 3D 智能客厅:五路真实传感器驱动的数字孪生课堂_image_8.webp
[DF创客社区.zip
](https://)图 8 学生实验台:三条滑块分别调整光照、噪声、湿度的触发线,实时显示当前值与结果预测

40 分钟的课堂流程:前 3 分钟教师只做一个遮光动作让学生猜原因;3–12 分钟讲清链路并让每组打开自己的页面,此时各组数值不同,正好说明「真实环境」;12–25 分钟做基础与进阶任务卡,填记录表;25–33 分钟各组汇报,把不同触发线的结果并排比较;33–38 分钟抛回差、8 秒确认、手动 20 秒三道挑战题;最后 2 分钟带全班点「恢复初始」并收板。可印发的分层任务卡与记录表放在附件文档里。

演示视频

本文配有一段操作演示视频,依次展示遮光关帘、拍手关窗、哈气开空调、按 A / B 键、切换昼夜时段与学生实验台调参。视频建议控制在一分半到两分钟,画面与解说要点见附件《投稿发布说明》,其中给出逐句口播稿。若单个动作只有十几秒,也可按社区建议截成几个小 GIF 放在对应文字旁边。

(发布时在此处插入演示视频)

七、注意事项与踩过的坑

现象 原因 处理
照抄原文的 80/200 光照阈值完全不动作 light.read() 是 0–4095 原始 ADC,不是勒克斯 使用开机基线标定,不要按绝对光照值硬套
声音数值与分贝对不上 sound_level() 是映射到 0–100 的整数 界面只标「噪声」不标 dB,阈值按基线加偏移
空调开了关不掉 关闭阈值离基线太近,温湿度双双回落的条件永远不成立 关闭余量必须大于 DHT11 精度(约 ±2°C / ±5%RH),本项目取 +2.0°C / +11%RH
按键偶尔没反应 DHT11 单次读取约 2 秒,被塞进 200 ms 主循环 温湿度放独立线程缓存,采样间隔不小于 1 秒
板载屏自动跳到阈值页 触摸屏幽灵触摸 只保留两处小热区,加 1.5 秒冷却与 60 秒自动回主页
网页显示 502 电脑设了代理且未排除本机地址,或本地会话级服务已退出 用板子的局域网地址;排查本机时用 --noproxy 绕过代理
到学校后地址打不开 M10 记住的是家里 WiFi,且路由器重新分配 IP 看板载小屏上的「电脑访问」地址;最省事是把手机热点名称密码改成与家里一致
双击 HTML 一片黑 ES module 与 importmap 在 file:// 下被拦截 用一键启动脚本或 HTTP 地址,页面已内置中文提示
改了代码页面没变化 浏览器缓存了旧的 CSS / JS 按一次 Ctrl + F5 强刷
4K 大屏卡顿 高系统缩放下渲染分辨率过高 大字模式已把像素比锁到 1,必要时把 Windows 缩放设为 100%
时间显示「时间未校准」 M10 无硬件 RTC,断电后未同步 NTP 联网等待校时;页面会诚实提示,不显示假时间
夜晚看不到窗外夜景 夜间光照低于关帘线,状态机正确地把窗帘合拢了 这是真实传感器驱动的正确结果;点一下「窗帘」按钮或给传感器照点光
全班共一块板时页面乱跳 状态机只有一份,多人操作互相覆盖 改为轮流派代表,或让其他组用本地演示模式

还有两条属于工程习惯:M10 的系统菜单服务是 Restart=always,重启自建服务时曾遇到主进程不响应 SIGTERM 卡在 deactivating,处理方式是按精确服务单元定向结束再拉起,不要用通配 pkill;所有数值与结论都应来自现场实测,文档里的理论值不能照抄。

八、实测与验证

真机环境(2026 年 11 月 6 日实测):行空板 M10,Debian 内核 4.4.143-rockchip,Python 3.12.7,pinpong 0.6.2,P21 外接 DHT11,页面地址 http://192.168.1.92:8000,两个 systemd 服务均 active 且 enabled,/api/state 返回 source = M10 真机、has_dht = true、simulated = []、NTP 已校准。

浏览器端用调试协议做了真实交互实测:在传感器卡片上按下并拖动,拖拽前 HUD 各层均为 pointer-events: none、设备按钮为 auto;拖拽中状态标记为真、读数板保持可见;松手后观察窗口内保持无遮挡,之后平滑恢复;全程无运行时异常。昼夜三态实测:白天 12:00 环境光 0.62、日光 1.45、亮蓝天空无星;黄昏 18:24 为 0.50 / 0.84、橙紫天空微星;夜晚 22:18 为 0.47 / 0.22、深蓝天空星 0.85;三次设备按钮文本均为「灯光关」,证明昼夜未篡改状态。

五个动作的验证口径都写进了附件《原理拆解与落地指导》:按 A / B 看按钮与 MANUAL 倒计时,遮光与松手看光照是否越过两条线,拍手看噪声峰值与 8 秒计时,哈气看湿度峰值与双回落条件。拍手与哈气的峰值受人和距离影响,建议现场看着页面数字微调阈值。

九、可扩展方向

这套装置刻意把「真实」与「虚拟」划得清楚:真实的是输入与判断,虚拟的是执行与画面。这一点留给课堂的扩展空间很大。

  • 把虚拟执行器逐个换成真实继电器、舵机、灯带,让学生比较「虚拟先跑通」与「实物接入」的成本差别
  • 把 HTTP 轮询换成 MQTT 或 WebSocket,接入 Home Assistant 等平台
  • 记录一节课的温湿度与光照,画出曲线,讨论采样率与滤波
  • 增加「回家模式」等组合规则,或用多块 M10 控制多个房间
  • 把 3D 场景换成温室、校园或鱼菜共生系统,迁移到科学、劳动与跨学科课程

对器材条件有限的学校来说,先用虚拟的屋子把道理讲明白,再逐步接真实硬件,是一条成本低、风险小、迭代快的路径。这也是我最想和社区同行讨论的一点:在乡村课堂里,一个「坏了刷新就能重来」的数字孪生装置,究竟能替掉多少演示风险、又能保住多少动手的真实感。

十、结语

从一块 M10、一个外接温湿度模块,到一间能转着看、会随昼夜变化的客厅,中间真正花时间的不是把 3D 画得漂亮,而是把每一条规则放到真实教室里反复试:字太浅就按对比度重新调,几块屏不同步就统一成一份状态,空调关不掉就把回差余量加大,换教室就让它自己重新标定,拖拽被卡片挡住就让 HUD 让位。

最后留在课堂上的是很朴素的一件事:学生遮一下光,窗帘自己合上了;他改了一个数,屋子的脾气就变了。「感知、传输、判断、执行、反馈」不再需要背,因为它刚刚在眼前发生过一次。

相关附件与来源声明

随文附件:

  • 3d-smart-home_投稿附件.zip:完整工程源码(含本地 Three.js)、两份 systemd 服务配置示例、一键启动脚本与部署脚本
  • 《行空板 K10 × Three.js 3D 智能家居:原理拆解与落地指导》:含 M10 适配分析与真机部署实录
  • 《学校大屏部署手册》:三套现场方案、出发前清单与翻车速查表
  • 《智慧小屋 · 课堂学生动手实施方案》:三种组织形态、40 分钟流程与可印发任务卡
  • 《3D 智能客厅》项目汇编:全部文档、留档截图与迭代排障实录
  • 投稿配图 8 张(统一 1600 × 900 横版),演示视频 1 段

来源与原创声明:

硬件清单

创作许可协议

本项目采用 CC BY(署名) 进行许可。

所需材料/产品

加载全部

    Gravity: DHT11温湿度传感器(Arduino兼容)

    Gravity: DHT11温湿度传感器(Arduino兼容)

    Gravity: DHT11温湿度传感器(Arduino兼容)

    行空板M10(UNIHIKER)Python教学主控板 - 蘑菇云科创教育

    行空板M10(UNIHIKER)Python教学主控板 - 蘑菇云科创教育

    行空板M10(UNIHIKER)Python教学主控板 - 蘑菇云科创教育

相关推荐

评论(0)
- 没有更多了 -

创作许可协议

本项目采用 CC BY(署名) 进行许可。

相关推荐

所需材料/产品

Gravity: DHT11温湿度传感器(Arduino兼容)

Gravity: DHT11温湿度传感器(Arduino兼容)

Gravity: DHT11温湿度传感器(Arduino兼容)

行空板M10(UNIHIKER)Python教学主控板 - 蘑菇云科创教育

行空板M10(UNIHIKER)Python教学主控板 - 蘑菇云科创教育

行空板M10(UNIHIKER)Python教学主控板 - 蘑菇云科创教育