如何解决Arduino伺服对象在我自己的库中不起作用
我写了一个库,供其他人慢慢将伺服器从一个位置扫到另一个位置。它没有按我的意图工作,因此我不得不从库中删除伺服对象。相反,我让新版本计算伺服位置并返回这些值。但是我真的很想知道为什么它不起作用。
带有私有Servo对象的头文件
#include <Arduino.h>
#include <Servo.h>
class ServoSweep {
public:
ServoSweep( byte _servoPin,byte _min,byte _max,byte _speed ) ; // constructor 1
ServoSweep( byte _servoPin,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 _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 _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,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对象,抖动就会开始。
伺服对象有什么问题?我认为这是必须的。
解决方法
问题最有可能是在您的构造函数中。这些行:
<div>
<img src="https://picsum.photos/200" />
</div>
构造函数中的正在尝试使用可能尚未准备好的硬件。您正在全局范围内调用构造函数,因此在init()运行并设置硬件之前可能会发生这些事情。因此,当init()确实运行时,可能是覆盖了伺服库已写入计时器1的值。
这是一个常见问题和常见的新手陷阱。构造函数应该初始化变量并设置值和事物,但是它们不是用于处理硬件的。为此,您需要可以从安装程序调用的begin()或init()方法。考虑一下伺服库如何具有必须在设置中调用的附加函数。如果有可能在构造函数中执行此操作,则他们将让构造函数获取引脚号并执行。考虑一下您需要调用Serial才能工作的begin方法。那是同一回事,需要设置硬件,您需要能够控制何时发生。
因此,再做一个方法:
servo.write( pos ) ;
servo.attach( servoPin ) ;
然后从安装程序中为每个对象调用它,并从构造函数中删除这些行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。