基于TPYBoard与接近开关的金属检测仪DIY实战
2026/5/16 19:58:38 网站建设 项目流程

1. 项目概述:从零打造一个实用的金属检测仪

在嵌入式开发和物联网项目中,传感器信号的采集与处理是基础中的基础。今天,我想分享一个非常经典且实用的入门项目:使用TPYBoard开发板和LJ12A3-4-Z/BX金属接近开关,DIY一个功能完整的金属检测仪。这个项目看似简单,但它完美地串联了硬件接线、数字信号读取、逻辑判断和输出控制这几个嵌入式开发的核心环节。无论你是刚接触MicroPython的新手,还是想找一个可靠的案例来验证硬件交互逻辑,这个项目都能提供清晰的路径。

这个金属检测仪的核心原理,是利用接近开关检测金属物体,并将检测到的“有”或“无”金属的状态,转化为一个清晰的数字信号(0或1)发送给TPYBoard。开发板在接收到这个信号后,根据我们编写的程序逻辑,去控制一个LED灯的亮灭。你可以把它看作一个最小化的“感知-决策-执行”系统原型。通过这个项目,你不仅能学会如何让开发板“感知”外部世界,还能掌握如何让它基于感知结果做出“反应”,这是迈向更复杂自动化项目(如自动门、安防报警、产线分拣)的第一步。

2. 核心元器件选型与原理深度解析

2.1 主控板:为什么选择TPYBoard v102?

在这个项目中,我选择了TPYBoard v102作为主控核心。市面上能跑MicroPython的开发板不少,比如ESP32、Raspberry Pi Pico,为什么独选它呢?这背后有几个实际的考量。

首先,开发效率与语言友好性。TPYBoard v102基于STM32F405,原生支持MicroPython。对于嵌入式入门者或者快速原型开发来说,MicroPython比传统的C语言友好太多。你不需要搭建复杂的交叉编译环境,不用深究寄存器配置,直接用Python语法写几行代码,通过数据线拖拽就能运行,极大降低了学习和调试门槛。其次,引脚设计与电源管理。TPYBoard v102的引脚布局清晰,直接标明了“X”“Y”等组别,并且提供了多个VIN(5V输入)和3.3V输出引脚。我们的接近开关工作电压是6-36V DC,可以直接从开发板的VIN引脚取电,省去了额外准备电源的麻烦,让接线更加简洁。最后,社区与生态。虽然不如Arduino或ESP系列庞大,但TPYBoard有相对稳定的中文资料和社区支持,遇到基础问题更容易找到解决方案,这对于项目顺利推进很重要。

注意:务必确认你手中的是TPYBoard v102(或其他兼容型号)。不同版本(如v10x系列)的引脚定义可能有细微差别,代码中的“Y1”、“X1”等引脚名称需要根据实际板卡手册进行核对。

2.2 传感器:LJ12A3-4-Z/BX接近开关工作机制

金属检测的“眼睛”是LJ12A3-4-Z/BX这款电感式接近开关。理解它的工作原理,是正确使用和调试的基础。它内部核心是一个高频振荡电路,通过其前端的感应线圈产生一个交变电磁场。

没有金属物体靠近这个电磁场有效检测距离(本例型号为4mm)时,电路处于一种谐振状态,内部比较器输出高电平。此时,它的信号输出线(通常是黑线或蓝线,需以实物为准)会输出一个“1”(高电平,通常等于其供电电压)。当有金属物体(特别是铁、钢等磁性金属)进入检测范围时,金属内部会产生涡流效应,吸收掉振荡电路的能量,导致振荡减弱或停止。这个变化被内部电路捕获,触发器翻转,输出电平从“1”变为“0”(低电平,接近0V)。同时,传感器自带的红色LED指示灯会点亮,为我们提供直观的视觉反馈。

这里有几个关键点需要展开:

  1. 检测对象:这种电感式接近开关对导电良好的金属(尤其是铁磁性金属)最敏感。对于铜、铝等非铁磁性金属,其检测距离会显著缩短,甚至可能无法可靠触发。如果你的应用场景涉及多种金属,选型时需要特别注意传感器的说明。
  2. 输出类型:我们用的这款是NPN常开型(NO)。所谓“常开”,就是无金属时输出线内部是“断开”的(对外呈现高阻态,通过上拉电阻表现为高电平“1”),有金属时内部“闭合”到负极(输出低电平“0”)。这是最常见的类型,接线和理解逻辑都相对直观。
  3. 三线制接线:棕色线(或红色线)接电源正极(V+),蓝色线接电源负极(GND),黑色线(或白色线)为信号输出线。我们的接线图就是基于此。

2.3 其他辅助元件

  • 面包板:用于无需焊接的快速电路搭建和测试,是原型开发的神器。
  • 发光二极管(LED):作为执行单元,用于直观显示检测结果。需要串联一个约220Ω-1kΩ的限流电阻,防止电流过大烧坏LED或开发板IO口。本项目为了简化,直接使用了开发板IO口的驱动能力,对于普通小功率LED,短时间测试问题不大,但长期使用或驱动更大负载,务必加限流电阻
  • 杜邦线:连接各元器件的桥梁。建议准备多种颜色(红-电源正、黑-电源负、黄/绿-信号线),便于区分和检查。
  • USB数据线:为TPYBoard供电和程序下载。

3. 硬件电路搭建与接线实操详解

正确的硬件连接是项目成功的基石。任何一处接线错误都可能导致传感器不工作、开发板损坏,或者逻辑混乱。下面我将一步步拆解接线过程,并解释每一步背后的道理。

3.1 接线原理图与分步解析

虽然原文提到了接线,但我们可以更系统地规划。整个系统的电力流动和数据流动路径如下:

  1. 建立公共地(GND):这是所有电子电路的参考零点,必须首先确保所有GND连接在一起。将TPYBoard的任何一个“GND”引脚,用杜邦线连接到面包板的负电源轨上。同样,将接近开关的蓝色线(负极)也连接到这个负电源轨。这样就建立了统一的参考地。

  2. 为接近开关供电

    • 电源正极:将TPYBoard的“VIN”引脚(提供5V电压,来自USB)用杜邦线连接到面包板的正电源轨。
    • 传感器取电:将接近开关的棕色线(正极)连接到正电源轨。至此,接近开关获得了工作所需的电源(VIN -> 正极轨 -> 棕色线;GND -> 负极轨 -> 蓝色线)。上电后,传感器自身的电路开始工作。
  3. 信号线连接

    • 将接近开关的黑色线(信号输出)连接到TPYBoard的“Y1”引脚。Y1在这里被我们配置为输入(Input)模式,用于“侦听”传感器发送来的高电平“1”或低电平“0”。
    • 上拉电阻的考虑:NPN常开型传感器在无金属时,输出线内部是悬空的。为了防止这个悬空状态被TPYBoard的输入引脚误读为不确定的电平(可能引发误触发),我们需要在软件或硬件上确保一个确定的默认高电平。幸运的是,TPYBoard的Pin对象在初始化Pin.IN模式时,可以启用内部上拉电阻。我们在代码中会通过Pin(‘Y1’, Pin.IN, Pin.PULL_UP)来实现,这样在物理上,就相当于在Y1引脚和3.3V之间连接了一个电阻,将悬空状态“拉”成了高电平。这是数字输入电路中一个非常重要且常见的抗干扰措施。
  4. 输出控制线连接

    • 将LED的正极(长脚)通过一个220Ω的限流电阻连接到TPYBoard的“X1”引脚。X1在这里被配置为推挽输出(Pin.OUT_PP)模式,具有较强的驱动能力,可以直接输出高电平(3.3V)点亮LED,或输出低电平(0V)熄灭LED。
    • 将LED的负极(短脚)连接到面包板的负电源轨(GND)。

3.2 接线完成后的检查清单

在通电前,花一分钟按照下表逐项检查,可以避免绝大多数硬件故障:

检查项目正确连接错误后果
电源极性接近开关棕线(+)接VIN/正轨,蓝线(-)接GND/负轨接反可能永久损坏传感器
信号线接近开关黑线接TPYBoard Y1无法读取信号
LED极性LED长脚(正)通过电阻接X1,短脚(负)接GNDLED不亮或损坏
共地TPYBoard GND、面包板负轨、传感器蓝线、LED短脚全部连通电路不工作,电平参考混乱
限流电阻LED回路中串联了电阻(强烈建议)可能烧毁LED或过载损坏X1引脚

4. 软件程序设计:从简单循环到稳健应用

硬件准备就绪后,我们让系统“活”起来的任务就交给了软件。下面我们来深入剖析代码,并探讨如何让它更健壮、更实用。

4.1 基础代码逐行解读

我们先看原文提供的核心代码,并加入详细注释:

# main.py -- 金属检测仪主程序 import pyb from machine import Pin # 1. 初始化引脚 # 将Y1引脚初始化为输入模式,并启用内部上拉电阻。 # Pin.PULL_UP是关键,它为悬空的NPN传感器输出提供了一个默认的高电平。 y1 = Pin('Y1', Pin.IN, Pin.PULL_UP) # 将X1引脚初始化为推挽输出模式,用于驱动LED。 x1 = Pin('X1', Pin.OUT_PP) # 2. 主循环 while True: # 使用 True 比 1 更符合Python习惯 # 无金属时:传感器输出高电平(1),内部上拉使其稳定为1 if y1.value() == 1: # 打印当前状态到串口终端,用于调试 print("No metal detected. Signal: ", y1.value()) # 控制LED熄灭:输出低电平(0) x1.value(0) # 有金属时:传感器输出低电平(0),将Y1引脚拉低 else: # 打印检测到金属的状态 print("Metal Detected! Signal: ", y1.value()) # 控制LED点亮:输出高电平(1) x1.value(1) # 可选:增加一个短暂的延时,降低CPU占用率,稳定读取。 # pyb.delay(50) # 延时50毫秒

代码逻辑流:程序上电后,进入while True死循环。在每一轮循环中,它都会执行以下操作:

  1. 读取:通过y1.value()函数,读取Y1引脚当前的电压状态,并将其转化为数字值1(高,约3.3V)或0(低,约0V)。
  2. 判断:使用if-else语句判断这个值。如果等于1,说明传感器没有检测到金属;如果不等于1(即等于0),说明检测到了金属。
  3. 执行:根据判断结果,通过x1.value()函数,向X1引脚写入相应的电平(0或1),从而控制LED的熄灭或点亮。
  4. 反馈:通过print语句将状态打印到串行终端(如PuTTY、Thonny),方便开发者实时监控系统状态,这是调试过程中极其重要的一环。

4.2 进阶优化:增加去抖动与状态指示

基础代码可以工作,但在实际应用中,传感器信号可能会因为机械振动、电磁干扰而产生瞬间的抖动,导致LED快速闪烁,逻辑不稳定。我们需要引入软件去抖动

# main.py -- 增强版金属检测仪程序(带去抖动) import pyb from machine import Pin y1 = Pin('Y1', Pin.IN, Pin.PULL_UP) x1 = Pin('X1', Pin.OUT_PP) # 状态变量,记录上一次稳定的检测结果 last_stable_state = y1.value() current_state = last_stable_state # 去抖动计时器相关变量 debounce_time = 0 DEBOUNCE_DELAY_MS = 30 # 去抖动延时,通常20-50ms print("Metal Detector Started. Initial state:", last_stable_state) while True: # 读取当前瞬时状态 reading = y1.value() current_time = pyb.millis() # 获取当前运行时间(毫秒) # 去抖动逻辑核心 if reading != current_state: # 状态发生变化,重置去抖动计时器 debounce_time = current_time current_state = reading # 如果状态变化持续了一段时间(超过去抖动延时) if (current_time - debounce_time) > DEBOUNCE_DELAY_MS: # 并且这个持续后的状态与上次记录的不同 if current_state != last_stable_state: last_stable_state = current_state # 更新稳定状态 # 根据新的稳定状态执行动作 if last_stable_state == 1: print("Stable State: No Metal.") x1.value(0) # 关LED else: print("Stable State: Metal Detected!") x1.value(1) # 开LED # 主循环延时,降低CPU负载 pyb.delay(10)

优化点解析

  1. 去抖动:这是最关键的改进。它通过一个时间窗口(DEBOUNCE_DELAY_MS)来过滤掉短时间内的信号抖动。只有当信号状态保持稳定超过这个时间(如30ms),才被认为是有效的状态变化,并更新输出。这能有效防止因干扰导致的误动作。
  2. 状态变量:使用last_stable_state记录上一次确认的稳定状态,避免在状态未真正改变时重复执行操作和打印信息。
  3. 时间函数pyb.millis()返回系统上电后的毫秒数,是进行非阻塞延时和计时的基础。
  4. 降低CPU占用:循环末尾的pyb.delay(10)让每次循环间隔10ms,既保证了响应速度,又大幅降低了处理器负载。

4.3 如何将程序烧录到TPYBoard

  1. 连接开发板:用USB线将TPYBoard连接到电脑。电脑会将其识别为一个U盘(名为“PYBFLASH”)。
  2. 编辑代码:使用任何文本编辑器(如VS Code、Notepad++)或专用的MicroPython IDE(如Thonny),将上述优化后的代码保存为main.py文件。注意:TPYBoard上电后会自动执行根目录下的main.pyboot.py文件。
  3. 上传文件:将保存好的main.py文件,直接复制或拖拽到“PYBFLASH”这个U盘盘中。
  4. 复位运行:按下TPYBoard上的复位键(RST),或者重新拔插USB线。程序将自动开始运行。
  5. 查看输出:要查看print()的调试信息,你需要一个串口终端工具。可以使用Thonny(内置REPL),或者独立的串口工具(如PuTTY、MobaXterm)。在设备管理器中找到TPYBoard对应的串口号(如COM3),在终端软件中设置相同的波特率(通常是115200),即可看到实时打印的检测状态信息。

5. 系统调试与功能扩展思路

5.1 上电调试与常见问题排查

即使按照指南操作,第一次也可能遇到问题。别担心,这是学习过程的一部分。请按照以下流程排查:

现象可能原因排查步骤与解决方案
LED常亮或不亮1. LED或电阻接反/接触不良。
2. 代码中输出逻辑写反。
3. X1引脚损坏。
1. 断电,用万用表通断档检查LED回路。
2. 在代码中手动测试:添加x1.value(1)x1.value(0)看LED是否响应。
3. 换一个IO口(如X2)试试。
传感器无反应(指示灯不亮)1. 电源接反或未接通。
2. 传感器检测距离不足或金属类型不对。
3. 传感器损坏。
1. 用万用表测量接近开关棕-蓝线间电压,应为5V左右。
2. 用一块铁质物体,在传感器感应面4mm内缓慢移动观察。
3. 更换一个已知良好的传感器测试。
串口无输出/乱码1. 串口号选择错误。
2. 波特率设置错误。
3. 代码中print未执行。
1. 确认设备管理器中的正确COM口。
2. 将终端波特率设置为115200再试。
3. 在代码开头加一句print(“Start”)测试。
逻辑混乱(有金属时LED灭)1. 传感器输出类型判断错误(NPN常开/常闭)。
2. 代码中if-else判断条件写反。
1. 用万用表测量有/无金属时,传感器黑线对GND电压,确认是“1->0”还是“0->1”。
2. 根据实测结果,调整代码中的判断逻辑。
响应不稳定(LED闪烁)1. 信号干扰。
2. 机械振动导致距离微变。
3. 未使用去抖动程序。
1. 确保信号线(黑线)不要与电源线长距离平行捆扎。
2. 固定好传感器和被测物体。
3.务必使用带去抖动的代码

5.2 项目功能扩展与进阶玩法

基础功能实现后,这个平台可以轻松扩展,变身成更有趣、更实用的装置:

  1. 声光报警器:除了LED,可以连接一个蜂鸣器。当检测到金属时,让LED闪烁的同时蜂鸣器鸣叫,增强警示效果。
  2. 计数器与数据记录:在代码中增加一个计数器变量。每次从“无金属”状态变为“有金属”状态时,计数器加1,并通过串口或OLED屏幕显示累计检测次数。这可以用于简单的产线零件计数。
  3. 联网上报:如果使用支持Wi-Fi的TPYBoard型号(或外接ESP-01s模块),可以将检测到金属的事件通过MQTT协议发送到云平台(如阿里云、ThingsBoard),实现远程手机报警或数据统计。
  4. 区分金属类型(进阶):单个电感式传感器很难区分金属类型。但可以尝试使用两个不同检测频率的传感器,或者结合电容式传感器,通过检测信号强度或变化模式的不同来进行粗略分类,但这需要更复杂的信号处理和标定。
  5. 机械联动:用TPYBoard控制一个继电器模块,当检测到金属时,继电器吸合,可以控制一个真正的自动门电机、电磁铁或报警器电源,将数字信号转化为真实的物理动作。

这个DIY金属检测仪项目,从硬件连接到软件编程,再到调试优化,完整地走通了一个嵌入式感知控制系统的闭环。它麻雀虽小,五脏俱全。最关键的是,你通过亲手实践,理解了数字信号“0”和“1”如何从物理世界中被感知、传递,并最终驱动另一个设备产生动作。这个“感知-决策-执行”的框架,是自动化领域无数应用的基石。希望你在成功点亮LED之后,能沿着这些扩展思路继续探索,把它改造成属于你自己的、更强大的工具。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询