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







Zitieren

Lesezeichen