2016-08-11 4 views
-1

PD 컨트롤러를 사용하여 모터 위치를 성공적으로 제어했습니다. 그러나 프로그래밍 관련 문제가 있습니다. (전역 변수로 루프에모터가 움직이지 않습니다

#define encoder0PinA_M1 2 
#define encoder0PinB_M1 22 
int EnablePin = 8; 
int PWMPin1 = 3; 
int PWMPin2 = 11; 


volatile signed int encoder0Pos = 0; 
unsigned long LastTime; 
signed int Input; 
signed int Scaled_PID; 
float PID_Output, Scaled_PID1; 
signed int ErrorSum,ErrorDiff,Error,LastError; 
float kp=6; 
float ki=0; 
float kd=1; 
int SampleTime = 10; 
int TimeChange; 
unsigned long Now; 


void setup() 
{ 
    pinMode(encoder0PinA_M1, INPUT); 
    //digitalWrite(encoder0PinA_M1, HIGH);  
    pinMode(encoder0PinB_M1, INPUT); 
    pinMode(EnablePin, OUTPUT); 
    pinMode(PWMPin1, OUTPUT); 
    pinMode(PWMPin2, OUTPUT); 
    //digitalWrite(encoder0PinB_M1, HIGH);  
    attachInterrupt(0, doEncoder, CHANGE); 
    Serial.begin (9600); 
    Serial.println("start");     
} 

void PID() 
{ 
    Now = millis(); 
    TimeChange = Now - LastTime; 
    if(TimeChange >= SampleTime) 
    { 
    Error = Input - encoder0Pos; 
    ErrorSum = ErrorSum + Error; 
    ErrorDiff = Error - LastError; 

    PID_Output = kp * Error + ki * ErrorSum + kd * ErrorDiff; 

    LastError = Error; 
    LastTime = Now; 

    } 
} 

void speedlimitforward() 
{ 
    if (PID_Output >= 15) 
    { 
    PID_Output= 15; 
    } 
    if(PID_Output <= -15) 
    { 
    PID_Output=-15; 
    } 
    Scaled_PID = PID_Output+15; 
    digitalWrite(EnablePin, HIGH); 
    analogWrite(PWMPin1,Scaled_PID); 


} 

void speedlimitbackward() 
{ 
    if (PID_Output >= 20) 
    { 
    PID_Output= -20; 
    } 
    if(PID_Output <= -20) 
    { 
    PID_Output= 20; 
    } 
    Scaled_PID = PID_Output+20; 
    digitalWrite(EnablePin, HIGH); 
    analogWrite(PWMPin2,Scaled_PID); 
} 




void loop() 
{ 
    Input=50; 
    PID(); 
    speedlimitforward(); 
} 

void doEncoder() 
{ 
    if (digitalRead(encoder0PinA_M1) == digitalRead(encoder0PinB_M1)) 
    { 
    encoder0Pos++; 
    } else { 
    encoder0Pos--; 
    } 

}

당신이 내 코드를 보면, 내가 선언 한 입력) 나는 50 카운트에 (입력에 값을 제공 : 여기

내 코드입니다 이 코드). 이 코드는 정상적으로 작동하고 50 개의 인코더 카운트에서 모터가 정지합니다.

그러나 위의 코드에서 루프를 아래의 코드로 변경하면 모터가 움직이지 않습니다. 나는 언젠가 50 카운트 대기로 이동 0 수에 다시오고 싶지 :

void loop() 
{ 
    Input=50; 
    PID(); 
    speedlimitforward(); 

    delay(2000); 
    Input=0; 
    PID(); 
    speedlimitbackward(); 

    delay(2000); 
    Input=-100; 
    PID(); 
    speedlimitbackward(); 

} 
+0

1) 이것은 C가 아닙니다. Arduino는 C가 아닙니다. 2) 'volatile'은 원자 적 액세스를 보장하지 않습니다. 3) 이것은 디버깅 서비스가 아닙니다. 디버거를 사용하십시오. 4) Arduino에서 부동 소수점을 사용하는 것이 가장 좋은 방법입니다. 스케일 된 정수를 사용하십시오. – Olaf

답변

1
  • 당신이 same question in other places을 질문하고 답변을받을 경우에, 나는 당신이 여기 다시 와서 자신의 질문에 대답해야한다고 생각 응답으로 표시하십시오. 그렇지 않으면 사람들이 그것에 시간을 보낼 것입니다.

  • 문제는 분명히 delay(2000)이며 코드를 보면 그 이유를 알 수 있습니다. 하나의 지시 만하면 루프가 시작된다는 것입니다. 시간을 확인하고 모터가 이동해야하는지 확인하려면의 길이를 기준으로 을 기준으로합니다. 따라서 지연을 넣으면 다음에 루프가 실행될 때 이미 시간이 완전히 소비되어 모터가 움직이지 않습니다.

  • 당신이 할 수있는 일은 모터가 무엇을하고 있는지 추적하고 그에 따라 움직이는 것입니다. 예를 들어, movement_completed과 같은 변수를 유지하고 이동 함수가 이동을 완료했을 때 반환되는 값을 할당합니다. 해당 변수가 설정된 후에 만 ​​다음 동작 세트로 이동하십시오.

내가 여기 주요 문제는 loop() 지속적으로 호출되는 것을 기억해야한다는 것입니다 생각, 그냥 한 번 실행 것이 아니다. 모터가 첫 번째 코드로 멈춰있는 이유를 분명하게 이해해야합니다 (두 번째 코드와 함께 움직이지 않는 이유를 이해할 수 있습니다).

+0

@ Dhav1991 http://forum.arduino.cc에서 실제 arduino 포럼에 대해 아는 경우 stackoverflow에서 왜 여기 물어보십시오. – datafiddler

관련 문제