1. 项目概述:从“捕杀”到“捕捉”的智能人道主义方案
家里闹老鼠,这事儿估计不少朋友都遇到过。传统的老鼠夹、粘鼠板,要么血腥,要么残忍,处理起来也麻烦。作为一个常年鼓捣Arduino和各种传感器的电子爱好者,我一直在想,能不能用技术手段做一个更“文明”的解决方案?既能解决问题,又不对这些小生命造成伤害。于是,就有了这个基于Arduino和超声波传感器的智能捕鼠器项目。
这个项目的核心思路很简单:用一个容器作为陷阱,入口处安装超声波传感器实时监测。当老鼠被容器内的诱饵吸引,进入探测范围时,Arduino会立刻驱动一个微型舵机,触发一个巧妙的机械机构,瞬间关闭容器盖子,实现无害捕捉。之后,你可以轻松地把容器拿到野外放生。整个系统成本低廉,主要部件就是Arduino Nano、一个HC-SR04超声波传感器和一个微型舵机,其他都是生活中常见的材料,比如塑料罐、橡皮筋、小木块等。
它不仅是一个实用的家庭小工具,更是一个绝佳的嵌入式系统学习项目。你将从中学到传感器数据采集、微控制器逻辑判断、执行机构(舵机)控制以及简单的机械结构设计,完整地走通一个物联网设备的“感知-决策-执行”闭环。无论你是想解决实际问题,还是想找个有趣的练手项目,这个DIY捕鼠器都值得一试。
2. 核心硬件选型与电路设计解析
2.1 主控与传感器:为什么是Arduino Nano和HC-SR04?
选择Arduino Nano作为大脑,几乎是所有入门级嵌入式项目的首选。原因有三:第一,尺寸小巧,非常适合这种需要塞进有限空间的项目;第二,拥有足够的I/O口(本例仅需3个数字口),且自带USB转串口芯片,编程调试极其方便;第三,社区资源庞大,任何问题几乎都能找到答案。相较于UNO,Nano在保持性能的同时体积更优;相较于更小的ATTiny系列,Nano的开发便利性和功能完整性又胜出一筹。
传感器方面,HC-SR04超声波模块是性价比之王。它的工作原理是经典的“渡越时间法”:触发引脚(Trig)收到一个至少10微秒的高电平脉冲后,模块会自动发射8个40kHz的超声波脉冲,并检测回波。当接收到回波时,回声引脚(Echo)会输出一个高电平,其持续时间与超声波往返时间成正比。我们通过Arduino测量这个高电平的持续时间t(单位微秒),已知声速v在空气中约为340米/秒(受温湿度影响,但室内应用误差可接受),那么距离d的计算公式为:d = (v * t) / 2。由于v约为340m/s = 0.034 cm/μs,所以公式可简化为d = t * 0.034 / 2 = t * 0.017(单位厘米)。HC-SR04的探测距离在2cm到400cm之间,精度可达3mm,对于检测老鼠是否“进门”绰绰有余。
注意:HC-SR04的测量角度约为15度,属于小角度探测。在安装时,要确保其探测锥形区域能完整覆盖容器入口的内部空间,避免出现探测死角让老鼠“溜边”进去却没触发。
2.2 执行机构:微型舵机的选择与控制逻辑
执行关闭动作,我选择了常见的9克微型舵机(塑料齿轮)。为什么不直接用继电器控制电磁铁或电机?主要考虑的是可控的运动轨迹和保持力。舵机可以精确地旋转到一个特定角度(本例中可能是0度和90度两个位置),并且能在不通电的情况下,通过机械结构保持位置(尤其是带有塑料齿轮组有一定自锁性),这对于“锁定”关闭状态至关重要。而普通直流电机需要额外的限位开关和复杂的控制电路才能实现同样效果。
舵机有三根线:电源(Vcc,通常红色)、地线(GND,通常棕色或黑色)和信号线(Signal,通常橙色或黄色)。控制原理是通过信号线发送脉冲宽度调制(PWM)信号。脉冲的高电平持续时间通常在1ms到2ms之间,对应着舵机输出轴0度到180度的位置(不同品牌略有差异)。Arduino的Servo库帮我们封装了这些细节,我们只需调用servo.write(angle)函数即可。
在本项目中,舵机的初始位置是“待发”状态,连接着一根触发用的钢丝。当超声波传感器检测到目标进入,Arduino立即命令舵机快速转动到一个预定角度,这个动作会拉动或释放与之相连的机械触发机构,从而在橡皮筋的拉力下瞬间关闭盖子。
2.3 电路连接与供电方案
电路连接非常简单,遵循“先电源后信号”的原则。以下是接线明细表:
| 元件 | 引脚 | 连接至 Arduino Nano 引脚 | 说明 |
|---|---|---|---|
| HC-SR04 | Vcc | 5V | 超声波传感器电源 |
| HC-SR04 | Trig | D2 | 触发控制信号 |
| HC-SR04 | Echo | D3 | 回波接收信号 |
| HC-SR04 | Gnd | GND | 公共地 |
| 微型舵机 | Vcc (红) | 5V | 注意:需评估电流 |
| 微型舵机 | GND (棕/黑) | GND | 公共地 |
| 微型舵机 | Signal (橙/黄) | D9 | PWM控制信号 |
整个系统的耗电大户是舵机。微型舵机在空载静止时电流很小(约10mA),但在转动瞬间,特别是遇到阻力时,电流可能飙升至200-500mA。而Arduino Nano的板载5V稳压芯片,其输出能力有限(通常约500mA)。如果同时为传感器、Arduino和舵机供电,在舵机动作瞬间可能导致电压骤降,引起Arduino复位。
实操心得:供电的坑我踩过。最初我用一个旧的手机充电器(5V1A)通过Nano的Vin引脚供电,测试时一切正常。但当我将整个系统装入容器并连续测试触发时,偶尔会出现系统重启。用万用表监测5V引脚电压发现,舵机动作瞬间电压会跌至4.5V以下。解决方案有两个:一是使用输出能力更强的5V电源(如2A以上的电源适配器或充电宝);二是采用外部供电方案,即电源正极同时接入Nano的Vin和舵机的Vcc,电源负极同时接两者的GND,让大电流不经过Nano板载稳压器。
对于移动使用场景,一个常见的20000mAh充电宝足以让这个系统连续工作数周。建议选择带开关的充电宝,或者制作一个简单的电源开关,方便在不使用时彻底断电。
3. 机械结构设计与组装要点
3.1 陷阱容器的选择与改造
容器是整个装置的物理基础,其选择至关重要。原文使用了方形塑料巧克力罐,这是一个非常好的选择。为什么是方形而不是圆形?原因在于安装的便利性与结构的稳定性。方形容器的平面侧面便于固定传感器支架、舵机座和作为结构加强筋的小木块。圆形容器曲面不易粘合,且内部机构布局困难。
改造第一步是制作入口。在容器一侧靠近底部的位置,切割出一个足够老鼠进入的开口。尺寸建议:高约5-6厘米,宽约4-5厘米。开口边缘务必用砂纸打磨光滑,防止划伤老鼠或钩住诱饵。一个关键技巧:在开口内侧上方,用热熔胶固定一个小“门檐”,这可以防止老鼠轻易从内部顶开盖子逃脱。
容器的盖子需要改造为活动翻盖。你需要确定盖子的旋转轴心。可以在容器口两侧钻孔,插入一根坚固的钢丝或竹签作为转轴。更简单的方法是,直接利用容器原有的铰链结构(如果有),或者用强力胶布在背面制作一个柔性铰链。
3.2 触发与闭锁机构详解
这是项目的机械核心,其可靠性直接决定捕鼠成功率。整个机构可以分解为“蓄能”、“触发”和“释放”三部分。
蓄能机构:由橡皮筋提供动力。在盖子处于打开状态时,橡皮筋处于拉伸状态,储存了弹性势能。你需要计算橡皮筋的拉力。拉力太小,盖子关闭速度慢、力量弱,老鼠可能逃脱;拉力太大,对触发机构的强度和精度要求极高。经过测试,使用2-3根普通的办公用橡皮筋(串联或并联)提供的拉力较为合适。将橡皮筋一端固定在容器底部附近,另一端连接在盖子远离转轴的一端。
触发机构:这是连接电子系统(舵机)和机械系统(盖子)的桥梁。原文使用了“笔杆+钢丝”的巧妙设计。具体做法:
- 取一支废旧圆珠笔的笔芯(塑料管),将其一端用热熔胶垂直固定在打开的盖子上。
- 剪一段约3-4厘米的结实钢丝(如回形针拉直),将其一端弯成一个小钩。
- 将钢丝的另一端用热熔胶或AB胶牢牢固定在微型舵机的舵盘(舵机摇臂)上。
- 在容器主体上,位于笔杆正下方,安装一个“触发钩”。这个钩子可以用另一段钢丝弯成,并固定在小木块上。它的作用是钩住笔杆,使盖子克服橡皮筋拉力保持打开。
- 最后,用一根细线或橡皮筋,连接笔杆顶端和舵机钢丝上的小钩。此时,系统处于待触发状态:笔杆被触发钩扣住,盖子打开;舵机钢丝钩与笔杆上的线连接。
释放机制:当超声波传感器检测到老鼠进入,Arduino驱动舵机快速旋转一个角度(例如90度)。舵盘转动,拉动钢丝钩,钢丝钩通过细线拉扯笔杆。笔杆受到侧向力后,从触发钩上脱扣。此时,蓄能的橡皮筋瞬间释放,拉动盖子迅猛关闭。舵机的这个动作行程很小,但力量集中,足以实现可靠的脱扣。
注意事项:机械调试是成败关键。组装好后,务必手动模拟触发数十次。重点观察:1. 笔杆与触发钩的扣合是否紧密,轻微震动是否会意外脱扣?2. 脱扣过程是否顺畅,有无卡滞?3. 盖子关闭后是否严丝合缝?4. 舵机拉动的力度和方向是否最优?你可能需要反复调整钢丝钩的形状、笔杆的长度、细线的连接点,甚至橡皮筋的拉力。这是一个需要耐心和细心的过程。
3.3 电子部分的安装与防护
将焊好线的迷你面包板、Arduino Nano和连接好的传感器用热熔胶或尼龙扎带固定在那块作为加强筋/安装板的小木块上。安装超声波传感器时,确保其探测面正对容器内部,且前方无遮挡。可以考虑用乐高积木块或3D打印一个小支架来调整传感器的角度和高度,使其探测波束中心对准陷阱中央。
关于防护:老鼠有啃咬电线的习性。所有裸露的导线,特别是传感器和舵机的连接线,在穿过容器内部空间时,最好用螺旋护套管或简单的吸管套一下,或者用热熔胶将线缆固定在容器壁高处它们难以触及的位置。虽然这不是绝对防护,但能大大降低风险。
4. Arduino程序代码深度剖析
代码的逻辑并不复杂,但细节决定稳定性。下面我们逐段分析一个增强版的代码,它包含了防误触发和状态指示功能。
#include <Servo.h> // 引入舵机库 // 引脚定义 const int trigPin = 2; const int echoPin = 3; const int servoPin = 9; const int ledPin = 13; // 使用板载LED作为状态指示 // 参数设置 const int detectionDistance = 10; // 触发距离,单位厘米。根据容器大小调整,通常设为入口深度的一半。 const unsigned long trapDelay = 3000; // 触发后,等待盖子完全关闭再复位的时间(毫秒) const int servoOpenAngle = 0; // 舵机“待发”角度 const int servoCloseAngle = 90; // 舵机“触发”角度 // 变量声明 Servo myServo; long duration; int distance; bool isArmed = true; // 陷阱是否处于“布防”状态 void setup() { Serial.begin(9600); // 初始化串口,用于调试输出距离值 pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(ledPin, OUTPUT); myServo.attach(servoPin); myServo.write(servoOpenAngle); // 初始化舵机位置 delay(500); // 给舵机时间归位 digitalWrite(ledPin, HIGH); // 布防状态,LED常亮 Serial.println("Trap Armed and Ready!"); } void loop() { if (isArmed) { // 1. 发射超声波脉冲 digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); // 持续10微秒的高电平触发信号 digitalWrite(trigPin, LOW); // 2. 测量回波高电平持续时间 duration = pulseIn(echoPin, HIGH, 30000); // 设置超时30ms,对应约5米距离 // 3. 计算距离 distance = duration * 0.034 / 2; // 单位:厘米 // 4. 调试输出(可注释掉) Serial.print("Distance: "); Serial.print(distance); Serial.println(" cm"); // 5. 逻辑判断:如果检测到物体距离小于设定值 if (distance > 0 && distance < detectionDistance) { // 距离>0用于过滤无效读数 triggerTrap(); } delay(50); // 每次测量间隔50ms,避免信号相互干扰 } } void triggerTrap() { Serial.println("Target Detected! Triggering..."); isArmed = false; // 进入“已触发”状态,防止连续触发 digitalWrite(ledPin, LOW); // LED熄灭,表示已触发 // 驱动舵机执行触发动作 myServo.write(servoCloseAngle); delay(500); // 确保舵机动作完成 Serial.println("Trap Closed. Waiting for reset."); delay(trapDelay); // 等待一段时间,让盖子稳定关闭,也模拟处理时间 // 此处可以添加其他功能,如蜂鸣器报警 // tone(buzzerPin, 1000, 2000); // 在实际应用中,这里不会自动复位。需要人工处理老鼠后,手动复位系统和机构。 // 为了方便测试,我们添加一个手动复位模拟(通过串口发送命令) // waitForManualReset(); } // 用于测试的串口复位函数 void waitForManualReset() { Serial.println("Send 'r' to rearm the trap."); while (!Serial.available()) { // 等待串口输入 } char command = Serial.read(); if (command == 'r' || command == 'R') { myServo.write(servoOpenAngle); delay(500); isArmed = true; digitalWrite(ledPin, HIGH); Serial.println("Trap Rearmed!"); } }代码关键点解析:
- 防抖与滤波:超声波传感器在复杂环境中可能产生偶然的误读数(比如灰尘、气流)。代码中通过两个措施增强可靠性:一是设置
distance > 0的条件,过滤掉因超时返回0的无效数据;二是可以扩展代码,例如采用连续三次测量中有两次满足条件才触发的中值滤波法,进一步抗干扰。 - 状态管理:引入
isArmed布尔变量至关重要。一旦触发,立即将其设为false,防止在盖子关闭过程中,因为老鼠挣扎或传感器再次探测到静止目标而反复动作,导致机构紊乱。 - 参数可调:
detectionDistance和trapDelay作为常量定义在开头,方便根据实际容器尺寸和机械动作时间进行微调,无需深入修改逻辑代码。 - 调试支持:利用串口输出实时距离信息,是调试传感器位置和触发阈值的利器。板载LED的状态指示也能直观反映系统是处于布防还是已触发状态。
5. 系统调试、优化与实战部署
5.1 分阶段调试流程
不要一次性组装完再测试,应分阶段验证:
- 电子单元测试:仅连接Arduino、传感器和舵机(不连接机械部分)。上传一个简单的测试程序,让串口打印距离值,同时用手在传感器前移动,观察数值变化是否灵敏、连续。然后让程序在探测到物体时控制舵机转动,观察舵机反应是否迅速、准确。
- 机械机构空载测试:在不安装电子部分的情况下,手动设置触发机构,测试盖子关闭的力度、速度和可靠性。反复测试脱扣的灵敏度。
- 机电联合空载测试:将电子部分和机械部分连接,但容器内不放诱饵。用手或一根棍子模拟老鼠进入,测试整个自动触发-关闭流程是否顺畅。重点观察舵机动作能否可靠地导致机构脱扣。
- 负载测试:在容器内放置一个重量和老鼠相当的物体(如一小袋沙子),再次进行触发测试,确保关闭力度足以克服轻微阻力。
5.2 常见问题与排查技巧
在实际制作和调试中,你可能会遇到以下问题:
| 问题现象 | 可能原因 | 排查与解决思路 |
|---|---|---|
| 传感器读数不稳定或为0 | 1. 接线错误或接触不良 2. 电源电压不足 3. 传感器前方有吸音材料(如软布) 4. 测量周期太快,上次回波干扰 | 1. 用万用表检查Vcc电压是否稳定在5V,重新插接杜邦线。 2. 尝试单独为传感器供电。 3. 确保探测路径开阔,表面坚硬。 4. 在 loop()中增加delay(50)以上。 |
| 舵机不转动或抖动 | 1. 电源功率不足(最常见) 2. 信号线接触不良 3. 机械负载过重卡死 | 1.首要检查:用外接5V2A电源单独给舵机供电测试。 2. 检查信号线是否连接到支持PWM的引脚(如D9)。 3. 断开舵机与机械机构的连接,空载测试是否正常。 |
| 机构偶尔无法触发 | 1. 触发钩与笔杆扣合太紧或太松 2. 舵机拉力不足或行程不对 3. 橡皮筋拉力过大 | 1. 精细调整触发钩的角度和笔杆的接触点,保证扣合稳定且脱扣顺滑。 2. 调整舵机钢丝钩的长度和角度,优化力臂。 3. 减少橡皮筋数量或更换弹性系数小的橡皮筋。 |
| 盖子关闭不严或反弹 | 1. 橡皮筋拉力不够 2. 转轴摩擦力大 3. 盖子重心或形状导致闭合不畅 | 1. 增加橡皮筋或更换更粗的橡皮筋。 2. 在转轴处涂抹少许润滑油。 3. 在盖子边缘粘贴一圈软橡胶条,既能密封又能缓冲。 |
| 误触发(没老鼠也关) | 1. 探测距离设得太远 2. 传感器被飘动的窗帘、昆虫等干扰 3. 代码逻辑无防抖 | 1. 适当减小detectionDistance,确保只探测容器最内部区域。2. 调整传感器角度,避开外部移动物体。或为传感器加装纸筒,限制探测视野。 3. 在代码中加入软件滤波(如前文提到的多次判断)。 |
5.3 实战部署与人性化考量
调试成功后,就可以部署了。选择老鼠可能活动的路径,如墙角、橱柜边。容器内部放置强有力的诱饵,花生酱、坚果、培根油是经典选择,气味浓郁且不易被一下子叼走。
一个重要的人道主义细节:捕捉到老鼠后,应尽快处理。长时间困在狭小空间会导致老鼠极度紧张甚至死亡。准备一个厚实的袋子或另一个容器,在野外或无人的地方轻轻将其释放。考虑到动物福利,可以在陷阱容器内预先放一点吸水材料(如棉花球)和一小块苹果,提供一点水分。
这个项目最大的乐趣在于,它完美地结合了软件、硬件和机械。当你看到自己设计的系统成功完成一次自动捕捉时,那种成就感是纯粹的。它不仅仅是一个捕鼠工具,更是一个关于如何用温和的技术解决问题的生动案例。希望你在制作过程中,不仅能收获一个实用的小装置,更能享受到创造和解决问题的乐趣。