You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Arduino向Android发送初始锁状态异常致舵机故障求助

解决HC-06蓝牙连接时舵机失效的问题

看起来你遇到的核心问题是阻塞式循环占用了全部CPU资源,导致舵机无法得到足够的资源维持PWM信号。咱们一步步拆解和解决:

问题根源

你写的while(!blue.available()){ blue.println(pos); }是一个死循环——只要蓝牙模块没有数据传来,Arduino就会一直卡在这个循环里反复发送状态,完全没时间处理舵机的PWM更新(哪怕setup里已经设置了舵机位置,舵机也需要持续的信号来保持姿态,后续的操作也会被彻底阻塞)。同时,高频的串口发送也会干扰SoftwareSerial和Servo的定时器资源,让舵机彻底罢工。

修复方案

把阻塞的while改成非阻塞的if判断,这样每次loop循环都会检查一次蓝牙状态:如果没有数据,就发送一次初始状态,然后立刻继续执行后面的代码,不会卡住CPU。同时我们还要完善几个细节:

修改后的完整代码

#include <Servo.h>
#include <SoftwareSerial.h>
#include <EEPROM.h>

char state;
Servo myservo;
int btx = 3;
int brx = 2;
SoftwareSerial blue(btx, brx);
int pos = 0;

void setup() {
  Serial.begin(9600);
  myservo.attach(9);
  blue.begin(9600);
  
  // 初始化EEPROM默认状态(第一次运行时,EEPROM值为0,默认设为锁定)
  int storedState = EEPROM.read(0);
  if (storedState == 1) {
    // 解锁状态
    myservo.write(70);
    delay(200);
    pos = 1;
  } else if (storedState == 2) {
    // 锁定状态
    myservo.write(180);
    delay(200);
    pos = 2;
  } else {
    // 默认锁定
    myservo.write(180);
    delay(200);
    pos = 2;
    EEPROM.write(0, 2);
    EEPROM.commit(); // 确保数据写入EEPROM
  }

  // 连接后立即发送初始状态(加个短延时确保蓝牙连接稳定)
  delay(500);
  blue.println(pos);
}

void loop() {
  // 非阻塞式发送状态:如果蓝牙无数据,发送一次当前状态
  if (!blue.available()) {
    blue.println(pos);
    // 加个短延时避免高频发送,减轻串口压力
    delay(100);
  }

  String voice = "";
  while (blue.available()) {
    delay(10);
    char c = blue.read();
    if (c == '#') {
      break;
    }
    voice += c;
  }

  if (voice.length() > 0) {
    if (voice == "open") {
      myservo.write(70);
      pos = 1;
      EEPROM.write(0, 1);
      EEPROM.commit();
      blue.println(1);
      delay(15);
    } else if (voice == "close") {
      myservo.write(180);
      pos = 2;
      EEPROM.write(0, 2);
      EEPROM.commit();
      blue.println(2);
      delay(15);
    }
  }
}

关键改动说明

  1. 移除阻塞循环:把while(!blue.available())改成if(!blue.available()),这样每次loop只会发送一次状态,不会卡住CPU,舵机就能正常工作。
  2. 添加EEPROM默认处理:第一次运行时EEPROM值为0,我们默认设置为锁定状态,避免未知状态导致的异常。
  3. 确保EEPROM写入生效:每次EEPROM.write后调用EEPROM.commit()(Arduino 1.6.6及以上版本支持),保证状态被真正保存到EEPROM。
  4. setup中提前发送初始状态:在setup里完成舵机初始化后,加个短延时再发送状态,确保蓝牙连接稳定后能收到初始值,不需要等loop循环。
  5. 降低发送频率:在非阻塞发送后加delay(100),避免高频发送占用过多串口资源,减少和Servo的冲突。

额外注意事项

  • 如果你的Arduino是Uno/Nano这类AVR板,SoftwareSerial和Servo可能存在定时器冲突(Servo用定时器1,SoftwareSerial用定时器0或2),如果还是有问题,可以试试用硬件串口(Serial)代替SoftwareSerial,或者更换舵机引脚到不冲突的定时器通道。
  • 舵机的delay(200)是为了让舵机完成转动,这个时间可以根据你的舵机实际转动速度调整。

内容的提问来源于stack exchange,提问作者MissPaper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:16:27