☰
JDY18蓝牙透传模块从接线到手机实测:串口透传与AT指令避坑指南
2026/10/15 16:07:26 网站建设 项目流程

简介:JDY18使用例子是一份面向BLE蓝牙应用开发者的实践示例包,重点演示JDY18模块与外部设备通信的两种常用方式。资源包含串口通信与IIC通信两个完整C语言示例,压缩包内共2个源文件,整体仅4KB,结构清晰、便于快速移植到物联网或嵌入式项目中。串口示例覆盖串口初始化、数据发送接收、中断驱动与错误检测处理,适合无线透传场景;IIC示例则从协议时序、设备寻址、主从通信模式到读写操作逐步展开,帮助理解JDY18作为主设备与传感器等从设备的交互过程。通过这两个示例,读者可以掌握BLE低功耗蓝牙模块的实际配置方法与调试思路,直接参考源码完成基础通信功能。目前已有1366人学习,适合正在开发基于BLE的物联网产品、希望借助JDY18快速实现无线数据交换的嵌入式开发者。

1. JDY18使用例子:从串口到手机,一块透传模块的前半小时

第一次拿到 JDY18,多数人手里就是一块带邮票孔的小板子,默认波特率 9600,接上电手机就能在蓝牙列表里搜到它。这块模块的任务非常单一:把串口上收到的字节原封不动搬到蓝牙对端,再把对端发来的内容原样吐回串口。所以 JDY18 使用例子的核心,就是搞清楚两条线怎么接、AT 指令怎么发、数据从哪进又从哪出。这个方向特别适合两类人:一类是刚接触蓝牙透传、想快速给传感器数据加一条无线通道的开发者;另一类是把 JDY18 塞进硬件 Demo,需要低成本搞定无线配参和日志输出的个人开发者。新手按下面这套流程走,一个晚上能跑通整条链路;老手可以直接跳到避坑那一章,看透传丢包和 AT 指令不回应的边界条件。

2. JDY18 接线与 AT 指令:最小系统先让模块开口说话

JDY18 本质上是一个蓝牙 SoC 加上晶振和天线匹配电路,外部只需要电源和一组串口就能工作。它的工作方式是典型的串口透传,手机侧把它当成一个蓝牙串口设备,单片机侧把它当成一个普通 UART 外设。选它的理由很实际:价格低、默认配置可用、AT 指令改参数方便、主从模式能覆盖点对点和一主多从的场景。这一章先把最小硬件系统搭起来,再用 AT 指令让模块“开口说话”。刚上电的模块就是一块白板,所有行为都由串口发过去的指令决定,所以接线和指令格式这两件事必须先做对。

2.1 JDY18 引脚定义与最小接线:四根线就够了

JDY18 的引脚不算多,真正跑通透传只需要 VCC、GND、TXD、RXD 四根线,另外两个引脚在做状态检测和深度休眠控制时才会用到。先记住一个原则:单片机发送数据到模块的 RXD,模块回数据从 TXD 出来,所以两边一定是交叉连接。

下面是最常用的引脚功能,新手第一次接线就照着这张表来:

引脚方向作用接线目标
VCC输入模块电源接 3.3V 或 5V,推荐 3.3V
GND输入电源地与单片机共地,必须接
TXD输出模块串口发送接单片机 RXD
RXD输入模块串口接收接单片机 TXD
EN输入使能/唤醒引脚悬空即可,默认开启
STATE输出连接状态指示可接 LED,配对成功后拉高

接线时最容易翻车的地方是交叉连接被忽略。用 USB 转 TTL 小板调试时,小板的 TXD 要接模块 RXD,小板的 RXD 接模块 TXD,直连的话模块永远收不到数据。另外 VCC 的电压选择有个玄学:JDY18 的板载稳压能承受一定范围的输入,但 5V 供电时模块发热明显,长时间跑透传我一般直接给 3.3V,电平匹配也更干净。模块的 TXD 引脚输出的是 3.3V 电平,接 5V 单片机 RX 时虽然多数情况能识别,但稳妥起见加一颗分压电阻更保险。

USB 转 TTL 小板的推荐接线顺序是:先接 GND,再接 VCC,最后接 TXD 和 RXD。带电插拔串口线偶尔会把模块 RXD 脚打坏,尤其 USB 转 TTL 小板刚从电脑拔下来还带着电荷的时候。上电后观察模块上的 LED,慢闪表示已经进入可配对状态,这一步确认了,硬件最小系统就算通了。

2.2 用串口助手发 AT 指令:配置名字、波特率与主从模式

模块通电后第一件事不是写单片机代码,而是用串口助手发几个 AT 指令确认通信没问题。JDY18 的 AT 指令格式和常见的蓝牙透传模块类似,每条指令以回车换行结尾,模块收到后返回 OK 或 ERR。注意这里有个普遍坑:指令结尾必须有换行,串口助手里要勾选“发送新行”,否则模块一直不响应。

我用串口助手“发新行”发下面这几条指令验证模块状态,也可以直接用 Python 脚本走一遍,后面写自动化配置时要用:

import serial import time ser = serial.Serial('COM3', 9600, timeout=1) time.sleep(1.5) # 模块上电后需要时间完成初始化 ser.write(b'AT\r\n') # 测试指令,返回 OK 说明链路通 time.sleep(0.5) print(ser.read_all().decode()) ser.write(b'AT+NAMEJDY18-DEV\r\n') # 修改蓝牙广播名 time.sleep(0.5) print(ser.read_all().decode()) ser.close()

这段代码的作用很简单:打开串口、等模块初始化、发一条 AT 测试指令再发一条改名字的指令。参数说明里有两个点最容易出问题:一是time.sleep(1.5)不能省,模块上电后串口还没准备好时发的指令会被丢掉,血泪经验是刚上电就发指令大概率返回空;二是AT+NAME后面直接跟名字,不要加等号,JDY18 这类模块的指令格式和某些带等号格式的模块不同,发错就回 ERR。

改波特率用的指令是AT+BAUD加编号,比如AT+BAUD4对应 9600,AT+BAUD7对应 115200。不同固件版本对编号的定义不完全统一,我一般先保持默认 9600 跑通业务,确定需要更高吞吐再改。改完之后有一个特别容易忽略的动作:串口助手和单片机那边的波特率必须同步改成新值,否则两边各说各话,返回的全是乱码。改名字和波特率这类参数是即时生效并保存到模块内部的,掉电不会丢,所以不需要每次上电重配。

2.3 改完参数必做的两件事:断电重启与重新配对

不少人在串口助手把名字和 PIN 码改完,直接拿手机去连,结果搜不到或者连不上,然后开始怀疑模块坏了。其实大部分情况只是漏了“断电重启”和“重新配对”这两步。JDY18 改完广播名后,手机端蓝牙列表里的旧名字可能还缓存着,需要模块重新上电广播一次,手机端也要在蓝牙设置里忽略旧设备再重新搜索。

配对码的问题更隐蔽。出厂默认 PIN 码一般印在模块背面的标签上,如果你用 AT 指令改过 PIN,手机端之前记住的旧配对信息就失效了。Android 手机的处理方式是到蓝牙设置里找到该设备,选择“忽略此设备”再重新配对;iOS 设备则是到蓝牙设置里点设备旁边的感叹号,忽略后重新搜索。最容易让人迷惑的是模块从机模式和手机连接之间的关系:JDY18 出厂默认是从机模式,也就是被动等待手机连接,这是最稳的组合方式,新手不要先去改主从。

3. JDY18 单片机收发例程:把数据真正从串口搬到蓝牙

硬件通了、AT 指令能回 OK,下一步就是把 JDY18 接进单片机系统里。这一章从选型差异讲起,分别给出 Arduino 和 STM32 两种常见平台的例程代码。JDY18 对单片机来说就是一个普通串口设备,所以核心代码就是串口初始化、中断接收、数据转发这三件事。不同的平台差异主要在串口资源上:Arduino 的硬件串口只有一组,软件模拟串口成了常见选择;STM32 串口多,收发框架可以写得更完整。

3.1 选 STM32 还是 Arduino:两块板子的接入差异

Arduino 生态里最常见的做法是用 SoftwareSerial 库在任意两个数字引脚上模拟一组串口,把 JDY18 挂在软串口上,USB 调试口保留给电脑。这样做的优点是接线灵活、代码短,缺点是软串口在高波特率下容易丢字节,9600 波特率下收发几十个字节没问题,往上到 38400 就得注意每次发送的数据量。STM32 平台则是直接使用 USART 外设,硬件 FIFO 加中断接收,稳定性和吞吐都要好一截,代价是初始化代码长不少。

用 STM32 时电平可以直接匹配,因为 JDY18 的 TXD 就是 3.3V 电平,和 STM32 的 IO 电平一致,不需要分压。Arduino 上如果板子本身是 5V 逻辑,建议给 JDY18 的 RXD 脚串一个 1k 电阻限流,防止 5V 高电平长期打在模块引脚上。两个平台我都在项目里用过,结论很直接:做快速原型、验证功能用 Arduino,做正式设备和长时间运行用 STM32。JDY18 不做协议解析也不参与复杂逻辑,代码层面的工作量主要在串口数据如何不丢、不重、不粘连。

3.2 Arduino 例程:从 AT 配置到双向透传的最短代码

下面的例程是一个完整的双向透传框架,电脑串口输入的内容发给手机,手机发来的内容打印到电脑串口。同时上电后自动发一条 AT 指令,用来确认模块活着。

#include <SoftwareSerial.h> SoftwareSerial bt(10, 11); // RX=10 接模块 TXD,TX=11 接模块 RXD void setup() { Serial.begin(9600); // 调试串口,连接电脑 bt.begin(9600); // 软串口,波特率与模块一致 delay(1500); // 等待 JDY18 完成上电初始化 bt.println("AT"); // 唤醒/测试,带换行,模块才认 Serial.println("BT Ready"); } void loop() { if (bt.available()) { Serial.write(bt.read()); // 模块数据转发到电脑串口 } if (Serial.available()) { bt.write(Serial.read()); // 电脑串口数据转发给模块 } }

逻辑说明:SoftwareSerial bt(10, 11)创建一组软串口,两个参数分别是 RX 和 TX 引脚,接法要和 2.1 节的交叉原则对上,10 号引脚接模块的 TXD,11 号引脚接模块的 RXD。bt.println("AT")里的println自动补上回车换行,正好满足 AT 指令的结尾要求,如果用bt.print发指令,模块大概率不回。delay(1500)是给模块留初始化时间,放在bt.begin()之后是常见做法,但注意它阻塞了主循环,实际项目里上电后可以先做别的任务再发指令。

这个例程跑通后,用手机连上模块,发一串字符,电脑串口监视器里立刻能看到。反过来电脑往串口发数据,手机 App 里也会出现。整个链路没有校验、没有协议,这就是透传模块的原始工作方式。后续要加协议就在这个桥接位置上做处理,比如在Serial.write(bt.read())之前加一个缓冲区,凑够一帧再输出。

3.3 STM32 的中断接收写法:不丢字节的透传框架

STM32 上我一般用两个 USART,USART1 接 JDY18,USART2 接调试输出,用一个环形缓冲区把接收和转发解耦。核心是单字节中断接收,每收到一个字节就存进缓冲区,主循环查缓冲区再转发,避免在中断里做耗时操作导致溢出。

#define RX_BUF_SIZE 128 uint8_t rx_buf[RX_BUF_SIZE]; uint8_t rx_head = 0; uint8_t rx_tail = 0; uint8_t rx_byte; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { rx_buf[rx_tail] = rx_byte; rx_tail = (rx_tail + 1) % RX_BUF_SIZE; HAL_UART_Receive_IT(&huart1, &rx_byte, 1); // 重新挂载接收 } } int main(void) { HAL_Init(); // 省略时钟、GPIO、USART 初始化代码 HAL_UART_Receive_IT(&huart1, &rx_byte, 1); // 启动单字节中断接收 while (1) { while (rx_head != rx_tail) { uint8_t d = rx_buf[rx_head]; rx_head = (rx_head + 1) % RX_BUF_SIZE; HAL_UART_Transmit(&huart2, &d, 1, 10); // 转发到调试串口 } } }

逻辑说明:HAL_UART_RxCpltCallback是串口接收完成回调,每收到一个字节就进一次中断,把数据放进环形缓冲区后立刻重新调用HAL_UART_Receive_IT挂下一次接收。主循环里的while不断检查缓冲区是否有新数据,有就转发。参数说明:RX_BUF_SIZE要大于实际业务里最大单包长度,128 字节对手机发来的控制指令绰绰有余;HAL_UART_Transmit的最后一个参数是超时毫秒数,这里给 10,串口没准备好时最多等 10 毫秒就放弃,防止主循环卡死。

环形缓冲区的实现是这套代码的关键,读写指针各自累加并取模,不依赖清空操作,天然防止覆盖。如果直接把HAL_UART_Transmit放进中断回调里,短数据没问题,长数据时阻塞在中断里会丢掉后续字节,这是很多 STM32 透传丢数据的原因之一。

3.4 波特率匹配:9600 之外的另两个常用档位

透传场景里,9600 是最保守的选择,短距离、小数据量、调试阶段用这个最稳。数据量上来之后,我一般先把波特率提到 38400,这是稳定性和吞吐量的平衡点,JDY18 在这个波特率下长时间跑不丢字节。115200 在近距离无干扰时可以跑,但单片机侧要做流控或者保证接收缓冲区足够大,否则高波特率下中断响应不及时就会丢数据。

波特率适用场景注意事项
9600传感器数据、AT 配置、调试默认值,最稳,任何固件版本都支持
38400日志输出、批量数据上传需要同步改单片机串口波特率
115200大文件传输、频繁双向通信包长要短,接收端用中断或 DMA

改波特率一定要记住:AT 指令改的是模块侧参数,修改后模块立即生效,串口助手和单片机必须同步切换。如果改完后模块不回任何指令,大概率是电脑端波特率还停在旧值上。这时候把波特率调回旧值再发一次指令就能恢复。

4. JDY18 与手机 App 透传实测:链路通不通一次回环见分晓

单片机侧的串口收发写好了,接下来把手机拉进链路,做一次完整的透传实测。这一步的目的是验证三个问题:手机能不能发现并连上模块、数据从手机到单片机能不能完整到达、单片机回的数据手机能不能收到。三个问题都通过,这条无线链路就真正可用了。这一章从手机连模块的流程讲起,给出一个最小回环测试方案,最后讨论怎么在透传之上加一层协议,把裸字节变成可靠业务数据。

4.1 手机端连接流程:搜索、配对、选择一个能用的串口服务

手机连 JDY18 和平常连蓝牙耳机不太一样,关键区别在于 JDY18 暴露的是一个串口服务,而不是音频服务。Android 手机的做法是:打开系统蓝牙设置,搜索设备,找到你通过 AT 指令改好的名字,点击配对并输入 PIN 码。配对成功之后,打开任意一个“蓝牙串口”类 App,在设备列表里选择 JDY18,App 内部会主动去连接模块上的串口服务,连接成功就能收发数据了。

需要注意一个坑,配对成功和串口连接成功是两回事。系统蓝牙设置里显示“已配对”,不代表 App 能直接收发数据,App 连接时如果提示“连接失败”或“Service Discovery Failed”,先回系统设置里忽略设备重新配对一次。iOS 设备的情况更严格,部分 iOS 版本对经典蓝牙 SPP 服务的支持有限,市面上的透传调试 App 在 iOS 上经常连不上 JDY18 这类经典蓝牙模块。如果你手里只有 iOS 设备,建议先借一台 Android 手机完成链路验证,这是做 JDY18 调试最省时间的路子。

选 App 的时候看两点:支持 SPP(Serial Port Profile)而不是只支持 BLE;能切换 ASCII 和 HEX 显示模式。透传调试时 ASCII 模式方便读文字,排查乱码时切到 HEX 才能看到原始字节。

4.2 回环测试:手机发一句、单片机回一句

链路验证最有效的方式是回环测试。手机端 App 发一串字符给 JDY18,模块从串口吐给单片机,单片机收到后原样返回,手机 App 看到返回内容就说明整条链路是通的。单片机侧可以用 Arduino 例程加一点逻辑,识别到特定结尾符就回一条消息。

#include <SoftwareSerial.h> SoftwareSerial bt(10, 11); void setup() { Serial.begin(9600); bt.begin(9600); delay(1500); } void loop() { static String s = ""; while (bt.available()) { char c = bt.read(); s += c; if (c == '\n') { bt.print("echo:"); bt.print(s); bt.print("\r\n"); s = ""; } } }

逻辑说明:这段代码按行读取数据,手机发来的内容以换行符作为一帧结束的标志,收到完整一行后原样返回并加上echo:前缀。bt.print和bt.println的区别在这里体现为手动拼接,因为要控制返回格式。参数说明:String s这种方式在长时间大流量下会有内存碎片问题,做调试验证没问题,正式项目建议换成字符数组加下标的方式。

回环失败时先别急着查模块,用前面的 AT 流程确认串口链路是好的,再检查手机 App 连的是不是 JDY18。最阴间的现象是手机连上了一个邻居的同类模块,数据发过去完全不回。所以做实测之前,先用 AT 指令把名字改成不容易撞车的名字,避免误连。

4.3 从串口数据到业务数据的三个转换点

透传模块只保证字节从 A 到 B,不保证业务语义正确。实际项目里在 JDY18 之上还要做三件事:帧界定、完整性校验、格式统一。帧界定解决的是“一包数据从哪开始在哪结束”的问题,常见方案是包头加包尾,比如0xAA开头、0x55结尾,中间放长度字段;完整性校验用 CRC 或累加和,防止无线传输中某一位被干扰;格式统一是说收发双方约定好用 ASCII 字符串传还是十六进制字节传,调了两天一度想换模块,最后发现只是手机 App 把数据按 UTF-8 显示而我发的是 GBK,换到 HEX 模式一看字节完全正确。所以排查乱码第一条永远是看原始字节,别依赖文本显示。

5. JDY18 使用中高频踩坑的 5 个翻车现场:现象、原因与处理

JDY18 本身不复杂,但实际用起来翻车点密集,而且很多坑是模块环境问题,不算模块本身。这一章整理了 5 个最常见的现场,每个都按“现象 -> 原因 -> 解决”给出来,都是我实际调模块时反复踩过的。新手遇到问题时按顺序对照,大概率能直接定位到原因。

5.1 手机搜不到模块:上电时序和供电不稳最容易背锅

现象:模块接好线、通上电,手机蓝牙列表刷了好几遍,始终看不到模块名字。原因分三种:供电不足导致模块没有正常启动、模块还处于连接状态没有进入广播、广播名被改过但模块没重启。用电脑 USB 口加杜邦线给模块供电,线长或接触不良时电流不够,模块上电瞬间崩溃又重启,LED 表现为亮一下又灭。解决:先换独立供电,用 USB 转 TTL 小板的 3.3V 输出直连模块 VCC;确认模块 LED 在慢闪,慢闪说明在广播,快闪说明有设备连着;改过名字就断电再上电,让模块重新广播一次。注意手机蓝牙缓存,搜索前先把旧设备忽略掉。

5.2 搜索到了但连接一直转圈:配对缓存和主从模式冲突

现象:手机能看到模块名字,点击连接,状态一直显示“正在连接”或“配对中”,几秒后失败。原因:手机之前用旧 PIN 和模块配对过,后来 AT 指令改了 PIN,手机端缓存的是旧配对信息;另一种可能是模块被设置成了主模式,主动去连其他设备,不再作为从机等待手机连接。解决:到手机蓝牙设置里找到该设备点“忽略”,再重新搜索配对;用串口发 AT 指令把模块切回从机模式,做法是参考 AT 指令表找到主从配置项,设成从机后断电重启。如果你不确定当前主从状态,最简单的办法是恢复出厂设置,绝大多数模块支持AT+RESTORE指令,恢复后重新改名配 PIN。

5.3 收发全是乱码:波特率不一致和文本编码的混淆

现象:手机和单片机都显示能收发数据,但内容全是看不懂的符号。原因:单片机串口波特率和模块不一致,两边参考时钟不同步,字节位全部错位;或者是数据本身是十六进制字节,被 App 按文本模式显示出来。解决:先确认模块的实际波特率。怎么确认?串口助手从 9600 开始逐一试,每个波特率下发AT\r\n,看哪个能回OK。找到实际波特率后把单片机代码里的波特率改成一致,这个问题基本消灭。文本编码问题切到 HEX 模式看原始字节,如果 HEX 正确、文本乱,就是显示层问题,不用改代码。

5.4 AT 指令回 ERR 或完全无响应:换行符和控制字符

现象:发AT没反应,发AT+NAMEJDY18返回ERR。原因:模块对指令结尾的换行符敏感,有些串口助手默认只发\n,模块要的是\r\n;另一类情况是指令格式写错,JDY18 的指令是AT+NAME后直接跟名字,不需要等号,习惯性写成AT+NAME=DEV就会报错。解决:串口助手里勾选“发送新行”并确认换行格式是 CRLF;对照模块指令表逐字核对命令格式;发指令前先发一条空指令或AT确认模块在响应状态。如果AT都不回,先查接线和波特率,不要怀疑模块坏了。

5.5 透传过程莫名丢字节:缓冲区和单包长度上限

现象:手机发来一长串内容,单片机收到的中间缺了一截,或者尾部被截断。原因:模块单次透传长度有限,数据超长会被分片或者丢弃;单片机串口接收缓冲区不够大,数据到达速度超过主循环读取速度时有覆盖;软串口在高波特率下本身不稳定。解决:业务层把数据分片发送,每片控制在 128 字节以内,中间加小延时让单片机有时间处理;单片机侧用 3.3 节的环形缓冲区替代逐字节转发;波特率优先用 9600 或 38400,不要一上来就 115200。如果丢包集中在某一片区域,检查是不是靠近电机或电源模块,蓝牙在 2.4G 频段受到干扰时表现为偶发重传和丢包,把模块天线尽量远离金属和干扰源。

6. JDY18 进阶用法:一条低成本无线调试通道的搭法

JDY18 跑透传不是终点,我用的最多的其实是把它当成一条无线调试通道。做法很简单:单片机侧用 JDY18 替代调试串口,所有日志通过蓝牙直接打到手机屏幕,不用拖着一根 USB 线调设备。具体配置是模块固定 38400 波特率,单片机的日志模块单独分配一个串口接 JDY18,日志格式统一成带时间戳的文本:“[ms] [level] message”。这样设备装进外壳之后,依然能从手机读到运行日志,比拆壳插线效率高很多。

配这个方案时有个细节:JDY18 放在设备内部,天线要和金属外壳保持至少 1cm 距离,否则距离缩水到两三米。实测空旷环境下十米内稳定,隔一堵墙掉到五米以内,穿两面墙就时断时续。所以无线调试通道适合近距离和桌面调试场景,设备装好后如果需要远程观察,我会再考虑加协议层做重传,而不是指望透传本身可靠。功耗方面模块峰值电流比纯待机高不少,静态功耗可以接受,但电池供电的设备要加休眠控制,用 EN 引脚做唤醒输入,这是我后来才补上的设计。

另外一个小习惯是我的血泪经验:新到手的模块第一件事永远是发AT确认通信,不要直接写业务代码。模块、USB 小板、单片机三方都可能是问题源,先固定两个变量再动第三个,排查速度会快很多。JDY18 这样的透传模块用熟了之后,很多无线需求都能快速落地,希望帮到你。

本文还有配套的精品资源,点击获取

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

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

立即咨询