Draco Malfoy
Level-1
- Beiträge
- 1.168
- Reaktionspunkte
- 82
-> Hier kostenlos registrieren
Guten Abend zusammen.
Gesucht wird eine Möglichkeit, serielle Kommunikation mit einem ET200Si Modul dergestalt zu bewerkstelligen, daß ein Paketversand mit definierten Wartezeiten zwischen den Zeichen möglich ist. Die Schnittstellen-Baugruppe hat die Bestellnummer 6ES7 138-4DF01-0AB0 und benutzt im Normalfall die Bausteine FB 2 S_SEND_SI und FB 3 S_RECV_SI.
Da in dem zugehörigen Siemens-Beispielprojekt für die serielle Kommunikation die gewünschte Funktionalität so nicht dargestellt ist, habe ich mal einen kleinen Baustein in SCL verfasst. Eins vorab: ich kenne mich in SCL kaum aus. Gibt es eine Hoffnung, daß dieser Code in Etwa funktionieren könnte ?
Dank allseits im Voraus!
Gesucht wird eine Möglichkeit, serielle Kommunikation mit einem ET200Si Modul dergestalt zu bewerkstelligen, daß ein Paketversand mit definierten Wartezeiten zwischen den Zeichen möglich ist. Die Schnittstellen-Baugruppe hat die Bestellnummer 6ES7 138-4DF01-0AB0 und benutzt im Normalfall die Bausteine FB 2 S_SEND_SI und FB 3 S_RECV_SI.
Da in dem zugehörigen Siemens-Beispielprojekt für die serielle Kommunikation die gewünschte Funktionalität so nicht dargestellt ist, habe ich mal einen kleinen Baustein in SCL verfasst. Eins vorab: ich kenne mich in SCL kaum aus. Gibt es eine Hoffnung, daß dieser Code in Etwa funktionieren könnte ?
Dank allseits im Voraus!
Code:
FUNCTION_BLOCK "FB 23_ASCII-COMMUN"
TITLE = ASCIICOM
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : Malfoy
FAMILY : 'MDP-82'
NAME : ASCII
VERSION : 1.0
//Serielle Kommunikation über die RS-232 Schnittstelle mittels 6ES7 138-4DF01-0AB0 ET200Si Modul
VAR_INPUT
Start_Initialisierung : Bool;
FIRST_STATE : Bool;
END_VAR
VAR
Timer_WAITINGTIME {OriginalPartName := 'TON'; LibVersion := '1.0'} : TON;
RECIVE_DATA : "S_RECV_SI";
SEND_DATA : "S_SEND_SI";
COUNTER_ZEICHEN_IM_BEFEHL : Int;
COUNTER_BEFEHLE : Int;
END_VAR
VAR CONSTANT
DBB_OFFSET : Int := 1;
DB_OFFSET : Int := 30;
CARRIER_WAITING_TIME : Time := T#37mS;
END_VAR
BEGIN
IF #Start_Initialisierung AND NOT #FIRST_STATE THEN
// -------------------------------------
// SENDEN - FB 2_S_SEND_SI MULTIINSTANZ;
// -------------------------------------
//
#SEND_DATA.REQ := "SEND_ WORK_DB_SI_0".S_SEND_SI_REQ;
#SEND_DATA.R := "SEND_ WORK_DB_SI_0".S_SEND_SI_R;
#SEND_DATA.LADDR := "SEND_ WORK_DB_SI_0".S_SEND_SI_WORK_LADDR;
#SEND_DATA.DB_NO := "SEND_ WORK_DB_SI_0".S_SEND_SI_WORK_DB_NO;
#SEND_DATA.DBB_NO := "SEND_ WORK_DB_SI_0".S_SEND_SI_WORK_DBB_NO;
#SEND_DATA.LEN := "SEND_ WORK_DB_SI_0".S_SEND_SI_WORK_LEN;
#SEND_DATA.DONE := "SEND_ WORK_DB_SI_0".S_SEND_SI_DONE;
#SEND_DATA.ERROR := "SEND_ WORK_DB_SI_0".S_SEND_SI_ERROR;
#SEND_DATA.STATUS := "SEND_ WORK_DB_SI_0".S_SEND_SI_WORK_STAT;
#SEND_DATA.COM_RST := "SEND_ WORK_DB_SI_0".S_SEND_SI_COM_RST;
END_IF;
//**************************PERMANENTE ANWEISUNGEN***************************************//
//***************************************************************************************//
//********BEFEHLE WERDEN IM SOURCE DATEN_DB in Blöcken mit je 30 Zeichen abgelegt *******//
//
// -----------------------------------------------------------------------------------------------------------------------------
// Ein Befehl erhält die Array-Adresse: Grundadresse (bsplsw. DB20.DBB10) + Offset von 30 Zeichen, wobei nicht immer alle 30
// Zeichen gesendet werden müssen, sondern nur die Länge, die aktuell in dem Counter ZEICHEN anhängig von dem Stand des
// Counters BEFEHLE abgelegt ist. Anm.: Korrekte Werte eintragen / überprüfen
// -----------------------------------------------------------------------------------------------------------------------------
//
#COUNTER_BEFEHLE := 17;
IF #FIRST_STATE AND NOT #Start_Initialisierung THEN
WHILE (#COUNTER_BEFEHLE <> 0) DO
//
//------------------------------------------------
//KORREKTE ZEICHENLÄNGE DEN BEFEHLEN ZUORDNEN:
// -----------------------------------------------
//
CASE #COUNTER_BEFEHLE OF
0: #COUNTER_ZEICHEN_IM_BEFEHL := 18; // Zeichenlänge des ersten Befehls;
1: #COUNTER_ZEICHEN_IM_BEFEHL := 20; // Zeichenlänge des zweiten Befehls;
2..8: #COUNTER_ZEICHEN_IM_BEFEHL := 18; // Zeichenlänge der Befehle 3 bis 9;
9: #COUNTER_ZEICHEN_IM_BEFEHL := 22; // Zeichenlänge des 10. Befehls;
ELSE
#COUNTER_ZEICHEN_IM_BEFEHL := 18; // Darüber hinaus;
END_CASE;
//
// ------------------------------------------------------------
// TIMER FÜR DIE NÄCHSTE ÜBERTRAGUNG SETZEN, WENN ABGELAUFEN:
// ------------------------------------------------------------
//
IF (#Timer_WAITINGTIME.IN <> true) THEN
#Timer_WAITINGTIME.IN := true;
#Timer_WAITINGTIME.PT := #CARRIER_WAITING_TIME;
END_IF;
//
// -----------------------------------------------------------------------------
// DATENLÄNGE ABHÄNGIG VOM COUNTER -> UNNÖTIG DA ZEICHENWEISE GESENDET WIRD ??
// -----------------------------------------------------------------------------
//
IF (#COUNTER_ZEICHEN_IM_BEFEHL <> 0) THEN
#SEND_DATA.LEN := 1;
END_IF;
//
// -----------------------------------------------------------------
// DATEN SENDEN PER SCHLEIFE mit TIMER (jeweils 1 Zeichen lang):
// -----------------------------------------------------------------
//
WHILE (#COUNTER_ZEICHEN_IM_BEFEHL <> 0) DO
IF NOT #SEND_DATA.ERROR AND #SEND_DATA.DONE AND #Timer_WAITINGTIME.Q THEN
IF NOT #SEND_DATA.REQ THEN
#SEND_DATA.REQ := true;
END_IF;
#COUNTER_ZEICHEN_IM_BEFEHL := #COUNTER_ZEICHEN_IM_BEFEHL - 1; // Schleifenzähler dekrementieren
#SEND_DATA.DBB_NO := #SEND_DATA.DBB_NO + #DBB_OFFSET; //Offset für den nächsten Zugriff generieren
#Timer_WAITINGTIME.IN := false; // Unterbrechung des Timers On Delay setzen
END_IF;
END_WHILE;
#SEND_DATA.DBB_NO := #SEND_DATA.DBB_NO + #DB_OFFSET; // Offset für den folgenden Befehl generieren
#COUNTER_BEFEHLE := #COUNTER_BEFEHLE - 1; //Schleifenzähler dekrementieren
END_WHILE;
END_IF;
END_FUNCTION_BLOCK
Zuletzt bearbeitet: