2017-05-06 152 views
0

私は、自動アンテナ追跡システムのPIDモータ位置制御を実装して、制御工学プロジェクトを行っています。システムには、DCモータ、アブソリュートエンコーダ、モータドライバが含まれています。Arduino PID DCモータ位置制御

すべてが期待通りに機能しますが、1つのこと。モータは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

質問のコードを読んでいない場合は、質問に答えるべきではありません。 –

関連する問題