手把手教你用STM32F103C8T6和JDY-23蓝牙模块做个手机遥控小夜灯(附完整代码)
从零打造智能蓝牙小夜灯STM32F103C8T6与JDY-23实战指南深夜起床开灯刺眼的体验想必大家都不陌生。去年冬天我女儿总被卧室顶灯惊醒于是萌生了制作可调光小夜灯的想法。经过多次迭代这套基于STM32和蓝牙模块的解决方案不仅解决了实际问题还成了全家都爱不释手的智能小物件。下面就将这个项目的完整实现过程分享给大家包含硬件选型技巧、协议设计思路和可商用的代码架构。1. 硬件选型与核心组件解析选择适合的硬件是项目成功的第一步。经过对比测试我最终确定的硬件组合在性价比和易用性上达到了完美平衡主控芯片STM32F103C8T6Blue Pill开发板72MHz Cortex-M3内核完全胜任蓝牙通信控制丰富的GPIO和USART接口市场价格约15-25元性价比极高蓝牙模块JDY-23 vs HC-05深度对比特性JDY-23HC-05协议版本蓝牙5.0蓝牙2.1工作电流8mA(连接状态)30-40mA传输距离60米10米默认波特率960038400价格约12元约25元提示JDY-23的BLE特性使其更适合电池供电场景而HC-05在需要音频传输时更有优势LED选择建议使用5730贴片LED亮度可达60-80流明工作电压3.2-3.4V需配合铝基板散热2. 硬件连接与电路设计正确的电路连接是项目稳定的基础。下面是最小系统的接线方案/* 引脚定义 */ #define LED_PIN GPIO_Pin_1 // PA1 #define BT_TX_PIN GPIO_Pin_9 // PA9 (USART1_TX) #define BT_RX_PIN GPIO_Pin_10 // PA10 (USART1_RX) #define OLED_SCL GPIO_Pin_8 // PB8 #define OLED_SDA GPIO_Pin_9 // PB9实际接线时需注意电源处理开发板USB供电时需确保蓝牙模块和LED共用3.3V电池供电场景建议增加LC滤波电路信号线处理TX/RX交叉连接MCU_TX→BT_RXMCU_RX→BT_TXI2C总线需加上拉电阻4.7KΩLED驱动电路graph LR PA1 --|限流电阻| LED -- GND实际项目中请替换此图表为文字描述注意使用PWM调光时MOSFET驱动比三极管方案效率更高3. 蓝牙通信协议设计稳定的通信协议是项目成功的关键。我设计的协议框架经过3个月实际使用零故障协议格式[命令类型][参数]*#[校验和]完整指令集基础控制LED_ON*#开启灯光LED_OFF*#关闭灯光高级功能LED_DIM50*#设置50%亮度LED_CLRFF0000*#设置RGB颜色GET_STATUS*#获取当前状态协议解析核心代码void USART1_IRQHandler(void) { static uint8_t state 0; static uint8_t index 0; uint8_t rxData USART_ReceiveData(USART1); switch(state) { case 0: // 等待起始符 if(rxData !rxFlag) state 1; break; case 1: // 接收命令内容 if(rxData *) state 2; else buffer[index] rxData; break; case 2: // 验证结束符 if(rxData #) { buffer[index] \0; rxFlag 1; index 0; state 0; } break; } USART_ClearITPendingBit(USART1, USART_IT_RXNE); }4. 完整软件架构实现采用模块化设计方便后续功能扩展工程目录结构├── CMSIS ├── Libraries ├── User │ ├── main.c │ ├── bluetooth.c │ ├── led.c │ ├── oled.c │ └── protocol.c └── Project关键功能实现蓝牙模块初始化void BT_Init(uint32_t baudrate) { USART_InitTypeDef USART_InitStruct; // 时钟使能代码省略... USART_InitStruct.USART_BaudRate baudrate; USART_InitStruct.USART_WordLength USART_WordLength_8b; USART_InitStruct.USART_StopBits USART_StopBits_1; USART_InitStruct.USART_Parity USART_Parity_No; USART_InitStruct.USART_Mode USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART1, USART_InitStruct); USART_Cmd(USART1, ENABLE); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); }PWM调光实现void LED_SetBrightness(uint8_t percent) { TIM_OCInitTypeDef TIM_OCInitStruct; uint16_t pulse (percent * LED_MAX_PULSE) / 100; TIM_OCInitStruct.TIM_OCMode TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse pulse; TIM_OCInitStruct.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC2Init(TIM3, TIM_OCInitStruct); }5. 项目优化与扩展方向基础功能实现后可以考虑以下增强功能低功耗优化启用STM32的STOP模式配置蓝牙模块自动休眠硬件上增加电源管理电路手机APP开发使用MIT App Inventor快速原型开发Android Studio开发专业控制界面加入情景模式阅读/夜灯/唤醒云端接入# 示例MQTT消息转发 import paho.mqtt.client as mqtt def on_connect(client, userdata, flags, rc): client.subscribe(home/bedroom/light) def on_message(client, userdata, msg): if msg.payload.decode() ON: # 发送蓝牙指令 ble_send(LED_ON*#) client mqtt.Client() client.on_connect on_connect client.on_message on_message client.connect(mqtt.server.com, 1883, 60) client.loop_forever()实际部署时发现在2.4GHz WiFi密集区域调整蓝牙信道能显著改善稳定性。通过AT指令修改JDY-23的工作信道ATCH10\r\n这个项目最让我惊喜的是孩子的反应——她现在已经会用自己的平板电脑调节灯光颜色了。技术真正的价值不就在于让生活变得更美好吗