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