Hallo allerseits,
ich versuche gerade zwei DC-Motoren synchron laufen zu lassen. Der Aufbau ist wie folgt. Zwei Motoren werden über einen Pololu Motor Treiber gesteuert . An den Motoren befinden sich jeweils ein Geber, die die Impulse an einen Encoder (Robogaia) übergeben und mir als Zahlenwert ausgibt(mega.XAxisGetCount()). 2000 Counts sind eine Umdrehung. Die Geber haben leider keinen Index Channel und ich richte die Motoren aus, die makiert sind, bevor ich sie starte.
Gesteuert wird über ein Delphi-Programm, mit dem ich erstmal den Motor1 starten bzw. stoppen kann.
Ich wollte mit der Arduino PID Library die Motoren regeln lassen. Und zwar dreht sich z.b. Motor 1 mit einer Geschwindigkeit von sagen wir mal 20 und Motor 2 soll jetzt versuchen synchron zu Motor 1 zu laufen.
Als Sollwert habe ich den Count-Wert von Motor1 und also Istwert habe ich den Count-Wert des Motor2. Und dann berechnet mir myPID.Compute() eine Stellgröße. Sagen wir mal, dass bei der ersten Messung der Setpoint einen Wert von 400 Counts und der Input von 340 Counts liefert und der Fehler beträgt dann 60 Counts. Dann sollte Motor2 sich bisschen schneller drehen bis der Fehler quasi Null wird. Und ist der Fehler negativ, sollte er sich langsamer drehen usw.
Das Problem ist, dass er nicht regelt, sondern nur mit voller Geschwindigkeit dreht. Ich habe auch schon mit den Parameter kp, ki und kd rumgespielt, also mit sehr kleinen Werten oder D-Anteil auf Null usw, aber es kommt immer auf das gleiche hinaus.
Limitiert habe ich mit setLimits, weil er sonst zu schnell drehen würde.
Ich habe der Übersichtlichkeit Codezeilen entfernt, die jetzt nicht zum PID gehören.
#include <MegaEncoderCounter.h>
#include "DualMC33926MotorShield.h"
#include<PID_v1.h>
DualMC33926MotorShield md;
MegaEncoderCounter mega;
// Definiere die Variablen für PID Regler
double Setpoint, Input, Output;
int speedo;
boolean isReset = false;
PID myPID(&Input, &Output, &Setpoint, 3, 0.5, 0, P_ON_M, DIRECT); //P_ON_M specifies that Proportional on Measurement be used
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Dual MC33926 Motor Shield init()");
md.init(); // Ports für Motortreiber werden initialisiert
Serial.println("Mega Encoder Counter initialisieren");
MegaEncoderCounter(4);
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(18, 23);
myPID.SetSampleTime(100);
mega.XAxisReset();
mega.YAxisReset();
// Input = mega.XAxisGetCount();
// Setpoint = mega.YAxisGetCount();
speedo = 20;
}
void loop() {
if (!isReset) {
Input = (double)mega.YAxisGetCount();
Setpoint = (double)mega.XAxisGetCount();
int fehler = (int)Setpoint -Input; // Nur für Testzwecke... ansich braucht man es nicht
myPID.Compute();
Output = (int)Output;
md.setM2Speed(Output);
mega.XAxisReset();
mega.YAxisReset();
}
}
PIDv3_netzwerk.ino (4.33 KB)