Es folgen Programme des Beispielkapitels.
web901
CODESYS-Programm PI-Regler
Listing 9.1 und Listing 9.2: CODESYS Hauptprogramm und Funktionsbaustein Beispiel 9.1.2
PROGRAM PLC_PRG VAR INIT:BYTE:=0; Regler:PI_REGLER; (*Instanz des Funktions- blocks PI_REGLER*) A_IN AT %IW1:INT; (*Analog-Kanal 2*) A_OUT AT %QW1:WORD; (*Analog-Kanal 2 Ausgang*) Drehzahl:REAL; (*in U/min*) Fuehrungsgroesse: REAL := 0; (*in U/min*) Stellgroesse: REAL := 0; (*in Volt*) Kp:REAL := 0; Tn:REAL := 0; T0:REAL := 0.05; d0:REAL := 0; d1:REAL := 0; END_VAR (**Initialisierung Regler und Zähler (falls gesteckt)******) CASE INIT OF 0: (*Initialisierung Zähler (falls gesteckt)*) INIT:=1; RETURN; 1: (*********Initialisierung des Reglers********************) (*Die folgenden Variablen werden über Winfact gesetzt *) Kp:= (INT_TO_REAL(%IW256))*0.001; Tn:= (INT_TO_REAL(%IW257))*0.001; Fuehrungsgroesse:=(INT_TO_REAL(%IW259))*0.1; IF Kp = 0 THEN (* ist WinFACT nicht in Betrieb! *) Kp:=6; 217 Tn:=0.9; Fuehrungsgroesse := 1; END_IF (*Diskretisierung des Reglers*) d0 := Kp *T0 /(2*Tn) + Kp; d1 := Kp *T0 /(2*Tn) - Kp; INIT:=2; RETURN; 2: (* CASE 2: Ausführung wenn INIT = 2*) (******** Einlesen Daten Analogeingang***************) Drehzahl:=INT_TO_REAL(A_IN)*0.00030518509; (******************Aufruf Funktionsblock PI-REGLER ********) Regler(xk:=Drehzahl, wk:=Fuehrungsgroesse, rd0:=d0, rd1:=d1); Stellgroesse:=Regler.yk; %QW257:=REAL_TO_INT(Drehzahl* 1000); (*Speichere Regelgröße in %QW257 für Boris*) %QW258:=REAL_TO_INT(Stellgroesse*1000); (*Speichere Stellgröße in %QW258 für Boris*) (**********analoge Ausgabe*************************) A_OUT:=REAL_TO_INT( Stellgroesse * 3276.7); (*Umrechnung Real in Zahlenformat für die analoge Ausgabe*) (* Zur Sicherheit keine negative Spannungsausgabe *) IF A_OUT > 32767 THEN A_OUT:= 0; (* 0V = Motor stopp *) END_IF END_CASE
FUNCTION_BLOCK PI_REGLER VAR_INPUT wk: REAL := 0; xk: REAL := 0; rd0:REAL := 0; rd1:REAL := 0; END_VAR VAR_OUTPUT yk: REAL; END_VAR VAR Min_Stell: REAL := 0.0; (*kleinster Wert von y k *) Max_Stell: REAL := 10.0; (*größter Wert von y k *) 218 ek: REAL := 0.0; (*Regelfehler *) ek1: REAL := 0.0; (*Regelfehler k-1*) yk1: REAL:=0.0; (*Stellgröße k-1*) END_VAR ek := wk - xk; yk := yk1 + rd0*ek +rd1*ek1; (*Stellgrößenbegrenzung ohne AWR*) IF yk < Min_Stell THEN yk := Min_Stell; ELSIF yk > Max_Stell THEN yk := Max_Stell; END_IF yk1:=yk; ek1:=ek; %QW260:=REAL_TO_INT(xk*100); %QW261:=REAL_TO_INT(yk*100);
web903
DC-Motor Beispiel 9.1.4
Listing 9.3: Der DC-Motor wird inklusive Regelung im Zustandsraum dargestellt und simuliert.
# -*- coding: utf-8 -*- """ DC-Motor mit P-PI-Lageregler im Zustandsraum und G(s) Kaskade gemäß Faulhaber MC5005 Created on 12.4. 2019, mod. 20.8.24 @author: philippsen """ import numpy as np import control as ct import matplotlib.pyplot as plt Tc = 1e-3 # Ersatzzeitkonstante Stromregelkreis zpiJ = 47.119e-6 # Meine Berechnung 2pi7,5e-6 KL = 1 # Integrierbeiwert Lagestrecke cPsi= 0.0318 # Datenblatt Faulhaber Ks = cPsi/zpiJ # Verstärkung Teilstrecke a= 16 KR= 1/(a*Ks*Tc) # Verstärkung Drehzahlregler gemäß SymOpt Tnv = a*a*Tc # Nachstellzeit Drehzahlregler Tnv = 2*a*Tc # Nachstellzeit Drehzahlregler modifiziert Kreib=1e-5 a1 = KR*Ks; a2 = a1*Tnv; a3 = Tnv; a4 = a3*Tc null = np.roots([a4*a2, 0, (a3*a1 - a2*a2 ), 0, -a1*a1]); wi = np.max(null) Kkrit = (1/KL)*(a3*a2*wi**4 - a2*a1*wi**2 -a4*a1*wi**4 +a2*a1*wi**2)/( (a2**2)*(wi**2) + a1**2 ) Kv= Kkrit/40 # Verstärkung Lageregler Ar = np.array([[0, KL, 0, 0], [0, -Kreib/zpiJ, cPsi/zpiJ, 0], [-KR*Kv/Tc, -KR/Tc, -1/Tc, 1/Tc], [-KR*Kv/Tnv, -KR/Tnv, 0, 0]]) br = np.array([[ 0. ],[ 0], [KR*Kv/Tc],[KR*Kv/Tnv]]) cr = np.array([1, 0, 0, 0]) C = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) D = np.array([[ 0. ],[ 0], [0],[0]]) DCkreis = ct.ss(Ar, br, cr, 0) t, y, x =ct.step_response(DCkreis,return_x=True) plt.subplot(3,1,1) plt.plot(t,x[0,:]) plt.title('Lageregelkreis DC-Motor'); plt.ylabel('Lage') plt.xlabel('t [s]') plt.grid(True) plt.subplot(3,1,2) plt.plot(t,x[1,:],'g') plt.xlabel('t [s]'); plt.ylabel('n(t)') plt.grid(True) plt.subplot(3,1,3) plt.plot(t,x[2,:],'r') plt.xlabel('t [s]'); plt.ylabel('Strom') plt.grid(True) plt.figure() # neue Plot-Funktion DCkreis = ct.ss(Ar, br, C, D) ct.step_response(DCkreis).plot( title='Sprungantwort Lageregelkreis')