【问题标题】:Arduino servo not working when using wrapper and inheritance使用包装器和继承时,Arduino伺服不工作
【发布时间】:2021-08-02 05:15:29
【问题描述】:

我正在构建一个相当复杂的机械臂,因此我编写了一个具有继承的类来控制不同的伺服系统,而无需编写太多代码。这些类如下所示(有些东西被省略了):

在servoPart.h中:

#include <Servo.h>

#ifndef SERVO_PART_H
#define SERVO_PART_H

 class ServoPart {
 protected:
      virtual void doJob() = 0;
 private:
      Servo servo;
 public:
      ServoPart(int pin, int minPWM, int maxPWM) {
           servo.attach(pin, minPWM, maxPWM);
      };

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

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

在base.h中:

#include "servoPart.h"

#ifndef BASE_H
#define BASE_H

class Base : public ServoPart {
private:
    void doJob() {/* implementation */};
public:
    Base(int pin, int stepsize = 5) : ServoPart(pin, 771, 2193) {
    };
};
#endif

在 main.cpp 中:

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

#define SERVO_BASE 9

Base base(SERVO_BASE);

void setup() {
    Serial.begin(9600);
    delay(500);
    base.setAngle(80);
    Serial.println(base.getPosition());    // <-- prints 80
    delay(500);
    base.setAngle(110);
    Serial.println(base.getPosition());    // <-- prints 110
}

void loop() {

}

伺服似乎设置为 80/110,但是没有任何动作。如果我在main.cpp 中创建伺服对象并在那里使用servo.write(),伺服会移动,这意味着问题不在于伺服或连接/电路。是否有可能是我初始化基础的方式出现了故障?在设置函数之前使用Base base(SERVO_BASE)

【问题讨论】:

  • 你在哪里调用那个名为servo的私有Servo的构造函数?调用 attach 是不够的。
  • @Abel 在 Base 构造函数中:Base(int pin, int stepsize) : ServoPart(pin, 771, 2193) { }。这不正确吗?
  • 你是在调用Servo伺服的构造函数时被问到的,而不是ServoPart构造函数的调用。
  • 哦,感谢您的澄清!那在 ServoPart 类中,在私有部分:Servo servo; 和构造函数 servo.attach(pin);。至少这就是我在 main.cpp 中使用伺服类时的做法。编辑:如果您看一下 Arduino IDE Servo 示例,他们会以同样的方式进行操作。使用Servo myservo; 创建一个伺服,然后调用attach 激活它

标签: c++ class inheritance arduino servo


【解决方案1】:

找到解决办法here:在构造函数中调用servo.attach()时,变量初始化的顺序搞乱了。创建一个init() 函数在setup() 中调用可以解决这个问题。

【讨论】:

    【解决方案2】:

    我想我会澄清的。 在 C++ 中,如果您没有指定的构造函数,则成员会调用其默认构造函数。

    如果以下代码不存在

    ServoPart(int pin, int minPWM, int maxPWM) {
               servo.attach(pin, minPWM, maxPWM);
          }
    

    相当于

    ServoPart():servo() {}
    

    缺少的步骤是伺服的默认构造函数。 允许您使用构造函数的解决方案是

    ServoPart(int pin, int minPWM, int maxPWM):servo() {
               servo.attach(pin, minPWM, maxPWM);
          }
    
    

    【讨论】:

    • 感谢您的回复,但问题只是我需要从 ServoPart 构造函数中单独调用附加函数。初始化Servo servo;就够了
    • 这就是人们感到困惑的原因。当以相同的顺序执行相同的步骤时,它们将产生相同的结果。有很多方法可以告诉编译器做同样的事情。有时缺少代码会导致执行更多指令。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 1970-01-01
    相关资源
    最近更新 更多