我是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
}
答案 0 :(得分:3)
您正在溢出 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);
}
答案 1 :(得分:0)
作为一个注释,你可能在https://robotics.stackexchange.com/上有更多的Arduino /伺服运气。
您在串行输出上看到了什么? ch3是从0到45还是从0到180?不要忘记map()
旨在做你手边的工作。
我的第一个怀疑是,你偶尔会从pulseIn
回来0,因为你已经超时,或者你在脉冲中间开始阅读(这可能导致更短的脉搏)比你期望的那样。)