TIA Rezepturverwaltung Standardwert statt Aktualwert wird in Script eingelesen

fbrue

Level-2
Beiträge
34
Reaktionspunkte
6
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich habe eine 1512 und WinCC Adv. auf einer Simatic PC Station im Einsatz.
Nun zum Problem:

Ich habe in der HMI eine Rezepturveraltung. In der PLC ist in einem DB eine Struktur, die mit dieser Rezepturverwaltung verknüpft ist. Ich habe ein VB-Script, welches mir eine Liste mit zum Beispiel allen Artikelnummern der Rezepturelemente erstellt. Darin schreibe ich über eine Schleife mit der Systemfunktion "SetDataRecordToPLC" immer wieder in den DB und lese nach jedem mal schreiben wieder in die HMI ein und verarbeite die Artikelnummer weiter. Nun ist mir aufgefallen, dass obwohl ich den richtigen Wert im DB stehen habe, immer eine Null einlese. Kopiere ich mir den Wert aus dem DB in eine beliebige andere Variable, lese ich den korrekten Wert ein. Woran kann das liegen?

Update: Ich habe nochmal ein bisschen rumprobiert, und folgendes festgestellt: Ich lese immer den Wert ein, den ich in der Rezeptur unter "Standardwert" für die Artikelnummer eingestellt habe. Beim Beobachten sehe ich die korrekte Artikelnummer drin stehen, versuche ich lesend darauf zuzugreifen bekomme ich den Startwert ausgegeben.
 
Ok, es wird noch kruder.
In der Beschreibung zur Systemfunktion steht:

"Überträgt den angegebenen Rezepturdatensatz direkt vom Datenträger des Bediengeräts an die Steuerung, die mit dem Bediengerät verbunden ist.
Hinweis
Die Werte des Rezepturdatensatzes müssen dabei nicht am Bediengerät angezeigt werden."

Wähle ich am HMI einen DS aus und führe mein Script aus, dann wird der DB nur mit der Artikelnummer des aktuell ausgewählten DS gefüllt, wenn ich direkt aus der Schnittstelle der Rezeptur lese. Kopiere ich den Wert auf eine andere Variable treten die Probleme nicht auf.

Hier mal mein Script dazu:
Code:
Sub ArtNo_to_PLC()
'--Variablendeklaration--
Dim k, ArtNo, Arr_ArtNo(10), LastTime, StopTime, i

'--Schleife über Anzahl der vorhandenen Artikelnummern--
For k=1 To 10

    '--Systemfunktion Lese den Datensatz des k-ten Elementes der Rezepturverwaltung--
    SetDataRecordToPLC 1, k, hmiOn, "Wait"
    Do Until SmartTags("Wait") = 4
    Loop
   
    '--Verzögerung--
    StopTime= Now+0.01/24/3600
    Do
        If Now>LastTime + 1/24/3600 Then
            i = i+1
            LastTime= Now
        End If
    Loop Until Now>=StopTime
   
    '--Aus irgendeinem Grund kann ich nicht die Artikelnummer direkt aus dem DB lesen, sondern kopiere sie in der PLC in eine neue und lese daraus--
    ArtNo = SmartTags("_14_IDB_copyartno")

    '--Array füllen--
    Arr_ArtNo(k) = ArtNo
   
Next

'--Array in PLC Array kopieren--
SmartTags("Test-DB für neue PDTs_ArrayArtNo") = Arr_ArtNo  

End Sub
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Versuche mal die Systemfunktionen SetDataRecordTagsToPLC und GetDataRecordTagsFromPLC, da wird zwischen PLC-Variablen und HMI-Rezeptur-Variablen kopiert.

Tipp: Bei der Auswertung der Statusvariable nicht nur auf Status = 4 warten. Bei einem Fehler enden die Systemfunktionen mit Status = 12.

'--Aus irgendeinem Grund kann ich nicht die Artikelnummer direkt aus dem DB lesen, sondern kopiere sie in der PLC in eine neue und lese daraus--
HMI-Variablen, von deren Verwendung die WinCC RT nichts weiß, werden nicht vor Verwendung aktualisiert, sondern erst irgendwann NACH dem Lesezugriff. Wann genau das ist, ist nicht garantiert. Eine Zeitlang warten kann helfen, muß aber nicht! Lesen mit Lesestatus geht nur mit Rezeptur-Variablen oder mit selbstgebasteltem Handshake. Für mehr Infos zu diesem Verhalten verwende die Forumssuche mit den Suchwörtern GetDataRecordTagsFromPLC und SetDataRecordTagsToPLC

Achtung: Die WinCC RT kann nicht mehrere VBS-Skripts gleichzeitig ausführen. Solange ein VBS-Skript läuft (und z.B. in einer Warteschleife läuft) wird kein anderes VBS-Skript ausgeführt. Beachten, falls man auch noch VBS-Skripte bei Ereignissen ausführen lassen will. Die werden solange in eine begrenzte Warteliste eingetragen. Dabei kann es passieren, daß die Warteliste überläuft und/oder Skripte nicht mehr in der erwarteten Reihenfolge ablaufen.

Harald
 
Tipp: Bei der Auswertung der Statusvariable nicht nur auf Status = 4 warten. Bei einem Fehler enden die Systemfunktionen mit Status = 12.
Das hatte ich noch auf dem Schirm, ist nur noch nicht mit implementiert. Aber trotzdem Danke.

HMI-Variablen, von deren Verwendung die WinCC RT nichts weiß, werden nicht vor Verwendung aktualisiert, sondern erst irgendwann NACH dem Lesezugriff. Wann genau das ist, ist nicht garantiert. Eine Zeitlang warten kann helfen, muß aber nicht! Lesen mit Lesestatus geht nur mit Rezeptur-Variablen oder mit selbstgebasteltem Handshake. Für mehr Infos zu diesem Verhalten verwende die Forumssuche mit den Suchwörtern GetDataRecordTagsFromPLC und SetDataRecordTagsToPLC
Interessant. Gibt es eine Erklärung, warum die erst nach dem Lesen aktualisiert werden?

Die von dir vorgeschlagene Systemfunktion SetDataRecordTagsToPLC schreibt jeweils nur den angezeigten DS der Rezeptur in die PLC, oder?
Ich hatte SetDataRecordToPLC verwendet, da ich odrt direkt die Datensatznummer direkt angeben kann und nicht erst den Datensatz anzeigen lassen muss.
 
Noch eine Frage hintendran:
Ist es irgendwie möglich, die Anzahl der aktuell in der Rezeptur vorhandenen Elemente herauszufinden?
Mir fällt aktuell nur der Weg ein, die Rezeptur zu exportieren und in der csv dann zu zählen. Aber so recht gefällt mir das nicht..
Gibt es da einen einfacheren Weg?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Gibt es eine Erklärung, warum die erst nach dem Lesen aktualisiert werden?
Mit PLC-Variablen verbundene HMI-Variablen werden in der Regel nur bei Verwendung aktualisiert (um unnötige Kommunikationslast zu vermeiden), es sei denn, deren Erfassungsart ist auf "Zyklisch fortlaufend" eingestellt. Wenn eine Variable nicht im aktuellen Bild verwendet wird, sondern nur in einem Skript, dann weiß die WinCC RT nichts von deren Verwendung und aktualisiert die Variable nicht. Erst nach einem Lese-Zugriff im Skript weiß die RT daß die Variable verwendet wird und aktualisiert den Wert (liest den Wert aus der PLC). Das Skript wartet aber nicht auf das aktualisieren der Variable, sondern arbeitet sofort mit dem Wert von vor der Aktualisierung weiter. Das kann ein Startwert oder ein alter Wert von der letzten Aktualisierung sein.

Die von dir vorgeschlagene Systemfunktion SetDataRecordTagsToPLC schreibt jeweils nur den angezeigten DS der Rezeptur in die PLC, oder?
Ich hatte SetDataRecordToPLC verwendet, da ich odrt direkt die Datensatznummer direkt angeben kann und nicht erst den Datensatz anzeigen lassen muss.
SetDataRecordTagsToPLC schreibt die aktuellen Werte der Rezepturvariablen in die PLC. Dazu muß kein Rezeptur-Datensatz geladen oder angezeigt sein.
Ob Du direkt mit den Rezepturvariablen oder mit im HMI gespeicherten Datensätzen arbeiten willst/mußt, mußt Du wissen.

Harald
 
Das verstehe ich noch nicht so ganz. Wenn ich die Systemfunktion SetDataRecordTagsToPLC benutze, dann kann ich an die ja nur die gewünschte Rezeptur und eine optionale Ausgabe parametrieren. Also wird immer der DS in die PLC übertragen, der am Bediengerät angezeigt wird. Das habe ich eben grad auch nochmal getestet, in der Hilfe steht dazu auch "Die Rezepturvariablen enthalten die Werte des Datensatzes, der am Bediengerät angezeigt wird "

Mit der Systemfunktion SetDataRecordToPLC kann ich hingegen die Datensatznummer angeben und somit die Systemfunktion über eine Schleife durchlaufen lassen, wie ich es aktuell auch mache

Vielleicht habe ich auch mein Problem schlecht formuliert. Ich habe eine Rezeptur mit einer variablen Anzahl an Datensätzen. Von all diesen Datensätzen brauche ich die Artikelnummern einzeln in einem DB stehen, um dazu weitere Parameter zuordnen zu können
 
Zuletzt bearbeitet:
Den Fehler hatte ich gefunden, ich muss aber nochmal hier anknüpfen, neues Thema lohnt sich glaube ich mal nicht dafür:

Ich habe ein Skript, dass ich benutze um die Anzahl der Elemente in der Rezepturverwaltung herauszufinden.
Code:
'--Bestimmt die Anzahl der vorhandenen Datensätze in der Rezeptur--

'--Variablendeklaration--
Dim k

'--Initialisierung--
k = 1

'--Schreibt so lange den Datensatz in die PLC, bis die Systemfunktion Fehler (Wait=12) gibt--
Do Until SmartTags("Wait") = 12
    SetDataRecordToPLC 1, k, hmiOn, "Wait"
    Do Until SmartTags("Wait") = 4
    If SmartTags("Wait") = 12 Then
        Exit Do 
    End If
    Loop
    k = k+1
Loop
'--k anpassen, sodass es der Nummer der Datensätze entspricht--
k = k-2

Sobald die Systemfunktion 12 gibt weiß ich, ich habe versucht ein Element zu lesen, was es nicht gibt und kann mir aus dem k die korrekte Anzahl berechnen. Nun bricht die Systemfunktion jedoch sporadisch, also leider nicht reproduzierbar, immer mal wieder vorher ab. Ich habe keine Dokumentation dazu gefunden, in welchen Fällen genau die Funktion "Wait"=12 sonst noch gibt, außer eben bei "Error"..
Sieht jemand meinen Fehler darin? Ich verschwende seit Tagen Zeit an dem Problem und weiß nicht, woran es liegen soll.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo fbrue,

Datensätze sind nicht zwingend ohne Lücke abgelegt...
Beispielszenario:
+ Ursprünglich 10 Rezepte mit Nummer 1-10 abgelegt.
+ Danach wird Rezept mit Nr. 3 gelöscht
-> 9 Rezepte mit den Nummer 1-2 und 4-10 vorhanden


Gruß, Fred


PS:
Besser wäre es, die Systemfunktion "LeseDatensatzName" zu verwenden, dann brauchst du den Umweg über die Steuerung oder weitere Hilfskonstrukte nicht.
 
Die Datensätze sind definitiv ohne Lücke abgelegt.
Der Import erfolgt in meinem Fall nur über eine CSV, darin ist sichergestellt, dass es keine Lücken gibt. DS Löschen ist für den normalen Bediener nicht möglich.

Die Systemfunktion probiere ich gleich mal aus
 
Also, die Funktion funktioniert definitiv schneller als die bisher verwendete.
Es kommt aber trotzdem zu Laufzeitfehlern bei einer größeren Anzahl an Elementen. Mal werden alle DS durchlaufen und die korrekte Anzahl ausgegeben, mal weniger. Dabei bricht es immer unterschiedlich ab, mal nach 4, mal nach 78,... Die Meldung dazu sagt jedes mal: "Datensatzbearbeitung nicht möglich, da bereits eine Rezepturaktion läuft". Wie kann eine neue Rezepturaktion getriggert werden während eine läuft, wenn ich doch eine Do Until Schleife habe, bis die gestartete Funktion wirklich abgearbeitet ist?
 
Code:
'--Schreibt so lange den Datensatz in die PLC, bis die Systemfunktion Fehler (Wait=12) gibt--
Do Until SmartTags("Wait") = 12
    SetDataRecordToPLC 1, k, hmiOn, "Wait"
    Do Until SmartTags("Wait") = 4
    If SmartTags("Wait") = 12 Then
        Exit Do
    End If
    Loop
    k = k+1
Loop
Das
Until SmartTags("Wait") = 12
SetDataRecordToPLC 1, k, hmiOn, "Wait"
[..]
erzeugt ja dass umgehend mehrere Datensätze geschrieben werden, ohne Verzögerung.
Erst wenn aus SetDataRecordToPLC das Ergebniss "4 = System Function was successfully completed" kommt wird das Do Until abgebrocken.

Die Meldung dazu sagt jedes mal: "Datensatzbearbeitung nicht möglich, da bereits eine Rezepturaktion läuft".
Ja genau.

Du kannst es umändern so dass die nächste SetDataRecordToPLC erst aufgerufen wird wenn die vorige fertig ist.
Aber das ganze gefällt mir nicht. VBS ist nicht für so etwas 'avanziertes' gemeint.
 
Das
Until SmartTags("Wait") = 12
SetDataRecordToPLC 1, k, hmiOn, "Wait"
[..]
erzeugt ja dass umgehend mehrere Datensätze geschrieben werden, ohne Verzögerung.
Erst wenn aus SetDataRecordToPLC das Ergebniss "4 = System Function was successfully completed" kommt wird das Do Until abgebrocken.
Warum? Die Schleife wird so lange ausgeführt, bis die Funktion eine Fehlermeldung gibt, ja. Aber es wird doch versucht den ersten DS zu Importieren, dann wird über die nächste schleife gewartet bis das erfolgreich abgeschlossen ist, dann inkrementiere ich meine Zählvariable und starte den nächsten Import. So ist zumindest mein Gedankengang gewesen und ich bin der Meinung das habe ich auch programmiert. Die IF-Anweisung im zweiten Do Until Lopp brauche ich, da sonst mein Skript für immer in dem Loop hängen würde. Aber falls ich dort einen Fehler habe, gerne aufzeigen. Ich sitze schon so lange an diesem eigentlich Simplen Problem, dass ich bestimmt schon etwas Betriebsblind bin.:rolleyes:

Ich bin generell kein Freund von dem ganzen VBS Kram, wo es geht verzichte ich auf Skripte und versuche es anders zu Lösen. Aber hier habe ich keine andere Lösung gefunden
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Du hast recht, die nächste Schleife sorgt für das gewartet wird.
Aber wenn wird der Variabel "Wait"geschrieben ? Ich denke nur wenn SetDataRecordToPLC aufgerufen wird.
Also wird die Schleife nie beendet weil "Wait" immer nur den Wert bei ersten Aufruf bekommt.
Wie es mehr oder weniger funktioniert verstehe ich nicht.
 
Ich sage ja, man wird Betriebsblind..
Ich habe mit dem Siemens Support geschrieben, hier die Lösung falls es jemanden interessiert:
DIe Funktion "ExportiereDatensätze" schreibt für alle Rezepturen und für alle Datensätze eine txt-Datei mit den Inhalten des Rezepturcontrols.

Da können Sie dann einfacher und stabiler bestimmen, wie viele Datensätze eine Rezeptur hat.

Das schlimme ist, sowas habe ich schon mal an anderer Stelle programmiert gehabt und wieder verworfen.
Ich mache nur keine TXT sondern eine csv, aber so Funktioniert es jetzt.
 
Zurück
Oben