2017-05-06 248 views
0

我正在做一個控制工程項目,爲自動天線跟蹤系統實現PID電機位置控制。該系統包含直流電機,絕對編碼器和電機驅動器。Arduino PID直流電機位置控制

一切按預期工作,但有一件事。電機不能在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; 
} 

代替OFF簡單的現值減去誤差設定點。上面的代碼返回從當前值到設定點的最短路徑。

-2

我還沒有讀取您的代碼。但是,要達到「設定值」(SV),您應該給出「當前值」(PV)錯誤限額(EA)

例如:EA = SV - PV。 如果EA =(-2,+ 2)學位則達「現在的位置」

而且,你不應該使用角度的程度,你應該把它轉換成位置(脈衝計算)

。希望理念可以幫助你。

+1

如果您沒有閱讀問題中的代碼,則不應回答問題。 –

相關問題