2017-05-06 6 views
0

저는 자동 안테나 추적 시스템을위한 PID 모터 위치 제어를 구현하는 제어 엔지니어링 프로젝트를 진행하고 있습니다. 이 시스템에는 직류 모터, 절대치 엔코더 및 모터 드라이버가 포함되어 있습니다.Arduino PID DC 모터 위치 제어

모든 것이 예상대로 작동하지만 한 가지. 모터는 0도 (350 - 359, 0 - 10도) 근처의 설정 값에서 정지 할 수 없습니다. 사용 코드 :

#include <PID_v1.h> 
int RPWM = 5; 
int LPWM = 6; 
int L_EN = 7; 
int R_EN = 8; 
boolean pin_state[10]; 
byte input_pin[] = {1, 2, 3, 4, 9, 10, 11, 12, 13}; 
int dec_position = 0; 
int dc = 0; 
double kp = 50, ki = 45, kd = 2; 
double input = 0, output = 0, setpoint = 0; 
volatile long encoderPos = 0; 
PID myPID(&input, &output, &setpoint, kp, ki, kd, DIRECT); 

void setup() { 
    pinMode(L_EN, OUTPUT); 
    pinMode(R_EN, OUTPUT); 
    pinMode(RPWM, OUTPUT); 
    pinMode(LPWM, OUTPUT); 
    for (byte i = 0; i < 9; i++) { 
    pinMode(input_pin[i], INPUT); 
    } 
    TCCR1B = TCCR1B & 0b11111000 | 1; 
    myPID.SetMode(AUTOMATIC); 
    myPID.SetSampleTime(1); 
    myPID.SetOutputLimits(-255, 255);   
    digitalWrite(L_EN, HIGH); 
    digitalWrite(R_EN, HIGH); 
} 

void loop() { 
    if (Serial.available() > 0) { 
    String baca = Serial.readString(); 
    setpoint = baca.toInt(); 
    } 
    ReadEncoder(); 
    input = dc; 
    myPID.Compute(); 
    pwmOut(output); 
} 

void pwmOut(int out) { 
    if (out > 0) { 
    analogWrite(RPWM, out);//Sets speed variable via PWM 
    } 
    else { 
    analogWrite(LPWM, abs(out));//Sets speed variable via PWM 
    } 
} 

void ReadEncoder() { 
// FOR READING ENCODER POSITION, GIVING 0-359 OUTPUT CORRESPOND TO THE ENCODER POSITION 
    for (byte i = 0; i < 9; i++) { 
    pin_state[i] = !(digitalRead(input_pin[i])); 
    } 
    dec_position = (pin_state[8] * 256) + (pin_state[7] * 128) + (pin_state[6] * 64) + (pin_state[5] * 32) + (pin_state[4] * 16) + (pin_state[3] * 8) + (pin_state[2] * 4) + (pin_state[1] * 2) + pin_state[0]; 
    dc = map(dec_position, 0, 500, 0, 360); 
} 

설정 값이 10-350 사이의 값일 때 시스템이 제대로 작동합니다. 그러나 모터가 회전하지 않을 때 모터는 결코 회전을 멈 춥니 다.

나는 약간의 위치 오버 슈트로 인해 인코더가 매우 큰 오류를 읽는 것으로 알고 있습니다.

예를 들어, 설정 점이 0도이면 모터가 회전하여 도달합니다. "현재"위치가 0도에 근접함에 따라 모터 회전이 느려지지만 시스템에 오버 슛이 발생하지 않습니다. 따라서 1 도의 오버 슈트로 인해 오차 값이 -359 (설정 점 - 현재 위치)가되고 모터가 다시 회전하여 원하는 위치에 도달합니다.

이 문제를 해결하는 방법에 대한 도움이 필요합니다. 나쁜 영어로 죄송합니다.

+0

해결되었습니다. 솔루션에 대한 이메일을 보내주십시오. [email protected] –

+0

후손에 대한 대답을위한 저장소로 사용하기 위해 사이트에 질문을 올린 다음 대답을 찾은 다음 도움을주기 위해 답변을 게시하지 않았습니다. 같은 상황에있는 다른 것들? 쿨하지 않아. – slightlynybbled

+0

솔루션이 이미 게시되었습니다. Thx –

답변

0

다음은 솔루션

double error; 
if (SP>PV) { 
    if (abs(SP-PV) < abs(-360 + SP - PV)) error = SP - PV; 
    else error = -360 + SP - PV; 
} 
else{ 
    if(abs(SP-PV)< abs(360 - PV + SP)) error = SP - PV; 
    else error = 360 - SP + PV; 
} 

대신 오프 간단한 현재 가치를 뺀 오류의 설정 값입니다. 위의 코드는 현재 값에서 설정 값까지 최단 경로를 반환합니다.

-2

아직 코드를 읽지 않았습니다. 그러나 "설정 값"(SV)에 도달하려면 "현재 값"(PV)에 오차 허용치 (EA)를 주어야합니다.

예 : EA = SV - PV. EA는 = (-2, + 2) 정도가 그때는 "지금 위치"

에 도달, 당신은 각도 정도를 사용해서는 안 경우, 위치 (펄스에 의해 계산)

희망으로 변환해야 개념은 당신을 도울 수 있습니다.

+1

질문에서 코드를 읽지 않았다면 질문에 대답해서는 안됩니다. –