2013-02-11 5 views
4

저는 Arduino와이 포럼에 처음 왔으며이 튜토리얼 외에도 첫 번째 Arduino 프로젝트입니다.Arduino 및 RC 송신기

저는 rc 송신기/수신기와 Arudino를 사용하여 서보를 제어하려고합니다. RC 수신기에 서보를 직접 연결하는 대신 Arduino를 사용하는 이유는 RC가 1000Hz ~ 2000Hz의 PWM을 생성 할 수 있지만 내 서보의 전체 동작 범위를 얻으려면 600Hz ~ 2400Hz의 PWM이 필요하기 때문입니다 . 내가 시도한 것은 pulseIn()에서 값을 읽은 다음이 값을 아래의 코드 (서보 라이브러리를 사용)로 작성된대로 0에서 180도까지 매핑하는 것입니다.

그러나이 코드를 사용하면 모터 동작이 이상합니다. 라디오 송신기 제어 스틱을 이동 범위 내에서 움직이면 모터는 0도에서 45도까지 회전하고 다시 45에서 0, 0에서 45까지 회전하고 0에서 180도까지 스위핑하는 대신 다시 0으로 돌아갑니다. 누구든지 도움이나 조언을 제공해 줄 수 있습니까?

https://robotics.stackexchange.com/에 대한 자세한 아두 이노/서보 행운을 가질 수있다, 참고로 당신에게

#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

서보는 _width_ modulated 신호로 제어됩니다. 너비 단위는 빈도가 아닌 시간입니다. 위의 질문에서 입력 값은 1000 - 2000 마이크로 초입니다. 원하는 출력은 전체 각도 회전을 얻기 위해 600-2400 마이크로 초입니다. 질문에 'Hz'를 추가하는 수정이 잘못되었습니다. – jdr5ca

답변

0

대단히 감사합니다.

직렬 출력에서 ​​무엇을 보십니까? ch3은 0에서 45까지 또는 0에서 180까지 순환합니까? map()은 여기서하고있는 일을하기 위해 설계된 것을 잊지 마십시오.

내 첫 번째 의심은 시간이 초과되었거나 맥박 중간에 독서가 시작 되었기 때문에 가끔씩 pulseIn에서 0을 얻고 있다는 것입니다. 이는 예상보다 짧은 맥박을 유발할 수 있습니다.).

3

데이터 형식이 오버 플로우되었습니다. 부호있는 값은 -32768 ~ +32767 만 가능합니다. int docs

귀하의 수식은 모두 입니다. 컴파일러는 더 큰 중간 값이 필요하다고 추측하지 않습니다. 180을 곱하면 적색 플래그가됩니다. (2000-1250) * 180 = 135000 = boom

수학을 이해하려면 아래 테스트 프로그램에 나와있는 수식을 개별 작업으로 나누십시오. 이것은 컴파일러가 여러분을 위해 무엇을하는지에 대한 것입니다.

아래 프로그램을 실행하면 오류가 표시됩니다. 최대 값이 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); 
}