ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Arduino控制HC-05蓝牙模块:AT指令与透传模式切换全攻略

2026/8/19 11:07:39 拓冰建站 浏览量
Arduino控制HC-05蓝牙模块:AT指令与透传模式切换全攻略 1. 项目概述蓝牙模块的双面人生玩过Arduino的朋友对那个蓝色的小板子HC-05蓝牙模块肯定不陌生。它便宜、好用是让单片机项目“无线化”的入门神器。但很多人对它的认知可能就停留在“配对-连接-收发数据”这个固定流程上把它当成一个简单的无线串口。如果你也是这么想的那可能只发挥了它一半的功力。这个项目的核心就是彻底解锁HC-05的两种工作模式AT指令模式和透传模式。你可以把它想象成一个人的两种状态AT模式是“配置状态”就像你拿着手机进入设置菜单调整Wi-Fi名称、密码、音量大小而透传模式是“工作状态”就是你正常用手机聊天、看视频。HC-05在出厂时默认处于透传模式直接就能用。但如果你想改变它的名字、配对密码、通信速率甚至主从角色就必须先让它进入AT模式进行配置。所以“HC-05 AT Mode Normal Mode Controller using Arduino”这个项目本质上是一个基于Arduino的HC-05蓝牙模块模式切换与控制器。它要解决的核心问题是如何用一块Arduino板子既作为上位机比如电脑或手机的代理又作为下位机HC-05模块的指挥官灵活地在两种模式间切换并完成复杂的参数配置。这不仅仅是接上线、发个指令那么简单里面涉及到电压匹配、状态机控制、串口监听与转发等一系列实操细节。无论是想批量配置一批模块还是想做一个集成蓝牙配置功能的智能设备这个项目都能给你一套完整的、可复现的解决方案。2. 核心思路与硬件连接解析2.1 为什么需要Arduino作为“中间人”你可能会问HC-05不是有AT指令吗我直接用USB转TTL模块连接电脑串口工具如Arduino IDE的串口监视器或Putty发送AT指令不就行了理论上可以但实操中会遇到几个麻烦模式切换的物理操作让HC-05进入AT模式通常需要在模块上电的同时按住板载的按键或拉高KEY引脚。用USB转TTL模块操作时你需要手动控制电源和按键的时序非常不便且容易失败。配置与应用的分离如果你的项目最终需要Arduino通过蓝牙与手机通信那么配置好的HC-05最终还是要接到Arduino上。如果配置过程独立于Arduino你就需要反复插拔接线增加了硬件损坏的风险和复杂度。自动化与集成化需求如果你想做一个产品设备上电后能自动检查并配置蓝牙模块参数或者允许用户通过一个按钮就能重置蓝牙设置那么将配置逻辑集成在Arduino程序中就是必须的。因此用Arduino作为“中间人”是最优雅的方案。Arduino一方面通过硬件串口Serial与电脑通信接收来自电脑的配置命令另一方面通过软件串口SoftwareSerial与HC-05通信既能向HC-05发送AT指令也能监听HC-05返回的数据。同时Arduino的一个数字引脚可以控制HC-05的KEY引脚实现程序化的模式切换。这样所有操作都可以通过电脑向Arduino发送指令来完成实现了配置流程的软硬件一体化。2.2 硬件连接图与关键细节正确的连接是成功的一半这里有几个极易出错的点需要特别注意。Arduino Uno/Nano HC-05 Bluetooth Module —————————————————————————————————————————————— 5V/VCC —————— VCC GND —————— GND Pin 10 —————— TXD Pin 11 —————— RXD Pin 9 —————— KEY/EN连接详解与避坑指南电源VCC GND务必确保HC-05的VCC连接到Arduino的5V引脚。虽然有些HC-05模块标称支持3.3V逻辑但其核心芯片和射频部分工作在3.3V板载的LDO低压差线性稳压器会将输入的5V降至3.3V。如果接3.3V可能导致供电不足模块工作不稳定或无法启动。串口交叉连接TX/RX这是串口通信的基本原则TX发送端接RX接收端。所以Arduino的Pin 11软件串口的RX接HC-05的TXDArduino的Pin 10软件串口的TX接HC-05的RXD。接反了自然无法通信。关键引脚KEY这个引脚用于控制模块的工作模式。当KEY引脚悬空或为低电平时模块处于透传模式。当KEY引脚被拉高接VCC即高电平时模块进入AT指令模式。我们通过Arduino的Pin 9来控制它这样就可以用程序digitalWrite(9, HIGH/LOW)来切换模式。状态引脚STATE这个引脚通常可以忽略不接。它用于指示模块的连接状态高电平表示已连接对于本项目不是必需的。重要提示在连接和拔插任何杜邦线时务必确保Arduino和HC-05处于断电状态。带电操作极易因瞬间短路或电压冲击损坏模块或单片机引脚。3. 软件设计与核心代码实现3.1 软件架构与状态机设计整个程序的逻辑可以看作一个简单的状态机它需要处理两个串口的数据流并根据用户指令切换HC-05的模式。核心状态有两个命令模式HC-05处于AT模式KEYHIGH。此时Arduino将从电脑硬件串口接收到的所有字符原封不动地转发给HC-05软件串口同时将HC-05的回复转发回电脑。相当于一个透明的串口桥让你可以直接和HC-05“对话”。透传模式HC-05处于正常工作模式KEYLOW。此时Arduino可以选择性地桥接两个串口或者执行其他应用程序逻辑。我们需要一个命令来触发模式切换。这里设计一个简单的协议当从电脑串口接收到特定字符串如“ATMODE”Arduino就执行切换KEY引脚电平、延时、重新初始化软件串口等一系列操作。3.2 核心代码分步解析下面是一个功能完整、注释详细的Arduino Sketch示例。我们将使用SoftwareSerial库来创建与HC-05通信的软串口。#include SoftwareSerial.h // 定义引脚 #define BT_KEY_PIN 9 // 连接HC-05的KEY引脚 #define BT_RX_PIN 10 // 连接HC-05的TXD #define BT_TX_PIN 11 // 连接HC-05的RXD // 创建软件串口对象参数为(RX, TX) SoftwareSerial BTSerial(BT_RX_PIN, BT_TX_PIN); // 全局变量记录当前模式 bool atMode false; // false为透传模式true为AT指令模式 void setup() { // 初始化硬件串口与电脑通信 Serial.begin(9600); while (!Serial) { ; // 等待串口连接对于Leonardo等板子很重要 } Serial.println(HC-05 Controller Ready.); Serial.println(Commands: ); Serial.println( ATMODE : Switch to AT Command Mode); Serial.println( NORMAL : Switch to Normal (Pass-through) Mode); Serial.println( In AT Mode, type AT commands directly.); // 初始化KEY引脚为输出模式并默认设置为低电平透传模式 pinMode(BT_KEY_PIN, OUTPUT); setBTPassThroughMode(); // 初始化软件串口HC-05默认透传模式波特率为9600 BTSerial.begin(9600); } void loop() { // 1. 检查电脑硬件串口是否有数据传来 if (Serial.available()) { String command Serial.readStringUntil(\n); // 读取一行命令 command.trim(); // 去除首尾空格和换行符 // 处理模式切换命令 if (command.equalsIgnoreCase(ATMODE)) { switchToATMode(); } else if (command.equalsIgnoreCase(NORMAL)) { switchToPassThroughMode(); } else { // 如果不是切换命令则视为要发送给HC-05的数据 // 如果在AT模式直接转发 if (atMode) { BTSerial.println(command); // 注意这里发送了换行符因为大多数AT指令需要以\r\n结尾 // SoftwareSerial的println()默认发送\r\n符合AT指令要求。 } else { // 如果在透传模式也可以选择转发或者做其他处理 // 这里我们选择也转发实现双向透传 BTSerial.print(command); // 透传模式下通常按字节原样转发不额外加换行 } } } // 2. 检查HC-05软件串口是否有数据返回 if (BTSerial.available()) { // 将HC-05返回的数据转发给电脑串口监视器 Serial.write(BTSerial.read()); } } // 函数切换到AT指令模式 void switchToATMode() { if (atMode) { Serial.println(Already in AT Mode.); return; } Serial.println(Switching to AT Command Mode...); // 关键步骤1拉高KEY引脚 digitalWrite(BT_KEY_PIN, HIGH); // 关键步骤2给HC-05一个反应时间同时确保模块处于稳定状态 // 先关闭软串口避免干扰 BTSerial.end(); delay(100); // 关键步骤3重新上电通过断开再连接VCC来模拟不我们通过重新初始化串口并发送AT指令来测试。 // 更稳妥的做法在拉高KEY后断开再连接VCC。但硬件上不便操作。 // 替代方案拉高KEY后重新以AT模式波特率通常是38400初始化软串口。 // 注意有些HC-05在KEY拉高后波特率会自动切换到38400无论之前是什么。 BTSerial.begin(38400); // 尝试以38400的波特率通信 delay(100); // 等待稳定 // 关键步骤4发送测试指令AT期待返回OK BTSerial.println(AT); delay(200); // 等待HC-05响应 bool success false; unsigned long startTime millis(); while (millis() - startTime 1000) { // 等待1秒 if (BTSerial.available()) { String response BTSerial.readString(); Serial.print(HC-05 Response: ); Serial.print(response); if (response.indexOf(OK) 0) { success true; break; } } } if (success) { atMode true; Serial.println(\nSwitched to AT Mode successfully. You can now send AT commands.); Serial.println(Note: Baudrate is now 38400 for AT commands.); } else { Serial.println(\nFailed to switch to AT Mode. Please check wiring and power.); // 失败则尝试恢复 digitalWrite(BT_KEY_PIN, LOW); delay(100); BTSerial.end(); BTSerial.begin(9600); // 恢复默认波特率 } } // 函数切换到透传模式 void switchToPassThroughMode() { if (!atMode) { Serial.println(Already in Normal (Pass-through) Mode.); return; } Serial.println(Switching to Normal Mode...); // 关键步骤1拉低KEY引脚 digitalWrite(BT_KEY_PIN, LOW); // 关键步骤2结束当前软串口可能是38400波特率 BTSerial.end(); delay(200); // 等待HC-05模式切换稳定 // 关键步骤3以透传模式默认波特率通常是9600重新初始化软串口 BTSerial.begin(9600); delay(100); atMode false; Serial.println(Switched to Normal Mode. Ready for data pass-through.); }代码关键点解读双串口监听loop()函数的核心是同时监听Serial和BTSerial任何一端收到数据就立刻转发到另一端。这构成了双向通信的基础。模式切换的时序这是最容易出错的地方。从透传模式切换到AT模式必须确保KEY引脚在模块上电前或复位前就被拉高。我们的代码通过BTSerial.end()和BTSerial.begin()配合延时模拟了一个“复位”过程。digitalWrite(BT_KEY_PIN, HIGH)后必须要有足够的延时delay(100)让模块内部状态稳定。波特率切换很多HC-05模块在AT模式下其通信波特率是固定的38400与透传模式下的可配置波特率默认9600不同。因此在switchToATMode()函数中我们用BTSerial.begin(38400)重新初始化软串口。如果切换失败很可能是波特率不对可以尝试其他常见波特率如9600、19200、57600等。确认机制切换模式后发送一个简单的AT指令并等待OK回应这是一个很好的确认操作能让你在串口监视器里直观看到切换是否成功。4. 实操流程与AT指令应用4.1 完整操作步骤硬件连接按照第2部分的图示用杜邦线连接Arduino和HC-05。再三检查TX/RX是否交叉VCC是否接5V。上传代码将上面的代码复制到Arduino IDE中选择正确的板卡如Arduino Uno和端口点击上传。打开串口监视器上传成功后打开IDE的串口监视器。将右下角的波特率设置为9600与代码中Serial.begin(9600)一致行结束符选择“Both NL CR”即同时发送换行和回车这是AT指令的标准要求。初始状态上电后串口监视器会打印欢迎信息和命令提示。此时HC-05应处于透传模式KEY低电平。切换到AT模式在串口监视器顶部的输入框中输入ATMODE不区分大小写然后点击发送。你会看到“Switching to AT Command Mode...”的提示以及HC-05返回的“OK”响应。这表明切换成功。发送AT指令现在你可以直接在输入框里输入任何HC-05支持的AT指令了。例如AT测试连接应返回OK。ATNAME?查询当前蓝牙名称返回NAME:name。ATNAMEMyHC05设置蓝牙名称为“MyHC05”成功返回OK。ATPSWD?和ATPSWD1234查询和设置配对密码默认为1234。ATUART?和ATUART9600,0,0查询和设置波特率、停止位、校验位9600,0,0表示9600波特率1位停止位无校验。ATROLE?和ATROLE0查询和设置角色0从机1主机2回环。ATADDR?查询模块的蓝牙MAC地址。ATVERSION?查询固件版本。切换回透传模式输入命令NORMAL模块将切换回透传模式波特率也变回9600。此时再发送AT指令将不会得到“OK”回应因为模块不再处于指令监听状态。测试透传在透传模式下你可以用手机蓝牙搜索并配对“MyHC05”或你设置的名字输入密码“1234”。然后使用一个串口调试APP如“蓝牙串口”或“Serial Bluetooth Terminal”连接该模块。在手机APP和Arduino IDE的串口监视器之间互相发送消息应该能实现双向实时通信。4.2 常用AT指令集与参数详解为了让你配置时心里有数这里整理一份最常用的AT指令速查表。注意每条指令后必须跟上回车换行\r\nArduino的println()函数会自动添加。指令功能描述示例发送示例响应成功参数说明AT测试指令检查连接ATOK无参数ATNAME?查询蓝牙名称ATNAME?NAME:HC-05返回当前名称ATNAMEname设置蓝牙名称ATNAMEMyRobotOKname新名称最长20字符ATPSWD?查询配对密码ATPSWD?PSWD:1234返回当前密码ATPSWDpwd设置配对密码ATPSWD0000OKpwd4位数字密码ATUART?查询串口参数ATUART?UART:9600,0,0格式波特率,停止位,校验位ATUARTb,,设置串口参数ATUART115200,0,0OKb波特率(1200-1382400)s停止位(01位,12位)p校验位(0None,1Odd,2Even)ATROLE?查询角色ATROLE?ROLE:00从机1主机2回环ATROLErole设置角色ATROLE1OK设为1可让模块主动连接其他设备ATADDR?查询蓝牙地址ATADDR?ADDR:98d3:31:fcb1a5返回6字节MAC地址ATVERSION?查询版本信息ATVERSION?VERSION:2.0-20100601固件版本日期ATRESET软件复位模块ATRESETOK复位后需等待几秒ATORGL恢复出厂设置ATORGLOK重置所有参数为默认值设置参数后的保存大部分HC-05模块在收到设置指令如ATNAME...后参数会立即生效并保存到Flash中无需额外保存命令。但执行ATRESET或重新上电后新参数才会在透传模式下完全生效。5. 深度排查常见问题与解决方案实录即使按照步骤操作你也可能会遇到各种“玄学”问题。下面是我在多次项目中踩过的坑和解决方案这些在官方文档里可找不到。5.1 问题一发送“ATMODE”后无响应或返回乱码现象发送切换命令后Arduino串口监视器没有显示“OK”或者显示一堆乱码字符。排查思路检查硬件连接再次强调这是90%问题的根源。用万用表测量KEY引脚在发送命令后的电压确认是否为高电平接近5V。检查TX/RX线是否接反。检查波特率在switchToATMode()函数中我们假设AT模式波特率是38400。但有些批次或版本的HC-05其AT模式波特率可能是9600或19200。尝试修改代码BTSerial.begin(38400)中的波特率值逐个尝试。检查行结束符确保Arduino IDE串口监视器的行结束符设置为“Both NL CR”\r\n。如果只设置了“Newline”\nHC-05可能无法正确识别命令。电源干扰HC-05在发射信号时瞬时电流较大可能引起Arduino板载电压不稳。尝试在HC-05的VCC和GND之间并联一个100μF的电解电容进行电源滤波。初始化延时不足在digitalWrite(BT_KEY_PIN, HIGH)后和BTSerial.begin()前增加delay(500)甚至更长的时间给模块足够的状态稳定时间。5.2 问题二AT模式切换成功但发送AT指令不返回“OK”现象切换模式时收到了“OK”但随后发送AT或其他指令却无反应。排查思路模式维持确保在发送AT指令的整个过程中KEY引脚始终保持高电平。检查代码逻辑是否有其他地方意外改变了KEY引脚的状态。软件串口冲突SoftwareSerial库在某些Arduino板子上特别是使用AVR芯片的对高波特率支持不稳定。38400对于16MHz的Arduino Uno来说压力不大但如果遇到问题可以尝试换用AltSoftSerial库更稳定但占用固定引脚或NeoSWSerial库。指令格式确认发送的指令是“AT”而不是“at”或“At”虽然大部分HC-05不区分大小写但最好用大写。确保指令后面跟了换行。监听回复我们的示例代码在switchToATMode()函数中只监听了一次回复。在后续的loop()中确保atMode标志已设置为true并且BTSerial的数据被正确转发到了Serial。可以在loop()里加一句调试代码if (atMode) { Serial.print([); Serial.print(millis()); Serial.println(] AT Mode Active); }来确认状态。5.3 问题三透传模式下手机无法连接或连接后无法通信现象手机能搜索到蓝牙名称但配对失败或配对成功但APP连接后无法收发数据。排查思路密码错误最可能的原因。用AT指令ATPSWD?确认当前密码。手机配对时输入的密码必须完全一致。默认是1234。角色冲突如果你的HC-05被设置为ATROLE1主机模式它将尝试主动连接其他设备而不是被连接。确保在作为从机使用时角色是0。用ATROLE0设置并复位。波特率不匹配手机APP和HC-05在透传模式下的通信波特率必须一致。HC-05默认是9600。如果你的APP不支持更改波特率或者HC-05的波特率被改成了别的值比如115200就会导致连接后乱码或无法通信。用ATUART?查询并用ATUART9600,0,0改回9600然后务必执行ATRESET或重新上电。多设备连接干扰HC-05一次只能维持一个蓝牙连接。确保没有其他设备比如你的电脑或其他手机已经连接了它。APP权限问题在手机上确保已授予蓝牙串口APP“位置”权限在Android上蓝牙扫描需要此权限并且蓝牙和GPS定位服务已打开。5.4 问题四模块异常发热或频繁断开连接现象模块摸起来烫手或者工作时好时坏。原因与解决电源问题这是首要怀疑对象。使用独立的5V/1A电源适配器给Arduino供电而不是不稳定的电脑USB口。确保电源线能提供足够电流。接线虚焊或接触不良特别是VCC和GND接触电阻会导致压降和发热。检查杜邦线接头和面包板如果使用的接触情况。模块损坏如果上述都排除了模块仍异常发热可能是内部短路或芯片损坏。只能更换模块。我个人在实际操作中的体会是HC-05虽然简单但细节决定成败。最重要的三点经验第一电源一定要干净、足量一个廉价的USB线可能就是所有灵异事件的罪魁祸首第二模式切换的时序和波特率是两大拦路虎耐心地通过打印调试信息一步步确认每个阶段的状态第三善用AT指令查询当前状态在遇到问题时不要猜用ATNAME?、ATUART?等指令把模块的“底细”摸清楚很多问题就迎刃而解了。最后再分享一个小技巧如果你需要频繁配置多个HC-05模块可以把这套Arduino控制器代码固化下来做一个专用的“HC-05配置器”。甚至可以用一个旋钮开关来选择不同的预设配置如不同的名称、密码实现一键刷机这会比用电脑串口工具手动操作高效得多。