【问题标题】:Arduino and RC TransmitterArduino 和 RC 发射器
【发布时间】:2013-02-11 07:19:19
【问题描述】:

我是 Arduino 和这个论坛的新手,这是我除了教程之外的第一个 Arduino 项目。

我正在尝试使用 rc 发射器/接收器和 Arudino 来控制伺服。我使用 Arduino 而不是将伺服直接连接到 RC 接收器的原因是 RC 只能生成 1000µs 到 2000µs 的 PWM,而我需要 600µs 到 2400µs 的 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 
}

【问题讨论】:

  • 伺服由脉冲宽度调制信号控制。宽度单位是时间,而不是频率。在上面的问题中,输入的值为 1000 - 2000 微秒。所需的输出是 600 - 2400 微秒以获得完整的角旋转。在问题中添加“Hz”的编辑不正确。

标签: arduino


【解决方案1】:

您正在溢出 int 数据类型。带符号的值只能是 -32768 到 +32767。见int docs

您的公式都是 int 的,编译器不会猜测您可能需要更大的中间值。乘以 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);
}

【讨论】:

    【解决方案2】:

    请注意,您可能在https://robotics.stackexchange.com/ 上获得更多 Arduino/伺服运气。

    您在串行输出上看到了什么? ch3 是从 0 循环到 45 还是从 0 循环到 180?不要忘记map() 旨在完成您在此处手动执行的操作。

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

    【讨论】:

      猜你喜欢
      • 2020-06-13
      • 2021-11-06
      • 1970-01-01
      • 2013-07-30
      • 2016-10-27
      • 1970-01-01
      • 1970-01-01
      • 2014-08-26
      • 2012-06-24
      相关资源
      最近更新 更多