Konvertierung INT_TO_DINT

der_NooB

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

ich bin neu in CODESYS und ST und komme aus S7. Ich lerne die Software und die Sprache gerade kennen. Bitte seid nicht böse auf mich🥲

also ich probiere eigentlich was einfaches:
ich habe als Bezeichnern
TotalWeight: INT;
Weight1: INT;
Weight2: INT;

und dann im Programm will ich es ganz einfach auf DINT konvertiere, aber geht nicht, was mich eigentlich wundert
TotalWeight := INT_TO_DINT (Weight1) + (Weight2);

danke im voraus
 
Zuviel Werbung?
-> Hier kostenlos registrieren
"Das habe ich tatsächlich gemacht, aber warum brauche ich dann die Konvertierung?"
INT_TO_DINT
soweit ich mich erinnern kann bei S7 ging es so

wenn ich TotalWeight als DINT deklariere dann klappt mit oder ohne INT_TO_DINT
 
Wenn Du zwei INT addierst und damit der Maximalbereich eines INT überschritten wird, dann klappt es natürlich nicht.

Also mußt Du TotalWeight als DINT deklarieren, damit die Zahl "reinpaßt".

Dazu muß aber wenigstens eine Summand ein DINT sein, sonst addiert er nur 2 INT miteinander und es kommt zum Überlauf. Dabei ist es irrelevant, ob die aufnehmende Variable vom Typ DINT ist.
Indem Du also Weight1 explizit in einen DINT konvertierst, wird Weight2 implizit auch zu einem DINT. Nun addierst Du zwei DINT miteinander, das Ergebnis kannst Du dem TotalWeight zuweisen.

Sofern TotalWeight kein DINT ist, ist das Ergebnis Weight1+Weight2 zwar intern korrekt, bei der Zuweisung wird aber ein 32Bit-Wert in eine 16Bit-Variable gespeichert und es gehen Informationen verloren.
 
Am saubersten wäre es tatsächlich so:
Code:
TotalWeight := INT_TO_DINT(Weight1) + INT_TO_DINT(Weight2);
Damit ist alles DINT und es findet keine implizite Konvertierung statt. Implizite Konvertierungen sollte man meiden, da nie ganz klar ist, was im Hintergrund passiert und ob das dem entspricht was man möchte/erwartet.
Ich kann jetzt nur für TwinCAT sprechen, dort wird zur Ablage von Zwischenergebnissen immer die größte Variante der beteiligten Variablen verwendet. Hier wäre das bei einem 32Bit System DINT und bei einem 64-Bit System LINT. Theoretisch würde da die Addition funktionieren, aber es würde am Ende halt auch wieder eine implizite Konvertierung stattfinden, die man vermeiden sollte.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn Du zwei INT addierst und damit der Maximalbereich eines INT überschritten wird, dann klappt es natürlich nicht.

Also mußt Du TotalWeight als DINT deklarieren, damit die Zahl "reinpaßt".

Dazu muß aber wenigstens eine Summand ein DINT sein, sonst addiert er nur 2 INT miteinander und es kommt zum Überlauf. Dabei ist es irrelevant, ob die aufnehmende Variable vom Typ DINT ist.
Indem Du also Weight1 explizit in einen DINT konvertierst, wird Weight2 implizit auch zu einem DINT. Nun addierst Du zwei DINT miteinander, das Ergebnis kannst Du dem TotalWeight zuweisen.

Sofern TotalWeight kein DINT ist, ist das Ergebnis Weight1+Weight2 zwar intern korrekt, bei der Zuweisung wird aber ein 32Bit-Wert in eine 16Bit-Variable gespeichert und es gehen Informationen verloren.
Achso

Das Heißt, wenn ich INT_TO_DINT verwende, bezieht es sich nicht auf die aufnehmende Variable, sondern auf die Operanden. ok

das hat immer noch Weight1 und 2 nicht u DINT konvertiert.
ich komme durcheinander ehrlich gesagt :(


dankeschön für deine Hilfe
 

Anhänge

  • Screenshot 2024-04-16 141256.png
    Screenshot 2024-04-16 141256.png
    57,1 KB · Aufrufe: 11
Nein, Du hast sie ja als INT angelegt, das kannst Du während der Laufzeit nicht verändern. Nur für den Moment der Rechenoperation sagst Du dem Programm "tu mal so als ob das DINT-Variablen wären".

Wenn Du in den beiden Variablen größere Werte speichern willst, dann mußt Du sie auch als DINT anlegen.

Um das mal bildlich zu machen: Du hast sie als 200ml-Gläser (INT) angelegt. Wenn beide voll sind, kannst Du die Addition nicht in einem 200ml-Glas speichern, Du brauchst die 500ml-Karaffe (DINT). Beim Zusammenschütten kannst Du so tun, als ob Du zwei Karaffen addierst (INT_TO_DINT) und in eine dritte schüttest, dadurch ändert sich aber nicht, daß Du doch nur 200ml-Gläser in der Hand hast.

Und wie @oliver.tonn schon sagte: Um es sauber und transparent zu machen, solltest Du Weight2 auch explizit mit INT_TO_DINT konvertieren.

Oder aber Du deklarierst beide sofort als DINT.
 
also ich probiere eigentlich was einfaches:
ich habe als Bezeichnern
TotalWeight: INT;
Weight1: INT;
Weight2: INT;

und dann im Programm will ich es ganz einfach auf DINT konvertiere, aber geht nicht, was mich eigentlich wundert
TotalWeight := INT_TO_DINT (Weight1) + (Weight2);
...
soweit ich mich erinnern kann bei S7 ging es so
Das funktioniert auch bei S7 so nicht, weil Weight1 explizit zu DINT gewandelt wird und damit nicht mehr in den INT TotalWeight passt.
Das, was die Kollegen hier vor alles erklärt haben, gilt alles genau so auch für S7.
🤷‍♂️
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das funktioniert auch bei S7 so nicht, weil Weight1 explizit zu DINT gewandelt wird und damit nicht mehr in den INT TotalWeight passt.
Das, was die Kollegen hier vor alles erklärt haben, gilt alles genau so auch für S7.
🤷‍♂️
ich habe leider 0 Erfahrung gemacht, ich habe es nur gelernt mit Tia-Portal und WinCc.
und jzt muss ich mit Codesys arbeiten, deswegen bin ich dabei es zu besser zu verstehen, damit ich an dem Programm was ändern kann
danke
 
Nein, Du hast sie ja als INT angelegt, das kannst Du während der Laufzeit nicht verändern. Nur für den Moment der Rechenoperation sagst Du dem Programm "tu mal so als ob das DINT-Variablen wären".

Wenn Du in den beiden Variablen größere Werte speichern willst, dann mußt Du sie auch als DINT anlegen.

Um das mal bildlich zu machen: Du hast sie als 200ml-Gläser (INT) angelegt. Wenn beide voll sind, kannst Du die Addition nicht in einem 200ml-Glas speichern, Du brauchst die 500ml-Karaffe (DINT). Beim Zusammenschütten kannst Du so tun, als ob Du zwei Karaffen addierst (INT_TO_DINT) und in eine dritte schüttest, dadurch ändert sich aber nicht, daß Du doch nur 200ml-Gläser in der Hand hast.

Und wie @oliver.tonn schon sagte: Um es sauber und transparent zu machen, solltest Du Weight2 auch explizit mit INT_TO_DINT konvertieren.

Oder aber Du deklarierst beide sofort als DINT.
vielen dank für die Ausführliche Erklärung.
ich habe es mehr mal gelesen 😪

und eine letzte frage habe ich noch, was nutzt mir es wenn die Variable so tun als ob die DINT, wenn die mir am Ende eh den 16BIT geben oder bearbeiten werden.

Wann nutzt ihr das überhaupt ?
 
Es nutzt Dir, wenn Du zwei kleine Variablen addiert in eine große speichern möchtest.
Damit die Addition überhaupt funktioniert und nicht an sich bereits einen Überlauf während der Berechnung produziert, mußt Du die erst einmal vorübergehend in DINT konvertieren, damit sie Addition korrekt funktioniert und Du das Ergebnis in einem DINT speichern kannst.

Deutlicher wird es ggf. bei komplexeren Rechnungen:

TotalWeight := Weight1 / Weight2 * 100;
Wenn Du hier nur mit INT rechnest, ergibt das beispielsweise:
Weight1 = 100;
Weight2 = 200;
TotalWeight = 0; --> 100/200 = 0.5, kann nicht gespeichert werden = 0

Wenn Du das korrekt berechnen möchtest, kannst Du während der Rechnung z.B. in REAL konvertieren:
TotalWeight := INT_TO_REAL(Weight1) / INT_TO_REAL(Weight2) * 100.0;
Hier ergibt sich dann für TotalWeight = 50.

Du nutzt also andere Datentypen, weil Du mit den gegebenen nicht korrekt rechnen kannst.
Die eigentliche Variable wird dadurch aber nicht verändert.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
vielen dank für die Ausführliche Erklärung.
ich habe es mehr mal gelesen 😪

und eine letzte frage habe ich noch, was nutzt mir es wenn die Variable so tun als ob die DINT, wenn die mir am Ende eh den 16BIT geben oder bearbeiten werden.

Wann nutzt ihr das überhaupt ?
Um zwei Integer Variablen im vollen Umfang addieren zu können ohne einen Überlauf zu riskieren muss das Ergebnis in ein DINT abgelegt werden. Bei mehr als nur einer Berechnung kann die Ablage des Zwischenergebnisses durch die SPS hier zum Problem werden, wie ich aus eigener Erfahrung gelernt habe. Daher sollten alle Zahlen vor der Berechnung auf den Typ der Zielvariablen explizit konvertiert werden. Es gibt zwar auch die implizite Konvertierung, aber die ist mit Vorsicht zu genießen, da man auf diese keinen Einfluss hat.
Ein anderes Beispiel wäre die Skalierung eines Analogwertes, hier wird über eine Formel ein Integerwert in eine Realzahl umgerechnet, auch hier sollte der Integerwert erst in eine Realzahl gewandelt werden ehe mit der Berechnung begonnen wird.
Schau Dir mal diesen Beitrag an, dann wird Dir das Ganze vielleicht klarer.
 
ich habe es nur gelernt mit Tia-Portal
Bei TIA Portal oder Step7 Classic kommt nicht so eine schöne Meldung wie bei dir.
1713272620537.png

Nur weil keine Meldung kommt, bedeutet das aber nicht, dass alles passt. Bei TIA / Step7 geht man noch von der Eigenverantwortung des Programmierers aus. D.h. es kann zu einem Überlauf kommen und bei dem Rechenergebniss kommt einfach nur "Müll" raus.
 
Es nutzt Dir, wenn Du zwei kleine Variablen addiert in eine große speichern möchtest.
Damit die Addition überhaupt funktioniert und nicht an sich bereits einen Überlauf während der Berechnung produziert, mußt Du die erst einmal vorübergehend in DINT konvertieren, damit sie Addition korrekt funktioniert und Du das Ergebnis in einem DINT speichern kannst.

Deutlicher wird es ggf. bei komplexeren Rechnungen:

TotalWeight := Weight1 / Weight2 * 100;
Wenn Du hier nur mit INT rechnest, ergibt das beispielsweise:
Weight1 = 100;
Weight2 = 200;
TotalWeight = 0; --> 100/200 = 0.5, kann nicht gespeichert werden = 0

Wenn Du das korrekt berechnen möchtest, kannst Du während der Rechnung z.B. in REAL konvertieren:
TotalWeight := INT_TO_REAL(Weight1) / INT_TO_REAL(Weight2) * 100.0;
Hier ergibt sich dann für TotalWeight = 50.

Du nutzt also andere Datentypen, weil Du mit den gegebenen nicht korrekt rechnen kannst.
Die eigentliche Variable wird dadurch aber nicht verändert.
Um zwei Integer Variablen im vollen Umfang addieren zu können ohne einen Überlauf zu riskieren muss das Ergebnis in ein DINT abgelegt werden. Bei mehr als nur einer Berechnung kann die Ablage des Zwischenergebnisses durch die SPS hier zum Problem werden, wie ich aus eigener Erfahrung gelernt habe. Daher sollten alle Zahlen vor der Berechnung auf den Typ der Zielvariablen explizit konvertiert werden. Es gibt zwar auch die implizite Konvertierung, aber die ist mit Vorsicht zu genießen, da man auf diese keinen Einfluss hat.
Ein anderes Beispiel wäre die Skalierung eines Analogwertes, hier wird über eine Formel ein Integerwert in eine Realzahl umgerechnet, auch hier sollte der Integerwert erst in eine Realzahl gewandelt werden ehe mit der Berechnung begonnen wird.
Schau Dir mal diesen Beitrag an, dann wird Dir das Ganze vielleicht klarer.
Ihr seid der Hammer! Vielen lieben Dank ^_^
Das hat mir enorm geholfen <3
 
Zurück
Oben