Probleme mit DBs in SCL

chrissi

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

ich arbeite grade an meiner Diplomarbeit, bin so gut wie fertig nur der letzte Rest fehlt noch.
(Benutze CPU314C-2 DP und ein Kommunikationsmodul CP340)

Ich bekomme Messwerte von einem Messgerät an die SPS geschickt. Funktioniert auch alles soweit. Die Messwerte kommen in Form eines Strings '+v.nnnnnnnnE+xx'. Also insgesamt 8 Nachkommastellen. Diesen String will ich in einen Realwert umwandeln. Dafür muss ich jedoch die 8. Nachkommastelle rausschneiden. Dafür gibt es mehrere Möglichkeiten. Nun will ich das in SCL machen.

Das Problem an der Sache ist, dass wenn ich einen empfangenen Messwert weiterverarbeiten will. Die ersten beiden Zeichen immer überschrieben werden mit der Länge des Strings und somit weg sind.

Schon bei einer einfachen Wertezuweisung tritt das auf:

Code:
Db40.Messwert[0]:=Db20.Messwert[0];

Wäre nett wenn mir jemand sagen könnte, wo das Problem liegt.

MfG

Chrissi
 
Wie werden die Messwerte empfangen? Werden sie direkt in dem DB geschrieben? Hast Du hier ein STRING definiert, oder ein Array, oder gar nichts - einfach Platz reserviert?

In jedem Fall ist es eher unwahrscheinlich, dass die ersten zwei Zeichen von dem Längen-Info überschrieben werden, eher findest Du den ersten Zeichen in DB20.Messwert[2].

Wenn Du in einem VAT sehen kannst, dass in DB20.Messwert[2] tatsächlich Zeichen drei zu finden ist und nicht Zeichen eins, dann brauchen wir etwas mehr info über DB-Struktur und Programm um weiter zu kommen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
...ganz einfach auch ohne SCL

Kopiere den String


1.Steller + 2.Stelle + Zeichenfolge [+v.nnnnnnnnE+xx]

in ein ARRAY of BYTE

verschieben die Zeichen "E+xx" eine Stelle nach vorn
Reduziere die den Zahlenwert in der "2.Stelle" um eins.

kopieren das Array auf einen "verkürzten" STRING zurück

dann kann Du STRING_TO_REAL machen.


... das alles geht auch mit STRING Befehlen direkt im SCL
aber so kann du ggf. besser in der VAT sehen,was passiert.



Gruß
 
Schon mal danke für die schnellen Antworten!

Die Messwerte werden über das CP340 emfpangen (FB2) und direkt in den DB20 geschrieben. Die Ausgabe beobachte ich über ein Panel. Da stimmt dann auch noch alles.

DB20 ist ein Array von 16 Strings. Ein string ist 14 byte groß.
Vor dem Array befinden sich noch zwei Char, in denen werden noch zwei Info zeichen von dem Messgerät reingeschrieben. Diese beiden Zeichen kommen automatisch und ich brauche sie nicht weiter.

DB40 ist genauso aufgebaut wie DB20.

Der DB20 stimmt ja (überprüfe ich wie bereits gesagt mit einem Panel) nur wenn ich eine Wertzuweisung wie oben angeführt mache, sind die ersten beiden Zeichen im DB40 murks bzw. Längen angaben. (schau ich mir auch mit dem Panel an)

Habe mir mittlerweile auch schon überlegt das ohne SCL zu machen (wegen Zeitdruck) aber ich möchte eigentlich schon gerne wissen woran das Problem liegt :)
 
Geht dass denn in SCL - Array von Typ STRING?

Wenn die Daten in DB20 richtig anliegen, denn muss das Problem bei SCL liegen und da kenne ich mich leider nicht aus.

Hast Du es wirklich ausprobiert, die Abfrage ab DB20.Messwert[2] zu machen, statt ab DB20.Messwert[0]?

Übrigens die ersten zwei Bytes sind die maximale Länge und die tatsächliche Länge des STRINGs. Dies ist einfach das Siemens Format und wird automatisch berücksichtigt wenn man mit STRINGs arbeitet.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich gebe auf SCL ist ein garstiges degeneriertes irgendwas. Mensch Step7 lerne endlich ST!

In ST ging das so:
Code:
    tmpZahl        := STRING_TO_REAL(MID(inStr, 10, 1));  (*Zahl mit Vorzeichen*)
    tmpExponent := STRING_TO_INT(MID(inStr, 3, 12)); (*Exponent mit Vorzeichen*)

Dann eben noch Errechnen fertig.
 
@Zotos:
so wie in deinem Beispiel würde es in SCL auch aussehen ...

@Chrissi:
Ich vermute, dass du bei deiner String-Verschmickelung irgendetwas nicht berücksitigt hast. Stell doch mal den Code deines SCL-Scriptes hier ein. Eigentlich ist das, was du vorhast wirklich kein Problem.

@IFBS:
In SCL kann man sich auch anschauen, was das Script so treibt ...
 
Mensch Step7 lerne endlich ST!

Wurde ich gerne, aber mein Arbeitgeber ist zu geizig Step7 Professionell zu kaufen! :D

Abgesehen davon, das hätte man fast so einfach und sicherlich performanter in AWL realisieren können.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Zotos:
so wie in deinem Beispiel würde es in SCL auch aussehen ...

Bei meiner alten SCL Version wir schon bei STRING_TO_REAL gemekert ;o(

Aber nach dem Suchen in der Hilfe:

Code:
R_STRNG und STRNG_R 

Die Funktionen R_STRNG (FC 30) bzw. (FC 39) wandeln eine Variable im REAL*Format in eine Zeichenkette oder eine Zeichenkette in eine REAL-Variable. Die Zeichenkette wird mit 14 Stellen dargestellt: 
±v.nnnnnnnE±xx
 
Hier erstmal mein Code (ich weiß es geht einfacher mit DELETE oder so, aber ich war/bin verzweifelt und habe vieles ausprobiert :ROFLMAO: )

Code:
   FUNCTION Test :REAL
VAR
    test1 : STRING[10];
    test2: STRING[4];
    test3: STRING[14];
END_VAR

test1:=LEFT(IN := Db20.Messwert[0]  // IN: STRING
     ,L :=10  // IN: INT
     ); // STRING
 
 test2:=RIGHT(IN :=Db20.Messwert[0]  // IN: STRING
              ,L :=4  // IN: INT
              ); // STRING

test3:=CONCAT(IN1 := test1 // IN: STRING
              ,IN2 :=test2  // IN: STRING
              ); // STRING
                 
// Db40.Messwert[0]:=Db20.Messwert[0]; <- habe ich zu Testzwecken mal reingeschrieben, um zuschaun was dabei überhaupt rauskommt
DB60.neu[0]:=STRNG_R(S := test3  // IN: STRING
        ); // REAL
Test := DB60.neu[0];
END_FUNCTION


Habe viel drin rumgewurschtelt... bin halt grade dabei alles mögliche auszuprobieren... Meiner Meinung nach müsste das eigentlich auch alles recht einfach sein. Hm... nunja hoffe ihr könnt mir weiter helfen!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
als Erstes ist mir aufgefallen, dass deine Test-Strings nicht initialisiert sind. Da ist SCL allerdings eigen. Am Anfang (vor dem ersten Benutzen) müsste also stehen :
Code:
Test1 := "" ;
Test2 := "" ;
Test3 := "" ;
Danach lassen die sich schon mal benutzen - davor (leider) nicht.

Ansonsten - was ist mit den DB20.Messwert[0] und DVB40.Messswert[0] ?
 
Danke für die schnelle Antwort!
Probiere ich sofort aus.

DB40.Messwert[0] ist so ne Art Zwischenspeicher. Und ich wollte halt schaun was passiert wenn ich den String der in Db20.Messwert[0] "anfasse". Ich gebe beide über ein Panel aus. Da ich mir nen String ja nicht in VAT angucken kann.
 
Ich habe jetzt die Funktion mal mit einen vorgegebenen String probiert. (habe einen Wert in DB20.Messerwert[0] reingeschrieben) Das hat funktioniert. Nur sobald ich einen empfangenen Wert nehme geht es nicht :confused:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
...
dann hast du bei dem empfangenen String ggf. das gleiche Problem oder der empfangene String ist nicht richtig im Header deklariert (tatsächliche Länge). Das solltest du auf jeden Fall mal checken ...
 
Die Ausgabe beobachte ich über ein Panel. Da stimmt dann auch noch alles.
Daraus habe ich verstanden, dass die Werte im DB stimmten. Aber vielleicht meint chrissi ein Panel am Messinstrument (oder an der Station wo das Messinstrument zu finden ist).

Am besten die Bytes im DB in einem VAT beobachten und gucken ob alles stimmt.

Ich gebe beide über ein Panel aus. Da ich mir nen String ja nicht in VAT angucken kann.
Wenn der STRING liegt, z.B., ab Byte null in DB20, dann im VAT beobachtest Du:
DB20.DBB0 als hex oder dezimal - maximale Länge des STRINGs (eingegeben bei der Deklarierung)
DB20.DBB1 als hex oder dezimal - aktuelle Länge des empfangenen STRINGs
DB20.DBB2 als Zeichen - erstes Zeichen im STRING
DB20.DBB3 " " - zweites " " "
DB20.DBB4 ... etc. bis zum Ende des STRINGs.
 
Zuletzt bearbeitet:
Teste es doch mal ohne das RIGHT und dafür mit MID

tmpZahl := MID(IN:=inStr, L:=10, P:=1);
tmpExponent := MID(IN:=inStr, L:=4, P:=12);

myReal := STRNG_R(CONCAT(IN1:=tmpZahl, IN2:=tmpExponent));
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen zusammen,

also das Panel ist an der SPS angeschlossen.

Ich habe mir dann den empfangenen Wert der in DB20 steht angeguckt und den Wert der in DB40 steht, nachdem ich

DB40.Messwert[0]:=DB20.Messwert[0];

emacht habe.

Und ich war halt der meinung, dass die Ausgabe der beiden Werte über das Panel identisch sein müssten. Sind sie halt aber nicht.
Mein Ausbilder hat schon überlegt ob die version von SCL evtl zu alt bzw. fehlerhaft ist. Ich habe grade V5.3 installiert.

Teste es doch mal ohne das RIGHT und dafür mit MID

habe ich auch schon getestet. Sobald ich den emfpangenen Wert von DB20 weiterverarbeite, "verschwinden" die ersten beiden Zeichen.

Wenn ich jedoch selber in den DB20 was schreibe und damit arbeite funktioniert es. :confused:
 
Hallo Chrissi,
kontrollier doch trotzdem vielleicht mal, was in den Kopf-Bytes von deinem String für Werte drin stehen (mich interessiert von allen Dingen Byte 1 - aktuelle Länge). Wenn dir Länge falsch drinsteht könnte auch bei der Zuweisung etwas schief laufen.
Der Unterschied zwischen der manuellen Eingabe des Strings und dem importierten String ist, dass deine Visu schon weiss, wie der String richtig auszusehen hat - deine Datenübertragung vielleicht nicht ...
 
Hallo hier mal mein Db40 (ich fange bei Byte 0 an, ohne was davor stehen zu haben)


Struct
Messwert ARRAY[0..15] ''
STRING[25]


Habe mir das nun in der VAT mit DB40.Dbb0 usw. angeguckt.
und dort ist es nun so, dass bevor der erste string anfängt 4 Bytes sind. DB40.DBB0 = 19
DB40.DBB1 = 00

das 2. und 3. Byte haben ebenfalls 00 drin stehen.
Danach fängt erst Messwert [0]. (also ab Byte 4)

will ich den DB als string mit dem Panel ausgeben. Muss ich jedoch angeben, dass ich das ab Byte 2 gezeigt haben will, sonst werden die ersten 2 zeichen nicht angezeigt.
 
Zurück
Oben