Hallo Leute,
wie der Betreff schon andeutet habe ich Probleme beim regeln mit der PID Library und erhoffe mir Hilfe und evtl Tipps ![]()
Zu meinem Aufbau: Arduino Mega2560. Heizplatte aus Kupfer ca 505020 mm (darin ist noch eine Luftkühlung integriert, die für jetzt aber irrelevant ist). Geheizt mit 4 * 200W Heizpatronen und Überwachung mit einem PT100 Thermofühler. Direkt gesteuert wir ein Manson HCS3602 0-32VDC/0-30A , wobei die Spannung auf 24V gelegt wird und der Strom analog über einen MCP4725 DAC gesteuert wird.
Soweit so gut. Der Arduino liest die Temperatur genau aus (zurzeit von 0-100°C -> später wahrscheinlich 0-250°C). Netzteil lässt sich auch relativ einwandfrei steuern und Platte hab ich auch bis auf 100°C aufgeheizt bis jetz. (also linear: Steck 20A rein bis 60°C erreicht sind und stell dann den Strom auf 0A -> cirka 90-100°C Endtemperatur)
Zu meinem jetzigen Problem. Ich habe die PID Library implementiert und steuere mittels dieser das Netzteil. das Problem ist das er gewaltig überschwingt (je nach Kp und Ki) teils ist die Ausgangstemperatur ca 28°C, Sollwert ist 40°C und er schwingt bis zu 90°C über.
Hab bereits einige Tests gefahren mit unterschiedlichen P und I werten aber bin zurzeit noch nicht schlau geworden daraus, vorallem weil es ewig dauert bis die Platte wieder unter 30°C ist (logischerweise).
Was mir aufgefallen ist, ist das er erst bei der Solltemperatur anfängt gegenzusteuern.. also bei 41° langsam den Strom runterdreht und je größer die Temperatur und somit der Fehler desto schneller. aber eben nicht so wie ich es will, das er das bereits deutlich unter der Solltemperatur macht.
Hier kurz mein Code, ich werde später noch versuchen Beispielbilder der Messungen in einen Post anzuhängen. (Sind auf Excel aufgezeichnet, mit den unterschiedlichen PID konstanten)
#include <Wire.h>
#include <Adafruit_MCP4725.h>
#include <Adafruit_ADS1015.h>
#include <PID_v1.h>
Adafruit_MCP4725 DAC_strom;
Adafruit_MCP4725 DAC_spannung;
Adafruit_ADS1115 ADC_PT100(0x48);
//PID Objekt erzeugen
double Setpoint = 40, Input, Output, Kp = 2, Ki = 5, Kd = 0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd,P_ON_M, DIRECT);
double temp = 0;
void setup() {
Serial.begin(9600);
Serial.println("ClearRange,A,1,D,50000");
Serial.println("LABEL,Zeit,Temperatur");
ADC_PT100.begin();
DAC_strom.begin(0x60);
DAC_spannung.begin(0x61);
DAC_spannung.setVoltage(2730, false); //Setzen der Spannung des Netzteils auf 24V (äquivalten 2730Bit / 3.333V)
DAC_strom.setVoltage(0, false);
//PID setzen
Input = Temp_auslesen();
myPID.SetOutputLimits(0, 3500); //PID Limits setzen, SetOutputLimits(min,max)
//PID SetTunings(Kp, Ki, Kd, POn), wenn die tuning paramter sich verändern.. evtl für verschiedene Temperturbereiche, schnellere Anfahrtszeiten
//PID SetSampleTime(int>0 in ms), wie oft der alkorithmus ausgeführt wird. Default ist 200ms.
//PID SetCOntrollerDirection(Direction:Direct/Reverse) sollte direct passen, ist default
myPID.SetMode(AUTOMATIC); //PID SetMode() eingeschaltet
}
void loop() {
Input = Temp_auslesen();
myPID.Compute();
DAC_strom.setVoltage(Output, false);
Temp_ausgabe(Temp_auslesen(), 300); //Temperaturausgabe über Funktion Temp_ausgabe mit float von Temp_auslesen alle 300ms
}
//----------------------Unterfunktionen-------------------------------
double Temp_auslesen() {
int16_t Messwandler_spg_bit = 0;
double Temperatur = 0 ;
Messwandler_spg_bit = ADC_PT100.readADC_SingleEnded(1);
Temperatur = Messwandler_spg_bit * (0.000187 * 20);
return Temperatur;
}
void Temp_ausgabe(double temperatur, int Ausgabeintervall) {
static long letzteAusgabe;
if (millis() - letzteAusgabe >= Ausgabeintervall) {
Serial.print("DATA,"); Serial.print(millis()/1000); Serial.print(","); Serial.println(temperatur);
letzteAusgabe = millis();
}
}
//---------------------------------------------------------------------






<-- Ki=1
<-- Ki = 5
<-- Ki =0.25
<-ki=0.05