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

伺服电机无法持续转动问题排查及代码优化需求

问题根源

原代码里的degrees数组是全局变量,但Move_motor函数接收的degree是传值参数——也就是说函数里修改的只是这个参数的副本,根本没更新全局的degrees数组。所以每次loop执行时,电机的度数还是初始的0,只能动一次5度,下一次循环又从0开始,看起来就像只转了瞬间就停了。另外,四次重复调用Move_motor完全可以用循环简化,避免冗余代码。

修复后的完整代码

#include <Adafruit_PWMServoDriver.h>
#include <Wire.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

const int MOTOR_COUNT = 4;
int motors[] = {0, 1, 2, 3};
int degrees[] = {0, 0, 0, 0};

void setup() {
  Serial.begin(9600);
  pwm.begin();
  pwm.setPWMFreq(50);
  pwm.setOscillatorFrequency(27000000); 
  
  // 初始化所有16个通道到0度位置
  for(int i=0; i<16; i++){
    pwm.setPWM(i, 0, 150);   
  }
  
  Serial.setTimeout(10);
}

// 单个电机的步进控制,直接操作全局degrees数组
void Move_motor(int motorIndex, int int_val){
  int &currentDegree = degrees[motorIndex]; // 引用全局数组的对应元素
  int motorPin = motors[motorIndex];
  
  if(int_val <= 1){
    currentDegree += 5;
    if(currentDegree > 180) currentDegree = 180;
        
    int pul = map(currentDegree, 0, 180, 150, 600);
    pwm.setPWM(motorPin, 0, pul);
  }
  
  else if(int_val >= 4){
    currentDegree -= 5;
    if(currentDegree < 0) currentDegree = 0;
        
    int pul = map(currentDegree, 0, 180, 150, 600);
    pwm.setPWM(motorPin, 0, pul);
  }
  // 中间值(int_val=2或3)对应操纵杆松开,电机停止
}

void loop() { 
  int analogPin[MOTOR_COUNT];
  int int_Pin[MOTOR_COUNT];
  
  // 批量读取操纵杆值并转换
  for(int i=0; i<MOTOR_COUNT; i++){
    analogPin[i] = analogRead(A0 + i); // 依次读取A0到A3引脚
    int_Pin[i] = map(analogPin[i], 0, 1023, 0, 5);
  }
  
  // 循环控制所有电机,替代四次重复调用
  for(int i=0; i<MOTOR_COUNT; i++){
    Move_motor(i, int_Pin[i]);
  }
  
  // 打印调试信息
  for(int j=0; j<MOTOR_COUNT; j++){
    Serial.print(int_Pin[j]);
    Serial.print("   "); 
  }       
  Serial.println("");
  
  // 可选:控制电机转动速度,可根据需求调整延迟时间
  delay(50);
}

关键修改说明

  • 修复度数更新问题:让Move_motor接收电机索引,直接引用全局的degrees数组元素,确保每次步进的度数能被保存,下次循环从当前度数继续转动。
  • 简化冗余代码:用MOTOR_COUNT常量统一管理电机数量,读取引脚、控制电机都用循环,避免重复写四次调用代码。
  • 优化引脚读取逻辑:通过A0 + i直接遍历A0到A3引脚,代码更简洁。
  • 调整初始化通道数:原代码初始化15个通道,驱动板实际是16通道,修正为i<16更准确。
  • 增加速度控制:loop里的delay(50)可以减缓电机步进速度,避免卡顿,可根据实际需求调整。

现在操纵杆保持拨动时,电机会持续步进转动直到极限位置;松开操纵杆时,电机停止在当前位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 21:13:23