2016-08-11 4 views
-1

Ich hatte Erfolg in der Kontrolle der Position meines Motors mit PD-Controller. Ich habe jedoch einige Probleme mit der Programmierung.Motor bewegt sich nicht

Hier ist mein Code:

#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--; 
    } 

}

Wenn Sie an meinem Code aussehen, ich habe als globale Variable und in Schleife erklärt Input() ich Wert auf Input geben (50 zählt in dieser Code). Dieser Code funktioniert einwandfrei und der Motor stoppt bei fast 50 Encoderzählungen.

Aber wenn ich die Schleife im obigen Code zu dem unten angegebenen Code ändere, bewegt sich mein Motor nicht. Ich mag es für einige Zeit auf 50 Zählung warten zu bewegen und kommt zurück auf 0 Zahl:

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

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

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

} 
+0

1) Dies ist nicht C. Arduino ist nicht C. 2) 'volatile' garantiert nicht atomaren Zugriff. 3) Dies ist kein Debugging-Service. Verwenden Sie den Debugger. 4) Die Verwendung von Fließkomma auf Arduino ist höchstwahrscheinlich eine schlechte Idee. Verwenden Sie skalierte Ganzzahlen. – Olaf

Antwort

1
  • Wenn Sie die same question in other places stellen und eine Antwort erhalten, ich glaube, Sie wieder hierher kommen sollten und Ihre eigene Frage beantworten und markieren Sie es als beantwortet, sonst werden die Leute Zeit darauf verbringen.

  • Das Problem ist eindeutig die delay(2000), und wenn man sich den Code anschauen werden Sie sehen, warum. Wenn Sie nur eine Anweisung haben, was passiert ist, dass die Schleife startet, überprüft die Zeit und sehen, ob der Motor bewegt werden muss, basierend darauf, wie lange vergangen ist. Wenn Sie also eine Verzögerung setzen, wird die Zeit beim nächsten Durchlauf der Schleife bereits vollständig verbraucht und der Motor bewegt sich nicht.

  • Was Sie tun können, ist zu verfolgen, was der Motor macht, und verschieben Sie es basierend darauf. Behalten Sie zum Beispiel eine Variable namens movement_completed und weisen Sie ihr einen Wert zu, der von den Bewegungsfunktionen zurückgegeben wird, wenn sie die Bewegung abgeschlossen haben. Erst nachdem diese Variable gesetzt ist, fahren Sie mit den nächsten Bewegungen fort.

Ich denke, dass das Hauptproblem hier ist, dass Sie sich daran erinnern müssen, dass loop() ständig aufgerufen wird, dann ist es nicht etwas, das nur einmal ausgeführt wird. Sie müssen ein klares Verständnis davon haben, warum Ihr Motor mit dem ersten Code stoppt (dann werden Sie verstehen, warum er sich nicht mit dem zweiten Code bewegt).

+0

@ Dhav1991 nicht sicher, warum Sie hier auf stackoverflow fragen, wenn Sie über das echte arduino forum bei http://forum.arduino.cc wissen – datafiddler