只用一块行空板 K10,把物联网课堂搬进一间会动的 3D 客厅
传感器是真的,灯、电视、窗帘、空调和窗户是虚拟的。
用一块行空板 K10、一个模拟声音传感器和一台电脑,搭出低成本、高展示度的物联网智能家居演示。

一、为什么做这个项目?
在中小学创客课堂里讲“智能家居”,很容易遇到两个现实问题。
第一是硬件成本高。要演示灯光、电视、窗帘、空调、窗户五种设备,往往需要准备继电器、灯具、电视模型、窗帘电机、舵机、空调模型……一套下来,器材多、接线复杂,课堂准备时间很长。
第二是演示效果不稳定。真实窗帘可能卡住,继电器有噪声,220V 灯具涉及用电安全;几十个学生轮流操作时,设备很容易出故障。
这个项目换了一个思路:
把传感器留在真实世界,把执行器搬进浏览器。
行空板 K10 负责采集按键、光线、温湿度和声音数据;电脑上的 Python 桥接服务负责判断和控制;浏览器里的 Three.js 3D 客厅负责“执行”:灯亮起来、电视播放画面、窗帘打开、空调出风、窗户滑动。
学生看到的不是一块冷冰冰的开发板,而是一间会回应自己动作的 3D 房子。

二、项目效果
- 按下 K10 的 A 键,3D 客厅里的落地灯亮起,室内电子屏显示“灯光:开”;
- 按下 B 键,电视播放动态画面,电视墙被蓝色光染亮;
- 用手遮住光线传感器,窗帘缓缓关闭;用手机手电筒照一下,窗帘重新打开;
- 对着声音传感器拍手或喊叫,窗户立刻关闭;安静 8 秒后自动打开;
- 对着温湿度传感器哈气,湿度升高,空调开启;环境舒适后自动关闭;
- K10 屏幕、3D 客厅墙上的电子屏、网页右上角数据栏,三处显示同一份状态。
所有设备状态都来自同一套服务端状态机,不会出现“K10 显示开、网页显示关”的情况。
演示视频
三、系统原理:一块板子、一个桥、一间虚拟房子
代码块
┌──────────────────────┐ UDP / JSON ┌──────────────────────────┐
│ 行空板 K10 │ 传感器、按键事件 ──▶ │ Python 桥接服务 │
│ · 按键 A / B │ │ · 接收 UDP :4210 │
│ · 光线传感器 │ ◀── 状态、事件 ACK ── │ · 自动化状态机 │
│ · 温湿度 AHT20 │ │ · HTTP :8000 │
│ · DFR0034 声音传感器 │ │ · 静态网页 + JSON API │
└──────────────────────┘ └────────────┬─────────────┘
│ HTTP
▼
┌──────────────────────────┐
│ 3D 网页(Three.js) │
│ 灯 / 电视 / 窗帘 / 空调 │
│ 窗户 / 室内电子显示屏 │
└──────────────────────────┘
这里有一个关键点:浏览器不能直接监听 UDP 端口。所以电脑上运行一个 Python 桥接服务,充当“翻译器”:
- K10 通过 WiFi 向电脑的 UDP 4210 端口发送传感器 JSON;
- 桥接服务运行自动化规则,维护灯、电视、窗帘、空调、窗户的状态;
- 桥接服务把状态回传给 K10,同时通过 HTTP 提供给浏览器;
- 浏览器每 380 ms 拉取一次
/api/state,点击设备时发送/api/command。
这样做还有一个好处:自动化逻辑只有一份。K10、网页、电子屏看到的是同一个“真相”,不会各算各的。
四、硬件清单与接线
| 器材 | 数量 | 说明 |
|---|---|---|
| 行空板 K10 | 1 | 主控、屏幕、WiFi、按键、光线、温湿度 |
| Gravity 模拟声音传感器 DFR0034 | 1 | 接在 P0 模拟口 |
| USB-C 数据线 | 1 | 供电和烧录程序 |
| 电脑 | 1 | 运行桥接服务和浏览器 |
| 同一局域网 WiFi | — | K10 与电脑需要在同一网络 |
为什么不用 K10 板载麦克风?
K10 的两个板载麦克风可以录音、做语音识别,但官方库没有直接输出“声音强度/声压级”的接口。因此这里使用模拟声音传感器,接到 K10 的 P0 模拟口。它的输出会随环境声音变化,适合做“噪声大关窗”的演示。
接线
| DFR0034 | K10 |
|---|---|
| VCC | 3V3 |
| GND | GND |
| AO | P0 |
整个项目不接继电器、不接 220V 灯具、不接窗帘电机,用电安全,适合课堂。


五、软件准备
项目只使用 Python 标准库和本地 Three.js,不需要安装数据库或云平台。
代码块
├─ index.html # 3D 页面入口
├─ css/style.css # 页面 HUD、控制栏、响应式样式
├─ js/main.js # Three.js 场景、动画、电子屏、API
├─ vendor/ # 本地 Three.js,无需联网加载
├─ server/
│ ├─ bridge.py # UDP ↔ HTTP 桥接 + 自动化状态机
│ └─ simulator.py # 没有 K10 时的 UDP 模拟器
├─ k10/main.py # 行空板 K10 MicroPython 程序
└─ docs/preview.png # 效果图
电脑上需要:
- Python 3.8 及以上;
- Chrome / Edge 等支持 WebGL 的浏览器;
- Thonny,用于给 K10 上传 MicroPython 程序。
六、快速复现
1. 先看效果:不接硬件也能演示
在工程根目录打开 PowerShell:
powershell
python server\bridge.py --demo
浏览器打开:
代码块
http://127.0.0.1:8000
--demo 会自动生成循环变化的温度、湿度、光照和噪声,适合课前试讲或没有硬件时展示。
2. 接上 K10
电脑运行:
powershell
python server\bridge.py

启动后会打印电脑局域网 IP,例如:
代码块
网页: http://127.0.0.1:8000
局域网: http://192.168.1.100:8000
UDP 端口: 4210
K10 配置: PC_IP = "192.168.1.100" PC_PORT = 4210
用 Thonny 打开 k10/main.py,修改顶部配置:
python
WIFI_SSID = "你的WiFi名称"
WIFI_PASSWORD = "你的WiFi密码"
PC_IP = "192.168.1.100" # 以 bridge.py 打印的 IP 为准
PC_PORT = 4210
把文件保存到 K10 设备,文件名必须是 **main.py**,然后复位运行。
Windows 如果弹出防火墙提示,请允许 Python 访问专用网络,或者手动放行 TCP 8000 和 UDP 4210。

3. 没有声音传感器也能调协议
powershell
python server\simulator.py
模拟器通过真实 UDP 协议发包,支持:
代码块
t 28.5 设置温度
h 72 设置湿度
l 80 设置光照
n 70 设置噪声
a / b 模拟按键 A / B
day/night 光照场景
quiet/noisy 安静 / 嘈杂场景
例如输入 n 35,窗户会关闭;再输入 quiet,约 8 秒后窗户自动打开。
七、自动化规则
| 输入 | 行为 |
|---|---|
| 按键 A | 开 / 关灯光 |
| 按键 B | 开 / 关电视 |
| 光照 < 80 lx | 关窗帘 |
| 光照 ≥ 200 lx | 开窗帘 |
| 温度 ≥ 27°C 或湿度 ≥ 70% | 开空调 |
| 温度 ≤ 25.5°C 且湿度 ≤ 65% | 关空调 |
| 噪声 > 30% | 立刻关窗 |
| 噪声 ≤ 20% 持续 8 秒 | 自动开窗 |
这里有三个适合课堂讲解的控制思想。
1. 死区 / 回差
窗帘不是“低于 200 就关”,而是低于 80 才关;空调也不是温度一降一点就关,而是要温度和湿度都降下来。
如果没有回差,传感器在阈值附近轻微波动,设备就会反复开关。这个现象在真实智能家居里同样存在,是很好的控制论入门例子。
2. 噪声回差
关窗阈值是 **> 30%,开窗阈值是 ≤ 20% 并持续 8 秒**。
为什么不直接“低于 30 就开窗”?因为环境噪声经常在 29/31 附近波动,窗户会反复开合。留出 10% 的回差,并加一个 8 秒确认时间,控制会更稳定。
3. 手动优先,自动恢复
在网页上点击窗帘、空调或窗户,会进入 20 秒手动模式。倒计时结束后,自动规则重新接管。
这模拟了真实智能家居中的“手动覆盖自动”逻辑,也方便老师在演示时临时改变状态。
八、K10 屏幕:只刷新数据,不刷新固定标签
K10 屏幕是 240 × 320 竖屏,使用 screen.init(dir=2)。界面大致如下:
代码块
┌──────────────────┐
│ K10 智能家居 UDP 在线 ●
│ 温度℃ 26.4 湿度% 58
│ 光照lx 320 噪声% 42
│ 灯光 A 开
│ 电视 B 关
│ 窗帘 开
│ 空调 关
│ 窗户 开
│ A灯 B电视 同步
└──────────────────┘
实现时有两个细节。
第一,所有坐标都在 0–239 内。
K10 的字体只有 16×16 和 24×24 两种字号;如果按 320 宽度排版,UDP 会只露出一个 U,设备状态也会在右侧被裁切。
第二,固定内容只画一次。
启动时先用 screen.clear() 清屏,画一次标题、卡片边框、设备名称和底部说明;进入主循环后,只清除并重绘数值、开关状态和连接状态区域。
这样做的直接效果是:
- 不再整屏闪烁;
- “K10 智能家居”“启动 UDP…”等旧文字不会残留;
- 固定标签不参与循环刷新,屏幕更干净。

九、UDP 协议:让数据可靠地跑一个来回
K10 每 200 ms 发送一帧 JSON:
json
{
"type": "sensor",
"boot": "k10-123456",
"seq": 18,
"sensors": {
"temp": 26.4,
"humi": 58.1,
"lux": 320,
"noise": 42
},
"events": [
{ "id": 3, "name": "a" }
]
}
电脑回传状态:
json
{
"type": "state",
"online": true,
"devices": {
"lamp": false,
"tv": true,
"curtain": true,
"ac": false,
"window": true
},
"ack_event": 3
}
按键事件会重复发送,直到收到 ack_event。桥接服务按事件 id 去重,因此即使 UDP 丢包、重发,灯光也只会切换一次。
boot 字段用于 K10 重启后重置事件序号,避免重启后的事件被误判为“旧事件”。
十、3D 客厅是怎么动起来的?
3D 部分使用 Three.js,全部资源放在本地 vendor/,不依赖外部 CDN。
场景里包含:
- 木地板、地毯、沙发、茶几、落地灯、绿植;
- 左墙电视和电视柜;
- 后墙窗户、推拉窗扇、窗帘、窗台;
- 壁挂空调和出风口;
- 墙上的室内电子显示屏;
- 茶几旁的迷你 K10 模型。
状态变化通过动画过渡:
- 灯光开启时,点光源、灯罩自发光、灯泡和地面暖色光池一起增强;
- 电视开启时,Canvas 绘制动态的“NIGHT SIGNAL”画面,并用蓝色光染亮电视墙;
- 窗帘打开时向两侧收拢,关闭时合拢;
- 窗户通过两扇窗扇的横向滑动表示开合;
- 空调开启时,出风口叶片摆动并显示气流粒子;
- 室内电子屏用 CanvasTexture 实时绘制温度、湿度、光照、噪声和五个设备状态。
网页上还可以直接点击 3D 物体控制设备;底部快捷栏、键盘 A/B 也可以操作。

十一、课堂演示脚本
下面是一套约 8 分钟的演示流程,适合在课堂投影或社团招新时使用。
1. 导入:什么是数字孪生?
先让学生看 3D 客厅,提问:
“这间房子是真的,还是假的?
传感器是真的,为什么灯和窗帘可以是假的?”
引出“数字孪生”:真实世界的数据,可以驱动虚拟世界里的对象;虚拟世界也可以反过来显示真实设备的状态。
2. 按键控制
按下 K10 的 A 键,灯光亮起;按 B 键,电视播放。
提示学生观察:K10 屏幕、网页、室内电子屏三处状态是否一致。
3. 光线控制窗帘
用手遮住 K10 的光线传感器,光照降到 80 lx 以下,窗帘关闭;用手机手电筒照一下,光照超过 200 lx,窗帘打开。
提问:为什么不在 150 lx 时反复开关?引出“回差”。
4. 声音控制窗户
对着 DFR0034 拍手或喊叫,噪声超过 30%,窗户立刻关闭;安静 8 秒后,窗户重新打开。
提问:如果噪声一直在 29–31 之间,会发生什么?为什么需要 20% 的开窗阈值和 8 秒确认?
5. 温湿度控制空调
用手捂住温湿度传感器或哈气,湿度升高,空调开启;等环境恢复后,空调关闭。
提示:真实空调不会因为湿度高 1% 就立刻动作,阈值和回差是工程中常见的“防抖”设计。
6. 手动覆盖自动
在网页上手动关闭窗帘,观察按钮出现 MANUAL,20 秒后自动规则重新接管。
提问:真实智能家居里,手动开关和自动策略冲突时,应该听谁的?
十二、面向课堂的分层任务
基础任务
- 修改灯光阈值,让窗帘在更暗或更亮时关闭;
- 修改空调开启温度;
- 修改噪声关窗阈值,观察演示效果。
进阶任务
- 在 3D 场景里增加一个“门”或“扫地机器人”;
- 给网页增加一个手动按钮;
- 让电子屏显示一条新的传感器数据。
挑战任务
- 用 MQTT 替代 UDP,把数据发到局域网服务器;
- 把传感器数据记录成 CSV,画出一节课的温湿度曲线;
- 增加“回家模式”:一键开灯、开空调、开窗帘;
- 让多个 3D 房间共享同一套设备状态。
十三、常见问题
| 现象 | 排查 |
|---|---|
| 网页一直“等待行空板数据” | 检查 PC_IP 是否是电脑局域网 IP;K10 和电脑是否在同一 WiFi;防火墙是否放行 UDP 4210 |
| 网页“桥接服务未连接” | 没有启动 bridge.py,或 8000 端口被占用 |
| K10 连不上 WiFi | K10 使用 2.4 GHz WiFi;避免需要网页认证的校园网 |
| 声音数值一直为 0 或 100 | 调整 DFR0034 电位器;修改 NOISE_FLOOR 和 NOISE_GAIN |
| K10 屏幕文字被裁切 | 当前布局固定为 240×320(dir=2),不要使用超过 239 的 x 坐标 |
| 屏幕闪烁或有残影 | 确认使用最新 main.py,固定标签只在启动时绘制,循环只刷新数据区域 |
| 3D 页面黑屏 | 必须通过 http://127.0.0.1:8000 `` 访问,不能直接双击 HTML;浏览器需支持 WebGL |
十四、还可以怎么扩展?
这个项目的价值不只在“演示一个智能家居”,而在于它提供了一个可扩展的物联网教学框架:
- 把虚拟执行器换成真实继电器、舵机、灯带;
- 把 UDP 换成 MQTT,接入 Home Assistant 或云平台;
- 增加历史数据、曲线、告警和语音控制;
- 用多个 K10 控制多个房间;
- 把 3D 场景换成校园、温室、鱼菜共生系统。
对创客课堂来说,先用虚拟执行器把逻辑跑通,再逐步接入真实硬件,是一种成本低、风险小、迭代快的教学路径。
十五、结语
物联网项目不只是“把传感器接上开发板”,更重要的是让学生理解一条完整链路:
感知 → 传输 → 判断 → 执行 → 反馈
行空板 K10 负责感知和交互,Python 桥接服务负责传输和判断,3D 客厅负责执行和可视化。硬件只保留了最必要的部分,学生却能看到一个完整、即时、可互动的智能家居系统。
把执行器放进屏幕里,把真实问题留在课堂里。
这或许就是低成本物联网创客课堂的一种好打开方式。
项目文件
server/bridge.py:UDP/HTTP 桥接与自动化server/simulator.py:无硬件 UDP 模拟器k10/main.py:行空板 K10 MicroPython 程序index.html、css/style.css、js/main.js:3D 网页docs/preview.png:效果图
参考文档



