Step 7 Adressregister in einem Multiinstanz FB nutzen

JanS

Level-1
Beiträge
3
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen alle zusammen,

ich habe folgende Frage:

Angenommen ich habe einen FB x erstellt welcher im FB y als Multiinstanz aufgerufen werden soll.
Hier ist nun das Problem, dass ich in dem FB x , 2 Eingänge vom Typ String a und String b habe.
Wobei ich den String b aus einer SQL-Datenbank abhole, hierbei ist das Problem, dass dieser keine Ist länge mit übermittelt bekommt.
Dies hat zur Folge, dass ich bei einem EQ-String (also dem Vergleich der beiden Strings) immer einen unterschied bekomme.

Ziel ist es nun, die Ist-länge von String a an String b zu schreiben.
Doch es scheitert schon dabei, einen festen Wert (5) als Ist-Wert zu nutzen.
kann hier wer helfen ?

LAR1 P#String b
L 5
T LB [AR1,P#1.0]


//Vergleichen der beiden Strings
CALL "EQ_STRNG"
S1 :=String a
S2 :=String b
RET_VAL:=#Equal
 
Kannst Du nicht besser dort, wo der String b mit den Werten aus der Datenbank beschrieben wird, auch die String-Istlänge eintragen? Oder bei der Deklaration den Anfangswert mit der max-Länge initialisieren?

Dein Versuch funktioniert nicht, weil
- "String b" liegt gar nicht in TEMP sondern in einem Instanz-DB, Du schreibst aber in TEMP (T LB ...)
- zu der Adresse P##String_b muß noch der Multiinstanzoffset aus AR2 addiert werden
- das ganze Vorgehen funktioniert überhaupt nicht, falls der Code für einen "optimierten" FB in einer S7-1500 verwendet werden soll

Code:
      TAR2                      //Multiinstanzoffset aus AR2
      UD    DW#16#FFFFFF        //Bereichskennung (DB) entfernen
      L     P##String_B         //Adresse String_B in dieser Instanz mit Bereichskennung (DI)
      +D                        //dazu addieren
      LAR1                      //AR1 und DI-Register enthalten nun die Anfangsadresse von String_B 

      L     DIB [AR1,P#0.0]     //String-Maxlänge
      T     DIB [AR1,P#1.0]     //als Istlänge eintragen


//So gehts auch, weil in AR1 die Bereichskennung DI ist:
      L     B [AR1,P#0.0]       //String-Maxlänge
      T     B [AR1,P#1.0]       //als Istlänge eintragen

PS: Leerzeichen in Symbolen (z.B. Variablennamen) sollte man verbieten.
Da Du anscheinend Leerzeichen verwendest: was für eine Step7-Version verwendest Du? Was für eine SPS programmierst Du?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Harald,

die Variablenamen String a und String b sind nur hier für die Veranschaulichung genommen, diese haben in der Steuerung einen anderen Namen.


-Also muss ich den Eingang der ja im IDB liegt, erst in den TEMP kopieren ?!
-
- Als Steuerung nutze ich eine 412-2PN.

Code:
// Funktion überspringen wenn AG nicht angemeldet ist
      U     #AG_Angemeldet
      SPBN  ott1

// Laden des Eingangs-String in den TEMP 
      CALL  "BLKMOV"
       SRCBLK :=#String_b_IN
       RET_VAL:=#Retval
       DSTBLK :=#String_b_TEMP

//Hier kommt nun der Teil von dir einfach so hin ??!
      TAR2                      //Multiinstanzoffset aus AR2
      UD    DW#16#FFFFFF        //Bereichskennung (DB) entfernen
      L     P##String_b_TEMP    //Adresse String_B in dieser Instanz mit Bereichskennung (DI)
      +D                        //dazu addieren
      LAR1                      //AR1 und DI-Register enthalten nun die Anfangsadresse von String_B


// nun müsste ich noch am Eingang des FB`S die Ist länge vom String_a eingeben dann könnte ich diese Zahl nehmen und an die Ist-länge vom String_b_Temp schreiben 


//Vergleichen der beiden Strings
CALL  "EQ_STRNG"
S1     :=#String_a_IN
S2     :=#String_b_TEMP
RET_VAL:=#Equal

// Wenn die beiden Strings ungleich sind
UN    #Equal
=     #Not_Equal

ott1: NOP   0

Gruß Jan
 
Hallo Jan

-Also muss ich den Eingang der ja im IDB liegt, erst in den TEMP kopieren ?!
Nein, wie kommst Du da drauf??

Ich würde nicht korrekt initialisierte STRINGs nicht mit BLKMOV kopieren, womöglich hält sich mal eine CPU-Firmware an die verworrene Dokumentation des BLKMOV bzgl. kopieren von STRING. ;)

Die Addition des Multiinstanz-Offsets der Instanz (aus AR2) zur Variablenadresse in dieser Instanz (P##String_b_IN) ist nur bei Instanz-Variablen nötig (IN, OUT, IN_OUT, STAT), nicht jedoch bei TEMP-Variablen - TEMP-Variablen beginnen in jeder Instanz bei LB0 und P##String_b_TEMP liefert immer schon die richtige Adresse (relativ zum Beginn des eigenen TEMP).

Code:
// Funktion überspringen wenn AG nicht angemeldet ist
      U     #AG_Angemeldet
      SPBN  ott1

//Übertragen der Ist-Stringlänge von String_a_IN zu String_b_IN:
      TAR2                      //Multiinstanzoffset aus AR2
      UD    DW#16#FFFFFF        //Bereichskennung (DB) entfernen
      L     P##String_a_IN      //Adresse String_a_IN in dieser Instanz mit Bereichskennung (DI)
      +D                        //dazu addieren
      LAR1                      //AR1 und DI-Register enthalten nun die Anfangsadresse von String_a_IN

      L     DIB [AR1,P#1.0]     //String-Istlänge String_a
      T     #temp_Byte          //merken

      TAR2                      //Multiinstanzoffset aus AR2
      UD    DW#16#FFFFFF        //Bereichskennung (DB) entfernen
      L     P##String_b_IN      //Adresse String_b_IN in dieser Instanz mit Bereichskennung (DI)
      +D                        //dazu addieren
      LAR1                      //AR1 und DI-Register enthalten nun die Anfangsadresse von String_b_IN

      L     #temp_Byte          //String-Istlänge String_a
      T     DIB [AR1,P#1.0]     //String-Istlänge String_b

//Vergleichen der beiden Strings
CALL  "EQ_STRNG"
S1     :=#String_a_IN
S2     :=#String_b_IN
RET_VAL:=#Equal

// Wenn die beiden Strings ungleich sind
UN    #Equal
=     #Not_Equal

ott1: NOP   0

Harald
 
Für sowas ist es sinnvoll eine Funktion zu schreiben die einen String als Any erwartet und anhand des Wiederholfaktors die Stringlänge schreibt. Diese Funktion kann man dann so oft mit verschiedenen Strings wie kann will verwenden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen ,

vielen Dank schon mal für die schnelle hilfe Harald, dein Code hat soweit funktioniert und ich konnte den rest soweit umsetzen.
Zusätzlich gucke ich nun noch ob an der ersten Stelle meines Strings ein " " oder eine "0" steht, wenn dies der Fall ist, dann springe ich auch zu ott1 und es wird nicht eskalliert.



Code:
      U     #AG_Angemeldet
      SPBN  ott1


//Übertragen der Ist-Stringlänge von String_a_IN zu String_b_IN:
      TAR2                              //Multiinstanzoffset aus AR2
      UD    DW#16#FFFFFF                //Bereichskennung (DB) entfernen, hier wird nur die Adresse benötigt
      L     P##AG_AU_NR_Start_IN        //Adresse String_a_IN in dieser Instanz mit Bereichskennung (DI)
      +D                                //dazu addieren
      LAR1                              //AR1 und DI-Register enthalten nun die Anfangsadresse von String_a_IN

      L     DIB [AR1,P#1.0]             //String-Istlänge String_a
      T     #TEMP_B                     //merken

      TAR2                              //Multiinstanzoffset aus AR2
      UD    DW#16#FFFFFF                //Bereichskennung (DB) entfernen
      L     P##AG_AU_NR_current_IN      //Adresse String_b_IN in dieser Instanz mit Bereichskennung (DI)
      +D                                //dazu addieren
      LAR1                              //AR1 und DI-Register enthalten nun die Anfangsadresse von String_b_IN

      L     #TEMP_B                     //String-Istlänge String_a
      T     DIB [AR1,P#1.0]             //String-Istlänge String_b


// Das 2 Zeichen der SQL - Auftragsnummer darf keine 0 sein.
      L     DIB [AR1,P#2.0]
      L     0
      ==I   
      R     #Not_Equal
      SPB   ott1

// Das 2 Zeichen der SQL - Auftragsnummer darf kein Leerzeichen sein.
// 32 = dez für Leerzeichen
      L     DIB [AR1,P#2.0]
      L     32
      ==I   
      R     #Not_Equal

      SPB   ott1


//Vergleichen der beiden Strings
      CALL  "EQ_STRNG"
       S1     :=#AG_AU_NR_current_IN
       S2     :=#AG_AU_NR_Start_IN
       RET_VAL:=#Equal_1
      UN    #Equal_1
      =     #Not_Equal

ott1: NOP   0
 
Zusätzlich gucke ich nun noch ob an der ersten Stelle meines Strings ein " " oder eine "0" steht, wenn dies der Fall ist, dann springe ich auch zu ott1 und es wird nicht eskalliert.
Code:
// Das [COLOR="#FF0000"]2[/COLOR] Zeichen der SQL - Auftragsnummer darf keine 0 sein.
      L     DIB [AR1,P#2.0]
      L     [COLOR="#FF0000"]0[/COLOR]
      ==I
Falls Du wirklich das Zeichen "0" meinst wie das Leerzeichen " ", dann müsstest Du nicht auf der Wert 0 sondern auf die ASCII-Nummer 48 (B#16#30) des Zeichens '0' vergleichen.
Code:
      L     DIB [AR1,P#2.0]
      L     '0'            //oder B#16#30 oder 48
      ==I

Harald
 
Immer wieder schön, solche AWL-Orgien.

Was hindert einen eigentlich daran, die Anforderungen auf einer zeitgemäßeren Ebene umzusetzen ? SCL Option nicht installiert, oder sprechen etwa Glaubensgründe dagegen ?
 
z.B. sowas Unbedeutendes wie Kundenvorgaben.
;)

Es kann ein Argument sein, aber auch da stellt sich die Frage, ob man das durch geschickte Gesprächsführung sinnvoll umgehen kann, oder den Auftrag ganz ablehnt. Kundenvorgabe, im Jahre 2016 nach Christus noch in einem AWL-Salat rumzuwühlen, insbesondere wenn man nachher auch noch sinnbehaftete Arbeitsergebnisse erwartet, ist schon ein starkes Stück. Ein Geschäftspartner von mir hat jetzt einen Auftrag verkackt, weil er sich auf Fremdsoftware eingelassen hat, die irgendwelche Praktikanten im dunklen Alkoholrausch geschrieben haben.
 
Zuletzt bearbeitet:
Es kann ein Argument sein, aber auch da stellt sich die Frage, ob man das durch geschickte Gesprächsführung sinnvoll umgehen kann, ...
Z.B. im Automotivebereich haben gerade die Großen noch unverrückbare Vorgaben aus Zeiten der Firmengründer. (Und auf Geld verzichten - wer's kann ...)
Und ich bin mir sicher, dass viele von deren Mitarbeitern auch AWL oftmals lesbarer finden als SCL. Nicht zu vergessen, dass bei Classic SCL eh' in AWL gewandelt wird.

Ich empfinde da eigene Preferenzen in der Programmiersprache nicht als Mass der Dinge.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich empfinde da eigene Preferenzen in der Programmiersprache nicht als Mass der Dinge.
Naja, solange sich niemand dagegen wehrt und alle so pflegeleicht und widerspruchslos sind, werden wir ggf. noch in 20 Jahren so programmieren. Ich verstehe nicht, wie man mit S5 Vorgaben überhaupt noch qualitatives Arbeitsergebnis abliefern kann, und noch weniger verstehe ich, wo für mich Mehrwert liegt, den Zirkus überhaupt mitzumachen. Wenn es dann nämlich soweit ist, daß SCL und CFC verlangt und gebraucht werden, dann habe ich es ja schon längst verlernt, bzw. während der Zeit nichts dazu gelernt, und womöglich noch entscheindende Entwicklungen nicht mitbekommen ?

Ist es denn wirklich so, daß im Automotivbereich so viele Firmen S5 Standards pflegen ? Ich kenne selbst nur eine, die so macht.
 
Zurück
Oben