第一部分 · 准备与接线
STEP 1⃣ 装好三个扩展包
目标:让 MakeCode 里出现灯带、光照、串口三类黑色积木。
- 打开 MakeCode(micro:bit 编程编辑器),新建项目。
- 左下角点「高级」→「扩展」,搜索并添加:neopixel(灯带库)、BH1750(光照传感器库)、serial(串口库)。
- 添加成功后,积木抽屉里会多出黑色/深蓝色的扩展积木。
💡 积木颜色口诀:红=变量、蓝=基础(当开机时/无限循环/暂停)、青=逻辑(如果…)、橙=数组、绿=循环、紫=输入·运行时间(ms)、黄=文本、黑=扩展包。
STEP 2⃣ 三线接线
目标:把三个模块接到扩展板的正确引脚上,接错一步程序都"装睡"。
| 模块 | 信号线 | 接哪里 | 电源线 |
|---|---|---|---|
| WS2812 灯带 | 数据 DI(三角箭头线) | P2 | VCC、GND |
| 声音传感器 | 模拟输出 AO | P0 | VCC、GND |
| BH1750 光照 | SDA、SCL | IIC 座(P20/P19) | VCC、GND |
⚠️ 灯带接头上的三角箭头方向要朝向主板(箭头是数据"传球"方向,反了灯全灭);VCC/GND 别接反。传感器都走 3.3V 档跳线帽。
第二部分 · 模块 1:当开机时(初始化,只跑一次)
STEP 3⃣ 初始化传感器和灯带
目标:micro:bit 一上电,先把 BH1750、灯带和串口表头准备好。
- 拖入蓝色积木「当开机时」——里面所有内容上电只执行一次。
- 黑色 BH1750 积木「设置 I2C 地址 35」放入,再放「打开 BH1750」——告诉主板传感器在哪、并启动它。
- 黑色 NeoPixel 积木「将 strip 设为引脚 P2 初始化 灯带 LED_NUM 颗 LED,模式 RGB (GRB 顺序)」——灯带对象起名
strip。 - 最后黑色串口积木「向串口写入一行
"time_ms,loud_sample,lux,level"」——这是测试数据的 CSV 表头。

STEP 4⃣ 创建 14 个变量
目标:在【变量】分类里新建下表全部变量,并按"设置值"依次拖入「将 XX 设为 XX」积木。
| 变量名 | 设置值 | 它是干嘛的 |
|---|---|---|
| 当前音量 | 0 | 存单次读到的声音数值 |
| 有效最大音量 | 0 | 存最近一段时间里的最大音量 |
| lux 亮度 | 0 | 存 BH1750 读到的光照数值 |
| 超标开始时间 | -1 | 灯点亮的起始时间,-1 = 灯没开 |
| 状态 | "QUIET" | 当前状态标记,开机默认安静 |
| 上次打印时间 | 运行时间 (ms) | 串口打印计时备用 |
| 音量列表 | 空数组 | 连续采集的音量数据存放处 |
| TH_TALK | 80 | 小声交谈阈值(超过=有人说话) |
| TH_LOUD | 200 | 大声噪音阈值(超过=喧闹) |
| SUSTAIN_MS | 1000 | 要持续大声多久才开灯(1 秒) |
| LUX_THRESHOLD | 200 | 光照分界值,低于它=环境暗 |
| WINDOW_MAX | 12 | 数组最多存 12 组音量 |
| LED_NUM | 10 | 灯带一共 10 颗灯珠 |
| noise_start_time | -1 | 大声噪音计时起点,-1=还没计时 |
⚠️ 重点:所有数字
-1 要用【数学】里的数字积木,不要加引号!写成文本 "-1" 会报红色类型错误。

第三部分 · 模块 2:无限循环(一遍遍重复的主程序)
STEP 5⃣ 采集音量 + 滑动窗口
目标:每轮循环读一次 P0 音量存进"音量列表",并且永远只保留最近 12 条。
- 拖入蓝色「无限循环」——后面所有积木全部放进它。
- 红色「将 当前音量 设为 模拟读取引脚 P0」(【输入】积木,P0 上接的就是声音传感器 AO)。
- 橙色「将值 当前音量 添加到 音量列表 结尾」。
- 青色「如果 音量列表的长度 > WINDOW_MAX 则」→ 里面放橙色「移除音量列表的第一个值」——超过 12 条就删最早的,像滚雪球一样只留最近 12 次。

STEP 6⃣ 遍历数组找最大音量
目标:从最近 12 条音量里挑出"最响的一下",防止偶尔一个杂音骗过程序。
- 红色「将 有效最大音量 设为 0」——每轮先清零重新找。
- 绿色「将数组 音量列表 中的元素逐个取出,以 值 引用」。
- 里面嵌青色「如果 值 > 有效最大音量 则」→ 红色「将 有效最大音量 设为 值」——挨个比武,最大的胜出。

STEP 7⃣ 读取光照值
目标:每轮循环问一次 BH1750"现在多亮?"
- 黑色 BH1750 积木「将 lux 亮度 设为 获取环境光强 (lx)」。

STEP 8⃣ 声音三层状态判断(核心逻辑!)
目标:用"如果…则…否则"搭出 QUIET / TALK / TRIGGER 三种状态,只有持续大声才触发。
- 青色「如果 有效最大音量 > TH_LOUD 则」——第一层:够不够吵?点外层齿轮加【否则】分支。
- 【则】里面(够吵,开始计时):
a. 青色「如果 noise_start_time = -1 则」→ 紫色「将 noise_start_time 设为 运行时间 (ms)」——第一次响才记开始时间,不重复记。
b. 青色「如果 运行时间 (ms) − noise_start_time > SUSTAIN_MS 则」→ 红色「将 超标开始时间 设为 运行时间 (ms)」+「将 状态 设为 "TRIGGER"」——满 1 秒,开灯! - 【否则】里面(不够吵):
a. 红色「将 noise_start_time 设为 -1」——计时清零重来。
b. 青色「如果 有效最大音量 > TH_TALK 则」→「状态 = "TALK"」,否则「状态 = "QUIET"」。

STEP 9⃣ 灯光控制:彩虹/白光/熄灭
目标:触发后的 2 秒窗口内,按环境亮暗决定灯带演什么节目。
- 青色「如果 (超标开始时间 ≠ −1)与(运行时间 (ms) − 超标开始时间 < 2000) 则」——灯已点亮且还不到 2 秒。【与】积木在逻辑分类,≠ 和 − 在数学分类。
- 里面再套青色「如果 lux 亮度 < LUX_THRESHOLD 则」:暗 → 黑色 NeoPixel「strip 显示彩虹特效(色相 1 到 360)」;点齿轮加否则 → 亮 → 「strip 显示 RGB (80,80,80)」柔和白光。
- 外层否则:「strip 显示 RGB (0,0,0)」全灭 + 「将 超标开始时间 设为 -1」重置开灯标记。
💡 RGB(80,80,80) 为什么不是 (255,255,255)?80 已经很亮,白光太刺眼还费电;(0,0,0) = 黑 = 熄灭。


STEP 10 串口打印数据 + 暂停
目标:每轮把 4 个关键数发给电脑记小本本,再让程序歇 50 毫秒。
- 黄色「组合字符串」依次拼:运行时间 (ms) +
","+ 有效最大音量 +","+ lux 亮度 +","+ 状态。 - 黑色串口积木「向串口写入一行 组合字符串」。
- 蓝色「暂停 (ms) 50」——每轮等 50ms,程序别跑太快(12 条窗口 ≈ 0.6 秒的数据)。

第四部分 · 烧录、测试与答辩
STEP 11⃣ 下载程序 + 观察现象
目标:把搭好的积木跑起来,对着现象记录测试数据。
- 点「下载」,把 hex 文件拷贝进
MICROBITU盘。 - 打开串口监视器,对照下表观察并记录:看到
TRIGGER出现、灯亮 2 秒后自动灭,就算成功。 - 把每种现象记进项目测试报告(时间、音量、lux、状态四列都有数据,评委最爱看)。
| 你制造的环境 | 状态列 | 灯带应该 |
|---|---|---|
| 安静不说话 | QUIET | 熄灭 |
| 小声交谈 | TALK | 不亮 |
| 持续大喊/拍手满 1 秒,同时遮住光敏 | TRIGGER | 彩虹流水 2 秒 |
| 持续大声满 1 秒,环境很亮 | TRIGGER | 柔和白光 2 秒 |
STEP 12 排查故障 + 答辩金句
目标:能自己修好问题,并能一口气讲清项目原理。
🔧 排错四件套:① 红色报错 → 检查
-1 是不是被写成带引号的文本,换成数学数字积木 ② 灯不亮 → 查 P2 接线、灯带箭头方向、供电 ③ 声音没反应 → 查 P0 接线,用螺丝刀转声音传感器上的电位器调灵敏度 ④ 光照数值不变 → BH1750 的 SDA/SCL 可能接反。🚀 拓展思考(可现场演示):① 改成"只要持续有声音灯就一直亮"怎么改?② 调 TH_TALK / TH_LOUD 改变声音灵敏度 ③ 调 SUSTAIN_MS 改变要大声多久才开灯。
🎤 答辩参考短句(背下来): 我的项目是声光感应智能灯带。声音传感器采集音量,BH1750 采集光照。 程序用滑动窗口记录最近 12 次音量,只有持续大声超过 1 秒才会触发点亮灯带。 环境暗的时候显示彩虹灯光,环境亮的时候显示白光,灯光保持 2 秒后自动关闭。 串口数据可以用来做阈值实验的记录。
声光控制灯带_实操教程 v1.0 · 2026-10-17 生成 · 内容来源:《声光控制 WS2812 灯带科创项目.MD》+ micro:bit 完整积木程序截图 V3(已切成 10 段对照图)· 配套:🛠️ 复赛实操教程 / 📌 扩展板针脚图解 · 进度存本机浏览器,不上传 · 打印版已隐藏按钮