Verzögerungsfunktion für ein EW gesucht

eloboy

Level-1
Beiträge
70
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute,

suche gerade einen Ansatz für eine Verzögerungsfunktion.

1.So allso es sollte jedes Bit des EW als Eingangsverzögerung unabhängig voneinander verzögern.

2. Wenn jetzt die Zeit erreicht ist dann sollte das Ausgangsbit solange auf true sein bis eine das Eingangsbit eine bestimmte Zeit aus ist.


Wer hat eine gute Idee?

danke schon mal
 
Habe im Anhang ein kurzes FUP Programm hinterlegt.
Im Programm wird dann mit #Altwert_EW0 Gearbeitet.

Viele Grüße Bernard
 

Anhänge

  • Ew_Verzögerung.JPG
    Ew_Verzögerung.JPG
    19,5 KB · Aufrufe: 87
aber ich will es auf jedes Bit und nicht auf dem ganzen Word.

So Fehler ist behoben, du mußt den Code in eine Quelle hinein kopieren und danach übersetzen.Der Baustein verbraucht allerdings 32 S5 Timer intern. Beschaltungsmuster liegt bei.

Code:
FUNCTION FC 3 : VOID
TITLE =
VERSION : 0.1


VAR_INPUT
  Einwort : WORD ;    
  Anf_s5_Timer_X_32 : INT ;    //Belegt ab der Anfangsnummer 32 s5 Timer
  Zeit_S5 : S5TIME ;    
END_VAR
VAR_OUTPUT
  Verzoegertes_Wort : INT ;    
END_VAR
VAR_TEMP
  AR1_Speicher : DWORD ;    
  AR2_Speicher : DWORD ;    
  schleife : INT ;    
  schleife_2 : INT ;    
  Timer_S5_T : INT ;    
  Pointer_Ausgang_Intern : DWORD ;    
  Ausgang_Intern : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =

//Rettung der AR Register
      TAR1  #AR1_Speicher; 
      TAR2  #AR2_Speicher; 

//*******************************************************************************
      L     P##Einwort; //Vorbelegung AR1 mit EW
      LAR1  ; 
      L     P##Verzoegertes_Wort; //Vorbelegung AR2 mit Verzoegertes Wort
      LAR2  ; 
      L     #Anf_s5_Timer_X_32; //Übergabe Anfangstimer
      T     #Timer_S5_T; 
      L     P#18.0; //Zustand Zwischenablage
      T     #Pointer_Ausgang_Intern; 
//*******************************************************************************
      L     16; 
next: T     #schleife; 
      U      [AR1,P#0.0]; //Indirektes  Einschlatverzoegerte Timer
      L     #Zeit_S5; 
      SE    T [#Timer_S5_T]; 
      U     T [#Timer_S5_T]; 
      =     L [#Pointer_Ausgang_Intern]; 
//++++++++++++++++++++++++++++++++++++++++++++++++++
      L     P#0.1; //Pointererhöhung um ein Bit
      +AR1  ; 
      +AR2  ; 
      L     1; // Timernummererhöhung um 1
      L     #Timer_S5_T; 
      +I    ; 
      T     #Timer_S5_T; 
//++++++++++++++++++++++++++++++++++++++++++++++++++
      L     #Pointer_Ausgang_Intern; //Erhöhung Pointer zwischenablage
      L     P#0.1; 
      +D    ; 
      T     #Pointer_Ausgang_Intern; 
//++++++++++++++++++++++++++++++++++++++++++++++++++
      L     #schleife; 
      LOOP  next; 
//*******************************************************************************
      L     P##Einwort; //Vorbelegung AR1 mit EW
      LAR1  ; 
      L     P##Verzoegertes_Wort; //Vorbelegung AR2 mit Verzoegertes Wort
      LAR2  ; 
      L     P#18.0; //Zustand Zwischenablage
      T     #Pointer_Ausgang_Intern; 
      L     16; 
nex2: T     #schleife; 
      UN     [AR1,P#0.0]; //Indirektes  Impuls Timer
      L     #Zeit_S5; 
      SI    T [#Timer_S5_T]; 
      U     T [#Timer_S5_T]; 
      O     L [#Pointer_Ausgang_Intern]; 
      =      [AR2,P#0.0]; 
      L     P#0.1; //Pointererhöhung um ein Bit
      +AR1  ; 
      +AR2  ; 
      L     #Pointer_Ausgang_Intern; //Erhöhung Pointer zwischenablage
      L     P#0.1; 
      +D    ; 
      T     #Pointer_Ausgang_Intern; 
      L     #Timer_S5_T; 
      L     1; // Timernummererhöhung um 1
      +I    ; 
      T     #Timer_S5_T; 
      L     #schleife; 
      LOOP  nex2; 
//*******************************************************************************
//Rückspielung der AR Register
      LAR1  #AR1_Speicher; 
      LAR2  #AR2_Speicher; 
END_FUNCTION
Viele Grüße Bernard
 

Anhänge

  • EW_Verzoegerung_2.JPG
    EW_Verzoegerung_2.JPG
    16,8 KB · Aufrufe: 60
Zuletzt bearbeitet:
generiere dir einen impuls der ausreichend genau für deine zeitauflösung ist. zb. 1s takt aus dem taktmerkerbyte der cpu...

wenn du dann jeden eingang 4s verzögern willst, dann mache ein array mit 4 worten. diese nutzt du als schiebregister.

mit eine flanke des sekundentaktes triggerst du nun dein schieberegister.

in etwa so:

u m100.4 /taktmerker 1s
fp m1.0
spbn move

l puffer[3]
t puffer [4]

l puffer[2]
t puffer[3]

l puffer[1]
t puffer [2]

l ew
t puffer[1]
move: nop 0


auswertung

l puffer[1]
l puffer[2]
ow
l puffer[3]
ow
l puffer[4]
ow
t aw

..und lass den scheiss mit den timern...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Schieberegister

Hallo Markus,

deine Idee mit dem Schieberegister ist schön und überschaubar.
Aber wenn nun die Einschaltzeit ungleich der Ausschaltverzögerung sein soll,was dann? Bei den "Scheiß Timern" muß man lediglich einen Parameter
hinzufügen und an einer Stelle im Programm einbinden.Wenn man will könnte man sogar für jedes einzelne Bit verschiedene Ein-Ausschaltzeiten definieren (Array[0..15] of s5time).

Viele Grüße Bernard
 
Hallo Markus,

deine Idee mit dem Schieberegister ist schön und überschaubar.
Aber wenn nun die Einschaltzeit ungleich der Ausschaltverzögerung sein soll,was dann?

wie meinst du das?

Bei den "Scheiß Timern" muß man lediglich einen Parameter
hinzufügen und an einer Stelle im Programm einbinden.Wenn man will könnte man sogar für jedes einzelne Bit verschiedene Ein-Ausschaltzeiten definieren (Array[0..15] of s5time).

Viele Grüße Bernard

dann mache das wengisten mit nem fb und nimm iec timer (sfb4)
 
Hallo Bernard,

da muss ich schon mal sagen "Respekt".
Ich hoffe doch Eloboy lässt sich mal zu einem Danke herab.

Das mit den 32 Zeiten gefällt mir auch nicht so, und es sollten dann schon variable Zeiten sein.
Mein erster Gedanke war auch wie Markus schreibt mit den IEC-Timern oder einfach Sekunden zählen.
dann mache das wengisten mit nem fb und nimm iec timer (sfb4)
Aber natürlich geht das nur mit einem FB, doch nun kommt der Adressenversatz ins spiel.
Vielleicht könnte der Baustein als FB mit variablen Zeitenwerten und Zeitgliedern dann doch ausarten und jeher unübersichtlich werden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Vielleicht könnte der Baustein als FB mit variablen Zeitenwerten und Zeitgliedern

Ich habe den Baustein nochmal überarbeitet.
Jedes Bit ist bzgl. seines zeitlichen Ein-Ausschalten einzeln einstellbar.
Für die Ein-Auszeiten wuden zwei Zeitarray`s als Eingangsgrössen definiert.Bei den Timern bin ich bei den S5Timern geblieben,weil sie sich besonders für die indirekte Adressierung eignen.Ein Ausgangsparameter benennt den letzten benutzten Timer.
Projekt und Beschaltungscode liegen bei.

Code:
FUNCTION "EW_ein_aus_Zeitversatz" : VOID
TITLE =
VERSION : 0.1
 
VAR_INPUT
  Einwort : WORD ; 
  Anf_s5_Timer_X_32 : INT ; //Belegt ab der Anfangsnummer 32 s5 Timer
  Zeitfeld_S5_Ein : ARRAY  [1 .. 16 ] OF S5TIME ; 
  Zeitfeld_S5_Aus : ARRAY  [1 .. 16 ] OF S5TIME ; 
END_VAR
VAR_OUTPUT
  Verzoegertes_Wort : WORD ; 
  Letzte_Timer_NR : INT ; 
END_VAR
VAR_TEMP
  AR1_Speicher : DWORD ; 
  AR2_Speicher : DWORD ; 
  schleife : INT ; 
  Timer_S5_T : INT ; 
  Pointer_Aus_Intern_ein : DWORD ; 
  Ausgang_Intern_ein : WORD ; 
  Pointer_Zeitfeld_Intern : DWORD ; 
  DBNR : INT ; 
  PointerAus_Intern_aus : DWORD ; 
  Ausgang_Intern_allgemein : WORD ; 
END_VAR
BEGIN
NETWORK
TITLE =
//Rettung der AR Register
      TAR1  #AR1_Speicher; 
      TAR2  #AR2_Speicher; 
//*******************************************************************************
//*******************************************************************************
      L     P##Einwort; //Vorbelegung AR1 mit EW
      LAR1  ; 
      L     P##Zeitfeld_S5_Ein; //Vorbelegung AR2 Anfang Zeitfeld ein
      LAR2  ; 
      L     #Anf_s5_Timer_X_32; //Übergabe Anfangstimer
      T     #Timer_S5_T; 
      L     P#16.0; //Zustand Zwischenablage Ausgang intern
      T     #Pointer_Aus_Intern_ein; 
//+++++++++++++++++++++++++++++++++++++++++++++++++++
      L     W [AR2,P#0.0]; //indirektes Adressieren Datenbaustein Zeitfeld EIN
      T     #DBNR; 
      L     D [AR2,P#2.0]; //Adressanfang der Zeiten
      T     #Pointer_Zeitfeld_Intern; 
//*******************************************************************************
      L     16; 
next: T     #schleife; 
//--------------------------------
      AUF   DB [#DBNR]; //indirektes öffnen des Datenbausteiens
      U      [AR1,P#0.0]; //Einzelnes Bir des Eingangswortes
      L     DBW [#Pointer_Zeitfeld_Intern]; //indirektes laden der verschiedenen Zeiten
      SE    T [#Timer_S5_T]; 
      U     T [#Timer_S5_T]; 
      =     L [#Pointer_Aus_Intern_ein]; //Zuweisung einzelnes Bit im Ausgangswort intern
//--------------------------------
      L     P#0.1; //Pointererhöhung ar1 um ein Bit
      +AR1  ; 
//--------------------------------
      L     P#2.0; 
      L     #Pointer_Zeitfeld_Intern; //Pointererhöhung Adresse Zeitfeld
      +D    ; 
      T     #Pointer_Zeitfeld_Intern; 
//--------------------------------
      L     1; // Timernummererhöhung um 1
      L     #Timer_S5_T; 
      +I    ; 
      T     #Timer_S5_T; 
//--------------------------------
      L     #Pointer_Aus_Intern_ein; //Erhöhung PointerAusgang_inter
      L     P#0.1; 
      +D    ; 
      T     #Pointer_Aus_Intern_ein; 
//--------------------------------
      L     #schleife; 
      LOOP  next; 
//*******************************************************************************
//*******************************************************************************
      L     P##Einwort; //Vorbelegung AR1 mit EW
      LAR1  ; 
      L     P##Zeitfeld_S5_Aus; //Vorbelegung AR2 Anfang Zeitfeld ein
      LAR2  ; 
      L     P#16.0; //Zustand Zwischenablage Ausgang intern ein
      T     #Pointer_Aus_Intern_ein; 
      L     P#28.0; 
      T     #PointerAus_Intern_aus; //Zustand Zwischenablage Ausgang intern aus
//+++++++++++++++++++++++++++++++++++++++++++++++++++
      L     W [AR2,P#0.0]; //indirektes Adressieren Datenbaustein Zeitfeld aus
      T     #DBNR; 
      L     D [AR2,P#2.0]; //Adressanfang der Zeiten
      T     #Pointer_Zeitfeld_Intern; 
//+++++++++++++++++++++++++++++++++++++++++++++++++++
      L     16; 
nex2: T     #schleife; 
//--------------------------------
      AUF   DB [#DBNR]; //indirektes öffnen des Datenbausteiens
      UN     [AR1,P#0.0]; //Einzelnes Bir des Eingangswortes
      L     DBW [#Pointer_Zeitfeld_Intern]; //indirektes laden der verschiedenen Zeiten
      SI    T [#Timer_S5_T]; 
      U     T [#Timer_S5_T]; 
      O     L [#Pointer_Aus_Intern_ein]; 
      =     L [#PointerAus_Intern_aus]; 
//--------------------------------
      L     P#0.1; //Pointererhöhung ar1 um ein Bit
      +AR1  ; 
//--------------------------------
      L     P#2.0; 
      L     #Pointer_Zeitfeld_Intern; //Pointererhöhung Adresse Zeitfeld
      +D    ; 
      T     #Pointer_Zeitfeld_Intern; 
//--------------------------------
      L     1; // Timernummererhöhung um 1
      L     #Timer_S5_T; 
      +I    ; 
      T     #Timer_S5_T; 
//--------------------------------
      L     #Pointer_Aus_Intern_ein; //Erhöhung PointerAusgang_inter ein
      L     P#0.1; 
      +D    ; 
      T     #Pointer_Aus_Intern_ein; 
      L     #PointerAus_Intern_aus; //Erhöhung PointerAusgang_inter aus
      L     P#0.1; 
      +D    ; 
      T     #PointerAus_Intern_aus; 
//--------------------------------
      L     #schleife; 
      LOOP  nex2; 
//Befehlsausgabe
      L     #Ausgang_Intern_allgemein; 
      T     #Verzoegertes_Wort; 
      L     #Timer_S5_T; 
      L     1; 
      -I    ; 
      T     #Letzte_Timer_NR; 
//*******************************************************************************
//Rückspielung der AR Register
      LAR1  #AR1_Speicher; 
      LAR2  #AR2_Speicher; 
      SET   ; 
      SAVE  ; 
 
END_FUNCTION

Viele Grüße Bernard
 

Anhänge

  • Ew_Verzögerung.JPG
    Ew_Verzögerung.JPG
    25,4 KB · Aufrufe: 14
  • Programm.zip
    39,4 KB · Aufrufe: 5
Da Markus ja was von "nimmste mal eben TON/TOF" schrieb, dachte ich mir, testest du mal gerade einen Baustein mit einem "ARRAY [0..15] OF TON".

Pustekuchen. Das scheint so nicht zu gehen. Nichtmal in SCL bekommt man das hin.
Jetzt habe ich mir gerade tierisch einen abgebrochen um das mittels UC und Parameterversorgung zu Fuß zu lösen, aber das kanns eigentlich auch nicht sein.

Ich gucke morgen mal ob das bei Codesys mit einem Array of TON auch nicht geht, oder ob das nur Siemens-Spezial ist.

Oder sollte das doch irgendwie anders gehen?

Dieser Code funktioniert zumindest:
Code:
FUNCTION_BLOCK "WORDVerzoegerung"
TITLE =Variable Ein/Ausschaltverzögerung mit TON/TOF
//Sollzeiten in Array: [0] = Bit 1.0, [8] = Bit 0.0
AUTHOR : TWI
VERSION : 0.1


VAR_INPUT
  wEinWord : WORD ;    //zu verzögerndes Wort
  tEinverz : ARRAY  [0 .. 15 ] OF //Keine Zeit T#0s einstellen!
  TIME  := T#3S;    
  tAusverz : ARRAY  [0 .. 15 ] OF //Keine Zeit T#0s einstellen!
  TIME  := T#4S;    
END_VAR
VAR_OUTPUT
  wVerzwort : WORD ;    //verzögertes Wort
END_VAR
VAR
  TONs : ARRAY  [0 .. 15 ] OF STRUCT     
   IN : BOOL ;    
   PT : TIME ;    
   Q : BOOL ;    
   ET : TIME ;    
   STATE : BYTE ;    
   STIME : TIME ;    
   ATIME : TIME ;    
  END_STRUCT ;    
  TOFs : ARRAY  [0 .. 15 ] OF STRUCT     
   IN : BOOL ;    
   PT : TIME ;    
   Q : BOOL ;    
   ET : TIME ;    
   STATE : BYTE ;    
   STIME : TIME ;    
   ATIME : TIME ;    
  END_STRUCT ;    
END_VAR
VAR_TEMP
  i : INT ;    
  dwAR2_save : DWORD ;    
  dwTONArrayOffset : DWORD ;    
  dwTIMEArrayOffset : DWORD ;    
  wEW_IN_temp : WORD ;    
  wEW_OUT_temp : WORD ;    
  wBitmask : WORD ;    
  xTON_IN : BOOL ;    
  xTON_Q : BOOL ;    
  tTON : TIME ;    
  tTOF : TIME ;    
END_VAR
BEGIN
NETWORK
TITLE =Timer bearbeiten

// Auf Temp Bereich kopieren, damit AR2 Offset hier nicht einbezogen werden muss
      L     #wEinWord; 
      T     #wEW_IN_temp; 

      L     W#16#0; 
      T     #wEW_OUT_temp; 

// Bitmaske initialisieren
      L     W#16#1; // wBitmask = (1 << 0);
      T     #wBitmask; 

      L     0; 
      T     #i; // i = 0;

      TAR2  #dwAR2_save; // AR2 sichern 
//--------------------------------------     
// Schleife
lop:  NOP   0; // do {  
// Array Offset nur einmal pro Schleifendurchlauf berechnen
      L     #i; 
      L     22; // sizeof(TON) und sizeof(TOF) = 22 Bytes
      *I    ; 
      SLD   3; 
      T     #dwTONArrayOffset; 

      L     #i; 
      L     4; // sizeof(TIME) = 4 Bytes
      *I    ; 
      SLD   3; 
      T     #dwTIMEArrayOffset; 
// Sollzeiten einlesen
      L     P##tEinverz; 
      +AR2  ; 
      L     #dwTIMEArrayOffset; 
      +AR2  ; 
      L     DID [AR2,P#0.0]; 
      T     #tTON; 

      LAR2  #dwAR2_save; // AR2 wiederherstellen

      L     P##tAusverz; 
      +AR2  ; 
      L     #dwTIMEArrayOffset; 
      +AR2  ; 
      L     DID [AR2,P#0.0]; 
      T     #tTOF; 

      LAR2  #dwAR2_save; // AR2 wiederherstellen
// Bit ausmaskieren
      L     #wEW_IN_temp; 
      L     #wBitmask; 
      UW    ; 
      SPP   bOn; // "Und" Verknüpfung war positiv (A1-Bit Statusregister)
      CLR   ; 
      =     #xTON_IN; 
      SPA   bEx; 
bOn:  SET   ; 
      =     #xTON_IN; 

//--------------------------------------
// Einschaltverzögerung  TON

// Offset auf TON Struktur bauen
bEx:  L     P##TONs; // Pointer auf TON Array
      +AR2  ; // AR2 Offset addieren
      L     #dwTONArrayOffset; 
      +AR2  ; // Offset in Array
// TON beschalten
      L     #tTON; 
// DID[AR2,P#2.0] wird automatisch in falsches Symbol umgewandelt!
      T     #tEinverz[0]; // Position "PT"

      U     #xTON_IN; 
      =     DIX [AR2,P#0.0]; // Position "IN"

      UC    "TON"; // Bausteinaufruf

// TON Ausgang lesen
      U     DIX [AR2,P#6.0]; // Position "Q"
      =     #xTON_Q; 

      LAR2  #dwAR2_save; // AR2 wiederherstellen

//--------------------------------------
// Ausschaltverzögerung TOF
      L     P##TOFs; // Pointer auf TOF Array
      +AR2  ; // AR2 Offset addieren
      L     #dwTONArrayOffset; 
      +AR2  ; // Offset in Array
// TOF beschalten
      L     #tTOF; 
// DID[AR2,P#2.0] wird automatisch in falsches Symbol umgewandelt!
      T     #tEinverz[0]; // Position "PT" ( 

      U     #xTON_Q; 
      =     DIX [AR2,P#0.0]; // Position "IN"

      UC    "TOF"; // Bausteinaufruf  

// TOF Ausgang lesen
      U     DIX [AR2,P#6.0]; // Position "Q"
      SPBN  of; 
// Ausgang von TOF ist gesetzt, bit in Word setzen
      L     #wBitmask; 
      L     #wEW_OUT_temp; 
      OW    ; 
      T     #wEW_OUT_temp; 

of:   LAR2  #dwAR2_save; // AR2 wiederherstellen
//--------------------------------------
// Bitmaske weiterschieben
      L     #wBitmask; // wBitmask <<= 1;
      SLW   1; 
      T     #wBitmask; 

      L     #i; 
      L     1; 
      +I    ; 
      T     #i; // i++;
      L     15; // } while (i <= 15);
      <=I   ; 
      SPB   lop; 
//--------------------------------------
// Temp Wort ausgeben
      L     #wEW_OUT_temp; 
      T     #wVerzwort; 

      LAR2  #dwAR2_save; // AR2 wiederherstellen
      SET   ; 
      SAVE  ; 
END_FUNCTION_BLOCK
 
...
Ich gucke morgen mal ob das bei Codesys mit einem Array of TON auch nicht geht, oder ob das nur Siemens-Spezial ist.
...

Um dem Nachschauen vorweg zu greifen: Ja CoDeSys (TwinCAT und Co.) können auch Arrays von Funktionsblöcken verwalten und somit auch von TON und TOF Arrays abbilden.

Auf der Siemens Seite würde ich es wohl mit dem Standard FC80 (TON_R oder so ähnlich) versuchen. Der Arbeitet mit dem OB1_Prevcycle und benöttigt nur ein Doppelwort (DINT?) zum Speichern, hier von kann man ja auch bei Siemens ein Array anlegen.
In SCL könnte man das ganze dann auch noch in eine For-Scheile packen und das Array via Index ansprechen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ew_Totzeit ohne S5Timer

So,habe den ganzen Mist noch einmal überarbeitet.Jetzt werden weder S5 noch IEC Timer verwendet.Habe denTipp von Zotos berücksichtigt und den FC80 genommen.Aus diesem habe ich die Timer gebaut die für die Funktionalitäten gebraucht wurden.Für die Errechnung der Zykluszeit wurde ebenfalls ein eigener Baustein erzeugt.
Alle Einschaltverzögerungen sowie die Impulszeiten sind für jedes Bit einstellbar,das Format ist t#Time.Die Restlaufzeiten jedes einzelnen Timers sind über Zeitfelder auslesbar.Das Kernprogramm ist in SCL erstellt.
Habe jetzte keine Lust mehr weiter zu proggen(meine Freundin drohte schon damit,mein neues Notebook in die
Tonne zu kloppen).
Pgrogramm liegt bei.
Beschaltungsmuster liegt bei
SCL Code
Code:
FUNCTION_BLOCK "ew_Totzeit"
VAR_INPUT//Eingänge
 einwort:WORD;//Totzeit Eingangswort
 ein_Bit AT einwort:ARRAY[1..16] OF BOOL;
 Zeitfeld_Ton:ARRAY[1..16] OF TIME;//Zeitfeld für Eingangsverzögerung
 Zeitfeld_Impuls:ARRAY[1..16] OF TIME; //Zeitfeld für Impulsverlängrung
 END_VAR
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
VAR_IN_OUT
//Durchgänge  
END_VAR
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
VAR_OUTPUT//Ausgänge
Auswort:WORD;//Totzeitverzögertes Ausgangswort
Feld_Rest_time_Ton:ARRAY[1..16] OF TIME;//Restzeiten aller Einschaltverzögerungen
Feld_Rest_time_impuls:ARRAY[1..16] OF TIME;//Restzeit aller Impulsverlängerungnen
END_VAR
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
VAR// statische Variablen
speicher_timer_ton:ARRAY[1..16] OF DINT;
speicher_timer_puls:ARRAY[1..16] OF DINT;
Taktzeit:"Zyklus_TIme";//Erzeugt Zykluszeit
Speicher_impuls:ARRAY[1..16] OF STRUCT
    Flag:bool;
    FLME_1:BOOL;
    FLME_2:BOOL;
END_STRUCT;
Flanken_Speicher:ARRAY[1..16] OF STRUCT
    FLME:BOOL;
    Impuls:BOOL;
    END_STRUCT;
Index:INT;
END_VAR
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
VAR_TEMP// LokaleVariablen
Auswort_intern_ton:WORD;
Auswort_intern_impuls:WORD;
ausgang_Bit_Ton AT Auswort_intern_ton:ARRAY[1..16] OF BOOL;
ausgang_Bit_impuls AT Auswort_intern_impuls:ARRAY[1..16] OF BOOL;
Zykluszeit_intern:INT;
END_VAR
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
BEGIN
//Vorbelegung index 
index:=1;
//Zykluszeit Messung
Taktzeit();
Zykluszeit_intern:=Taktzeit.Zykluszeit;
 
 FOR index:=1 TO 16 BY 1 DO
        //Einschaltverzögerung
        Time_TON(Timer_start :=ein_Bit[index]  // IN: BOOL
               ,Timer_reset :=false // IN: BOOL
               ,OB1_PREV_CYCLE :=Zykluszeit_intern // IN: INT
               ,TON_Time_Vorgabe :=Zeitfeld_Ton[index]  // IN: TIME
               ,Timer_Q :=ausgang_Bit_Ton[index]  // OUT: BOOL
               ,Timer_Rest_time :=Feld_Rest_time_Ton[index]  // OUT: TIME
               ,Timer_Speicher :=speicher_timer_ton[index]  // INOUT: DINT
               ); // VOID
        //Impulerzeugung Einschaltverzögerung zu Ende
        P_Flanke_in_SCL(p_Signal :=NOT ausgang_Bit_Ton[index]  // IN: BOOL
                        ,Impuls := Flanken_Speicher[index].Impuls // OUT: BOOL
                        ,flme :=Flanken_Speicher[index].FLME // INOUT: BOOL
                        ); // VOID
         //Nachlauf Eingang ist false
         Time_Impuls(Timer_start :=  Flanken_Speicher[index].Impuls  // IN: BOOL
                     ,Timer_reset :=false  // IN: BOOL
                     ,OB1_PREV_CYCLE :=Zykluszeit_intern  // IN: INT
                     ,Impuls_Time_Vorgabe :=Zeitfeld_Impuls[index]  // IN: TIME
                     ,Timer_Q :=ausgang_Bit_impuls[index]   // OUT: BOOL
                     ,Timer_Rest_time :=Feld_Rest_time_impuls[index] // OUT: TIME
                     ,Timer_Speicher :=speicher_timer_puls[index]  // INOUT: DINT
                     ,Speicher_bool_Zustand := Speicher_impuls[index].Flag // INOUT: BOOL
                     ,Flme_1 := Speicher_impuls[index].FLME_1// INOUT: BOOL
                     ,Flme_2 := Speicher_impuls[index].FLME_2 // INOUT: BOOL
                     ); // VOID
 END_FOR;
 //Befehlsausgabe
 Auswort:=Auswort_intern_impuls  OR Auswort_intern_ton;
OK:=true;
END_FUNCTION_BLOCK
Viele Grüße Bernard
 

Anhänge

  • Ew_Verzögerung.JPG
    Ew_Verzögerung.JPG
    27,6 KB · Aufrufe: 20
  • Programm_EW_Totzeit.zip
    44,6 KB · Aufrufe: 6
Zurück
Oben