尧图精选

基于STM32与HC-05蓝牙的智能家居控制系统设计与实现

🕒 发布时间:2026/9/3 2:11:12 📁 来源:尧图网络
想用STM32做个智能家居项目但Wi-Fi配置太麻烦每次改路由器密码都得重新烧录固件想用手机直接控制又不想折腾复杂的网络协议栈如果你正在寻找一个低成本、易上手、且能快速看到效果的嵌入式物联网方案那么“蓝牙版”的智能家居设计可能就是那个被你忽略的“最优解”。很多人一提到智能家居第一反应就是ESP8266/ESP32配Wi-Fi上云平台。这当然强大但对于一个旨在学习STM32、理解设备间直接通信、或快速搭建原型验证想法的开发者来说这套组合拳的门槛和复杂度可能远超你的实际需求。蓝牙特别是经典蓝牙Bluetooth Classic提供了一个更轻量、更直接的“设备到设备”通信通道。它不需要路由器不需要复杂的网络配置手机就是天然的控制中心和网关。基于STM32和蓝牙模块的方案其核心价值在于用最小的软硬件开销实现最直观的“手机-设备”交互闭环让你专注于设备控制逻辑本身而非网络基础设施。本文将带你从零开始完成一个基于STM32和HC-05蓝牙模块的智能家居控制系统设计。你不会只看到一堆代码和电路图我们会深入探讨为什么在Wi-Fi和低功耗蓝牙BLE大行其道的今天经典蓝牙方案依然有独特的适用场景如何避开蓝牙配置中的那些“坑”以及如何构建一个稳定、可扩展的固件框架。最终你将获得一个可以通过手机蓝牙串口APP控制LED、风扇用电机模块模拟、获取温湿度数据如DHT11的完整项目并掌握将任意STM32外设接入蓝牙控制的核心方法。1. 项目核心我们要解决什么问题这个项目看似是控制几个LED但其内核是一个通用的“命令-响应”式设备控制框架。我们真正要解决的是三个层次的问题通信层简化如何让单片机摆脱对Wi-Fi路由器和云服务的依赖实现与智能终端主要是手机的直连通信蓝牙串口模块将复杂的蓝牙协议栈转化为简单的串口数据透传使得STM32无需处理任何蓝牙协议只需像操作串口一样收发数据极大降低了开发门槛。控制协议设计如何定义一套简单、高效、可扩展的指令集让手机APP发送的字符串能够精确控制不同的设备状态并查询传感器数据这涉及到数据帧格式设计、解析器实现和状态机管理。系统稳定性如何确保在无线通信可能不稳定的情况下设备行为依然可靠例如蓝牙断开后设备应如何反应收到非法指令怎么办这需要我们在固件中考虑超时处理、指令校验和默认安全状态。对于学习者而言这个项目的价值远大于一个点灯实验。你将综合运用STM32的GPIO、定时器、USART、中断等核心外设并实践模块化编程和通信协议设计的思想。它为你打开了物联网设备开发的一扇门之后无论是转向更复杂的Wi-Fi物联网还是深入研究低功耗蓝牙BLE这里积累的经验都是宝贵的基石。2. 硬件选型与核心模块剖析工欲善其事必先利其器。一个清晰的硬件清单和模块理解是成功的第一步。2.1 硬件清单模块名称型号/关键参数在项目中的作用备注主控MCUSTM32F103C8T6 (核心板)系统大脑执行控制逻辑处理通信数据“蓝色药丸”核心板性价比高资源丰富。蓝牙模块HC-05 (主从一体)桥接STM32与手机实现无线串口透传经典蓝牙工作于2.4GHz兼容性强。温湿度传感器DHT11采集环境温湿度数据单总线协议精度适用于一般场景。执行单元1LED灯 (或继电器模块)模拟智能灯开关通过GPIO高低电平控制。执行单元2直流电机驱动模块(如L9110S)模拟智能风扇/窗帘开关PWM控制可实现调速。电源5V/2A USB适配器或3.7V锂电池为整个系统供电确保电流足够尤其电机启动时。其他杜邦线、面包板、USB转TTL调试器连接与调试必备。为什么是HC-05而不是BLE或Wi-Fi模块HC-05 (经典蓝牙)协议简单即插即用手机无需特定APP通用蓝牙串口APP即可连接稳定后带宽足够传输控制指令和传感器数据。适合连续数据流和实时控制场景学习成本最低。BLE (如HM-10)超低功耗但连接和通信模型复杂需要理解GATT、服务、特征值适合间歇性上报数据的传感器设备。对于需要频繁双向通信的控制场景开发难度更高。Wi-Fi模块 (如ESP-01S)需要配置网络依赖路由器可接入互联网功能最强大但复杂度最高功耗也更大。对于入门级智能家居控制原型HC-05在易用性和功能上取得了最佳平衡。2.2 电路连接示意图核心部分理解接线是硬件开发的基础。下图展示了最关键的STM32、HC-05和LED/电机的连接关系[文字描述连接图] STM32F103C8T6 HC-05蓝牙模块 执行单元 ------------------ ---------------- --------------- | | | | | | | PA9 (TX) ---|-----| RXD | | | | PA10(RX) ---|-----| TXD | | | | | | | | | | VCC (3.3V) --|-----| VCC | | | | GND ---------|-----| GND | | | | | | | | | | PA1 (PWM) ------------------------------| IN1 | L9110S |-- 电机 | PC13 (LED) ------------------------------| LED 阳极 | | | | (串联电阻) | | | | | ------------------ --------------- | | | | USB供电 公共地(GND)接线说明与注意事项电平匹配HC-05虽然支持3.3V-5V供电但其串口通信引脚是3.3V TTL电平。STM32F103的IO口也是3.3V因此可以直接连接。如果使用5V单片机如Arduino则需要在RX/TX线上加电平转换电路。电源去耦为蓝牙模块供电时建议在VCC和GND之间并联一个100uF的电解电容和一个0.1uF的瓷片电容以滤除电源噪声增强通信稳定性。状态引脚HC-05的STATE引脚可连接STM32的IO口用于检测蓝牙连接状态高电平表示已连接。本项目为简化暂不使用通过通信超时来判断连接。按键引脚HC-05的KEY引脚用于切换AT命令模式接高电平进入。我们通常通过USB转TTL模块在配置时使用系统运行时悬空即可。3. 软件架构与通信协议设计在动手写代码前设计好软件框架和通信协议能让开发过程事半功倍代码也更清晰健壮。3.1 系统软件架构我们采用分层和模块化的设计思想将系统划分为以下几个部分应用层 (Application) | |-- 命令解析器 (Parser) |-- 设备控制逻辑 (LED, Fan, Sensor) | 通信层 (Communication) | |-- 数据接收缓冲区 (Ring Buffer/USART IRQ) |-- 数据发送接口 | 硬件抽象层 (HAL) | |-- USART驱动 (用于蓝牙) |-- GPIO驱动 (用于LED) |-- TIM驱动 (用于PWM生成) |-- 外设驱动 (DHT11, 电机驱动) | 硬件层 (Hardware) | |-- STM32 MCU |-- HC-05, DHT11, LED, Motor etc.各层职责硬件层物理设备。硬件抽象层利用STM32 HAL库或标准库初始化并操作具体外设。这是与硬件直接打交道的一层。通信层负责通过USART与HC-05模块进行数据收发。核心是利用串口中断实现非阻塞数据接收将数据存入环形缓冲区避免数据丢失。应用层命令解析器从通信层的缓冲区中取出完整的数据帧根据预设的协议格式进行解析提取出命令和参数。设备控制逻辑根据解析出的命令调用硬件抽象层的接口执行具体的操作如开关灯、调节风扇速度、读取传感器并返回数据。3.2 自定义通信协议设计蓝牙串口传输的是原始字节流。我们需要定义一套简单的协议让STM32能理解手机发来的指令。协议设计的原则是简单、可扩展、有一定容错能力。我们设计一个基于“帧头命令参数帧尾”的文本协议格式#CMD,PARAM1,PARAM2,...; 示例#LED,ON; // 打开LED #FAN,128; // 设置风扇PWM占空比为128 (50%) #GET,TEMP; // 获取温度 #GET,HUMI; // 获取湿度帧头#用于标识一帧数据的开始。命令CMD如LEDFANGET。参数PARAM多个参数用逗号分隔。如ON/OFF 具体的PWM值或子命令TEMP。帧尾;用于标识一帧数据的结束。方便在流式数据中分割数据包。为什么用文本协议而不是二进制协议可读性强调试方便可以直接在串口助手中输入指令测试。易于实现解析简单使用strtok等字符串函数即可。足够使用对于本项目这种小数据量、控制型的应用文本协议的开销可以接受。在应用层我们需要实现一个状态机式的解析器依次寻找帧头、收集数据、验证帧尾最终提取出有效的命令和参数。4. 开发环境搭建与工程配置我们使用STM32CubeIDE进行开发它集成了STM32CubeMX图形化配置和Eclipse IDE非常适合初学者和快速原型开发。4.1 STM32CubeMX工程配置选择MCU新建工程选择STM32F103C8Tx。系统核心SYS-Debug: 选择Serial Wire(SWD调试)。RCC-High Speed Clock (HSE): 选择Crystal/Ceramic Resonator如果核心板有外部8MHz晶振。配置USART2用于蓝牙找到USART2。Mode选择Asynchronous(异步通信)。Parameter Settings:Baud Rate: 9600 (HC-05默认可后续在AT命令中修改为115200等)Word Length: 8 BitsParity: NoneStop Bits: 1Over Sampling: 16 SamplesNVIC Settings标签页使能USART2 global interrupt。这一步至关重要用于中断接收。配置GPIOPC13配置为GPIO_Output用于控制LED。初始输出电平设为低。PA1配置为TIM2_CH2用于产生PWM控制电机。后续在TIM2配置中设置。配置定时器TIM2用于PWM找到TIM2。Clock Source选择Internal Clock。Channel2选择PWM Generation CH2。Parameter Settings:Prescaler (PSC): 72-1 (系统时钟72MHz分频后为1MHz)Counter Period (ARR): 1000-1 (PWM频率 1MHz / 1000 1kHz)Pulse (占空比): 初始设为0。此时PA1会自动被配置为复用推挽输出。生成代码在Project Manager标签页设置好工程名、路径、IDESTM32CubeIDE。Code Generator中选择“为每个外设生成独立的.c/.h文件”。点击GENERATE CODE。4.2 关键代码中断接收与环形缓冲区STM32CubeMX生成的代码已经初始化好了外设。我们需要在main.c和自定义文件中添加业务逻辑。首先实现一个环形缓冲区ring_buffer.c/h来安全地存储串口接收到的数据。// ring_buffer.h #ifndef __RING_BUFFER_H #define __RING_BUFFER_H #include stdint.h #include stdbool.h #define RBUF_SIZE 256 // 缓冲区大小可根据需要调整 typedef struct { uint8_t buffer[RBUF_SIZE]; uint16_t head; // 写指针 uint16_t tail; // 读指针 } ring_buffer_t; void rbuf_init(ring_buffer_t *rbuf); bool rbuf_put(ring_buffer_t *rbuf, uint8_t data); bool rbuf_get(ring_buffer_t *rbuf, uint8_t *data); uint16_t rbuf_available(ring_buffer_t *rbuf); bool rbuf_is_empty(ring_buffer_t *rbuf); bool rbuf_is_full(ring_buffer_t *rbuf); #endif// ring_buffer.c #include ring_buffer.h void rbuf_init(ring_buffer_t *rbuf) { rbuf-head 0; rbuf-tail 0; } bool rbuf_put(ring_buffer_t *rbuf, uint8_t data) { uint16_t next_head (rbuf-head 1) % RBUF_SIZE; if (next_head rbuf-tail) { return false; // 缓冲区满 } rbuf-buffer[rbuf-head] data; rbuf-head next_head; return true; } bool rbuf_get(ring_buffer_t *rbuf, uint8_t *data) { if (rbuf_is_empty(rbuf)) { return false; } *data rbuf-buffer[rbuf-tail]; rbuf-tail (rbuf-tail 1) % RBUF_SIZE; return true; } uint16_t rbuf_available(ring_buffer_t *rbuf) { return (rbuf-head - rbuf-tail RBUF_SIZE) % RBUF_SIZE; } bool rbuf_is_empty(ring_buffer_t *rbuf) { return (rbuf-head rbuf-tail); } bool rbuf_is_full(ring_buffer_t *rbuf) { return ((rbuf-head 1) % RBUF_SIZE) rbuf-tail; }接着在main.c中重写USART2的中断回调函数将接收到的数据存入环形缓冲区。// main.c 顶部添加 #include ring_buffer.h ring_buffer_t uart2_rx_buf; // 在 /* USER CODE BEGIN 0 */ 区域添加 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart-Instance USART2) { uint8_t rx_byte 0; // 从UART数据寄存器读取一个字节 rx_byte (uint8_t)(huart-Instance-DR 0xFF); // 存入环形缓冲区 rbuf_put(uart2_rx_buf, rx_byte); // 重新使能接收中断等待下一个字节 HAL_UART_Receive_IT(huart2, rx_byte, 1); } }在main函数的初始化部分启动串口接收中断。// 在 /* USER CODE BEGIN 2 */ 区域添加 uint8_t rx_temp; HAL_UART_Receive_IT(huart2, rx_temp, 1); // 启动第一次接收中断 rbuf_init(uart2_rx_buf); // 初始化环形缓冲区5. 命令解析器与设备控制实现有了数据接收机制接下来实现应用层的命令解析和设备控制。5.1 命令解析器实现创建一个command_parser.c/h文件。// command_parser.h #ifndef __COMMAND_PARSER_H #define __COMMAND_PARSER_H #include ring_buffer.h #define MAX_CMD_LEN 64 #define MAX_PARAMS 5 typedef struct { char cmd[16]; char params[MAX_PARAMS][16]; uint8_t param_cnt; } parsed_command_t; void parser_init(void); bool parser_process(ring_buffer_t *rbuf, parsed_command_t *pcmd); void exec_command(parsed_command_t *pcmd); #endif// command_parser.c #include command_parser.h #include string.h #include stdio.h #include main.h // 用于调用设备控制函数 #include dht11.h // 假设有DHT11驱动 // 外部设备控制函数声明 extern void led_set_state(bool state); extern void fan_set_speed(uint8_t speed); extern float read_temperature(void); extern float read_humidity(void); static char rx_line_buffer[MAX_CMD_LEN]; static uint8_t line_index 0; static bool frame_started false; void parser_init(void) { line_index 0; frame_started false; memset(rx_line_buffer, 0, sizeof(rx_line_buffer)); } bool parser_process(ring_buffer_t *rbuf, parsed_command_t *pcmd) { uint8_t ch; while (rbuf_get(rbuf, ch)) { // 1. 寻找帧头 # if (!frame_started) { if (ch #) { frame_started true; line_index 0; } continue; } // 2. 接收字符直到帧尾 ; 或缓冲区满 if (ch ;) { // 找到帧尾完成一帧 rx_line_buffer[line_index] \0; // 字符串结束符 frame_started false; // 开始解析这一行命令 return parse_line(rx_line_buffer, pcmd); } else { if (line_index (MAX_CMD_LEN - 1)) { rx_line_buffer[line_index] ch; } else { // 行缓冲区溢出丢弃本帧重新开始 frame_started false; line_index 0; } } } return false; // 没有解析出完整命令 } static bool parse_line(char *line, parsed_command_t *pcmd) { memset(pcmd, 0, sizeof(parsed_command_t)); char *token; token strtok(line, ,); if (token NULL) return false; strncpy(pcmd-cmd, token, sizeof(pcmd-cmd)-1); while ((token strtok(NULL, ,)) ! NULL pcmd-param_cnt MAX_PARAMS) { strncpy(pcmd-params[pcmd-param_cnt], token, sizeof(pcmd-params[0])-1); pcmd-param_cnt; } return true; } void exec_command(parsed_command_t *pcmd) { char response[64]; if (strcmp(pcmd-cmd, LED) 0) { if (pcmd-param_cnt 0) { if (strcmp(pcmd-params[0], ON) 0) { led_set_state(true); sprintf(response, #OK,LED ON;\r\n); } else if (strcmp(pcmd-params[0], OFF) 0) { led_set_state(false); sprintf(response, #OK,LED OFF;\r\n); } else { sprintf(response, #ERR,INVALID PARAM;\r\n); } HAL_UART_Transmit(huart2, (uint8_t*)response, strlen(response), 100); } } else if (strcmp(pcmd-cmd, FAN) 0) { if (pcmd-param_cnt 0) { int speed atoi(pcmd-params[0]); if (speed 0 speed 255) { fan_set_speed((uint8_t)speed); sprintf(response, #OK,FAN %d;\r\n, speed); } else { sprintf(response, #ERR,SPEED 0-255;\r\n); } HAL_UART_Transmit(huart2, (uint8_t*)response, strlen(response), 100); } } else if (strcmp(pcmd-cmd, GET) 0) { if (pcmd-param_cnt 0) { if (strcmp(pcmd-params[0], TEMP) 0) { float temp read_temperature(); sprintf(response, #TEMP,%.1f;\r\n, temp); HAL_UART_Transmit(huart2, (uint8_t*)response, strlen(response), 100); } else if (strcmp(pcmd-params[0], HUMI) 0) { float humi read_humidity(); sprintf(response, #HUMI,%.1f;\r\n, humi); HAL_UART_Transmit(huart2, (uint8_t*)response, strlen(response), 100); } } } else { sprintf(response, #ERR,UNKNOWN CMD;\r\n); HAL_UART_Transmit(huart2, (uint8_t*)response, strlen(response), 100); } }5.2 设备驱动与控制函数在main.c或独立的驱动文件中实现设备控制。// 在 main.c 的 /* USER CODE BEGIN 4 */ 区域或 device_control.c 中 // LED控制 void led_set_state(bool state) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, state ? GPIO_PIN_SET : GPIO_PIN_RESET); } // 风扇PWM控制 void fan_set_speed(uint8_t speed) { // speed: 0-255 对应 0%-100% 占空比 // ARR设置为1000所以Pulse speed * 1000 / 255 uint32_t pulse (speed * 1000) / 255; __HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_2, pulse); } // DHT11读取 (伪代码需根据实际DHT11驱动实现) float read_temperature(void) { // 调用DHT11驱动读取温度 // return temperature; return 25.5f; // 示例返回值 } float read_humidity(void) { // 调用DHT11驱动读取湿度 // return humidity; return 60.0f; // 示例返回值 }5.3 主循环集成最后在main函数的while (1)循环中整合所有模块。// 在 /* USER CODE BEGIN WHILE */ 区域 parsed_command_t cmd; parser_init(); while (1) { // 1. 检查并解析命令 if (parser_process(uart2_rx_buf, cmd)) { // 2. 执行命令 exec_command(cmd); } // 3. 可以在这里添加其他任务如传感器定时读取 // HAL_Delay(100); // 注意避免长时间阻塞建议用定时器 /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }6. 手机端控制与系统联调硬件和软件都准备好后进入激动人心的联调阶段。6.1 手机APP选择与配置在手机应用商店搜索“蓝牙串口”会有很多选择如“蓝牙串口助手”、“Serial Bluetooth Terminal”等。选择一款评价好的即可。关键操作步骤给系统上电HC-05模块上的LED会快速闪烁处于可配对状态。打开手机蓝牙设置搜索设备找到“HC-05”并配对。默认配对密码通常是“1234”或“0000”。打开蓝牙串口APP连接“HC-05”。连接成功后HC-05模块的LED会变为慢闪或常亮取决于型号。6.2 指令测试流程在APP的发送区输入以下指令进行测试测试LED发送#LED,ON;预期核心板上的LED或外接LED点亮APP可能收到回复#OK,LED ON;。发送#LED,OFF;预期LED熄灭回复#OK,LED OFF;。测试风扇电机发送#FAN,0;预期电机停止。发送#FAN,128;预期电机以中等速度转动。发送#FAN,255;预期电机全速转动。测试传感器查询发送#GET,TEMP;预期收到类似#TEMP,25.5;的回复。发送#GET,HUMI;预期收到类似#HUMI,60.0;的回复。6.3 调试技巧与问题排查问题现象可能原因排查步骤手机搜不到HC-051. 模块未供电或损坏。2. 模块处于AT模式LED慢闪。3. 手机蓝牙问题。1. 检查VCC/GND连接测量电压。2. 尝试给KEY引脚接高电平再上电用USB转TTL连接通过串口助手发送AT命令测试成功后发送ATRESET重启进入正常模式。3. 重启手机蓝牙或换一部手机测试。APP连接失败1. 配对密码错误。2. 模块已被其他设备连接。1. 尝试默认密码“1234”或“0000”。2. 断开其他设备连接或让模块断电重启。连接成功但发送指令无反应1. 串口波特率不匹配。2. STM32程序未运行或卡死。3. 指令格式错误。1. 确认STM32程序配置的波特率如9600与HC-05当前波特率一致。可用AT命令ATUART?查询并修改。2. 用调试器或串口打印检查STM32程序是否正常运行到主循环。3. 检查指令格式确保有#开头和;结尾无多余空格或中文符号。用PC串口助手直接连接STM32的USART2_TX引脚看STM32是否有回复以隔离蓝牙问题。控制动作混乱或执行错误1. 命令解析逻辑有bug。2. GPIO引脚配置错误。3. PWM输出引脚或定时器配置错误。1. 在exec_command函数中添加调试打印确认解析出的命令和参数是否正确。2. 用万用表测量控制LED的GPIO引脚电平是否随指令变化。3. 用示波器或逻辑分析仪检查PWM引脚是否有波形输出频率和占空比是否正确。通信一段时间后死机1. 环形缓冲区溢出。2. 串口中断服务函数处理不当导致卡死。3. 堆栈溢出。1. 增大RBUF_SIZE或在rbuf_put失败时增加错误处理。2. 确保中断回调函数HAL_UART_RxCpltCallback尽可能短只做存数据操作。3. 在STM32CubeIDE中适当增大堆栈大小。7. 项目优化与扩展方向一个基础版本完成后你可以从以下几个方面深化和扩展这个项目使其更接近一个真正的产品原型。7.1 软件优化协议增强增加校验和在帧尾前加入校验字段如XOR校验提高数据传输可靠性。支持长数据定义更复杂的协议支持传输传感器历史数据、设备状态查询等。二进制协议如果追求效率可以设计二进制协议用更少的字节表达相同的含义。固件框架升级引入RTOS如FreeRTOS将蓝牙通信、命令解析、设备控制、传感器采集等任务模块化提高系统响应能力和可维护性。状态机管理为每个设备设计独立的状态机管理其工作模式如自动、手动、定时。增加功能定时任务利用STM32的RTC或定时器实现定时开关灯、风扇。情景模式定义一条指令触发多个设备动作如#MODE,HOME;同时开灯、开风扇。数据上报设备主动定时上报传感器数据而不仅仅是被动查询。7.2 硬件扩展更多传感器接入光照传感器BH1750、人体红外传感器HC-SR501实现自动灯控接入烟雾传感器实现安防报警。执行器多样化使用继电器模块控制真实的台灯、插座使用步进电机控制窗帘使用舵机控制门锁。显示与交互增加OLED屏幕显示当前状态、温湿度、连接信息等。增加按键实现本地手动控制作为蓝牙控制的补充。电源管理设计电池供电方案并加入充电管理电路使设备可便携或用于无持续电源的场景。7.3 迈向更高级的物联网本项目的蓝牙方案是点对点和局域网内的控制。如果你想实现远程控制可以蓝牙网关添加一个树莓派或ESP32作为网关它同时连接家庭Wi-Fi和多个蓝牙设备。手机APP通过互联网与网关通信网关再通过蓝牙控制设备。这是智能家居产品的常见架构。直接替换为Wi-Fi模块将HC-05换成ESP-01SAT指令模式STM32通过串口AT命令控制ESP-01S连接Wi-Fi和服务器实现真正的物联网接入。此时通信协议和代码架构可以大部分复用只是底层通信介质从蓝牙变成了TCP/IP。8. 总结从原型到产品的思考通过这个“基于STM32的智能家居设计蓝牙版”项目我们完成了一个完整的嵌入式物联网设备开发闭环从硬件选型、电路连接到固件架构设计、通信协议制定再到模块化编程、调试排错。它不仅仅是一个点灯实验而是一个可扩展的设备控制框架。经典蓝牙在智能家居原型中的独特优势再次得到验证开发极其简单无需处理网络协议栈连接稳定直接手机就是天然交互终端成本低廉HC-05模块仅需十元左右。它非常适合作为物联网入门、课程设计、毕业设计或产品前期的功能验证。然而也要看到它的局限性通信距离短通常10米内、一对一连接受限、无法直接接入互联网。因此在实际产品选型时需要根据具体场景在成本、功耗、复杂度、功能之间做出权衡。对于不需要远程控制、设备数量少、交互频繁的近距离控制场景如智能玩具、个人工位设备、实验室仪器控制这个方案依然具有生命力。下一步你可以尝试将解析器模块和硬件驱动模块封装得更独立尝试移植到其他STM32型号或者挑战前文提到的“蓝牙网关”方案将这个简单的点对点控制升级为一个真正的分布式智能家居网络。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →