Arduino伺服对象在我自己的库中不起作用



我为其他人写了一个库,让他们慢慢地将伺服从一个位置扫到另一个位置。它并没有像我想要的那样工作,我不得不从库中删除伺服对象。相反,我让新版本计算伺服位置,并返回这些值。然而,我真的很想知道为什么它不起作用。

带有专用伺服对象的头文件

#include <Arduino.h>
#include <Servo.h>
class ServoSweep {
public:
ServoSweep( byte _servoPin, byte _min, byte _max, byte _speed  ) ;        // constructor 1
ServoSweep( byte _servoPin, byte _min, byte _max, byte _speed, byte _relayPin ) ;  // constructor 2
void sweep( );
void setState( uint8_t _state );
private:
Servo servo ;
unsigned long timeToRun ;
byte pos ;
byte state ;
byte prevPos;
byte servoPin ;
byte servoSpeed ;
byte servoMin ;
byte servoMax  ;
byte middlePosition ;
byte relayPresent ;
byte relayPin ;
} ;

和源文件:

#include "ServoSweep.h"
ServoSweep::ServoSweep( byte _servoPin, byte _min, byte _max, byte _speed ) {                   // constructor 1

servoPin = _servoPin ;
servoSpeed = _speed ;
servoMin = _min ;
servoMax = _max ;

middlePosition = ( (long)servoMax - (long)servoMin ) / (long)2 + (long)servoMin ;               // start with middle position
pos = middlePosition ;
servo.write( pos ) ;
servo.attach( servoPin ) ;
}
ServoSweep::ServoSweep( byte _servoPin, byte _min, byte _max, byte _speed, byte _relayPin ) {      // constructor 2

servoPin = _servoPin ;
servoSpeed = _speed ;
servoMin = _min ;
servoMax = _max ;
middlePosition = ( (long)servoMax - (long)servoMin ) / (long)2 + (long)servoMin ;
pos = middlePosition ;
servo.write( pos ) ;
servo.attach( servoPin ) ;
relayPresent = 1;
relayPin = _relayPin ;
pinMode( relayPin, OUTPUT ) ;
}

void ServoSweep::sweep () {
if( millis() > timeToRun ) {
timeToRun = millis() + servoSpeed ;
if( state ) {
if( pos < servoMax ) pos ++ ;
}
else {
if( pos > servoMin ) pos -- ;
}
if( prevPos != pos ) {
prevPos  = pos ;
if( relayPresent == 1 ) {
if( pos < middlePosition ) digitalWrite( relayPin,  LOW ) ;
else                       digitalWrite( relayPin, HIGH ) ;
}
servo.write( pos ) ;
}
}
}
void ServoSweep::setState( uint8_t _state ) {
state = _state ;
}

伺服信号是由arduino引起的完全抖动。我使用的示例草图:


#include "ServoSweep.h"
const int inputButton = 12 ;
const int servoPin1 = 2 ;
const int servoPin2 = 3 ;
unsigned long prev ;
byte state ;
//                   pin   min max speed (bigger speed = slower movement ;
ServoSweep servo1(servoPin1, 10, 30, 50) ; 
ServoSweep servo2(servoPin2, 10, 30, 50) ; 
void setup() {
pinMode( inputButton, INPUT_PULLUP ) ;
}
void loop() {

servo1.sweep();
servo2.sweep();
if( digitalRead( inputButton ) ) servo1.setState( 1 ) ; 
else                             servo1.setState( 0 ) ;
if( digitalRead( inputButton ) ) servo2.setState( 0 ) ; 
else                             servo2.setState( 1 ) ;

}

即使我在循环中注释掉所有代码,抖动也存在。一旦构建ServoSweep对象,抖动就开始了。

伺服对象出了什么问题?我想这一定是可能的。

问题很可能出现在构造函数中。这些线路:

servo.write( pos ) ;
servo.attach( servoPin ) ;

在构造函数中,正在尝试使用可能尚未准备好的硬件。您正在全局范围内调用构造函数,因此这些事情可能会在init((运行和设置硬件之前发生。因此,当init((运行时,它可能会覆盖伺服库写入计时器1的值。

这是一个常见问题,也是一个常见的新手陷阱。构造函数应该初始化变量并设置值和东西,但它们不是用来处理硬件的。为此,您需要一个可以从安装程序调用的begin((或init((方法。想想伺服库是如何具有附加功能的,您必须从设置中调用该功能。如果可以在构造函数中做到这一点,他们会让构造函数获取引脚号并执行。想想你必须调用的begin方法才能使Serial工作。这是同样的故事,有硬件需要设置,你需要能够控制何时发生。

所以再做一个方法:

void ServoSweep::begin()  {
servo.write( pos ) ;
servo.attach( servoPin ) ;
}

并从安装程序中为每个对象调用它,并从构造函数中删除这些行。

相关内容

最新更新