- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 5 von 5

Thema: Vorsteuerung bei PID-Regler

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    19.02.2010
    Beiträge
    67

    Vorsteuerung bei PID-Regler

    Anzeige

    E-Bike
    Hallo Forum,

    eigentlich ist die Frage eher allgemein, anstatt auf Bascom bezogen.
    Aber, da ich in Bascom programmiere und eben für das Bascom-Programm Hilfe benötige poste ich es hier.

    Ich habe in einem Bascom-Programm eine Function PID-Regler welche die Heizleistung für eine Temperaturregelung ausgibt.

    Code:
    Function Pid_regler(byval _text As String) As Byte
    Local _y As Single , _x As Single , _e As Single , _pid As Single , _pwm As Byte
    Local _kp As Single , _ki As Single , _kd As Single
    Local _proportionalteil As Single , _integralteil As Single , _differentialteil As Single
    Local _esum As Single , _ealt As Single
    Local _betrag_e As Word
    Local _schwelle As Word
    Local _esum_startwert As Single
    Local _integralteil_startwert As Single
    Local _pwm_max As Byte
    Const _ta = 1                                               'Abtastintervall
    
       Select Case _text
          Case "L":
                        Sreg.7 = 0
                        _pwm = Ocr1a
                        _y = T_ist_luft
                        Sreg.7 = 1
                        _x = Prog_temperatur_luft
                        _kp = Kp_l
                        _ki = Ki_l
                        _kd = Kd_l
                        _esum = Esum_luft
                        _ealt = Ealt_luft
                        _schwelle = Schwelle_l
                        _pwm_max = P_l_ueberw
    
                        'Annahme lineare Kennlinie
                        'P_heizung_luft=0 bei T_soll=20°C
                        'P_heizung_luft=85 bei T_soll=80°C
                        'bei _e=0 => P-Anteil=0 => Heizleistung wird durch I-Anteil bestimmt
                        '
                        '_integralteil = 0,0142 * ( T soll ) - 28,333
                        '_esum = _integralteil / (_ki * _ta) - e*Kp
                        _integralteil = T_ist_luft * 0.0142
                        _integralteil = _integralteil - 28.333
                        'Help_single = _x - _y
                        'Help_single = Help_single * _kp
                        '_integralteil = _integralteil - Help_single
                        If _integralteil < 0 Then _integralteil = 0
                        _integralteil_startwert = _integralteil
                        _esum_startwert = _integralteil / _ki
    
    
    
          Case "K":
                        Sreg.7 = 0
                        _pwm = Ocr1b
                        _y = T_ist_kondensat
                        Sreg.7 = 1
                        _x = Prog_temperatur_kondensat
                        _kp = Kp_k
                        _ki = Ki_k
                        _kd = Kd_k
                        _esum = Esum_kondensat
                        _ealt = Ealt_kondensat
                        _schwelle = Schwelle_k
                        _pwm_max = P_k_hzg_max
    
       End Select
    
       _e = _x - _y                                             'Regelfehler
       _betrag_e = Abs(_e)
    
       If _betrag_e > _schwelle Then
             If _e > 0 Then _pwm = 255 Else _pwm = 0            'Vollaussteuerung
             _esum = _esum_startwert                            'Vorgabe I_Anteil
          Else
    
             If _pwm > 0 And _pwm < _pwm_max Then _esum = _esum + _e
             _proportionalteil = _kp * _e                       'Proportionalteil berechnen
    
             _integralteil = _ki * _ta                          'Integralteil berechnen
             _integralteil = _integralteil * _esum
    
             _differentialteil = _e - _ealt                     'Differentialglied berechnen
             _differentialteil = _differentialteil * _kd
             _differentialteil = _differentialteil / _ta
    
             _pid = _proportionalteil + _integralteil           'Alle Glieder zusammenfassen
             _pid = _pid + _differentialteil
    
             _ealt = _e
    
             If _pid <= 255 And _pid >= 0 Then
                  _pid = Round(_pid)
                  _pwm = _pid
                Else
                  If _pid > 255 Then _pwm = 255 Else _pwm = 0
             End If
       End If
    
    '(
       Sreg.7 = 0
       Print Zeit_string ; Spc(2) ; Zaehler_long ; Spc(2) ;
       Help_string = Str(t_ist_luft) : Help_string = Format(help_string , "00.00")
       Print Help_string ; Spc(1);
       Help_string = Str(prog_temperatur_luft) : Help_string = Format(help_string , "00.00")
       Print Help_string ; Spc(1);
       _e = _e / 100
       Help_string = Fusing(_e , "#.##")
       Print Help_string ; Spc(2);
       Print Ausgabe(_proportionalteil) ; Spc(1) ; Ausgabe(_integralteil) ; Spc(1) ; Ausgabe(_integralteil_startwert) ; Spc(2) ; Ausgabe(_pid) ; Spc(2) ; P_l_soll ; Spc(2) ; N_l_soll
       Sreg.7 = 1
    ')
       Select Case _text
          Case "L":
                      Esum_luft = _esum
                      Ealt_luft = _ealt
          Case "K":
                      Esum_kondensat = _esum
                      Ealt_kondensat = _ealt
       End Select
       Pid_regler = _pwm                                        'Ausgang
    End Function

    Hierbei habe ich eine Temperatur-Schwelle definiert, unter welcher die Heizung voll gesteuert wird und innerhalb der Schwelle soll der Regler greifen.

    Weiterhin versuche ich mit esum_startwert eine Heizleistung zu ermitteln, welche unmittelbar nach überschreiten der Schwelle den I-Anteil des PID-Reglers füttern soll, um schon eine anähernde Heizleistung vorzugeben.

    Leider bin ich mit dieser Lösung ziemlich unzufrieden und würde gern wissen, wie man eine "Vorsteuerung" richtig realisiert.


    besten Dank

    BoGe-Ro

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Solange der Regler nur eine konstante Temperatur halten soll, braucht man eigentlich keine Vorsteuerung. Da reicht der Integralanteil eigentlich aus. Sinnvoll ist die Vorsteuerung nach meiner Erfahrung dann, wenn man einem vorgegeben relativ steilen Temperaturprofil folgen will. Da kommt dann zusätzlich zur Heizleistung noch Leistung auf Grund des aktuellen Profils dazu. Dabei ist die Temperatur nicht so wichtig, sondern mehr der Sollwert der Steigung und ggf. auch die Nähe zu einem Wechsel in der Steigung. Wenn man will kann man die Parameter dazu aus direkt aus der Wärmekapazität berechnen.

    Den Übergang zwischen der heurisctischen 2 Punktregelung und der PWM Regelung würde ich so machen, das sich ein glatter Übergang ergibt, gerade so als hätte man den Zustand der extremen Leistung auch mit dem PID-Regler erreicht. Den Wert für das Integral also so wählen das man beim Übergang in den PID-regler auch wieder an der Grenze der maximalen Leistung ist.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    19.02.2010
    Beiträge
    67
    Hallo,

    sicherlich ist der Begriff Vorsteuerung an der Stelle mit dem was ich meine verkehrt - ich war wirklich mies in Regelungstechnik.

    Jedenfalls genau diesen Übergang zwischen Steuerung und Regelung mein ich - un die nächste Zeit danach.

    Also, ich hab ursprünglich eine Systemidentifikation durchgeführt und mit den Werten über Ziegler-Nichols die Werte für einen PI-Regler bestimmt.

    Den D-Anteil hab ich aussen vor gelassen, da es hauptsächlich Reaktionen auf das Messwertrauschen gab und sich auch nur für Ta=1s auswirkten.

    Nun will ich mit relativ schwacher zur Verfügung stehender Heizleistung 20 Liter Wasser aufheizen, hierbei werden relativ schwache Anforderungen an die Genauigkeit gestellt.

    Leider seh ich hierbei, dass der I-Anteil erst sehr sehr langsam zum tragen kommt, die ohnehin geringe Heizleistung also anfangs nichtmal ganz zum Tragen kommt.

    Daher die Idee, unterhalb der Schwelle die Heizung voll anzusteuern.
    Bei Erreichen der Schwelle, schalte ich auf Regelung um und lade die Variable e_sum mit dem Wert vor, welchen ich aus vorherigen Tests ermittelt hab.

    Meiner Meinung nach ist dieser Wert der, der später zum Halten der Sollspannung notwendig ist.

    Nun habe ich durch die Steuerung der Heizleistung beinah die Soll-Temperatur, schalte um auf Regelung und geb dem I-Anteil (über e_sum) den Wert, der "genau der richtige" sein sollte und sehe, dass sich in nächster Zeit der I-Anteil nach unten integriert und sich danach erst wieder langsam hochhechelt.

    Auf ein Folgen eines Temperaturprofils kommt es wirklich nicht an, aber gerade dieses erste Einschwingen , oder eher des ersten Teils des Einschwingen möcht ich beschleunigen


    Gruß BoGe-Ro

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    13.07.2004
    Ort
    bei Stuttgart
    Alter
    42
    Beiträge
    760
    Hallo,
    also ich versteh auch deinen code nicht ganz, habe ihn aber auch nur kurz angeschaut warum ziehst du vom integralteil noch etwas ab?
    wie wäre es anstatt mit einer reglerumschaltung mit paramteränderunge von kp und ki? habe ich auch schon so gehandhabt. einfach bei weitem abstand vom sollwert den regler stärker anziehen?
    wenn du es bei klassischem pi lassen möchtest, würde ich es so probieren:
    heizen mit vollgas bis zur hälfte, oder so, dann damit es einen glatten übergang gibt, i_init=p_max-kp*e
    mfg jeffrey

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    19.02.2010
    Beiträge
    67
    erstmal herzlichen Dank für die Antworten.

    mein Fehler war selbsgemacht, der Teil, der den Initialisierungswert für den I-Anteil ausrechnet wurde immer durchgeführt, nicht nur ausserhalb der Schwelle wo der Regler arbeiten soll.

    Dies hab ich nun geändert und die Initialisierung für "beide" Regler mit reingenommen und nun gehts.

    die Funktion schaut nun so aus:

    Code:
    Function Pid_regler(byval _text As String) As Byte
    Local _y As Single , _x As Single , _e As Single , _pid As Single , _pwm As Byte
    Local _kp As Single , _ki As Single , _kd As Single
    Local _proportionalteil As Single , _integralteil As Single , _differentialteil As Single
    Local _esum As Single , _ealt As Single
    Local _betrag_e As Word
    Local _schwelle As Word
    Local _pwm_max As Byte
    Local _p_typ As Byte
    Local _t_typ As Word
    Local _m As Single , _n As Single
    Const _ta = 1                                               'Abtastintervall
    
       Select Case _text
          Case "L":
                        Sreg.7 = 0
                        _pwm = Ocr1a
                        _y = T_ist_luft
                        Sreg.7 = 1
                        _x = Prog_temperatur_luft
                        _kp = Kp_l
                        _ki = Ki_l
                        _kd = Kd_l
                        _esum = Esum_luft
                        _ealt = Ealt_luft
                        _schwelle = Schwelle_l
                        _pwm_max = P_l_ueberw
    
                        _p_typ = P_l_typ                        'typische Heizleistung bezogen auf
                        _t_typ = T_l_typ                        'typische Lufttemperatur
    
    
          Case "K":
                        Sreg.7 = 0
                        _pwm = Ocr1b
                        _y = T_ist_kondensat
                        Sreg.7 = 1
                        _x = Prog_temperatur_kondensat
                        _kp = Kp_k
                        _ki = Ki_k
                        _kd = Kd_k
                        _esum = Esum_kondensat
                        _ealt = Ealt_kondensat
                        _schwelle = Schwelle_k
                        _pwm_max = P_k_hzg_max
    
                        _p_typ = P_k_typ                        'typische Heizleistung bezogen auf
                        _t_typ = T_k_typ                        'typische Kondensattemperatur
    
    
       End Select
    
       _e = _x - _y                                             'Regelfehler
       _betrag_e = Abs(_e)
    
       If _betrag_e > _schwelle Then
             Help_single = _t_typ - 2000                        'delta T
             _m = _p_typ / Help_single                          'Anstieg Heizsteuerung
    
             Help_single = _m * _t_typ
             _n = _p_typ - Help_single                          'Abschnitt Heizsteuerung
    
             _integralteil = _m * _x
             _integralteil = _integralteil + _n
    
             If _integralteil < 0 Then _integralteil = 0
             _esum = _integralteil / _ki                        'Vorgabe I-Anteil
    
             If _e > 0 Then _pwm = 255 Else _pwm = 0            'Vollaussteuerung
    
          Else
    
             If _pwm > 0 And _pwm < _pwm_max Then _esum = _esum + _e
    
             _proportionalteil = _kp * _e                       'Proportionalteil berechnen
    
             _integralteil = _ki * _ta                          'Integralteil berechnen
             _integralteil = _integralteil * _esum
    
             _differentialteil = _e - _ealt                     'Differentialglied berechnen
             _differentialteil = _differentialteil * _kd
             _differentialteil = _differentialteil / _ta
    
             _pid = _proportionalteil + _integralteil           'Alle Glieder zusammenfassen
             _pid = _pid + _differentialteil
    
             _ealt = _e
    
             If _pid <= 255 And _pid >= 0 Then
                  _pid = Round(_pid)
                  _pwm = _pid
                Else
                  If _pid > 255 Then _pwm = 255 Else _pwm = 0
             End If
       End If
    
       Select Case _text
          Case "L":
                      Esum_luft = _esum
                      Ealt_luft = _ealt
          Case "K":
                      Esum_kondensat = _esum
                      Ealt_kondensat = _ealt
       End Select
       Pid_regler = _pwm
    End Function
    das Subtrahieren bei Integralteil kommt aus der Kennlinie.
    Ich möchte ja erst bei einer Solltemperatur über 20°C losheizen - also geht die Heizleistungskurve nicht durch Null, sondern hat einen Achsenabschnitt.


    Gruß BoGe-Ro

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen