ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

JDY-18蓝牙透传模块实战:从接线到Arduino双向通信

JDY-18蓝牙透传模块实战:从接线到Arduino双向通信 简介JDY18作为一款低功耗BLE蓝牙透传模块广泛应用于物联网、智能家居、健康监测等需要无线数据传输的场景。资源面向希望快速上手该模块的嵌入式开发者提供可直接阅读和移植的C语言示例代码。压缩包内共包含2个文件均为.c源文件整体大小仅4KB结构精简分别对应串口通信与IIC通信两种典型用法。串口示例覆盖波特率配置、数据收发、中断驱动与错误检测适合实现蓝牙模块与主控或PC之间的双向透传IIC示例则围绕协议时序、7位从机寻址、主从读写作答等核心要点展开可帮助打通模块与传感器等外设的数据链路通过对照源码学习能清晰梳理JDY18的初始化流程、事件处理机制和排错思路为开发实际BLE物联网产品打下基础目前已吸引1364人学习适合正在入门BLE应用或需要具体驱动参考的开发者。 JDY-18 这块蓝牙模块我在好几个项目里都一直在用。做智能家居小开关、给传感器的数据做无线回传、甚至是两台单片机之间的无线上位机调试靠的都是它。JDY-18 本质上是一个基于 Nordic nRF52832 芯片的低功耗蓝牙透传模块你把它当成一根无线的串口线就行手机或者另一块模块连上之后这边串口发什么那边蓝牙就收什么反过来同理。这篇文章我不打算念规格书就把我实际用过的接线方式、AT 配置命令、两套完整可跑的 Arduino 例子以及踩过的坑全部写出来给正准备上手或者已经被它折腾到怀疑人生的朋友做个参考。1. 先说清楚 JDY-18 是什么选型前要搞懂这几点1.1 模块的核心参数与定位JDY-18 最核心的身份是串口透传 BLE 模块。所谓透传就是模块内部已经把串口数据和蓝牙 GATT 通信的数据做了相互转换你不需要关心 BLE 协议栈怎么写的。模块上电后串口 TTL 电平收到什么字节它就把这些字节封装成 BLE 通知Notify发送给已连接的手机反过来手机往指定特征值Characteristic写入字节模块就会原封不动地从串口 TXD 吐出来。对单片机开发者来说它就是一个看不见线的串口。它基于 nRF52832 这颗芯片支持 BLE 5.0这也是我选它而不是那些老款 BLE 4.0 模块的主要原因。我实际在开阔场地测试遥感距离做到 50 米开外没有压力室内隔一两堵墙也基本稳定比老式模块在穿墙和新连接体验上好不少。项目参考值主控芯片Nordic nRF52832 (ARM Cortex-M4F)蓝牙版本BLE 5.0工作电压2.0V ~ 3.6V典型 3.3V串口波特率默认 9600可通过 AT 指令修改默认服务 UUID0xFFF0默认写特征值0xFFF1默认通知特征值0xFFF2默认名称通常是 JDY18 之类可修改1.2 为什么说它适合做快速原型市面上蓝牙模块不少JDY-08、JDY-10、JDY-23 这些我都用过。但 JDY-18 有几个点确实更适合做产品原型和小批量项目第一接线极简。真正干活只需要 VCC、GND、TXD、RXD 四根线不需要外部天线匹配网络不需要额外晶振模块自己自带 PCB 天线。第二AT 指令配置非常直接改名字、改波特率、改配对密码一个串口助手就能完成。第三nRF52832 的性能底子好处理速度快数据吞吐量比老平台高在 BLE 5.0 下理论上算上协议开销跑十几 KB/s 的串口透传也没什么问题。在选型时我还会提醒一句JDY-18 的输出电平是 3.3V TTL不是 5V。如果你的主控是 5V 的 Arduino Uno / Mega模块的 RXD 不能直接接主控的 TXD要做电平转换或者用分压电阻。这个细节我在第 2 节详细说。2. 拿到模块先别着急焊接线、上电自检和 AT 配置2.1 引脚说明与典型接线JDY-18 模块一般引出 6 个左右的引脚VCC、GND、TXD、RXD部分版本还有 SLEEP休眠控制和 STATE连接状态输出引脚。以我常用的接法为例用 Arduino Uno 的软件串口来连接JDY-18 引脚接 Arduino 引脚VCC3.3V绝对不能接 5VGNDGND必须共地TXDD8软件串口 RXRXDD9软件串口 TX需分压这里有个新手很容易踩的坑Arduino Uno 的 IO 口逻辑电平是 5V而 JDY-18 的 RXD 逻辑上限就是 3.6V。直接接上去短时间没什么事长期跑容易导致模块内部电平判断异常严重的甚至烧坏 RXD 引脚电路。我的处理办法是在 Arduino TX 到模块 RXD 之间串两个电阻做分压典型做法是 1k 串联、2k 下拉到地把 5V 分到约 3.3V。模块 TXD 输出本身是 3.3V接到 Arduino 的 RX 引脚则可以直接收ATmega328P 的高电平阈值只有约 3.0V3.3V 足够识别为高。如果不想折腾电阻直接换一块 ESP32、STM32 这类 3.3V 逻辑的主控问题自动消失。2.2 用串口助手先跑通 AT 指令模块上电前先保证三件事串口助手波特率设置成 9600Hex 显示不要开发送新行\r\n要打开。如果发送新行没开很多 JDY 系列模块会对 AT 指令无响应这是最容易被忽略的问题不是模块坏了。上电后在串口助手里一条一条发这些指令AT模块正常会回复OK。凡是配置类的指令我建议都等模块回 OK 再发下一条别一条命令连续轰炸模块处理时间很短但也有次序要求。修改模块名称方便在手机里找ATNAMEMyDevice设置波特率为 115200ATBAUD115200查看模块 MAC 地址ATMAC要注意不同批次的 JDY-18 固件AT 指令集可能略有差异。以上是基于 JDY 系列通用指令集的写法在我手里的模块上是稳定可用的。如果某个指令不识别发一条ATHELP或者ATVERSION看固件支持哪些命令。改完配置最好断电重新上电部分参数会要求重启才生效。提示AT 指令必须通过串口硬件连接发送。模块一旦被手机通过 BLE 连接上很多版本的固件会自动进入透传模式这时候 AT 指令往往不再响应。所以配置要趁没有连接的时候做连接后如果发现发 AT 没反应先把手机端断开。2.3 上电自检的三个关键信号我把模块通电后的体检顺序总结为三看一看电源电压。用万用表量 VCC 和 GND 之间有没有稳定的 3.3V波动超过 0.1V 就要检查供电。二看串口有没有乱码。如果发 AT 收到的是一堆符号八成是波特率不匹配或者供电纹波太大把串口信号干扰了。三看 STATE 引脚电平。模块没有 BLE 连接时 STATE 通常输出低电平连接成功后拉高。这引脚可以接主控的 GPIO作为手机是否在线的判断信号做低功耗项目时特别有用。这三步走通了后面的两个例子就都能跑。3. 例子一手机实时看传感器数据数据上行这个例子我做了一个小气象站单片机采集 DHT11 温湿度通过 JDY-18 每 2 秒发给手机手机端用 nRF Connect 这个 App 直接查看数据。整个过程不需要写手机 App非常适合验证模块是否工作正常。3.1 硬件连接Arduino Uno DHT11 JDY-18连线如下器件引脚ArduinoDHT11DATAD7JDY-18VCC3.3VJDY-18GNDGNDJDY-18TXDD8JDY-18RXDD9分压后DHT11 的数据脚我习惯接一个 10k 上拉电阻到 3.3V虽然很多模块内置上拉但外置一个更稳读数的成功率会好一些。3.2 Arduino 端代码整段程序逻辑很简单初始化串口然后循环里读传感器、通过软件串口发出去。#include SoftwareSerial.h #include DHT.h #define BT_RX 8 #define BT_TX 9 SoftwareSerial ble(BT_RX, BT_TX); #define DHTPIN 7 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(9600); ble.begin(9600); dht.begin(); ble.println(JDY18 sensor ready); } void loop() { float h dht.readHumidity(); float t dht.readTemperature(); if (isnan(h) || isnan(t)) { ble.println(ERR:SENSOR); } else { ble.print(TEMP:); ble.print(t, 1); ble.print(,HUMI:); ble.println(h, 1); } delay(2000); }这里有几个细节我强调一下第一发送数据我固定用println每条数据以换行符结尾这样手机端看到的数据是分行显示的方便阅读也方便后台写解析。第二波特率必须和模块当前配置一致模块默认 9600那代码里也写 9600。如果之前用 AT 改成了 115200这里就要同步改。第三DHT11 的采样周期本来就在 1 秒以上所以delay(2000)完全够发太快只会读到重复数据。3.3 手机端用什么工具看不用专门写 App手机装一个 nRF ConnectiOS/Android 都免费或者 LightBlue 就能看。操作的路径是扫描到你的模块名称默认是 JDY18如果你改了名字就是新名字点击连接然后找到 Unknown Service 或者 UUID 为 0xFFF0 的服务。进入服务后找到 0xFFF1 这个写特征值以及 0xFFF2 这个通知特征值。要开启接收数据需要先点击 0xFFF2 旁边的 Notify 按钮让它变成启用状态这样模块发过来的传感器数据才会持续地显示在应用界面上。如果看不到 Notify 选项把 App 的日志点开看有没有 CCC 配置错误多半是模块固件对客户端特征配置处理得比较特殊。我第一次调试时犯过一个低级错误数据不上来折腾了半天最后发现我只是把串口打开盯着电脑看根本没连手机。提醒各位透传数据是在 BLE 连接上跑的没有手机连接模块串口收到的数据不会往外发。4. 例子二手机反向控制单片机数据下行这个例子里JDY-18 从上报工具变成遥控器接收端。我用它做了一个蓝牙继电器开关手机发字符1继电器闭合发字符0继电器断开。4.1 先想清楚指令协议很多人做下行控制时直接让手机发个1或0就完事了这在测试阶段没问题但项目大了就不行。我习惯在上层就约定一个简单的帧格式指令帧: [头][命令][参数][结尾] 例子: # LED1 ON ;比如手机发送#LED1 ON;单片机收到后解析出灯 1 打开。这样做的原因是BLE 透传不会给你保证一次写等于一次完整指令协议栈可能把一次写入拆成多个通知或者把两次写入合并成一个包。单独发1/0这种单字符指令在数据量小的时候不容易出事但一旦后面加了更多指令没有帧边界就会乱套。4.2 控制 LED 的 Arduino 代码为了演示简单清晰下面例子用单字符控制 LED但我会在代码里保留一个简单的状态机解析框架方便你扩展成帧格式。#include SoftwareSerial.h #define BT_RX 8 #define BT_TX 9 SoftwareSerial ble(BT_RX, BT_TX); #define LED_PIN 10 void setup() { ble.begin(9600); pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LOW); } void loop() { while (ble.available()) { char c ble.read(); if (c 1) { digitalWrite(LED_PIN, HIGH); ble.println(ACK:LED ON); } else if (c 0) { digitalWrite(LED_PIN, LOW); ble.println(ACK:LED OFF); } // 扩展建议这里可以用 switch 状态机解析 # CMD ARG ; } }手机端我仍然用 nRF Connect这次要操作的是 0xFFF1 这个写特征值。在特征值界面写入方式选择 Write不是 Write Without Response然后在编辑框里输入数字1点发送。LED 应该立即点亮。同样的方式发0熄灭。4.3 为什么我建议每次下发都带反馈代码里我在收到指令后返回了ACK:LED ON这样的确认字符串。这个操作不是多余的BLE 无线链路有时候会出现空口丢包特别是手机和模块之间有遮挡的时候。如果只发不收你可能根本不知道那一条指令没到达。有了 ACK主控执行完动作就回一句手机端或者日志里能看到发过了和真执行了是不是对得上。我做过一个更复杂一点的版本MCU 收到指令后不仅执行动作还把当前状态打包上报类似于STATUS:LED1ON,RELAY2OFF这样手机端做任何状态同步都有据可依。做智能家居的窗帘、灯控这类设备时这种命令状态回读的闭环设计能少踩很多雷。5. 例子里最容易踩的坑无响应、乱码、掉线的排查实录5.1 常见问题速查表我整理了一个排查表基本覆盖我实际遇到过的所有情况现象常见原因解决办法发 AT 无任何回复TX/RX 接反对调两根线再试发 AT 无任何回复串口发送没带换行符打开串口助手的发送新行或手动加 \r\n发 AT 无任何回复模块已被手机连接断开手机 BLE 连接后再试手机搜不到模块模块没供电 / 进入休眠检查 VCC 电压与 GND唤醒模块手机搜到但连不上之前连接未正常断开手机关蓝牙重开或等模块超时释放连接串口收到乱码波特率不一致确认模块 AT 配置与代码/助手一致连接后数据收不到没开启 Notify在 App 里启用 0xFFF2 的通知距离稍远就掉线供电电压跌落换稳压电源别用电脑 USB 口勉强带载5.2 两条特别值得分享的排查经验第一条模块看起来死机的时候优先怀疑供电而不是固件。JDY-18 在 BLE 广播和连接状态切换的瞬间电流会有一个明显尖峰如果用的是普通 AMS1117 稳压模块或者劣质 USB 线压降一旦超过模块的工作下限它就会表现为时好时坏。我做过一个项目模块在办公室一直正常拿到现场就频繁掉线最后查出来是现场供电线的线径太细换一根粗线就再没出过问题。第二条手机连接调试时同一个时间段只让一台设备连接。JDY-18 是单连接模块如果之前测试时手机没有正常断开连接模块会一直认为通道被占用这时新手机扫描不到或者连不上。解决办法是断掉所有测试设备给模块断电再上电让它重新广播。5.3 软件串口的坑Arduino 的 SoftwareSerial 本身就是软件模拟的在高波特率或者同时收发数据量比较大的时候容易丢字节。我测试 JDY-18 时如果遇到偶尔丢数据第一件事不是怀疑模块而是先换硬件串口Arduino Uno 的 D0/D1试一遍确认是模块的问题还是软件串口的问题。如果只能用软件串口把波特率控制在 9600 会稳很多9600 以上就建议换主控或者用内置多串口的芯片比如 STM32、ESP32。另外 SoftwareSerial 默认状态下一次只能监听一个串口如果你同时接了其他传感器串口注意别把引脚定义冲突了。结语按我的使用经验这个模块还能怎么玩最后分享一个我现在比较常用的扩展玩法用两块 JDY-18 做一主一从实现两台单片机之间的无线串口桥接。配置时一块设成从机Slave另一块设为自动连接主模式Master连接成功后A 板串口发数据给从模块B 板的主模块收下来再从串口吐给 B 板。这个方案特别适合做有线串口不好拉的场景比如两个控制柜之间、机器人和上位机之间的通信。我实际用它跑过 115200 波特率的数据日志稳定度比想象中好。核心配置方式也不复杂就是一端用 AT 指令改成可连接的从机另一端设为主机并填对从机 MAC细节可以在模块手册里查到。不管是做温度上报、远程控制还是串口桥接JDY-18 解决的核心问题都是那一个让串口数据无线化。把这个原则想明白遇到任何新项目先用最简单的方式验证链路通不通再逐步往上面加业务逻辑就不太会被它折腾到。本文还有配套的精品资源点击获取
返回列表