2013-02-11 111 views
4

我是Arduino和本次论坛的新手,这是我除了教程之外的第一个Arduino项目。Arduino和RC发射器

我想用rc发射器/接收器和Arudino来控制伺服器。我使用Arduino而不是直接连接到RC接收器的原因是,RC只能产生1000Hz到2000Hz的PWM,而我需要600Hz到2400Hz的PWM来获得我的伺服器的全部运动范围。我试图做的是从pulseIn()读取值,然后将此值映射到0到180度,如下面的代码(使用伺服库)所写。

但是,使用此代码时,电机行为很奇怪。当我将无线电发射器控制杆移动通过它的运动范围时,电机从0度旋转到45度,从45度旋转到0度,0度到45度,再次回到0度,而不是从0度旋转到180度。任何人都可以请提供一些帮助或建议吗?

非常感谢您

#include <Servo.h> 
Servo myservo; 

int ch1; 
int ch2; 
int ch3; 
int degree; 

void setup() { 
    pinMode(7, INPUT); 
    myservo.attach(9); 
    Serial.begin(9600); 
} 

void loop() { 
    ch3 = pulseIn(7, HIGH, 25000); 
    degree = ((ch3-1250)* 180)/700; 
    Serial.print("Channel 3:"); 
    Serial.println(ch3); 
    myservo.write(degree); 
    delay(5); // waits 5ms for the servo to reach the position 
} 
+0

舵机通过脉宽调制信号进行控制。宽度上的单位是时间,而不是频率。在上面的问题中,输入的值是1000 - 2000微秒。所需的输出是600 - 2400微秒以获得完整的角度旋转。将“Hz”添加到问题的编辑不正确。 – jdr5ca 2013-02-13 07:53:36

回答

0

作为一个说明,你可以有更多的https://robotics.stackexchange.com/的Arduino /伺服运气。

你在串口输出中看到了什么? ch3是从0到45还是从0到180循环?不要忘记,map()旨在做你在这里手工做的事情。

我的第一个怀疑是,你偶尔会从pulseIn回0,或者是因为你超时,或者你是在脉搏中间开始阅读(这可能导致脉搏比预期的要短) )。

3

您正在溢出int数据类型。有符号值只能是-32768到+32767。请参阅int docs

您的公式全部为int's且编译器不会猜测您可能需要更大的中间值。乘以180是一个红旗。 (2000-1250)* 180 = 135000 =繁荣

要了解数学,请将公式分解为下面的测试程序中显示的各个操作。这实际上就是编译器为你做的。

运行下面的程序,您将看到失败。在out值达到45之后,中间值溢出并且公式分解。

in: 1040 out: 39 t0: -210 t1: 27736 t2: 39 
in: 1048 out: 41 t0: -202 t1: 29176 t2: 41 
in: 1056 out: 43 t0: -194 t1: 30616 t2: 43 
in: 1064 out: 45 t0: -186 t1: 32056 t2: 45 
in: 1072 out: -45 t0: -178 t1: -32040 t2: -45 
in: 1080 out: -43 t0: -170 t1: -30600 t2: -43 

将以下程序用作测试夹具。修改数据类型以使用unsigned int,您将可以使输出按照您的需要运行。

int ch3; 
int degree; 

void setup() { 
    ch3 = 1000; 
    Serial.begin(9600); 
} 

void loop() { 
    int t0, t1, t2; 

    degree = ((ch3-1250)* 180)/700; 

    t0 = ch3 - 1250; 
    t1 = t0 * 180; 
    t2 = t1/700; 

    Serial.print("in: "); 
    Serial.print(ch3); 
    Serial.print(" out: "); 
    Serial.print(degree); 
    Serial.print(" t0: "); 
    Serial.print(t0); 
    Serial.print(" t1: "); 
    Serial.print(t1); 
    Serial.print(" t2: "); 
    Serial.println(t2); 

    ch3 += 8; 
    if(ch3 > 2400) { 
     ch3 = 1000; 
    } 

    delay(100); 
}