Hallo zusammen, ich habe einen Code geschrieben, welcher meine Temperatur Regeln soll. Dabei habe ich ein Thermoelement mit einem MAX31850 mit meinenm Arduino Mega2560 verbunden. Dafür benutze ich die entsprechende Library und die Messung funktioniert soweit. Diese Messwerte will ich jetzt mithilfe der PID-Library in ein Ausgangssignal umwandeln. Leider reagiert der Controller nicht auf Temperaturschwankungen. Ich habe noch kein Tuning Für den Controller gemacht, da der Fehler irgendwie im Code steckt. Da ich keine Ahnung von Programmierung habe und selber den Fehler nicht finde, hoffe ich, dass mir hier jemand helfen kann. Der Code: ////////////////////////////////////////////////// //////Temperaturmessung #include <OneWire.h> #include <DallasTemperature.h> // Data wire is plugged into port 2 on the Arduino #define ONE_WIRE_BUS 2 // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); // arrays to hold device address DeviceAddress insideThermometer; //////////////////////////////////////////////////////////////////////// ////////// // Regelung #include <PID_v1.h> #define PIN_OUTPUT 4 //Define Variables we'll be connecting to double Setpoint, Input, Output; //Specify the links and initial tuning parameters double Kp=2, Ki=5, Kd=1; PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); void setup() { // start serial port Serial.begin(9600); Serial.println("Dallas Temperature IC Control Library Demo"); Input = sensors.getTempCByIndex(0); Setpoint = 50; //turn the PID on myPID.SetMode(AUTOMATIC); // Start up the library sensors.begin(); } void loop() { // call sensors.requestTemperatures() to issue a global temperature // request to all devices on the bus Serial.print("Requesting temperatures..."); sensors.requestTemperatures(); // Send the command to get temperatures Serial.println("DONE"); Serial.print("Temperature for the device 1 (index 0) is: "); Serial.println(sensors.getTempCByIndex(0)); Input = sensors.getTempCByIndex(0); myPID.Compute(); analogWrite(PIN_OUTPUT, Output); delay(500); // Wartezeit bis nächster Zyklus [ms] }
Kannst du die PWM messen ? Was heißt er reagiert nicht auf Schwankungen ? Gruß JackFrost
Hallo JackFrost, Danke für die schnelle Antwort. Mit "nicht reagieren" meinte ich, dass auch in dem Fall, dass die Sollwert Temperatur gemessen wurde, der Arduino ein volles Signal ausgegeben hat. Ich muss mich aber jetzt korrigieren. Der Code funktioniet jetzt. Ich habe den I- und den D-Anteil auf Null gesetzt.
Damit hast du nun nur noch einen P-Regler. Deine Werte waren falsch. Wenn er der PID bei erreichen des Sollwertes noch 100 % ausgibt ist der I-Anteil deutlich zu stark. Du musst den Wert für den I-Anteil deutlich vergrößern. Der I-Anteil ist kein echter I-Anteil, sondern ein Faktor. Bei 5 und 500 ms Samplezeit und einer Regelabweichung von 30 K hast du nach 1 s schon 100 % Stellgrad vom I Anteil. Wenn er 1 K drüber ist braucht der I-Anteil schon 25 s um den Stellgrad auf 0 zu senken. Kannst du die PWM messen ? Gruß JackFrost
:
Bearbeitet durch User
Wenn I-Anteil 0 geht's besser ? Klingt nach "windup". Im Integrator haben sich, durch was auch immer, mörderhohe Werte angesammelt, die den Regler in die Begrenzung treiben.
Die PWM kann ich leider nicht messen. Aber es stimtm, dass ich mir mal die größen Ordnung der Glieder in Abhängigkeit der Zeitschritte angucken sollte. Ich war nur zu sehr darauf fixiert, dass der Code an sich fehlerhaft ist. Ja ein Anti-Wind up Verfahren wäre evtl auch sinnvoll. So weit ich das beurteilen kann, müsste ich dann von der Arduino Library abstand nehmen und den PID-Controller selber schreiben/ bei Google suchen.
Bastian W. schrieb: > ist der I-Anteil deutlich zu stark. Du musst den Wert > für den I-Anteil deutlich vergrößern. Wie soll man das verstehen? Wenn man mit dem Auto kurz vor der Wand ist, muß man also Gas geben? :-))) Das meintest du sicherlich anders...
Leider bin ich nicht schlau genug für die ganze Thematik, deshalb habe ich mir Online Hilfe gesucht. http://www.rentanadviser.com/en/pid-fuzzy-logic/pid-fuzzy-logic.aspx
npn schrieb: > Bastian W. schrieb: >> ist der I-Anteil deutlich zu stark. Du musst den Wert >> für den I-Anteil deutlich vergrößern. > > Wie soll man das verstehen? > Wenn man mit dem Auto kurz vor der Wand ist, muß man also Gas geben? > :-))) > > Das meintest du sicherlich anders... Normal stellt man beim I-Anteil die Nachstellzeit Ti ein. Innerhalb dieser Zeit wird der Ausgang um die Regelabweichung erhöht. Nehmen wir an die Regelabweichung sei 3 K und Ti 10 s. Dann steigt der Ausgang um 3 % alle 10 Sekunden bis das Anti-Windup greift. Ist Ti aber 100 s ist der I- Anteil schwächer weil er dann 100 s für die 3 % braucht. Bei dem Arduino PID ist es aber ein Ki. Hier ist Ki = Samplezeit/Ti. Damit muss der TO das Ki deutlich verkleinern. Bei seiner Samplezeit von 500 ms ist der I-Anteil in nur zwei Durchläufen in der Begrenzung wenn die Starttemperatur 20 'C. Der P-Anteil ist unwirksam nur das D kann noch bisserl bremsen. Ein Ki von 0,025 könnte man mal testen und dann je nach Verlauf ändern. Gruß JackFrost
Bastian W. schrieb: > Normal stellt man beim I-Anteil die Nachstellzeit Ti ein. Das ist mir schon alles klar. Nur deine Formulierung war, sagen wir mal, etwas widersprüchlich :-) Deswegen auch die Smileys...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.