TIA SCL: FB-Inputs/-Outputs elegant in DB schreiben und auslesen

1513

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

ich habe in einem Projekt paar FC und FB für eine 1513-1 und 315-2 geschrieben (alles in AWL). Jetzt soll ich das auf eine 1212C übertragen, aber die kann ja kein AWL (und kein BLKMOV, und keine Anypointer,...) und muss deshalb alles nach SCL umschreiben. Ich verwende TIA Portal V13 SP1 Update 5 und STEP7 5.5.

Ein FB hat dabei beispielsweise die Eingänge DBnummer [INT] und 8 BOOLs mit aussagekräftigen Namen. Die BOOLs sollen in ein DB gespeichert werden. Auf der Ausgangsseite des FB stehen wiederrum andere 16 BOOLs mit Namen, die ihre Zustände einfach aus dem DB auslesen sollen.

In AWL konnte ich einfach
Code:
L %DIB0
T %DBB0
schreiben, um die 8 BOOLs in den aufgeschlagenen DB zu laden. In SCL bekomme ich das mit der Adressierung irgendwie nicht hin. Die "optimierten Bausteine" habe ich abgeschaltet. Ich könnte zwar 8 mal POKE_BOOL aufrufen, aber geht das nicht einfacher? Die anderen PEEK-/POKE-Befehle wollen alle ARRAYs haben, aber dann kann ich die DB-Einträge nicht mehr mit Namen versehen.


1513
 
Wenn man schön sauber jedes Bool einzeln anfasst, dann läßt sich das auch prima in SCL umsetzen. :D

Mit den unsauberen Byte-Zugriffen nagelt man sich sowieso auf bestimmte CPU-Familien fest, wo diese Zugriffe zufällig funktionieren - diese sind also kein Mittel, was man in heutigen Programmen verwenden sollte.

Im übrigen zwingst Du Deine S7-1200 oder S7-1500 nicht in die Knie, wenn Du denen den einzel-Bool-Zugriff zumutest. ;)
Eher mit den Byte-Zugriffen zwingst Du die CPUen in einen langsamen Kompatibilitäts-Emulationsmodus. Für die Byte-Zugriffe gibt es vermutlich keinen ernsthaften Grund? Falls Du tatsächlich Bools in Bytes/Words übertragen mußt, dann gibt es dafür die AT-Sicht und Slice-Zugriffe.

Harald
 
Wenn du auf SCL umschwenken willst dann ist es ggf. sinnvoller, das Baustein-Konzept noch einmal zu überdenken.
In SCL läßt sich sehr vieles elegant lösen, wenn man nicht AWL als Vorlage nimmt und meint, das irgendwie nachprogrammieren zu müssen ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn du auf SCL umschwenken willst dann ist es ggf. sinnvoller, das Baustein-Konzept noch einmal zu überdenken.
In SCL läßt sich sehr vieles elegant lösen, wenn man nicht AWL als Vorlage nimmt und meint, das irgendwie nachprogrammieren zu müssen ...

Gruß
Larry

Die Bausteine werden wohl so bleiben, weil die Funktionenaufteilung von meinem Projektgeber so gewünscht ist. Aber ich schau natürlich, was man in SCL vereinfachen oder gar weglassen könnte.


Bin gerade dabei, einen REAL-Eingang am FC in ein DB zu schreiben:
Code:
POKE(area := 16#84, dbNumber := #DBNo, byteOffset := (#instno_tmp-1)*4, value := #Value);

Der Wert wird im DB als DWORD (16#.....) angezeigt; in AWL war das nicht so. Kann man das in Gleitkommadarstellung ändern? Bei PEEK kann man ja DWORD_TO_REAL() nehmen.
 
Peek und Poke arbeiten m.E, nur mit den Grund-Datentypen, also Byte, Word und DWord. Das mußt du bei deiner Code-Erstellung beachten und ggf. notwendige Typ-Casts einbauen ... oder vielleicht doch das Konzept überdenken ...
 
Peek und Poke arbeiten m.E, nur mit den Grund-Datentypen, also Byte, Word und DWord. Das mußt du bei deiner Code-Erstellung beachten und ggf. notwendige Typ-Casts einbauen ... oder vielleicht doch das Konzept überdenken ...


Es klappt jetzt mit der Darstellung. Musste den Eingangsparameter von Real auf LReal ändern, dann in der POKE-Zeile zweimal casten (LReal zu Real und Real zu DWord)...



Keine Sorge, deine Zweifel am Konzept sind nicht an mir vorbeigegangen ;)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es klappt jetzt mit der Darstellung. Musste den Eingangsparameter von Real auf LReal ändern, dann in der POKE-Zeile zweimal casten (LReal zu Real und Real zu DWord)...
Was hat der zum FC übergebene Datentyp mit dem Anzeigeformat eines DWord zu tun?
Wozu soll die Übergabe eines REAL als LREAL gut sein???

Ich habe gewisse Sorgen, ob Du verstehst, was Du da programmierst ;)


Bin gerade dabei, einen REAL-Eingang am FC in ein DB zu schreiben:
Code:
POKE(area := 16#84, dbNumber := #DBNo, byteOffset := (#instno_tmp-1)*4, value := #Value);

Der Wert wird im DB als DWORD (16#.....) angezeigt; in AWL war das nicht so. Kann man das in Gleitkommadarstellung ändern?
Wo wird der DB-Wert "im DB" als 16#... angezeigt? (Hast Du ein Bild?)
Ist das DB-DWord als REAL deklariert?

Oder meinst Du den Wert, der beim Beobachten des Programms angezeigt wird?
Da wird nicht angezeigt, welcher Wert (und welcher Datentyp) in der DB-Adresse nach dem POKE steht, sondern der Wert den der Übergabeparameter "value" hat, und "value" hat einen Bitfolgen-Datentyp -> daher die Anzeige als 16#.. Frag' mal Siemens, ob man das Anzeigeformat der Übergabeparameter umstellen/wählen kann.
POKE schreibt nicht einen Datentyp sondern ein Bitmuster einer bestimmten Speichergröße an die angegebene Speicheradresse.

Wenn Du den Wert Deines FC-Eingangs #Value als Gleitkomma beobachten willst, dann könntest Du ihn auf eine temporäre REAL-Variable umkopieren. Dann ist das TIA vermutlich so schlau beim Beobachten der Zeile den Wert als Gleitkomma anzuzeigen.

Harald
 
Ist das DB-DWord als REAL deklariert?

Ja. Im DB benutze ich nur REALs und BOOLs. Vorher wurden im FC/FB Ein- und Ausgangsparameter für Gleitkommawerte als REAL deklariert. Jetzt sind die FC-/FB-Eingänge LREALs, die Ausgänge wie vorhin "nur" REAL (es gibt FCs/FBs nur mit Gleitkomma-Eingängen, nur mit Gleitkomma-Ausgängen oder mit beidem).

Oder meinst Du den Wert, der beim Beobachten des Programms angezeigt wird?
Ja genau das meinte ich; hatte in TIA den DB geöffnet und beobachtet (die Werte mit dem orangegelben Hintergrund). Hatte zwischendurch auch mal den Wert temporär umkopiert und so. Auf jeden Fall zeigte er mal den Gleitkommawert als DWord an (16#...), und beim anderen mal (ohne LREAL) hatte die Genauigkeit des im DB gespeicherten Werts gelitten.

Jetzt klappt aber alles.



1513
 
Ja genau das meinte ich; hatte in TIA den DB geöffnet und beobachtet (die Werte mit dem orangegelben Hintergrund). Hatte zwischendurch auch mal den Wert temporär umkopiert und so. Auf jeden Fall zeigte er mal den Gleitkommawert als DWord an (16#...), und beim anderen mal (ohne LREAL) hatte die Genauigkeit des im DB gespeicherten Werts gelitten.
Nochmal eindeutig formuliert:
Du hast einen DB, darin ist eine Variable als REAL deklariert. Du beobachtest direkt den geöffneten DB und TIA zeigt den Wert der REAL-Variable nicht als Gleitkommazahl sondern hexadezimal (16#...) an?
Dann ist entweder der Wert nicht als Gleitkommazahl darstellbar oder Dein TIA spinnt irgendwie.
Wo kam der Wert her, der mittels POKE in die REAL-Variable geschrieben wurde? Welchen Wert hatte der Wert?
Schreibt vielleicht nochwas auf die Variable, gibt es vielleicht Adressüberschneidungen?

Wenn man das Bitmuster eines REAL-Wertes (REAL_TO_DWORD) in ein DWORD schreibt (poked) und dann als REAL-Wert interpretiert, dann leidet keine Genauigkeit, denn es ist exakt der ursprüngliche REAL-Wert. Wie sah das "Genauigkeit gelitten" denn konkret aus?

Hast Du eine Vorstellung, wieso das Ausweichen zu LREAL und Wandeln zu REAL Dein Darstellungsproblem anscheinend löst?

Ich habe das Gefühl, daß an Deinem Programm was faul ist und Du nun nur Symptome beseitigst statt das Problem. Wenn man ein problematisches Programm und die gefundene Umgehung nicht versteht, dann darf man das Programm nicht für eine Industrieanlage nutzen, geschweige denn den Code in häufig verwendete "Standardbausteine" einbauen.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du hast einen DB, darin ist eine Variable als REAL deklariert.
Richtig. Genau wie der FC-Eingang (beim ersten Versuch).

Du beobachtest direkt den geöffneten DB und TIA zeigt den Wert der REAL-Variable nicht als Gleitkommazahl sondern hexadezimal (16#...) an?
Richtig, beim ersten Versuch bekam ich die hexadezimale Darstellung. Ich werde versuchen, das am Montag (auf der Arbeit) zu reproduzieren.

Wo kam der Wert her, der mittels POKE in die REAL-Variable geschrieben wurde? Welchen Wert hatte der Wert?
Im OB1 ist nur dieser eine FC, der einen REAL-Wert einliest und in die DB schreiben soll. Die Variable im DB ist auch als REAL deklariert.
Ich hatte es zuerst mit 514.32 probiert (ich gebe die Werte aus Testgründen direkt am FC-Eingang im OB1 an). Im DB angezeigt wurde 514.313, also Fehler nach der ersten Nachkommastelle. Andere Werte wurden ebenfalls falsch übernommen.

Schreibt vielleicht nochwas auf die Variable, gibt es vielleicht Adressüberschneidungen?
Siehe oben, im OB1 befand sich nur der besagte FC.

Wenn man das Bitmuster eines REAL-Wertes (REAL_TO_DWORD) in ein DWORD schreibt (poked) und dann als REAL-Wert interpretiert, dann leidet keine Genauigkeit, denn es ist exakt der ursprüngliche REAL-Wert.
Genau das dachte ich mir auch. Ich kenne die POKE-/PEEK-Befehle ja erst seit ein paar Tagen, wenn ich mich recht erinnere, verlangt POKE einen DWORD als value. Deswegen hatte ich mir auch nichts dabei gedacht, als value REAL_TO_DWORD(value) anzugeben. Sind ja beide 4 Byte. Ich könnte mal versuchen, den FC-Eingang "Value" in "Input" zu ändern.

Hast Du eine Vorstellung, wieso das Ausweichen zu LREAL und Wandeln zu REAL Dein Darstellungsproblem anscheinend löst?
Absolut nicht.



Am Montag werde ich mal alles reproduzieren. Gerne auch mit Code, um einen Fehler in TIA bei mir auszuschließen. Mich nervt vor allem, dass in AWL alles "einfach so" funktioniert hatte. L #Value, T DBD [AR1, P#0.0] oder so.


1513
 
Guten Morgen,

ich fühle mich gerade von TIA verschaukelt, weil das Problem mit den Nachkommastellen nicht mehr auftritt; obwohl die Meldung
Das Vorzeichen oder die Genauigkeit des Werts können verloren gehen.
immer noch erscheint. Ich habe den FC-Eingang "value" davor wieder auf REAL umgestellt.

Wenn ich im FC die Codezeile
Code:
POKE(area := 16#84, dbNumber := #DBNo, byteOffset := (#instno_tmp-1)*4, value := #Value);
[SIZE=1](instno_tmp ist eine Kopie des Eingangparameters Instanznummer)[/SIZE]
nutze und im OB1 den FC mit value 514.32 einfüge, dann bekomme ich im DB als Beobachtungswert 16#0000_0202 angezeigt. Wenn ich REAL_TO_DWORD(#value) nutze, bekomme ich die Gleitkommadarstellung. Und zwar die richtige; vor meinem Experiment mit LREAL wurden die Nachkommastellen falsch angezeigt. Warum auch immer.

Das Umwandeln ins Hex-Format kann ich mir nur dadurch erklären, dass POKE einen DWORD als value erwartet. In der Hilfe ist als Datentyp "Bitfolgen" angegeben.
 
Vielleicht nur so nebenbei ... LReal hat mit Sicherheit eine größere Datenbreite als Real ...
Ansonsten noch einmal mein Heinweis : SCL ist nicht unbedingt für derartige absolute Speicherzugriffe gemacht und gedacht.

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich fühle mich gerade von TIA verschaukelt, weil das Problem mit den Nachkommastellen nicht mehr auftritt; obwohl die Meldung
Das Vorzeichen oder die Genauigkeit des Werts können verloren gehen.
immer noch erscheint.
Mich würde interessieren, wofür genau diese Meldung/Warnung erscheint. (ich habe kein aktuelles TIA)


Wenn ich im [...] im OB1 den FC mit value 514.32 einfüge, dann bekomme ich im DB als Beobachtungswert 16#0000_0202 angezeigt. Wenn ich REAL_TO_DWORD(#value) nutze, bekomme ich die Gleitkommadarstellung. Und zwar die richtige; vor meinem Experiment mit LREAL wurden die Nachkommastellen falsch angezeigt. Warum auch immer.

Das Umwandeln ins Hex-Format kann ich mir nur dadurch erklären, dass POKE einen DWORD als value erwartet. In der Hilfe ist als Datentyp "Bitfolgen" angegeben.

Die Anzeige im Hex-Format statt Gleitkomma-Format macht TIA, weil DW#16#0000_0202 nicht im Gleitkommaformat darstellbar ist - es ist eine denormalisierte (subnormale) Zahl. Das Bitmuster DW#16#0000_0202 entspricht der Ganzzahl 514 dez.

POKE weiß nicht, was für einen Datentyp die Zielvariable hat. Deshalb erwartet POKE für den Parameter "value" einen Bitfolgen-Datentyp, welcher lediglich die Speichergröße angibt.
Wenn man selbst keine explizite Konvertierung für einen Realwert zu DWORD angibt, dann verwendet TIA offensichtlich selbständig die Konvertierung DINT_TO_DWORD(REAL_TO_DINT(realwert)), was ich als Bug bezeichnen würde. Korrekt wäre meiner Meinung nach REAL_TO_DWORD(realwert). POKE dürfte überhaupt keine Konvertierung benutzen, welche das Bitmuster verändert. TIA sollte entweder grundsätzlich den Bitstring zu BYTE/WORD/DWORD/LWORD übernehmen oder auf einer explizit anzugebenden Konvertierung bestehen und nicht heimlich/versteckt solche sinnfreien automatischen Konvertierungen praktizieren.

Du mußt unbedingt REAL_TO_DWORD(realwert) einsetzen.

Harald
 
Mich würde interessieren, wofür genau diese Meldung/Warnung erscheint. (ich habe kein aktuelles TIA)
Die Meldung erscheint beim Übersetzen unten im Reiter "Syntax". Ich denke mal der Grund ist die Gleitkomma-nach-Hex-Umwandlung. Wie du ja weiter unten schon gesagt hast, werden in Hex-Darstellung die Nachkommastellen "abgeschnitten".


Wenn man selbst keine explizite Konvertierung für einen Realwert zu DWORD angibt, dann verwendet TIA offensichtlich selbständig die Konvertierung DINT_TO_DWORD(REAL_TO_DINT(realwert)), was ich als Bug bezeichnen würde. Korrekt wäre meiner Meinung nach REAL_TO_DWORD(realwert). [...] Du mußt unbedingt REAL_TO_DWORD(realwert) einsetzen.
Würde ich dann auch als Bug bezeichnen. Ob Siemens das auch so sieht :confused:


Danke für die ganzen Infos! :cool:
 
Die Meldung erscheint beim Übersetzen unten im Reiter "Syntax". Ich denke mal der Grund ist die Gleitkomma-nach-Hex-Umwandlung. Wie du ja weiter unten schon gesagt hast, werden in Hex-Darstellung die Nachkommastellen "abgeschnitten".
Steht da nicht, auf welche Anweisung genau sich die Meldung bezieht? Ein paar eindeutige Worte mehr schreiben wäre echt hilfreich. Wir können nicht sehen, was auf Deinem Bildschirm steht. :rolleyes:
Ist aber jetzt auch egal. Mit zusätzlich länger Nachdenken kommt meine Glaskugel darauf, daß damit die implizite bzw. explizite Konvertierung des REAL zu DWORD gemeint ist. Die Warnmeldung ist bei der impliziten/automatischen falschen Konvertierung von TIA ja ganz OK, doch bei explizit angegebenem REAL_TO_DWORD ist die Warnmeldung fehl am Platz.


Bei REAL_TO_DWORD(realwert) werden keine Nachkommastellen abgeschnitten oder Vorzeichen entfernt. Es wird lediglich dem Compiler mitgeteilt, daß er den Wert (Bitstring) einer Variable ohne Konvertierung 1:1 in eine Variable anderen Datentyps übertragen soll. Wenn man die andere Variable im Gleitkommaformat beobachtet, dann sieht man, daß dabei nichts verloren gegangen ist.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Steht da nicht, auf welche Anweisung genau sich die Meldung bezieht? Ein paar eindeutige Worte mehr schreiben wäre echt hilfreich.
Mit zusätzlich länger Nachdenken kommt meine Glaskugel darauf, daß damit die implizite bzw. explizite Konvertierung des REAL zu DWORD gemeint ist.
Korrekt. Habe vergessen, es zu erwähnen. Ohne REAL_TO_DWORD() kommt die Meldung, mit dieser Anweisung kommt sie nicht.



1513
 
Zurück
Oben