Step 7 Fehlermeldung in SCL

spirit

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

um einen Linearmotor zu positionieren, muss z.B. der Wert L#198 in den Instanz-DB geladen werden.

Das klappt auch, wenn ich das direkt in den DB lade...

Aber nun möchte ich das in SCL mittels einer Zuweisung machen:

Wert := L#198;

Nun erhalte ich aber folgende Fehlermeldung: Unzulässiger Datentyp für Konstante.


Muss ich hier evtl. noch wandeln und warum muss eigentlich das "L#" vor dem Zahlenwert geschrieben werden?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Spirit,

das L#198 würdest du in AWL so schreiben - benötigen tust du es da aber auch nur dann wenn der Zahlenwert wirklich der eines Long-Integers ist. Das ist bei 198 absolut noch nicht der Fall.
Bei SCL kannst du darauf ganz verzichten. Wie kommst du darauf, dass zu benötigen ?

Gruß
Larry
 
Hm, also zunächst einmal "Wert" war jetzt nur so ein Beispiel um das Ganze zu vereinfachen...

In der Realität wird der Zahlenwert in einen Instanz-DB geschrieben; dieser wird vom Hersteller zur Verfügung gestellt:

Typ: DINT
Anfangswert: L#0

Hatte auch mal einen höheren Wert (glaube 1800) ohne dieses L# eingeschrieben; das hat aber nicht funktioniert. Offensichtlich wird das doch benötigt?

DB17.DBD22 := 198;

Da wird nicht gemeckert...

Weiß jetzt nur nicht, ob dieses L# nicht doch notwendig ist...

Ach und noch etwas:

Wenn ich dieses Laden von 198 an Bedingungen knöpfen möchte, z.B. wenn E0.0 TRUE ist - würde das dann nur mit IF... gehen?
 
Wenn du das so schreibst (absolute Adresse) :
DB17.DBD22 := 198;
... dann beschreibst du das Doppelwort als DWORD und nicht als DINT ... auch dann nicht, wenn das in dem DB so angelegt ist.


Wenn ich dieses Laden von 198 an Bedingungen knöpfen möchte, z.B. wenn E0.0 TRUE ist - würde das dann nur mit IF... gehen?
Ja ... es geht dann nur mit IF ... ohne ggf. auch in einer CASE-Abfrage (was aber im Grunde einem IF ähnlich ist).

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn du das so schreibst (absolute Adresse) :

... dann beschreibst du das Doppelwort als DWORD und nicht als DINT ... auch dann nicht, wenn das in dem DB so angelegt ist.
Gruß
Larry

Danke Larry,

verstehe ich jetzt zwar nicht so ganz - aber in AWL habe ich z.B. geschrieben:

L L#198
T DB17.DBD22

Damit hat es funktioniert...

Wie müsste ich das nun entsprechend in SCL schreiben?

Lieben Dank!
 
Hi ich nochmal oder schon wieder... :p

Wie könnte ich denn das Doppelwort als DINT beschreiben, bzw. wo genau liegt da der Unterschied - es wird doch auch so der Zahlenwert 198 geladen, oder?

Beschreibe ich das DINT, wenn ich in AWL programmiere:

Code:
L L#198
T DB17.DBD22

Danke!
 
Also wenn du mit Absolutadressen arbeitest ist das von Haus aus schon mal suboptimal, ganz besonders für SCL.

In SCL:
DB17.DD22 := DINT_TO_DWORD( 198 ) ;

Ansonten, wenn du ein symbolisches Arbeiten bevorzugst:
MyDB.MyDINT_22 := 198 ;

Mfg
Manuel
 
Sorry, mir ist das nicht klar...

DINT_TO_DWORD bedeutet doch, DINT nach DWORD zu wandeln. Somit wird der Zahlenwert 198 in das DatenbausteinDoppelwort geladen; richtig?

In dem Hersteller-DB ist jedoch angegeben:

Typ: DINT

Frage: Warum wandle ich es dann in ein DWORD? :confused:
 
Weil du bei Absoluten Adressen kein Format mitgibst. Da gibts dann nur byte word dword.
Ist bei AWL ja auch so. Darum musst du ihm das Format ja beim laden in den Accu mitgeben L#

In SCL machst du eine Typkonvertierung mit x_TO_x. Muss ich mich auch immer dazu zwingen das nicht zu vergessen.

mfG René
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Absolutadresse DBx.DDy ist immer vom Typ DWORD. Im Gegensatz zu AWL werden bei SCL die Datentypen der beiden Seiten überprüft. In AWL kann man alles mögliche sinn- oder nicht sinnvolle aufeinander schreiben.

Der Präfix für eine 32-Bit Ganzzahl lautet in SCL DINT#

Die korrekte Entsprechung für deinen AWL Code wäre demnach:
DB17.DD22 := DINT_TO_DWORD( DINT#198 );
 
Die Absolutadresse DBx.DDy ist immer vom Typ DWORD.

Irgendwie stehe ich vor einem Berg...

DD22 und DBD22 bezeichnen doch beide das Selbe, nämlich ein Datenbaustein Doppelwort.

1)
In AWL wird mir DD22 jedoch nicht angenommen; warum ist das so?

2)
Könnte ich in SCL dann auch schreiben?

DB17.DBD22 := DINT_TO_DWORD( DINT#198 );

3)
Dieses DINT# in SCL enstpricht also dem L# in AWL und besagt, dass ich eine 32-Bit-Zahl laden möchte, richtig? Was passiert, wenn ich es weglasse?


Dank' euch...
 
1)
In AWL wird mir DD22 jedoch nicht angenommen; warum ist das so?
Ganz einfach: weil AWL nicht SCL ist.

2)
Könnte ich in SCL dann auch schreiben?

DB17.DBD22 := DINT_TO_DWORD( DINT#198 );

Nein. Du musst immer die Datentypen der Operanden beachten.
Wenn man nur die Datentypen heranzieht, hast du eine Anweisung:
BYTE := DINT_TO_DWORD(DINT);

Du versuchst dann eine Wert vom Typ DWORD einer vom Typ BYTE zuzuweisen. Das meckert der Compiler zurecht an. Wenn du dir absolut sicher bist dass das richtig ist und du genau weißt was du da tuts, musst du eine explizite Typwandlung hinschreiben. Dann bist du selber dafür verantwortlich, wie die 4 Bytes eines Dword auf ein einzelnes Byte geschrieben werden soll.
Ein gutes SCL-Programm zeichnet sich dadurch aus, dass es wenige explizite Typumwandlung aufweist.

In AWL ist eine Anweisung eine einzelne Zeile. Und nur diese wird auf Korrektheit überprüft.

In SCL ist eine Anweisung komplexer, bei einer Wertzuweisung muss der ganze Ausdruck korrekt sein.

3)
Dieses DINT# in SCL enstpricht also dem L# in AWL und besagt, dass ich eine 32-Bit-Zahl laden möchte, richtig? Was passiert, wenn ich es weglasse?
In diesem konkreten Fall passiert nichts.

Es gibt aber Fälle in denen das zu einem Fehler führen kann:

Beispiel:
Code:
intVar : INT;
dintVar : DINT;

intVar := 30000;
dintVar := intVar * 10;

Du würdest jetzt wohl annehmen, dass in dintVar der Wert 300000 steht. Das ist aber nicht der Fall, denn dort steht der Wert -27680!
Wenn man sich die Datentypen der Zuweisung hinschreibt, bekommt man:
DINT := INT * INT;

Damit wird die Mulitplikation auf dem Datentyp INT ausgeführt. Dort gibt es dann einen Wertebereichsüberlauf.
Bei der Zuweisung auf den DINT wird dann eine implizite (automatische) Typwandlung auf DINT durchgeführt.

Um das Problem zu beheben, musst du schreiben:
Code:
dintVar := intVar * DINT#10;
oder
Code:
dintVar := intVar * INT_TO_DINT(10);

Dadurch wird intVar vorher durch die implizite Konvertierung auf DINT hochgezogen, und die Multiplikation erfolgt dann auf dem DINT Datentyp.

Das ist nicht nur bei SCL so, sondern auch bei anderen Sprachen wie C.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nein. Du musst immer die Datentypen der Operanden beachten.

Wenn man nur die Datentypen heranzieht, hast du eine Anweisung:

BYTE := DINT_TO_DWORD(DINT);

Du versuchst dann eine Wert vom Typ DWORD einer vom Typ BYTE zuzuweisen. Das meckert der Compiler zurecht an.

Lieben Dank für deine Geduld und super Beschreibung; nur kapiere ich sie nicht!

Nochmal ganz Grundsätzlich:

1)
DBx.DDy und DBx.DBDy bezeichnen doch das Selbe - nämlich ein Datenbaustein Doppelwort. Stimmt das?

2)
Nun habt ihr geschrieben, dass eine absolute Adresse, was ja unter 1) gegeben ist, immer vom Typ DWORD ist. Weiterhin schreibst du aber:

BYTE := DINT_TO_DWORD(DINT);

Müsste hier jetzt nicht stehen:

DWORD := DINT_TO_DWORD(DINT);

Denn wie oben geschrieben, handelt es sich doch um eine absolute Adresse!

3)
Wie schon geschrieben verlangt der DB doch einen Typ DINT.

Warum funktioniert das dann überhaupt, wir laden die Zahl 198 ja jetzt als DWORD und nicht als DINT?
 
Ähh ...
Ich fand die Erklärung, die Thomas hier geschrieben hat, eigentlich sehr umfassend und gut - vielleicht sogar die Beste dazu, die ich je gelesen habe. Ich wüßte dem bei besten Willen nichts mehr hinzuzufügen.
Du wirst in Verbindung mit den absoluten Adress-Zugriffen in SCL noch über so manche Hürde stolpern. Mit Bytes, Words und DWords kann man z.B. auch nicht Rechnen. Das liegt aber auch an SCL und den SCL-Spielreglen.

Gruß
Larry

Nachsatz:
was der DB verlangt ist bei absoluter Adressierung dem SCL vollkommen egal. SCL behandelt es so, wie von Thomas erläutert, da es keine Möglichkeit hat, festzustellen, wie die Adresse deklariert ist und ob überhaupt - das ist in AWL im Prinzip genauso (das hat Thomas aber auch sehr schön ausgeführt).
 
Zuletzt bearbeitet:
Aargh, hast völlig Recht mit 1) und 2)

Was ich geschrieben habe gilt für SCL: DBx.DBy, denn das ist ein Byte.

DBx.DBDy gibt es in SCL überhaupt nicht.
Als Größenpräfix gibt es in SCL nur DX (Typ BOOL), DB (Typ BYTE), DW (Typ WORD) und DD (Typ DWORD).

Aber zu 3)
Wenn du auf der linken Seite der Zuweisung schreibst:
DBx.DDy dann ist der Typ DWORD. Woher soll der Übersetzer wissen dass du dort einen DINT haben willst.

Am sinnvollsten wäre es darum, dem DB und der Variable ein passendes Symbol und einem passenden Datentyp zu geben, und dann symbolisch zu programmieren.

Was DINT_TO_DWORD macht steht in der Doku zu SCL:
"Übernahme des Bitstrings"
D.h. das Bitmuster das 198 als DINT hat, wird 1:1 in DWORD übernommen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ähh ...
Ich fand die Erklärung, die Thomas hier geschrieben hat, eigentlich sehr umfassend und gut - vielleicht sogar die Beste dazu, die ich je gelesen habe. Ich wüßte dem bei besten Willen nichts mehr hinzuzufügen.

Gruß
Larry

Das ist sicherlich absolut richtig. Sorry, ich versuche mich einzulesen aber momentan verstehe ich es überhaupt nicht!

Es fängt schon damit an, dass SCL bei mir nicht meckert, egal ob ich

DB17.DBD14 := DINT_TO_DWORD( DINT#198 );

oder

DB17.DD14 := DINT_TO_DWORD( DINT#198 );

schreibe.

Beim Übersetzen erhalte ich keinen Fehler!

Und wie gesagt, der DB verlangt den Typ DINT und wir laden doch jetzt die Zahl 198 als DWORD... oder stimmt das auch nicht?
 
Zuletzt bearbeitet:
Es fängt schon damit an, dass SCL bei mir nicht meckert, egal ob ich

DB17.DBD14 := DINT_TO_DWORD( DINT#198 );

oder

DB17.DD14 := DINT_TO_DWORD( DINT#198 );

schreibe.

Beim Übersetzen erhalte ich keinen Fehler!

Tatsache, stimmt sogar. Hab ich noch garnicht gesehen.
Dann hält sich der Compiler nicht an seine eigene Spezifikation.

Ich würde es aber so verwenden wie es in der Doku steht, sonst funktioniert das womöglich nach einem Update nicht mehr (wenn das Programm der Dokumentation angepasst wird).
 
Aber zu 3)
Wenn du auf der linken Seite der Zuweisung schreibst:
DBx.DDy dann ist der Typ DWORD. Woher soll der Übersetzer wissen dass du dort einen DINT haben willst.

Am sinnvollsten wäre es darum, dem DB und der Variable ein passendes Symbol und einem passenden Datentyp zu geben, und dann symbolisch zu programmieren.

Was DINT_TO_DWORD macht steht in der Doku zu SCL:
"Übernahme des Bitstrings"
D.h. das Bitmuster das 198 als DINT hat, wird 1:1 in DWORD übernommen.

Ok, das verstehe ich. Aber wir wollen doch links eigentlich DINT (wegen Datentyp in DB) haben und nicht DWORD.

Warum kommt der DB dann damit dennoch zurecht?
 
Zurück
Oben