基于Arduino Nano与TB6612FNG的超声波驱鸟装置设计与实现

发布时间:2026/9/20 11:24:08
基于Arduino Nano与TB6612FNG的超声波驱鸟装置设计与实现 1. 项目缘起与整体设计思路1.1 为什么要做一台超声波驱鸟装置住在城郊或者农村的朋友大概都有这个体会春天播下去的种子刚冒出嫩芽就被一群麻雀、喜鹊盯上了。你前脚走它们后脚就落下来啄得那叫一个干净。传统的稻草人、反光彩带、驱鸟剂刚开始还有点用过不了几天鸟就适应了该来还是来。打又不能打药又不能药确实挺头疼。我自家后院有一小片菜地种了点玉米和向日葵连续两年被鸟祸害得几乎绝收。后来琢磨着能不能用电子手段解决这个问题。查了一圈资料发现超声波驱鸟是一个相对成熟且对人和环境都比较友好的思路。它的原理并不复杂鸟类对特定频段的高频声波通常在15kHz到25kHz之间比较敏感会感到不适从而主动远离。而人耳对20kHz以上的声音基本听不见所以不会影响日常生活。这个项目我打算分几个部分来做Part 1主要解决的是核心控制板选型、电机驱动方案以及超声波发射模块的基础搭建。说白了就是先把“大脑”和“肌肉”搭起来让整个系统能跑通后面再逐步加入传感器、智能触发逻辑和外壳设计。1.2 核心器件选型为什么是Arduino Nano加TB6612FNG选主控板这件事我纠结了挺久。市面上的选择无非就是那么几种Arduino Uno、Arduino Nano、ESP32、STM32。最后我选了Arduino Nano原因有这么几个。第一是体积。驱鸟装置最终是要放到户外的体积越小越好布置。Nano比Uno小了不止一圈而且可以直接插在面包板上接线方便。第二是成本。Nano的国产兼容板价格非常便宜即使户外环境恶劣坏了也不心疼。第三是生态。Arduino IDE对新手极其友好库资源丰富ATmega328P这颗芯片虽然老但胜在稳定可靠资料铺天盖地遇到问题随便一搜就有答案。电机驱动这块我选了TB6612FNG。可能有人会问驱动一个小电机用L298N不就行了便宜又常见。但L298N有个致命缺点发热大、效率低。它是双极型晶体管工艺导通压降大驱动小电机的时候还好一旦电流上去那个散热片烫得能煎鸡蛋。TB6612FNG用的是MOSFET工艺导通电阻小效率高发热低而且体积只有L298N模块的三分之一左右。虽然价格贵一点点但对于户外设备来说稳定性和功耗才是第一位的。提示TB6612FNG的连续输出电流是1.2A峰值3.2A驱动小功率直流电机或者步进电机完全够用。如果你要驱动大功率电机这个方案就不合适了得换更大电流的驱动芯片。1.3 系统整体架构与工作流程整个系统的架构其实不复杂我画个简单的思路给大家捋一下控制核心Arduino Nano负责整个逻辑调度包括超声波发射的时序控制、电机转向控制、后续传感器数据的读取和处理。电机驱动TB6612FNG接收Nano发出的PWM信号和方向信号驱动一个直流电机或者步进电机用来带动超声波换能器做旋转扫描实现全方向覆盖。超声波发射模块由Nano直接产生方波信号经过简单的驱动电路放大后推动超声波换能器发声。供电部分户外使用的话我打算用18650锂电池组供电配合降压模块给Nano和TB6612FNG分别提供5V和电机所需的电压。工作流程大致是这样的Nano上电后先初始化各个引脚和定时器然后进入主循环。主循环里它一边控制电机缓慢旋转一边以间歇方式发射超声波脉冲。为什么要间歇发射因为持续发射不仅费电而且鸟类容易适应。间歇性的、频率变化的超声波驱赶效果会好很多。2. 核心细节解析与实操要点2.1 Arduino Nano的引脚分配与注意事项Arduino Nano虽然小但引脚该有的都有。ATmega328P这颗芯片有14个数字IO口和8个模拟输入口对于这个项目来说绰绰有余。不过在实际接线之前有几个坑我得先给大家指出来。首先是PWM引脚。Nano上标记为PWM的引脚是D3、D5、D6、D9、D10、D11。其中D3和D11由Timer2控制D5和D6由Timer0控制D9和D10由Timer1控制。这里有个关键点Timer0是Arduino内部用来做毫秒计时和串口通信的如果你动了Timer0的配置millis()和delay()函数就会出问题。所以我在这个项目里PWM输出尽量用D9和D10它们由Timer1控制不影响系统计时。其次是超声波频率的产生。要产生40kHz的方波用tone()函数是最简单的办法。但tone()函数本身也是基于定时器的它默认使用Timer2。如果你同时要用Timer2做PWM输出就会冲突。我的做法是超声波发射用tone()函数电机PWM用Timer1的D9和D10这样互不干扰。再一个是电源引脚。Nano的VIN引脚可以接受7-12V的输入电压板载的AMS1117稳压芯片会把它降到5V。但AMS1117的压差比较大输入电压如果接近7V输出可能不太稳定。我建议户外供电的话直接用降压模块降到5V然后从Nano的5V引脚输入这样更可靠。注意千万不要同时从VIN和USB口供电虽然Nano有保护电路但长期这样用对板子不好。调试的时候用USB部署的时候用电池养成好习惯。2.2 TB6612FNG的接线逻辑与真值表TB6612FNG模块的引脚不算多但第一次用的人容易搞混。我把它的核心引脚和功能列个表大家对着接线就不会错了。引脚名称功能说明接Nano的哪个脚VM电机供电正极接电池正极3-13.5VVCC逻辑供电正极接Nano的5VGND公共地接Nano的GND和电池负极STBY待机控制接Nano的D4高电平工作AIN1电机A方向控制1接Nano的D7AIN2电机A方向控制2接Nano的D8PWMA电机A速度控制接Nano的D9BIN1电机B方向控制1接Nano的D12BIN2电机B方向控制2接Nano的D13PWMB电机B速度控制接Nano的D10AO1/AO2电机A输出接电机A的两根线BO1/BO2电机B输出接电机B的两根线TB6612FNG的控制逻辑其实很简单记住一个真值表就行AIN1AIN2PWMA电机状态00X刹车短路制动10PWM正转01PWM反转11X刹车短路制动XX0停止自由滑行这里有个细节STBY引脚必须拉高模块才会工作。很多人第一次用的时候忘了接这个脚然后纳闷为什么电机不转。我建议直接把STBY接到Nano的一个IO口上这样代码里可以随时让驱动模块进入待机模式省电。2.3 超声波换能器的选型与驱动电路超声波换能器我选的是40kHz的开放式换能器型号是TCT40-16T。这个型号很常见价格便宜发射距离在空旷环境下能达到8到10米。虽然驱鸟效果和功率有关系但40kHz这个频率对鸟类来说已经足够敏感了。驱动电路这块Nano的IO口输出电流有限直接推换能器声音很小。我用了一个简单的三极管放大电路Nano的D3脚输出40kHz方波经过一个1kΩ的基极电阻驱动一个S8050 NPN三极管三极管的集电极接换能器的一端换能器另一端接5V。这样换能器两端的电压摆幅能达到接近5V声音强度足够了。如果你想让声音更大可以用推挽电路用两个三极管分别拉电流和灌电流这样换能器两端的电压摆幅能翻倍。不过对于Part 1的验证阶段来说单管驱动已经够用了。提示换能器是有极性的虽然长得像电容但正负极接反了声音会小很多。一般引脚长的是正极或者外壳上有标记。接之前用万用表测一下确认极性再焊。3. 实操过程与核心环节实现3.1 在Arduino IDE中配置开发环境工欲善其事必先利其器。Arduino IDE虽然简单但有几个设置不对后面会各种报错。我一步步说。首先去Arduino官网下载最新版的IDE安装过程一路下一步就行。装好之后打开第一件事是选择开发板。点击“工具”菜单找到“开发板”选择“Arduino AVR Boards”里面的“Arduino Nano”。然后选择处理器Nano有两种一种是老款的ATmega328P一种是新款的ATmega328POld Bootloader。如果你买的是国产兼容板大概率要选Old Bootloader否则上传会报错。接着选择端口。插上USB线之后在“工具”菜单的“端口”里会多出一个COM口选它就行。如果没看到端口说明驱动没装好。国产Nano用的CH340串口芯片需要单独装驱动网上搜“CH340驱动”下载安装即可。还有一个容易被忽略的设置编译器警告等级。我建议调到“全部”这样一些潜在的语法问题会提前暴露出来省得调试的时候抓瞎。3.2 安装必要的库文件这个项目Part 1阶段用到的库不多主要是TimerOne库用来精确控制定时器。虽然Arduino自带的tone()函数也能用但TimerOne库能让你更灵活地控制频率和占空比。安装方法很简单在IDE里点击“工具”-“管理库”搜索“TimerOne”找到Ben Buxton写的那个版本点击安装。装好之后在代码里#include TimerOne.h就能用了。另外如果你后面打算加DHT11温湿度传感器用来根据环境调整驱鸟策略还需要安装DHT库。在库管理器里搜索“DHT sensor library”选Adafruit的那个版本安装。安装完之后在代码里#include DHT.h然后定义传感器类型和引脚就行了。注意Adafruit的DHT库依赖一个叫Adafruit Unified Sensor的库安装的时候IDE会提示你一并安装点“安装全部”就行。很多人只装了DHT库编译的时候报错找不到头文件就是漏了这个依赖。3.3 核心代码实现与参数计算下面是我写的Part 1核心代码功能是让电机缓慢旋转同时超声波换能器间歇发射40kHz脉冲。代码不长但每一行都有讲究。#include TimerOne.h // 引脚定义 #define STBY 4 #define AIN1 7 #define AIN2 8 #define PWMA 9 #define ULTRASONIC_PIN 3 // 超声波参数 const unsigned int ULTRASONIC_FREQ 40000; // 40kHz const unsigned int BURST_DURATION 200; // 每次发射持续200ms const unsigned int BURST_INTERVAL 800; // 间隔800ms // 电机参数 const int MOTOR_SPEED 180; // PWM值范围0-255 unsigned long lastBurstTime 0; bool burstActive false; void setup() { // 电机驱动引脚初始化 pinMode(STBY, OUTPUT); pinMode(AIN1, OUTPUT); pinMode(AIN2, OUTPUT); pinMode(PWMA, OUTPUT); // 超声波引脚初始化 pinMode(ULTRASONIC_PIN, OUTPUT); // 使能TB6612FNG digitalWrite(STBY, HIGH); // 设置电机正转 digitalWrite(AIN1, HIGH); digitalWrite(AIN2, LOW); // 启动电机低速旋转 analogWrite(PWMA, MOTOR_SPEED); // 初始化定时器用于超声波发射 Timer1.initialize(1000000 / ULTRASONIC_FREQ / 2); Timer1.pwm(ULTRASONIC_PIN, 512); // 50%占空比 Timer1.stop(); // 先停止等主循环里控制 Serial.begin(9600); Serial.println(System initialized); } void loop() { unsigned long currentTime millis(); // 控制超声波间歇发射 if (!burstActive (currentTime - lastBurstTime BURST_INTERVAL)) { Timer1.resume(); burstActive true; lastBurstTime currentTime; Serial.println(Burst ON); } if (burstActive (currentTime - lastBurstTime BURST_DURATION)) { Timer1.stop(); burstActive false; Serial.println(Burst OFF); } // 电机速度渐变模拟扫描效果 static int speed 0; static int direction 1; speed direction * 2; if (speed 255 || speed 100) { direction -direction; } analogWrite(PWMA, speed); delay(20); }这段代码里有几个关键点我解释一下。定时器频率计算Timer1.initialize(1000000 / ULTRASONIC_FREQ / 2)。Timer1.initialize()的参数是定时器周期单位是微秒。我们要产生40kHz的方波周期就是1/40000秒也就是25微秒。方波需要高低电平各占一半所以定时器中断周期是12.5微秒。1000000 / 40000 / 2 12.5取整就是12微秒。实际上Timer1的精度有限12微秒对应的频率大概是41.67kHz和40kHz有偏差但换能器的谐振带宽比较宽这个偏差完全可以接受。占空比设置Timer1.pwm(ULTRASONIC_PIN, 512)。第二个参数是占空比范围0-1023512对应50%。50%占空比方波的能量效率最高换能器发声最响。间歇发射逻辑用millis()做非阻塞延时发射200ms停800ms。这样占空比是20%既省电又能避免鸟类适应持续声波。电机速度渐变让PWM值在100到255之间来回变化电机转速就会忽快忽慢。这样做的好处是超声波换能器的旋转速度不固定声波覆盖的角度更随机鸟类更难适应。3.4 电路搭建与上电测试接线的时候我建议分步进行不要一次性把所有线都插上。先接电源部分确认Nano能正常上电板载的电源指示灯亮。然后用USB线连电脑打开串口监视器看有没有输出“System initialized”。这一步过了说明主控没问题。接下来接TB6612FNG。先只接VCC、GND和STBY不接电机。上电后用万用表测一下TB6612FNG的VCC脚应该是5V。然后把STBY接到D4代码里已经把它拉高了。这时候用手摸TB6612FNG的芯片应该不发热。如果发烫赶紧断电检查接线。确认无误后接上电机和电机电源。电机电源我用的是12V的锂电池组接到VM脚。上电后电机应该开始缓慢旋转速度忽快忽慢。如果电机不转先检查STBY是不是高电平再检查AIN1和AIN2的电平组合最后检查PWMA有没有输出。最后接超声波部分。把换能器通过三极管驱动电路接到D3脚。上电后凑近听40kHz人耳听不见但你可以用手机录音功能录一段然后放慢播放如果能听到“嘀嘀嘀”的声音说明换能器在工作。更专业的做法是用示波器看D3脚的波形应该是40kHz的方波。提示测试的时候如果电机转动对超声波有干扰可以在电机两端并联一个0.1uF的瓷片电容滤掉高频噪声。这个坑我踩过电机一转超声波就断断续续的加了电容就好了。4. 常见问题与排查技巧实录4.1 电机不转或只抖动不旋转这是最常见的问题我遇到过好几次。排查思路按顺序来第一步查电源。TB6612FNG的VM脚必须有电而且电压要在3V到13.5V之间。很多人只接了VCC逻辑5V忘了接VM电机电源电机当然不转。用万用表量一下VM脚对GND的电压如果是0那就是没接电机电源。第二步查STBY。STBY脚必须为高电平模块才工作。如果你把它悬空了模块处于待机状态电机不转。我建议直接接5V或者接一个IO口并在代码里拉高。第三步查方向信号。AIN1和AIN2不能同时为高或同时为低否则电机处于刹车状态。正确的组合是一个高一个低。用万用表量一下这两个脚的电平确认组合正确。第四步查PWM信号。PWMA脚要有PWM输出电机才会转。如果PWM值为0电机就是停止状态。可以用analogWrite(PWMA, 128)测试一下或者用示波器看波形。第五步查电机本身。把电机直接接到电池上看转不转。如果直接接电池都不转那就是电机坏了换一个。4.2 超声波换能器声音小或没声音换能器不响原因通常有三个。一是驱动电流不够。Nano的IO口最大输出40mA直接推换能器声音很小。必须加三极管或者MOS管放大。我用的S8050三极管基极电阻1kΩ集电极电流能到500mA推换能器绰绰有余。二是频率不对。换能器的谐振频率是40kHz如果你给的频率偏差太大比如给了38kHz或者42kHz声音会明显变小。用tone()函数或者Timer1产生精确的40kHz方波偏差不要超过1kHz。三是极性接反。换能器有正负极接反了声音会小很多。用万用表二极管档测一下或者看引脚长短长的是正极。4.3 Arduino IDE上传失败的各种报错上传失败是新手最容易卡住的地方我把常见的报错和解决方法列个表。报错信息原因解决方法avrdude: stk500_recv(): programmer is not responding处理器型号选错工具-处理器-选Old Bootloaderavrdude: ser_open(): cant open device端口被占用或驱动没装关闭其他串口软件重装CH340驱动avrdude: verification error芯片型号不对或板子损坏确认选的是ATmega328P换一块板子试试编译报错TimerOne.h: No such file库没装库管理器搜索TimerOne并安装编译报错DHT.h: No such fileDHT库没装安装Adafruit DHT库和Unified Sensor库还有一个坑USB线的问题。有些USB线只能充电不能传数据插上之后电脑识别不到串口。换一根线试试最好是手机原装的那种数据线。4.4 电源干扰导致系统复位户外用电池供电的时候电机启动瞬间电流很大会把电池电压拉低导致Nano复位。我遇到过好几次电机一转串口就重新打印“System initialized”说明板子重启了。解决办法有两个。一是在电池和Nano之间加一个大电容比如1000uF的电解电容并联在Nano的5V和GND之间能吸收电机启动时的电流冲击。二是电机和Nano分开供电用两节电池分别给电机和控制板供电共地就行。我最后用的是第二种方案彻底解决了复位问题。提示如果你用18650电池组建议用两节串联得到7.4V然后经过降压模块降到5V给Nano同时7.4V直接给TB6612FNG的VM脚。这样电机和逻辑供电虽然同源但降压模块有一定的隔离作用比直接共用好很多。4.5 鸟类适应性问题与对策这个问题在Part 1阶段还不太明显但我要提前说一下。超声波驱鸟最大的挑战不是技术实现而是鸟类的适应性。如果每天都是同样的频率、同样的节奏鸟很快就会习惯驱赶效果直线下降。我的对策是随机化。在代码里加入随机数让超声波的频率在38kHz到42kHz之间随机跳变发射时长和间隔也随机变化。这样鸟就找不到规律不容易适应。另外可以配合电机的随机转向让声波来源方向也不固定。这个随机化逻辑我会在Part 2里详细实现Part 1先把基础框架搭好。目前这套代码已经能让系统跑起来电机转、超声波响基本功能都验证通过了。4.6 常见问题速查表为了方便大家快速定位问题我把上面提到的所有问题整理成一个速查表。现象可能原因排查方法解决措施电机不转VM没接电万用表测VM电压接上电机电源电机不转STBY悬空测STBY电平接5V或IO口拉高电机抖动PWM频率太低示波器看PWMA提高PWM频率到1kHz以上超声波无声驱动电流不足测换能器两端电压加三极管放大电路超声波声小频率偏差大示波器测D3频率调整Timer1参数上传失败Bootloader选错看报错信息选Old Bootloader系统复位电源干扰串口看是否重启加大电容或分开供电编译报错库缺失看报错头文件名库管理器安装对应库这套排查流程我用了很多次基本上90%的问题都能在前三步定位到。剩下的10%多半是硬件损坏换件就行。5. 个人实操心得与后续扩展思路5.1 几个让我少走弯路的经验第一个经验先画接线图再动手。我一开始图省事直接对着模块插线结果插错了好几根烧了一个TB6612FNG模块。后来我用Fritzing画了个接线图对着图接线一次成功。这个习惯我保持到现在不管多简单的电路先画图再接线。第二个经验代码分模块测试。不要一次性把电机、超声波、传感器全接上然后烧录代码。先测电机再测超声波最后合在一起。这样出问题的时候容易定位。我见过有人把所有东西接好结果不工作排查了一整天最后发现是超声波和电机共用了Timer1冲突了。第三个经验串口打印是好帮手。代码里多写几个Serial.println()把关键状态打印出来。比如电机速度、超声波开关状态、传感器读数。调试的时候打开串口监视器一目了然。比用LED闪烁判断状态方便多了。第四个经验电源一定要留余量。我一开始用9V电池供电电机一转就复位。后来换成12V的18650电池组问题就没了。电源的瞬时电流能力很重要不要卡着最低要求选。5.2 Part 2可以扩展的方向Part 1把基础框架搭好了Part 2我打算加几个东西。一是PIR人体红外传感器。当有人靠近的时候自动降低超声波功率或者暂停发射避免对人造成不适。虽然40kHz人耳听不见但长时间高强度照射总归不太好。二是DHT11温湿度传感器。鸟类的活动规律和温湿度有关系比如清晨和傍晚湿度高的时候鸟最活跃。根据温湿度数据动态调整驱鸟策略效果会更好。三是太阳能充电模块。户外部署的话电池总有耗尽的时候。加一块6V的太阳能板配合TP4056充电模块白天充电晚上用基本可以免维护运行。四是外壳设计。用3D打印一个防水外壳把电路板、电池、换能器都装进去留出超声波发射孔和电机轴孔。这个我还在画图等Part 2的时候一起分享。5.3 关于成本的一点实话这个项目Part 1阶段的物料成本大概是这样Arduino Nano兼容板15块TB6612FNG模块8块40kHz换能器2块S8050三极管几毛钱电阻电容加起来1块18650电池和降压模块算30块。总共不到60块钱。如果你买原版Arduino Nano光板子就要100多性价比就不高了。国产兼容板我用了一年多稳定性没问题烧了也不心疼。TB6612FNG模块国产的也很成熟没必要买进口的。唯一建议买好一点的是换能器。便宜的换能器谐振频率偏差大声音小寿命短。我买过一批2块钱的用了半个月就哑了。后来换了5块钱一个的用了大半年还好好的。这个钱不能省。5.4 最后分享一个调试小技巧如果你没有示波器怎么判断超声波换能器在工作我的土办法是用手机下载一个频谱分析APP把手机麦克风凑近换能器看频谱图上40kHz附近有没有峰值。虽然手机麦克风对40kHz的响应不太好但近距离还是能看到的。这个方法我用了很多次比盲猜靠谱多了。另外测试电机旋转的时候可以在电机轴上贴一小块反光纸用手机慢动作录像看旋转是否平稳。如果转速忽快忽慢太厉害可能是PWM频率太低把analogWrite的频率从默认的490Hz提高到3.9kHz会好很多。改频率的方法是在setup()里加上TCCR1B TCCR1B 0b11111000 | 0x01;这样D9和D10的PWM频率就变成3.9kHz了电机运行会平滑很多。这个项目我断断续续搞了快一个月中间烧过模块、炸过电容、被鸟嘲笑过无数次。但每次解决一个问题那种成就感还是挺上头的。Part 1的代码和电路我已经验证通过了接下来就是加传感器和做外壳。如果你也在跟鸟斗智斗勇不妨试试这个方案成本不高折腾起来也有意思。