基于Circuit Playground Express的红外激光对战系统设计与实现

发布时间:2026/5/15 14:03:17

基于Circuit Playground Express的红外激光对战系统设计与实现 1. 项目概述与核心思路如果你手头正好有两块Adafruit的Circuit Playground Express开发板又觉得单纯点亮LED或者做个温度计有点不过瘾那今天这个项目绝对能让你玩上瘾。我们将利用板子上一个常被忽略的功能——红外收发器来制作一套完整的、可互相对战的激光对战系统。这不仅仅是“遥控器控制另一个板子亮灯”那么简单我们会实现一个完整的游戏逻辑每被“击中”一次板子上的NeoPixel环形灯就会多亮起一盏直到被击中十次后“阵亡”所有灯变红并伴随音效。两块板子互为“枪”和“靶子”你可以和朋友来一场紧张刺激的对战或者把它当作一个有趣的射击靶来练习瞄准。这个项目的魅力在于它完美结合了硬件感知、无线通信和游戏逻辑。红外通信本身是一种非常经典且廉价的短距离无线技术我们每天用的电视遥控器就是最好的例子。在创客项目中利用它来实现设备间的简单指令传输既稳定又直观。Circuit Playground Express后面我们简称CPX板载了红外发射管TX和接收管RX这为我们省去了外接模块的麻烦。而MakeCode图形化编程环境则让编写复杂的“发射-接收-判断-反馈”逻辑变得像搭积木一样简单即使你没有深厚的代码功底也能轻松上手。整个项目的核心思路非常清晰将一块CPX设置为“发射器”当按下按钮时通过红外LED发射一个代表特定颜色比如靛蓝色的数字编码信号。另一块作为“接收器”的CPX在接收到这个信号后会解析这个数字并执行一系列游戏逻辑增加“被击中次数”的计数器根据次数点亮相应数量的LED并在达到上限后触发“阵亡”状态全红灯音效同时锁定自身无法再作为发射器使用直到复位。由于代码是对称的每块板子都同时具备发射和接收功能因此两块板子可以平等地对战。2. 硬件准备与电路解析2.1 核心硬件清单与选型考量这个项目对硬件的要求非常精简核心就是两块CPX开发板。我强烈推荐使用Adafruit原厂的Circuit Playground Express而不是经典的Circuit Playground后者没有红外功能或其他兼容板因为原厂板在MakeCode中的兼容性和库支持是最完善的。CPX可以看作是Arduino的一个高度集成、对初学者极其友好的版本它把你想得到和想不到的传感器、输出设备都集成在了一个小圆板上10个可编程RGB NeoPixel LED、运动传感器、温度传感器、光线传感器、声音传感器、两个按钮、一个滑动开关、一个红外收发器、一个扬声器甚至还有电容触摸接口。对于这个项目我们主要用到它的红外收发器、NeoPixel LED、按钮、扬声器和电源接口。除了开发板独立的供电是关键。CPX虽然可以通过USB供电但为了能拿着它到处跑、实现真正的“对战”我们必须使用电池供电。这里选择的是3节AAA电池盒带开关和JST-PH 2针接口的版本。为什么是3节AAA因为CPX的工作电压范围是3.3V-5.5V。3节全新的碱性电池可以提供约4.5V的电压正好落在理想区间既能稳定驱动板子所有功能又不会因电压过高造成风险。锂电池虽然能量密度高但单节3.7V的电压需要搭配升压电路而两节串联又可能超过5.5V对于这个简单项目来说AAA电池盒是最可靠、最安全易得的选择。你需要准备两个这样的电池盒以及总共6节AAA电池。最后你还需要两根Micro-USB数据线用于最初的程序烧录。一旦代码烧录完成并切换到电池供电数据线就可以收起来了。所以完整的清单是Circuit Playground Express 开发板 x 2带开关的3xAAA电池盒 x 2AAA碱性电池 x 6Micro-USB数据线 x 2注意务必使用碱性电池。可充电的镍氢电池如eneloop单节电压通常只有1.2V三节串联只有3.6V处于CPX工作电压的下限边缘可能导致红外发射功率不足、传输距离缩短或者在大电流驱动NeoPixel时出现不稳定。新手第一次搭建强烈建议用全新碱性电池排除电源问题。2.2 红外通信硬件原理浅析虽然我们用MakeCode积木编程但了解一点底层硬件原理能帮你更好地调试和理解项目。CPX上的红外通信系统主要由两部分组成红外发射管IR TX LED位于板子边缘标有“TX”的小透明LED。当它通电时会发出人眼不可见的红外光。在MakeCode中我们通过红外发送数字积木来控制它。实际上这个积木会让红外管以特定的频率通常是38kHz这是大多数红外接收头的标准载波频率闪烁将我们要发送的数字编码成一系列长短不同的红外脉冲。你可以把它想象成一个快速的、人眼看不见的“手电筒”在用莫尔斯电码发送信息。红外接收器IR Receiver位于板子另一侧标有“RX”的一个黑色的小方块。它的内部是一个光电二极管和一套解调电路。它的作用不是简单地检测有无红外光而是专门检测以38kHz频率调制的红外信号。这能有效过滤掉环境中常见的连续红外光源如太阳光、白炽灯的干扰只“听”我们发射器发出的特定“音调”的信号。当它收到正确的信号后会将其解调还原出数字信息并触发当红外接收到数据积木。这两个元件在板子上的物理位置是固定的。在进行对战时你需要确保发射器的TX LED大致对准接收器的RX窗口。红外光的传播有一定的散射角就像手电筒的光锥。默认情况下这个光锥比较宽容易瞄准但也少了点挑战性。后文我们会介绍如何通过加装“枪管”来收窄光束提升游戏难度和真实感。3. 游戏逻辑设计与MakeCode编程详解3.1 项目初始化与状态设置打开MakeCode编辑器建议使用桌面版或Chrome浏览器访问makecode.adafruit.com新建一个项目。我们所有的代码都将放在这个项目中并且同一份代码会同时烧录到两块CPX板子上因为它们角色是对等的。首先进行初始化。拖入一个当启动时积木。这个积木里的代码只会在板子通电或复位时执行一次用于设置游戏的初始状态。我们需要做两件事初始化NeoPixel灯环从“灯光...更多”类别中拖入设置所有像素颜色为 红色积木将其颜色改为“白色”。这行代码的作用是在游戏开始时将10个LED灯全部点亮为白色作为一个醒目的“设备已就绪”指示灯。白色光亮度高能清晰表明板子已上电且程序正常运行。创建并初始化变量这是游戏逻辑的核心。我们需要两个变量来记录状态。health生命值代表这个“目标”是否还能被射击或主动射击。我们设1为“存活”0为“被击毁”。初始值设为1。hits击中次数记录这个目标当前被击中了多少次。初始值设为0。在“变量”类别中点击“创建一个变量”分别创建这两个变量。然后拖入两个将 项目 设为 0的积木到当启动时循环内分别将health设为1将hits设为0。至此初始化部分完成。板子启动后会白灯全亮并且内部记录着生命值满格1被击中次数为0。3.2 发射器逻辑按钮触发与红外信号发送现在来构建“开枪”的逻辑。我们希望按下按钮A时板子能作为发射器向对方发送一个“子弹”信号。建立按钮监听从“输入”类别中拖入当 按钮 A 被点击积木。但这里有个关键细节被点击指的是“按下并释放”的完整动作。在快速对战游戏中我们希望按下的一瞬间就触发响应更快。所以点击积木上“A”旁边的下拉菜单将其改为A然后再点击“被点击”选择被按下。这样只要手指按下按钮事件就会立刻触发。添加视觉反馈因为红外光不可见开枪时我们需要一个可见的提示。CPX板载了一个单独的红色LED连接到引脚13在较新的MakeCode版本中这个引脚被直接命名为“LED”。从“引脚”类别在“高级”抽屉里拖入数字写入 引脚 A0 至 假积木。将其中的“A0”改为“LED”或“D13”“假”改为“真”。这行代码会在按下按钮时点亮这颗红色LED模拟“枪口闪光”。发送红外信号这是发射部分的核心。从“红外”类别拖入红外发送数字 0积木到按钮事件中。这个“0”就是我们要发送的消息内容。在这个游戏中我们发送的数字实际上代表一种“颜色代码”。例如我们可以定义发送“靛蓝色”代表一颗有效的子弹。从“灯光...更多”类别中找到颜色选择器积木通常是一个色块将其拖拽到红外发送数字积木的“0”上覆盖它然后在弹出的颜色选择器中选择“靛蓝”Indigo。这样当我们按下按钮A板子就会向外发射一个代表“靛蓝色”的红外编码信号。实操心得你可以为不同的按钮分配不同的“颜色子弹”。例如复制整个当 按钮 A 被按下的积木组合将按钮改为“B”发送的颜色改为“绿色”。这样一块板子就有了两种“武器”增加了游戏的可玩性。在接收逻辑里我们可以根据接收到的不同颜色数字来触发不同的效果比如不同颜色的击中光效。3.3 接收器逻辑信号解码与游戏状态更新接收器逻辑是整个游戏的“大脑”负责处理被击中后的所有反应。我们使用当红外接收到数据积木来响应。这个积木会提供一个名为receivedNumber新版本中叫num的变量里面存储着发送方发来的数字在我们这里就是颜色代码。添加接收指示同样为了直观知道收到了信号我们可以点亮红色LED。复制之前数字写入 LED 至 真的积木放到当红外接收到数据积木里面。构建核心游戏逻辑这里我们需要用条件判断来实现一个状态机。拖入一个如果 为 真 则积木。条件判断我们首先要检查自己的health是否为1即是否还存活。从“逻辑”类别拖入一个0 0积木替换掉“真”。将第一个“0”用变量health替换第二个“0”改为“1”。这个条件的意思是如果我的生命值等于1存活则执行接下来的被击中逻辑。存活状态下的处理如果分支 a.增加击中计数拖入以 1 为幅度更改 hits积木。 b.灯光反馈我们希望每被击中一次就多点亮一个NeoPixel。从“灯光”类别拖入设置像素颜色 从 0 至 0 为 红色积木。这里需要一点技巧将“从”后面的0替换为0将“至”后面的0替换为变量hits。但注意hits是从0开始计数的而像素索引是从0到9。为了从第一个灯开始点亮我们可以用hits - 1。更简单直接的方法是设置像素颜色从0至hits但第一次击中hits1时会点亮索引0和1两个灯不对。实际上我们需要的是点亮前N个灯。MakeCode有一个图形 绘制条形图到 高度 0积木在“灯光...更多”里但用在这里不直观。一个清晰的做法是设置像素颜色 从 0 至 hits 为 靛蓝并将颜色改为与发射信号一致的颜色如靛蓝。但这样每次都会重新设置从0到hits的所有灯。为了效果更好我们可以每次只点亮一个新的灯设置像素颜色 在 hits - 1 为 靛蓝。这里有一个关键点当hits为0时hits - 1是 -1会导致错误。因此安全的做法是在更改 hits之后用设置像素颜色 在 hits 为 靛蓝但第一次击中后hits1点亮的是索引1的灯第二个灯留出索引0的灯作为特殊状态这会让灯光顺序看起来不连续。经过实践最直观且无错的逻辑是在如果内部先更改 hits然后设置像素颜色 从 0 至 hits 为 靛蓝。这样第一次击中hits变为1时点亮索引0的灯第二次击中hits变为2时点亮索引0和1的灯以此类推。非常符合直觉。 c.判断是否被击毁被击中后需要判断是否达到了致命一击比如10次。拖入另一个如果 为 真 则积木条件设置为hits 10或你设定的最大生命值。如果条件成立说明目标被摧毁了。 i.更新生命状态在内部如果中加入将 health 设为 0。 ii.触发摧毁效果加入设置所有像素颜色为 红色并将颜色改为红色。再加入播放音调 中音 C 持续 四分之一拍从“音乐”类别可以选择一个更有冲击力的音效比如“power down”关机音效直到播放完毕。这会给玩家一个明确的“目标已摧毁”的声光反馈。死亡状态下的处理否则分支如果health不等于1即health为0说明这个目标已经被摧毁了。那么它不应该再对红外信号做出任何“被击中”的反应。我们可以在这里什么都不做或者加一个简单的提示比如让所有LED闪烁一下红色表示“我已死亡别打了”。但为了简化我们可以留空。关闭接收指示LED在当红外接收到数据的最后别忘了加入数字写入 LED 至 假来熄灭那个红色LED表示一次接收处理完成。完善发射逻辑的条件现在我们需要回过头去修改发射逻辑。一个已经被摧毁health为0的目标应该不能开枪。所以在当 按钮 A 被按下的事件处理中最外层也应该套上一个如果 health 1 则的判断。只有生命值为1时才能执行点亮LED和发送红外信号的操作。否则按下按钮应无反应。这模拟了“阵亡后无法攻击”的游戏规则。3.4 代码整合与调试技巧将上述所有积木按逻辑拼接起来你的完整代码块就形成了。它应该包含当启动时初始化灯光和变量。当 按钮 A 被按下内含如果 health 1判断处理发射子弹。当红外接收到数据内含如果 health 1判断处理被击中、更新状态、判断死亡并触发特效。在烧录代码前有几点调试建议分步测试不要一次性写完所有逻辑。可以先测试红外收发是否正常。写一个最简单的程序A板按下按钮发送数字1B板收到数字1后点亮所有LED。确保基本的通信是通的。利用串口输出在MakeCode的“串口”类别中有串行写入行积木。你可以在关键节点如发送信号时、收到信号时、变量改变时输出调试信息到控制台这对于排查逻辑错误非常有用。灯光状态辅助除了游戏逻辑灯你可以用板载的红色LEDLED作为状态指示灯。例如开机常亮表示就绪快速闪烁表示正在发送慢速闪烁表示已死亡等。当你确认代码逻辑无误后用USB线连接第一块CPX点击MakeCode编辑器的“下载”将程序烧录进去。然后对第二块CPX重复此操作。现在两块板子都拥有了相同的、完整的游戏程序。4. 机械组装、供电与实战优化4.1 电源组装与固定代码准备就绪后我们来解决供电和“持握”的问题。安装电池为两个电池盒各装入三节AAA电池。注意正负极方向电池盒内部通常有清晰的标识。连接开发板将电池盒的JST-PH插头连接到CPX板边缘的电源接口。这个接口有防反插设计方向不对是插不进去的可以放心操作。开启电源打开电池盒上的开关。此时CPX板应该会自动启动NeoPixel灯环亮起白色表示程序已运行设备进入待机状态。固定组合电池盒和CPX板是分离的玩起来不方便。我们需要将它们固定在一起。有两种简单可靠的方法尼龙扎带这是最牢固的方式。找两根较短的尼龙扎带分别穿过CPX板上的两个大孔它们本身就是为固定设计的和电池盒上的固定孔或缝隙拉紧并剪掉多余部分。这样组合体非常结实耐用。双面泡沫胶如果想更轻便或可拆卸可以使用高粘性的双面泡沫胶如VHB胶带。剪一小块粘在电池盒和CPX板背面之间用力按压几秒钟即可。这种方式足够应对桌面把玩但剧烈奔跑时可能有脱落风险。现在你得到了两个独立的、由电池供电的“游戏单元”。每个单元既是枪也是靶。4.2 提升游戏体验制作“枪管”默认情况下CPX的红外发射管TX LED发出的光锥角度较宽在几米内很容易就能“击中”目标游戏缺乏挑战性。我们可以通过添加一个“枪管”来收窄光束这就像给手电筒加了一个聚光透镜会让光斑变小传播更远但也要求你瞄得更准。材料选择与制作吸管最易得的材料。黑色或不透明的吸管效果最好可以减少内部杂散反射。将吸管一端剪齐直接套在TX LED上。如果有点松用一点点橡皮泥蓝丁胶在内部固定一下。废旧圆珠笔或签字笔的笔芯/笔杆取出内部的笔芯和油墨剩下的透明塑料笔杆是非常理想的枪管材料。长度适中透光性好。用纸卷制用黑色卡纸或普通纸涂黑紧紧卷成细管用胶带固定。你可以通过调整卷的层数来控制内径使其刚好能套住LED。安装方法直接将准备好的管状物套在CPX板上标有“TX”的透明红外发射LED上。如果套不紧可以用一小块可塑橡皮Poster Putty也叫蓝丁胶在管子和板子之间粘一下。这种材料不残留胶痕可反复使用非常适合这种临时固定。注意事项枪管不宜过长5-10厘米足矣。过长反而可能因为轻微的晃动导致瞄准线偏离更大。确保枪管内壁干净无遮挡。安装后你可以对着另一块板子的红外接收窗RX进行测试会发现需要更精确的瞄准才能触发击中效果游戏乐趣大大提升。4.3 游戏规则扩展与实战技巧基础版本已经很有趣但你完全可以在此基础上定制自己的规则修改生命值在初始化时将health的初始值设为5或10并在接收逻辑中判断hits 5等条件来触发死亡。同时记得修改灯光反馈的逻辑比如用hits * 2来控制点亮的灯数让进度显示更合理。添加复活机制目前“阵亡”后需要手动复位按一下板子背面的复位按钮。你可以编程实现长按某个按钮比如按钮B来重置游戏状态在当 按钮 B 被按下事件中设置health为1hits为0并重置灯光为白色。团队模式与颜色编码如果你有超过两块板子可以设计团队战。例如为团队A的板子编程使其只响应“蓝色”子弹发送数字代表蓝色被击中后亮蓝灯团队B则响应“绿色”子弹。这样通过发射不同颜色的信号就能区分敌我实现多人大乱斗。增加声音多样性除了被击毁时的音效你还可以为每次被击中添加一个简短的“嘀”声为每次发射添加一个“啾”的音效让游戏反馈更丰富。MakeCode的音乐库提供了很多现成的音效和旋律。实战对战时的小技巧环境光干扰强烈的日光或某些LED灯可能包含红外成分偶尔会干扰接收。尽量在室内光线稳定的环境下游戏。瞄准要领红外光沿直线传播。瞄准时想象你手中的“枪管”需要射出一条直线对准对方板子上那个黑色的红外接收窗口RX。有了枪管后需要更精细的瞄准。距离测试在开阔地有效射程大约在3-5米。隔着手臂、薄衣服等障碍物信号可能会衰减或中断。复位同步一局结束后双方需要同时复位板子按下复位键或通过你编程的复位功能才能开始新的一局确保起点公平。5. 常见问题排查与进阶思路即使按照步骤操作也可能会遇到一些小问题。下面是一个快速排查指南问题现象可能原因解决方案按下按钮自己的板子没反应红灯不亮没声音1. 电池电量不足或开关未开。2. 程序未成功烧录。3. 按钮A损坏罕见。1. 检查电池盒开关更换新电池测试。2. 重新通过USB连接电脑在MakeCode中点击“下载”再次烧录程序观察烧录过程是否报错。3. 尝试按下按钮B如果你编程了的话或测试其他功能如摇晃板子触发加速度计事件来确认板子是否正常运行。按下按钮自己板子红灯亮但对方板子无反应1. 距离太远或未对准。2. 枪管遮挡了发射管。3. 对方板子已“死亡”health0。4. 红外通信受强光干扰。1. 拉近距离1米内测试确保发射管TX正对对方接收窗RX。2. 暂时取下枪管测试。3. 复位对方板子按复位键。4. 移动到光线较暗或无直射阳光的地方测试。对方板子偶尔会自己亮灯或触发音效环境中存在其他红外信号源如电视遥控器、空调遥控器等。这是正常现象。我们的程序只响应特定的数字编码如代表靛蓝色的数字其他遥控器的编码不同通常不会触发。如果频繁误触发可以尝试在代码中改变发送的数字换一个不常用的颜色代码。NeoPixel灯光显示不正常颜色错乱、不按顺序亮1. 灯光控制逻辑有误特别是索引计算。2. 程序逻辑冲突多个事件同时修改灯光状态。1. 回头检查设置像素颜色 从 0 至 hits这部分逻辑确保hits变量在每次击中后正确递增。可以在每次更改hits后用串行写入行打印出它的值来调试。2. 确保在当启动时和当红外接收到数据中对灯光的控制是唯一的没有其他循环或事件在同时改变灯光。音效不播放或播放异常1. 扬声器被意外静音板子上的滑动开关拨到了“静音”一端。2. 音效积木被放在了错误的分支或条件中。1. 检查CPX板边缘的滑动开关确保它不在“静音”位置。2. 确认播放音效的积木如播放声音 power down 直到结束确实被放在了“目标被摧毁”的条件分支如果 hits 10 则内部里。对于想要更进一步的玩家这个项目可以作为一个跳板转向文本编程尝试用CircuitPythonAdafruit基于Python的固件重写这个游戏。你会对红外通信的底层协议如NEC编码有更深理解并能实现更复杂的消息传递如发送字符串命令、玩家ID、伤害值等。加入传感器利用CPX上的加速度计实现“甩枪上膛”或“躲避动作”快速移动板子进入短暂无敌状态的体感操作。制作外观用3D打印或纸板为你的“枪”和“靶子”制作一个炫酷的外壳把它从一个开发板原型变成一个真正的玩具。这个项目的精髓在于它用最简单的硬件和直观的图形化编程构建了一个包含完整状态逻辑和交互反馈的嵌入式系统。当你成功实现第一次对战射击时那种亲手创造交互乐趣的成就感是任何现成玩具都无法比拟的。

相关新闻