
在 RC 模型和机器人开发中舵机控制精度直接影响转向、云台稳定性和整体操控体验。传统调试方式需要反复连接电脑、修改参数、烧录固件效率低且不够直观。借助蓝牙模块实现无线调参可以实时调整舵机角度、速度、死区等参数快速优化响应曲线特别适合漂移车、航模云台等需要精细操控的场景。本文以 Arduino 和常见 SG90 舵机为例介绍如何通过 HC-05 或 HC-06 蓝牙模块搭建一套可实时调参的舵机控制系统。内容包括蓝牙通信协议设计、PWM 信号生成、参数存储与回调机制并给出完整的代码实现和调试步骤。无论你是刚接触舵机的新手还是希望优化现有 RC 系统都能按本文步骤完成一个可用的蓝牙调参模块。1. 理解舵机控制与蓝牙调参的核心机制1.1 舵机工作原理与 PWM 信号要求舵机内部通过电机、齿轮组和反馈电路构成闭环控制。其核心控制信号是 PWM脉冲宽度调制通过脉冲宽度来指定目标角度。常见舵机如 SG90 的控制信号周期为 20ms50Hz脉冲宽度在 0.5ms 到 2.5ms 之间对应 0° 到 180° 角度。舵机控制参数不仅包括目标角度还涉及转动速度、死区范围、中位校准等。手动调试时需要反复修改代码并烧录而蓝牙调参可以在运行中动态调整这些参数立即观察效果。1.2 蓝牙串口通信的基本流程HC-05、HC-06 等蓝牙模块本质是串口转无线模块配对后即可像有线串口一样收发数据。调参核心是定义一套简单协议让手机或电脑端的调试软件发送指令Arduino 解析后更新舵机参数。常用指令格式如SET:SPEED:100设置转速、SET:ANGLE:90设置角度、SAVE保存参数到 EEPROM。蓝牙调参的优势在于可实时调整并保存配置避免每次上电重新校准。1.3 参数存储与掉电保护舵机的中位值、极限角度、速度曲线等参数需要掉电保存。Arduino 的 EEPROM 可用于存储少量数据但需注意写寿命约 10 万次。在调参过程中应避免频繁保存通常只在用户确认优化完成后执行一次存储操作。2. 准备硬件与软件环境2.1 所需硬件清单组件型号/规格数量备注开发板Arduino Uno/Nano1需具备 PWM 输出和串口舵机SG90或类似 9g 舵机1工作电压 4.8-6V电流 100-200mA蓝牙模块HC-05 或 HC-061HC-05 支持主从模式HC-06 仅从模式电源5V 稳压电源1舵机单独供电避免电流不足杜邦线母对母、公对母若干连接电路电阻1kΩ、220Ω各 1可选用于蓝牙模块电平匹配2.2 软件工具与库准备Arduino IDE1.8.x 或以上串口调试助手如 CoolTerm、串口调试精灵手机端蓝牙调试 APP如 Bluetooth Terminal HC-05无需额外库使用标准 Servo 和 EEPROM 库2.3 电路连接示意图将组件按以下方式连接Arduino 5V → 蓝牙模块 VCC若电压不匹配可加电阻分压Arduino GND → 蓝牙模块 GND、舵机 GNDArduino TX (D1) → 蓝牙模块 RX可通过 1kΩ 电阻降压Arduino RX (D0) → 蓝牙模块 TX- 220Ω - Arduino RXArduino PWM 引脚 (D9) → 舵机信号线黄色/白色外部 5V 电源正极 → 舵机 VCC红色外部 5V 电源负极 → 舵机 GND棕色/黑色注意舵机工作电流较大务必单独供电避免从 Arduino 板载 USB 取电导致电压跌落或复位。3. 实现蓝牙调参的核心代码3.1 基础舵机控制与蓝牙通信以下代码实现蓝牙接收指令并控制舵机角度#include Servo.h #include EEPROM.h Servo myservo; int pos 90; // 默认角度 int speed 10; // 转动速度毫秒延迟每度 int deadzone 2; // 死区范围 void setup() { Serial.begin(9600); // 蓝牙模块默认波特率 myservo.attach(9); // 舵机信号线接 D9 myservo.write(pos); // 初始位置 loadConfig(); // 从 EEPROM 加载保存的参数 } void loop() { if (Serial.available() 0) { String command Serial.readStringUntil(\n); command.trim(); parseCommand(command); } } void parseCommand(String cmd) { if (cmd.startsWith(SET:ANGLE:)) { int newAngle cmd.substring(10).toInt(); setAngle(newAngle); } else if (cmd.startsWith(SET:SPEED:)) { speed cmd.substring(10).toInt(); Serial.println(SPEED SET: String(speed)); } else if (cmd SAVE) { saveConfig(); Serial.println(CONFIG SAVED); } } void setAngle(int target) { if (abs(target - pos) deadzone) return; // 死区判断 int step (target pos) ? 1 : -1; while (abs(target - pos) deadzone) { pos step; myservo.write(pos); delay(speed); } }3.2 参数保存与加载函数添加 EEPROM 存储功能避免每次上电重新调参struct Config { int center; int maxLeft; int maxRight; int moveSpeed; }; void loadConfig() { Config config; EEPROM.get(0, config); // 检查是否首次使用全为 0xFF if (config.center 0 || config.center 180) { config.center 90; config.maxLeft 30; config.maxRight 150; config.moveSpeed 10; EEPROM.put(0, config); } pos config.center; speed config.moveSpeed; } void saveConfig() { Config config; config.center pos; config.maxLeft 30; // 根据实际调整 config.maxRight 150; config.moveSpeed speed; EEPROM.put(0, config); }3.3 扩展指令支持与错误处理增加更多调参指令和基本校验void parseCommand(String cmd) { if (cmd.startsWith(SET:ANGLE:)) { int newAngle cmd.substring(10).toInt(); if (newAngle 0 newAngle 180) { setAngle(newAngle); Serial.println(ANGLE: String(newAngle)); } else { Serial.println(ERROR: Angle 0-180); } } else if (cmd.startsWith(SET:DEADZONE:)) { deadzone cmd.substring(13).toInt(); Serial.println(DEADZONE: String(deadzone)); } else if (cmd GET:CONFIG) { Serial.print(CENTER:); Serial.print(pos); Serial.print(,SPEED:); Serial.print(speed); Serial.print(,DEADZONE:); Serial.println(deadzone); } else { Serial.println(UNKNOWN CMD); } }4. 调试与验证步骤4.1 蓝牙配对与连接测试给 Arduino 和蓝牙模块上电蓝牙模块指示灯应快速闪烁等待配对。手机打开蓝牙设置搜索并配对 HC-05 或 HC-06默认密码 1234 或 0000。打开蓝牙调试 APP选择已配对模块建立连接。在 APP 中输入TEST并发送查看 Arduino 串口监视器是否收到数据。4.2 基础指令验证流程按顺序测试以下指令观察舵机响应测试指令预期结果排查重点SET:ANGLE:90舵机转动到中间位置电源是否充足信号线是否接对SET:ANGLE:0舵机转到最左PWM 脉冲范围是否正确SET:ANGLE:180舵机转到最右机械结构是否卡住SET:SPEED:5设置快速转动速度值是否生效SET:SPEED:50设置慢速转动延迟时间是否变化SAVE参数保存EEPROM 写入是否成功断电重启舵机回到保存位置EEPROM 读取是否正确4.3 常见问题与解决方案问题现象可能原因解决方式蓝牙连接失败模块未进入配对模式、密码错误长按模块按键进入 AT 模式检查状态舵机不转动电源不足、信号线接触不良单独供电检查杜邦线连接角度不准或抖动PWM 信号干扰、机械负载过大加滤波电容减轻舵机负载指令无响应串口波特率不匹配、指令格式错误确认蓝牙与代码波特率一致检查换行符5. 优化与扩展方向5.1 增加 PID 调节改善响应性能对于需要精确位置控制的云台可加入 PID 算法改善超调和平稳性float Kp 0.5, Ki 0.01, Kd 0.1; float error, lastError, integral, derivative; void smoothSetAngle(int target) { while (abs(target - pos) deadzone) { error target - pos; integral error; derivative error - lastError; float output Kp * error Ki * integral Kd * derivative; int step constrain(output, -5, 5); // 限制最大步进 pos step; myservo.write(pos); lastError error; delay(10); } }5.2 多舵机支持与同步控制扩展代码支持多个舵机适用于双舵机云台或复杂机械结构Servo servos[3]; int servoPins[3] {9, 10, 11}; void setup() { for (int i 0; i 3; i) { servos[i].attach(servoPins[i]); } } // 指令格式SET:SERVO:1:ANGLE:90 void parseMultiCommand(String cmd) { if (cmd.startsWith(SET:SERVO:)) { int servoIndex cmd.substring(9, 10).toInt(); int angle cmd.substring(17).toInt(); if (servoIndex 0 servoIndex 3) { servos[servoIndex].write(angle); } } }5.3 手机端调试界面开发使用 MIT App Inventor 或 Android Studio 开发简易调试界面提供滑块控制角度、按钮保存配置、实时状态显示等功能。通过蓝牙串口协议与 Arduino 通信提升调试效率。6. 生产环境注意事项6.1 电源管理与抗干扰设计舵机与控制系统电源分离避免电机噪声影响数字电路。在舵机电源端并联 100μF 电解电容和 0.1μF 陶瓷电容滤波。蓝牙模块天线远离电机和电源线减少信号衰减。6.2 通信安全与错误恢复增加指令校验码防止误触发。设置看门狗定时器在通信超时时自动恢复安全位置。关键参数设置范围限制避免极端值损坏机械结构。6.3 固件升级与维护保留蓝牙 DFU设备固件升级功能可通过无线方式更新程序。添加版本查询指令便于现场维护时确认固件版本。日志记录调参历史支持参数回滚和故障分析。蓝牙调参不仅适用于 RC 模型在机器人关节控制、摄像机云台、自动化设备定位等场景都有实用价值。掌握本方案后可进一步探索总线舵机、ESP32 蓝牙一体化方案等高级应用构建更复杂的运动控制系统。