从零构建:基于JDY-18蓝牙与STM32的智能灯光APP控制系统

张开发
2026/7/1 21:23:13 15 分钟阅读
从零构建:基于JDY-18蓝牙与STM32的智能灯光APP控制系统
1. 项目背景与硬件准备智能家居正在改变我们的生活方式而灯光控制是最基础也最实用的应用场景之一。最近我在工作室搭建了一个基于JDY-18蓝牙模块和STM32的智能灯光控制系统整个过程从硬件连接到APP开发都亲自动手实现。这个方案特别适合刚接触嵌入式开发的朋友因为用到的都是性价比极高的常见硬件一块STM32F103C8T6最小系统板十几块钱就能买到、JDY-18蓝牙模块比HC-05更便宜、几个LED灯珠再加上手机就能玩转智能照明。先说说为什么选择JDY-18蓝牙模块。相比常见的HC-05它有几个明显优势首先是价格便宜近一半其次功耗更低待机电流只有8μA最重要的是支持蓝牙4.2标准传输距离最远可达30米。我在实测中发现隔着两堵墙都能稳定控制灯光这对于家庭使用完全足够了。硬件清单具体需要准备STM32F103C8T6最小系统板蓝色小板JDY-18蓝牙模块注意要买带底板的版本LED灯珠建议RGB三色各一个杜邦线若干USB转TTL模块用于初始配置安卓手机用于安装控制APP2. JDY-18蓝牙模块配置拿到蓝牙模块后第一步是进行基础配置。这里有个小坑要注意新买的JDY-18默认波特率是115200但为了兼容性建议改为9600。我用的是PL2303 USB转TTL模块连接时特别注意TX-RX要交叉连接即模块的TX接JDY-18的RX模块的RX接JDY-18的TXGND和VCC直接相连。打开串口调试工具推荐使用XCOM V2.2发送AT指令时要记得勾选发送新行。基础配置只需要三条指令ATBAUD4设置波特率为9600ATNAMEJDY-LIGHT设置设备名称ATROLE0设置为从机模式配置完成后记得断电重启模块。这时候用手机蓝牙搜索应该能看到名为JDY-LIGHT的设备。我刚开始调试时遇到模块无响应的情况后来发现是USB转TTL模块供电不足换成外部5V供电就正常了。建议大家在调试时先用外部电源给蓝牙模块供电避免这类问题。3. STM32硬件连接与开发环境搭建硬件连接其实非常简单核心就是串口通信和PWM输出。具体接线如下JDY-18的TX接STM32的PB11USART3_RXJDY-18的RX接STM32的PB10USART3_TXLED正极通过220Ω电阻接PA6TIM3_CH1 PWM输出共地连接必不可少开发环境我推荐使用Keil MDK社区版就够用。新建工程时要注意选择正确的芯片型号STM32F103C8添加标准外设库StdPeriph_Lib在Options for Target中勾选Use MicroLIB否则printf无法使用有个实用技巧在工程里添加串口重定向代码这样就能用printf调试了。具体是在usart.c中添加如下代码#include stdio.h int fputc(int ch, FILE *f) { USART_SendData(USART1, (uint8_t)ch); while(USART_GetFlagStatus(USART1, USART_FLAG_TC) RESET); return ch; }4. STM32程序设计详解整个程序可以分为三个关键部分串口通信、PWM输出和主控制逻辑。先来看串口初始化这是蓝牙通信的基础。在usart3.c中我们需要配置USART3为异步模式波特率9600启用接收中断void usart3_init(u32 bound) { // 时钟使能省略... GPIO_InitStructure.GPIO_Pin GPIO_Pin_10; // PB10复用推挽输出 GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_Init(GPIOB, GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin GPIO_Pin_11; // PB11浮空输入 GPIO_InitStructure.GPIO_Mode GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, GPIO_InitStructure); USART_InitStruct.USART_BaudRate bound; USART_InitStruct.USART_WordLength USART_WordLength_8b; USART_Init(USART3, USART_InitStruct); USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); USART_Cmd(USART3, ENABLE); }PWM输出部分使用TIM3的通道1关键是要正确设置自动重装载值(ARR)和预分频值(PSC)。我设置的PWM频率为1kHz适合大多数LED调光应用void TIM3_PWM_Init(u16 arr, u16 psc) { TIM_TimeBaseStructure.TIM_Period arr; // 自动重装载值 TIM_TimeBaseStructure.TIM_Prescaler psc; // 预分频 TIM_TimeBaseInit(TIM3, TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode TIM_OCMode_PWM1; TIM_OC1Init(TIM3, TIM_OCInitStructure); TIM_Cmd(TIM3, ENABLE); }主程序中通过解析蓝牙指令来控制灯光。我设计了一个简单的协议字符0关灯1-3设置不同亮度4-6控制RGB三色LEDwhile(1) { if(USART3_RX_STA 0x8000) { // 收到完整数据 switch(USART3_RX_BUF[0]) { case 0: TIM_SetCompare1(TIM3, 0); break; // 关闭PWM case 1: TIM_SetCompare1(TIM3, 50); break; // 20%亮度 case 2: TIM_SetCompare1(TIM3, 150); break; // 60%亮度 case 3: TIM_SetCompare1(TIM3, 350); break; // 100%亮度 // RGB控制省略... } USART3_RX_STA 0; // 清除接收标志 } }5. 手机APP开发实战考虑到大多数开发者没有安卓开发经验我选择了App Inventor2这个图形化工具。它完全在线开发无需安装IDE拖拽组件就能完成APP设计。首先在浏览器打开App Inventor官网新建项目后按以下步骤操作界面设计添加1个ListPicker选择蓝牙设备添加4个Button连接、断开、亮度、亮度-添加1个Slider亮度精细调节逻辑设计 关键是要使用BluetoothLE组件设置服务UUID为0xFFE0特征UUID为0xFFE1这是JDY-18的默认配置。具体代码块包括扫描蓝牙设备连接/断开处理发送控制指令我分享一个实用技巧在发送数据时最好添加简单的校验机制。比如发送亮度值时我采用Lxxx\n的格式STM32端解析时先检查首字母这样能避免误操作。完整的APP源码可以导出为aia文件我已经上传到GitHub文末会给出链接。6. 系统调试与优化建议实际调试中可能会遇到几个典型问题。首先是蓝牙连接不稳定这通常是因为天线摆放不当。JDY-18的PCB天线要避免被金属物体遮挡我建议将模块直立放置。其次是PWM调光时有闪烁这个问题困扰了我很久最后发现是电源问题——当使用USB供电时电流不足改用5V/2A的电源适配器后问题解决。对于想进一步优化的朋友我有几个建议增加状态反馈让STM32定时向APP发送当前亮度值添加场景模式比如阅读模式、影院模式等预设亮度实现定时功能通过APP设置定时开关加入OTA升级通过蓝牙更新STM32固件电源管理方面如果要做成产品可以考虑加入锂电池充放电管理电路配合JDY-18的低功耗特性可以实现数月待机。我在面包板上测试的完整系统在5V供电下驱动3个LED总电流约60mA完全可以用移动电源供电。

更多文章