Einstieg in die Regelungstechnik mit Python

Fachbuch von Hans-Werner Philippsen

Regelung Tiefsetzsteller

Die Spannung eines Tiefsetzstellers (Buck-Converter) soll mit Hilfe eines MicroPython-Programms geregelt werden. Der P-Kanal MosFet (SPP80 P06) wird von der Treiberschaltung L293D angesteuert, wobei ein Raspberry Pi Pico das Enable-Signal und das PWM-Signal bereitstellt. Die Ausgangsspannung wird über den Spannungsteiler dem ADW vom Raspberry Pi Pico zugeführt.

Im Kapitel 4.11 wurde auf die nicht lineare statische Kennlinie eines Tiefsetzstellers eingegangen. Je nach Arbeitspunkt und Belastung liegt eine unterschiedliche Verstärkung vor. Auch die Dynamik ist sehr stark vom Arbeitspunkt abhängig. Die Sprungantwort der Ausgangsspannung weist im unteren Arbeitsbereich (duty cycle 20-> 50%) mit einer geringen Last (RL = 60 Ω) ein P-T1 Verhalten auf:

Blau Spannung U2 , Rot Strom iL

Im oberen Arbeitsbereich (duty cycle 50-> 80%) mit einer großen Last (RL = 20 Ω) liegt ein P-T2s Verhalten vor:

Die Dynamik der Störsprungantwort ist ebenfalls vom Arbeitspunkt und der Last abhängig. Ein einfacher PI-Regler ist in der Lage seine Aufgaben zu erfüllen (schnelle, stabile Regelung), jedoch stellt sich je nach Arbeitspunkt und Last eine unterschiedliche Dynamik ein. Sprungantwort RL = 60 Ω, w = 4V->8V:

Sprungantwort RL = 20 Ω, w = 4V->8V:

Das gilt ebenso für die Störsprungantwort Störsprungantwort RL = 15->60 Ω, w = 8V:

Sprungantwort RL = 60->15 Ω, w = 8V:

Die digitale Regelung des Tiefsetzstellers wurde auf dem Raspberry Pi Pico mit Hilfe von MicroPython umgesetz. Die Abtastzeit konnte auf 500 μs reduziert werden. Dazu wurde das MicroPython Programm aus Listing 8.3 etwas modifiziert.

import machine , time
from micropython import const

blink = machine.Pin(25,machine.Pin.OUT)
takt = machine.Pin(1,machine.Pin.OUT)
enable = machine.Pin(22,machine.Pin.OUT)
ana = machine.ADC(machine.Pin(27))       # Analoger Eingang 
pwm0 = machine.PWM(machine.Pin(18))      # create PWM object from a pin
pwm0.freq(10000)         # set frequency
enable.value(True)       # L293d einschalten

T0 = 0.0005
Tw = int((T0 - 0.0002)*1000000)
Kp = const(6.88 ); Tn = 0.0091      # Reglerparameter

ymax = 99.0 # Begrenzung Stellg
Kid=  Kp*T0/(2*Tn)        # Ki diskretisiert
Tikorr =  0.96*Tn/T0    # Korrekturfaktor I-Anteil
ykk =0;  yk =0.0; yi1 = 0.0; ek1 = 0.0 # Anfangswerte
Kadw =  4.54*3.3/65535  # noch kalibrieren

w1 = const( 8.0 ); w2 = const( 12.0 ) # Sollwerte
blink.value(True)
start = time.ticks_ms() # get millisecond counter
for i in range(4000):
  x = Kadw*ana.read_u16()  
  if i < 2000:
      ek = w1 - x
  else:
      ek = w2 - x
      
# Anfang PI_AWR_REGLER, yk in %
  Intkorr = (ykk - yk)/Tikorr # Korrektur I-Anteil falls Begrenzung
  yi = yi1 + Kid*ek  +  Kid*ek1 - Intkorr # Berechnung I-Anteil
  ek1 = ek
  yi1=yi
  ykk =  Kp*ek + yi # Stellgroesse = P + I
  if ykk < 0 : # Begrenzung Stellgroesse
      yk = 0
  elif ykk > ymax :
      yk = ymax
  else:
      yk = ykk    # oder  yk ohne Begrenzung
# Ende PI-Regler

  dutyint = 65535 - int(655.35*yk) # Stellgröße in duty umrechnen
  pwm0.duty_u16(dutyint)
  time.sleep_us(Tw)
  #takt.value(not takt.value())

delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
print(delta)
blink.value(False)
pwm0.duty_u16(65535)

Mit Hilfe eines unterlagerten Stromreglers kann die Qualität der Regelung verbessert werden. Dazu sind jedoch die weitere Reduktion der Abtastzeit und ein Stromsensor erforderlich.

Theme von Anders Norén