You need to enable JavaScript to run this app. 使用封装与继承控制Arduino舵机时舵机不工作问题排查
优惠活动
大模型
产品
解决方案
定价
更多

使用封装与继承控制Arduino舵机时舵机不工作问题排查

故障原因确认

你遇到的故障确实是全局实例化Base类的初始化时机异常导致的,核心原理如下:

  • Arduino程序的执行顺序为:先运行所有全局对象的构造函数,之后才会完成硬件底层初始化(包括PWM定时器、串口等外设的配置),最后才进入setup()函数
  • 你在全局作用域实例化Base base(SERVO_BASE)时,父类ServoPart的构造函数会立刻调用servo.attach()绑定引脚,但此时Arduino的PWM定时器还未完成初始化,attach()操作实际没有生效
  • Servo类的read()方法本身不会读取舵机的实际位置,只是返回类内部存储的上次写入的角度值,所以你调用setAngle()后getPosition()能返回正常数值,但对应的PWM信号根本没有输出到引脚,舵机自然不会转动
  • 你直接在main.cpp中创建Servo对象并调用write能正常运行,是因为你把这个Servo对象的创建放在了setup函数内部,避开了全局初始化的时机问题,attach操作执行时硬件已经就绪。
修复方案

有两种常用的修复方式:

方案1:把attach操作延后到init方法中调用

修改ServoPart类的结构,把构造函数里的attach逻辑剥离到单独的初始化方法里,在setup()中手动调用:
servoPart.h修改后代码:

#include <Servo.h>

#ifndef SERVO_PART_H
#define SERVO_PART_H

class ServoPart {
protected:
    virtual void doJob() = 0;
private:
    Servo servo;
    int _pin;
    int _minPWM;
    int _maxPWM;
public:
    // 构造函数仅存储参数,不执行attach
    ServoPart(int pin, int minPWM, int maxPWM): _pin(pin), _minPWM(minPWM), _maxPWM(maxPWM) {};

    // 新增初始化方法,在setup中调用
    void init() {
        servo.attach(_pin, _minPWM, _maxPWM);
    }

    void setAngle(int angle) {
        servo.write(angle);
    };

    int getPosition() {
        return servo.read();
    };
};
#endif

main.cpp修改后代码:

#include <Arduino.h>
#include "base.h"

#define SERVO_BASE 9

Base base(SERVO_BASE);

void setup() {
    Serial.begin(9600);
    base.init(); // 手动执行初始化,此时硬件已完成配置
    delay(500);
    base.setAngle(80);
    Serial.println(base.getPosition());
    delay(500);
    base.setAngle(110);
    Serial.println(base.getPosition());
}

void loop() {

}

方案2:使用指针延迟实例化

全局只声明Base类的指针,在setup()中再动态创建对象,保证构造函数执行时硬件已经初始化完成:
main.cpp修改后代码:

#include <Arduino.h>
#include "base.h"

#define SERVO_BASE 9

Base* base; // 仅声明指针,不实例化

void setup() {
    Serial.begin(9600);
    base = new Base(SERVO_BASE); // 此时才执行构造函数调用attach,硬件已就绪
    delay(500);
    base->setAngle(80);
    Serial.println(base->getPosition());
    delay(500);
    base->setAngle(110);
    Serial.println(base->getPosition());
}

void loop() {

}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 13:15:08