Step 7 Adressberechnung in einer Multiinstanz

mikraka

Level-1
Beiträge
14
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen!

Ich habe einen FB programmiert, den ich als Multiinstanz in einem anderen FB mehrfach aufrufe.
Wie man die Anfangsadresse im Instanz DB berechnet weiß ich. D.h. ist der FB 100 Byte lang, so fängt der zweite FB beim 200ten Byte an usw.
Mein Problem ist folgendes: Im FB rufe ich den SFB Date and Time auf und lasse das Datum und die Zeit in den statischen Bereich schreiben.
Angenommen die Variable liegt im statischen Bereich bei der Adresse 12.0, so liegt die Variable vom zweiten FB bei 112.0
Wie kann ich die Ausgabe des SFB so dynamisieren, dass die Daten dort hingeschrieben werden?

Den ganz normalen FB, DB Aufruf habe ich gelöst, indem ich mir die Date and Time Variable ins AR1 schreibe und anschließend lade L B[AR1, P0.0]. Somit entnehme ich dem Datentyp dt die entsprechenden Infos die ich brauche.

Der CDT Output des SFB akzeptiert nur eine statische Variable vom Typ dt. Mit einem Pointer an der Stelle kam ich syntaktisch nicht weiter.

Vielleicht hat ja jemand eine Idee.


Liebe Grüße,

Kai
 
Habe ich das richtig verstanden, dass du aus einem FB mehrere Instanzen eines bestimmten FB und den SFB aufrufst, und das Ergebnis des SFB an eine bestimmte Stelle in die IDBs von den bestimmten FBs schreiben möchtest? Warum siehst du am FB nicht gleich einen Eingang vor, legst das Ergebnis des SFB in einer lokalen Variable ab und verschaltest die mit deim Eingang des FB?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich versuche es mal deutlicher zu erklären.
Es gibt den FB400. In diesem FB400 habe ich mehrere Multiinstanzen meines FB550 aufgerufen und dieser FB550 enthält den SFB date and time. Einige Daten des date and time typs muss ich extrahieren und weiterverarbeiten.
Nur der FB400 hat einen DB, den DB400. Der DB400 enthält die Daten aller FB550.
Ich nehme die Jahreszahl, den Monat und den Tag und multipliziere es mit einem Faktor. Das ganze ergibt ein Passwort.
Solange ich den FB550 mit DB aufrufe als nicht Multiinstanz, geht es.
Bei einer Multiinstanz berechnet man die Anfangsadresse der Multiinstanzdaten im Instanz DB. Wie das geht weiß ich. Mir geht es um die Dynamisierung des Formal Out Operanden des SFB Date and Time.

Ist das so verständlicher?
 
Was du machen willst, habe ich verstanden, aber deinen Ansatz nicht so richtig. Wenn du den FB550 im FB400 als Multiinstanz anlegst und das Ergebnis vom SFB im statischen Bereich vom IDB des FB550 liegt, dann hast du doch automatisch eine statische Variable im IDB des FB400, wo das Ergebnis von deinem SFB aus der Multiinstanz liegt.

Beispiel:
Im IDB vom FB550 steht jetzt mal nur die Variable "Ergebnis". Deine Multiinstanz im FB400 heißt "FB550_1". Im IDB deines FB400 steht dann die Variable "FB550_1.Ergebnis". Mit der kannst du doch direkt arbeiten, warum möchtest du da Adressen berechnen?
 
Also egal wofür und wiso...
Bei einem Multiinstanz FB steht im Adressregister 2 (Adr2) der Instanz-DB Offset.
Damit kannst du die Absolute Adresse im IDB berechnen.
Vorsicht bei der Änderung des ADR2 diese wird für Symbolische Zugriffe benötig. Also bevor du es änderst erst den Inhalt sichern und erst nach dem wiederherstellen wieder symbolisch auf Statische IDB-Daten zugreifen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mal angenommen meine erste Multiinstanz ist 100 Byte lang. In der zweiten Multiinstanz schreibt der SFB das Date and time Zeug in den statischen Bereich mit der Lokal Adresse 12.0. Wo landet der Inhalt dann im Instanz DB, bei 12 oder 112?
Oder muss ich mich darum nicht kümmern?
 
Eine Multiinstanz kann direkt auf seine eigenen lokalen Variablen zugreifen und muß sich nicht darum kümmern, auf welchen Adressen die im Mutter-IDB liegen. Nur wenn die Adressen der eigenen lokalen Variablen weitergereicht werden sollen, dann muß die Multiinstanz wissen, wo im Mutter-IDB die eigene Instanz liegt - das wird der Multiinstanz über den Multiinstanz-Offset in AR2 mitgeteilt. Die Berechnung der Adresse von Instanzvariablen ist aber nicht ganz so simpel wie Du wohl zu wissen glaubst. Eine Multiinstanz muß auch nicht wissen, auf welchen Adressen andere Instanzen oder Variablen der Mutter-Instanzen liegen - ein Zugreifen auf diese Variablen außerhalb der eigenen Instanz ist sehr schlechter Programmierstil.


Wenn ich Dich richtig verstehe, dann kannst Du ganz ohne undurchsichtige Adressrechnerei und indirektes Rumschreiben im übergeordneten IDB Dein Problem so lösen:

Dein FB550 sollte einen OUT vom Typ DT haben, den gibst Du am CDT Deines "SFB date and time" an:
Code:
CALL #SFB_date_and_time
 CDT:=#OUT_DT

Im FB400 rufst Du die FB550-Instanzen auf und legst an deren Ausgang Deine lokalen Variablen des FB400.
Code:
CALL #FB550_1
 OUT_DT:=#lokal_DT_1

CALL #FB550_2
 OUT_DT:=#lokal_DT_2

Was meinst Du mit "SFB Date and Time"? Ich kenne keinen SFB, der irgendwas mit Date und Time zu tun hat.
Meinst Du vielleicht den SFC1 "READ_CLK" zum lesen der Uhrzeit?
Willst Du die FB550-Instanzen nacheinander aufrufen? Die würden alle (fast) die selbe Uhrzeit ermitteln. Da würde es reichen, nur einmal die Uhrzeit zu lesen.

Harald
 
Hallo,

ein neuer Angriff:)
Ich versuche meine Problematik mal genauer zu erklären. Dabei werde ich den Code mit einfügen um sie Sachlage deutlicher zu machen. Vorweg es ist ein SFC und kein SFB - mein Versehen.

FB550: Password_Torque_Cntr

Code:
NW1: Uhrzeit auslesen
 CALL  "READ_CLK"
       RET_VAL:=#L_RET_Val
       CDT    :=#dtDate


      LAR1  P##dtDate                   // Start Adresse des Datum in das Adressregister 1 legen

NW2: Daten aus Date and Time extrahieren
//Jahr speichern


      L     B [AR1,P#0.0]
      T     #L_byYear


//Monat speichern


      L     B [AR1,P#1.0]
      T     #L_byMonth


//Tag speichern


      L     B [AR1,P#2.0]
      T     #L_byDay

NW3: Konvertiere BCD zu INT
 O(    
      L     #L_byYear
      BTI   
      T     #L_iYear
      SET   
      SAVE  
      CLR   
      U     BIE
      )     
      O(    
      L     #L_byMonth
      BTI   
      T     #L_iMonth
      SET   
      SAVE  
      CLR   
      U     BIE
      )     
      O(    
      L     #L_byDay
      BTI   
      T     #L_iDay
      SET   
      SAVE  
      CLR   
      U     BIE
      )     
      =     #L_xDummy
Anschließend verarbeite ich die Daten zu einem Passwort. Das ganze funktioniert als FB mit eigenem DB Aufruf tadellos. Es stehen die erwarteten Jahreszahlen, Monate und Tage in den Variablen.

Aber wenn ich diesen Baustein als Multiinstanz aufrufe, stehen Jahr, Monat und Tag nicht mehr nicht mehr dort. Daher war meine Annahme das sich alles verschiebt im Instanz DB. Aber wenn das nicht so ist wie du sagst, dann ist da wohl noch ein anderer Fehler.

Zur Offset Berechnung. Ich habe nicht gesagt das die Offset Berechnung "simpel" ist, aber ich kriege es hin.
Auch habe ich nicht vor die internen Instanzdaten des einen FB außerhalb von diesem weiterzuverarbeiten außer der Variablen die über die Formaloperanden Q, I oder IQ nach draußen gehen bzw. rein kommen. Alles andere ist tabu.

Kurz zur Funktionsweise des Bausteins.

Der Baustein hat einen Zähleingang. Mit diesem werden Fehler gezählt. Wurden drei Fehler registriert, gibt der Baustein ein Sperr-Bit aus.
Damit wird eine Funktion gesperrt, weil mehrmals ein bestimmtes Drehmoment überschritten wurde.
Aus dem Datum wird ein Passwort berechnet.
Der Kunde ruft uns an, da seine Maschine nicht mehr läuft und verlangt nach dem Passwort, um sie zu entsperren. So bekommen wir mit das die Übertretung stattfand.
Unsere Getriebe und Motoren sind so ausgelegt, das sie der geforderten Viskosität gerecht werden. Dazu ist noch eine Sicherheit mit eingerechnet. In der Vergangenheit sind uns Getriebe um die Ohren geflogen, weil einfach viel zähere Produkte als das wofür die Anlage ausgelegt ist, produziert wurden.
Da unsere Anlagen mehrere dieser Funktionen beinhalten, ist für jede einzelne eine Sperre vorgesehen. Daher der mehrfache Aufruf.
Der Kunde kann aber auch eine Unterlassung unterschreiben, dann kommt die Überwachungssoftware raus und er kann mit der Anlage machen was er will.

Den Inhalt der in der Date and Time Variable steht möchte ich nicht als Formal-Out-Operanden ausgeben, falls das so rüber kam.

Ich hoffe, dass ich es nicht noch komplizierter gemacht habe mit meiner "Erklärerei".

Liebe Grüße,

Kai
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nabend,

Das Problem ist die Multiinstanz... Wenn du hier mit dem AR1 auf eine Adresse im aktuellen staischen Bereich zeigen willst musst du dem Inhalt vom AR2 hinzuaddieren. (Im AR2 steht der Offset für die aktuelle Multiinstanz)
 
Einfache Lösung: Lege den temporären #dtDate in TEMP, dann brauchst Du keine Multiinstanz-Adressberechnungen.
Code:
Netzwerk 1: Uhrzeit lesen

      CALL  "READ_CLK"
       RET_VAL:=#L_RET_Val
       CDT    :=#L_dtDate

Netzwerk 2: Daten aus Date and Time extrahieren

      LAR1  P##L_dtDate         //Anfangsadresse der DT-Variable in AR1 

//Jahr extrahieren
      L     B [AR1,P#0.0]       // #L_dtDate Byte 0
      BTI   
      T     #L_iYear

//Monat extrahieren
      L     B [AR1,P#1.0]       // #L_dtDate Byte 1
      BTI   
      T     #L_iMonth

//Tag extrahieren
      L     B [AR1,P#2.0]       // #L_dtDate Byte 2
      BTI   
      T     #L_iDay

Netzwerk 3: Password berechnen und zurückgeben

      L     #L_iYear
      L     #L_iMonth
      +I    
      L     #L_iDay
      +I    
      T     #O_iPwd             //Password über OUT zurückgeben

Nach Deinen bisherigen Erklärungen würde ich den Baustein statt FB als FC machen (ich sehe keinen Grund für Instanzen), den Rückgabewert gerne als RET_VAL, dann kann er bei Bedarf auch schön von SCL aufgerufen werden.


PS: Ich halte nichts davon, produzierende Maschinen stillzulegen bis ein anzufordernder Entsperrcode eingegeben wird. Egal aus welchem Grund. Doch das ist mehr das Problem Eurer Kaufleute, Euren Kunden dies als notwendig zu erklären und die Verfügbarkeit des Entsperrcodes unter allen Umständen innerhalb von Minuten zu garantieren - inklusive Schadenersatz-Regelungen für Produktionsausfall, falls Ihr mal einen Entsperrcode zu spät liefert. Wir würden jedenfalls keine Maschine mit solchen Sperren kaufen.

Harald
 
Hallo!

Die Daten des Date and Time in den Temp-Bereich zu legen ist super! Das funktioniert wie Teufel. Danke für den Tipp.

Ich gebe dir Recht das die Passwort Lösung für produzierende Maschinen nicht so glücklich ist. Aber wie du schon vermutet hast, haben sich dies Leute in der Firma ausgedacht, denen es um die Gewährleistung geht und um die Kosteneindämmung. Zwei Kunden wurde dies jetzt angeboten und beide haben die Unterlassungserklärung unterschrieben und die Passwortlösung dankend abgelehnt. Wir aus der Automation haben schon einen gewissen Einfluss, da wir die Abläufe teilweise besser kennen als die Verfahrenstechnik, sind aber dennoch nur die Exekutive.

Vielen Dank nochmal und einen schönen Herbst Sonntag!

Liebe Grüße,

Kai
 
Zurück
Oben